diff --git a/meta-ti-test/recipes-graphics/libsdl2/libsdl2-ti.inc b/meta-ti-test/recipes-graphics/libsdl2/libsdl2-ti.inc
new file mode 100644
index 00000000..33ff0632
--- /dev/null
+++ b/meta-ti-test/recipes-graphics/libsdl2/libsdl2-ti.inc
@@ -0,0 +1,5 @@
+EXTRA_OECMAKE += "-DSDL_TESTS=ON \
+                  -DSDL_INSTALL_TESTS=ON \
+                 "
+PACKAGE_BEFORE_PN = "${PN}-tests"
+FILES:${PN}-tests += "${libexecdir} ${datadir}/installed-tests/SDL2"
diff --git a/meta-ti-test/recipes-graphics/libsdl2/libsdl2_%.bbappend b/meta-ti-test/recipes-graphics/libsdl2/libsdl2_%.bbappend
new file mode 100644
index 00000000..385aa801
--- /dev/null
+++ b/meta-ti-test/recipes-graphics/libsdl2/libsdl2_%.bbappend
@@ -0,0 +1,4 @@
+LIBSDL2_TI = ""
+LIBSDL2_TI:ti-soc = "libsdl2-ti.inc"
+
+require ${LIBSDL2_TI}
diff --git a/meta-ti-test/recipes-graphics/offscreen-demo/offscreendemo_0.0.1.bb b/meta-ti-test/recipes-graphics/offscreen-demo/offscreendemo_0.0.1.bb
new file mode 100644
index 00000000..6dc0e526
--- /dev/null
+++ b/meta-ti-test/recipes-graphics/offscreen-demo/offscreendemo_0.0.1.bb
@@ -0,0 +1,16 @@
+SUMMARY = "Lightweight Render Example"
+DESCRIPTION = "Lightweight Render Example. Heavily inspired by Eduardo Lima's gpu-playground, this attempts to act as the smallest demo of offscreen rendering."
+
+HOMEPAGE = "https://github.com/TexasInstruments/graphics-tests.git"
+
+SRC_URI = "git://github.com/TexasInstruments/graphics-tests.git;protocol=https;branch=master"
+SRCREV = "eac40e0073cb5f81688aee890e0a67f99678a290"
+
+LICENSE = "CC0-1.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=65d3616852dbf7b1a6d4b53b00626032"
+
+DEPENDS += "virtual/egl virtual/libgles2"
+
+inherit pkgconfig meson features_check
+
+REQUIRED_DISTRO_FEATURES = "opengl"
diff --git a/meta-ti-test/recipes-graphics/piglit/piglit-ti.inc b/meta-ti-test/recipes-graphics/piglit/piglit-ti.inc
new file mode 100644
index 00000000..707ef6a4
--- /dev/null
+++ b/meta-ti-test/recipes-graphics/piglit/piglit-ti.inc
@@ -0,0 +1,32 @@
+# add a config to point piglit at the default install location for deqp tests
+# if they are selected
+
+FILESEXTRAPATHS:prepend := "${THISDIR}/piglit:"
+
+SRC_URI += "file://0001-framework-add-and-use-TestPlaceholder-objects.patch"
+
+PACKAGECONFIG[deqp-gles] = ",,,opengl-es-cts"
+PACKAGECONFIG[deqp-vk] = ",,,vulkan-cts"
+
+do_install:append() {
+    if ${@bb.utils.contains('PACKAGECONFIG', 'deqp-gles', 'true', 'false', d)}; then
+        printf "%s\n" \
+            "[deqp-egl]" \
+            "bin=/usr/lib/opengl-es-cts/deqp-egl" \
+            "[deqp-gles2]" \
+            "bin=/usr/lib/opengl-es-cts/deqp-gles2" \
+            "[deqp-gles3]" \
+            "bin=/usr/lib/opengl-es-cts/deqp-gles3" \
+            "[deqp-gles31]" \
+            "bin=/usr/lib/opengl-es-cts/deqp-gles31" \
+            >> ${D}/${libdir}/piglit/piglit.conf
+    fi
+    if ${@bb.utils.contains('PACKAGECONFIG', 'deqp-vk', 'true', 'false', d)}; then
+        printf "%s\n" \
+            "[deqp-vk]" \
+            "bin=/usr/lib/vulkan-cts/deqp-vk" \
+            "[deqp-vksc]" \
+            "bin=/usr/lib/vulkan-cts/deqp-vksc" \
+            >> ${D}/${libdir}/piglit/piglit.conf
+    fi
+}
diff --git a/meta-ti-test/recipes-graphics/piglit/piglit/0001-framework-add-and-use-TestPlaceholder-objects.patch b/meta-ti-test/recipes-graphics/piglit/piglit/0001-framework-add-and-use-TestPlaceholder-objects.patch
new file mode 100644
index 00000000..26e0b21e
--- /dev/null
+++ b/meta-ti-test/recipes-graphics/piglit/piglit/0001-framework-add-and-use-TestPlaceholder-objects.patch
@@ -0,0 +1,128 @@
+From 2803263ccf460ced705fd4da589e2f09e3ec89d7 Mon Sep 17 00:00:00 2001
+From: Randolph Sapp <rs@ti.com>
+Date: Wed, 13 Aug 2025 17:52:42 -0500
+Subject: [PATCH] framework: add and use TestPlaceholder objects
+
+The actual Test classes are not that big, but with deqp-vk creating
+around 2800 instances currently, we quickly consume around 3GB of ram
+before beginning any tests. Given that a lot of these objects may not
+even be used, we can reduce memory overhead by using a placeholder
+namedtuple that is expanded to a full Test instance when requested from
+the TestDict class. This cuts the initial memory usage back to 1.6 GB.
+
+This does add a small lookup penalty, but given the lookup penalty is
+still smaller that the time it takes to create an instance of a Test, it
+results in a net improvement for most subsets of deqp tests. Not to
+mention this penalty can be split between threads, unlike previously
+when it was occurring in the single-threadded profile creation step.
+
+The following data was collected using a subset of 3151 deqp-vk tests:
+
+Threads   Test Execution Time (s)   TestPlaceholder Execution Time (s)
+-------   -----------------------   ----------------------------------
+1         2613.93                   2599.95
+8          413.31                    400.01
+32         299.75                    286.73
+
+Upstream-Status: Submitted [https://gitlab.freedesktop.org/mesa/piglit/-/merge_requests/1032]
+Signed-off-by: Randolph Sapp <rs@ti.com>
+---
+ framework/profile.py   | 23 ++++++++++++++++++-----
+ framework/test/base.py |  3 +++
+ framework/test/deqp.py |  4 ++--
+ 3 files changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/framework/profile.py b/framework/profile.py
+index 678e9d87c..969e0032e 100644
+--- a/framework/profile.py
++++ b/framework/profile.py
+@@ -45,7 +45,7 @@ from framework import grouptools, exceptions, status
+ from framework.dmesg import get_dmesg
+ from framework.log import LogManager
+ from framework.monitoring import Monitoring
+-from framework.test.base import Test, DummyTest
++from framework.test.base import Test, DummyTest, TestPlaceholder
+ from framework.test.piglit_test import (
+     PiglitCLTest, PiglitGLTest, ASMParserTest, BuiltInConstantsTest,
+     CLProgramTester, VkRunnerTest, ROOT_DIR,
+@@ -135,9 +135,9 @@ class TestDict(collections.abc.MutableMapping):
+                 "TestDict keys must be strings, but was {}".format(type(key)))
+
+         # Values should either be more Tests
+-        if not isinstance(value, Test):
++        if not (isinstance(value, Test) or isinstance(value, TestPlaceholder)):
+             raise exceptions.PiglitFatalError(
+-                "TestDict values must be a Test, but was a {}".format(
++                "TestDict values must be a Test or TestPlaceholder, but was a {}".format(
+                     type(value)))
+
+         # This must be lowered before the following test, or the test can pass
+@@ -164,8 +164,21 @@ class TestDict(collections.abc.MutableMapping):
+         self.__container[key] = value
+
+     def __getitem__(self, key):
+-        """Lower the value before returning."""
+-        return self.__container[key.lower()]
++        """Lower the value before returning. Remove placeholders as needed."""
++        item = self.__container[key.lower()]
++        if isinstance(item, TestPlaceholder):
++            try:
++                real_item = item.test_class(item.test_name)
++            except TypeError:
++                raise exceptions.PiglitFatalError(
++                    "Unable to expand the TestPlaceholder for the class: {}\n"
++                    "This was associated with the following key: {}".format(
++                        type(item), key
++                    )
++                )
++            self.__container[key.lower()] = real_item
++            return real_item
++        return item
+
+     def __delitem__(self, key):
+         """Lower the value before returning."""
+diff --git a/framework/test/base.py b/framework/test/base.py
+index 430064b9b..0efa38336 100644
+--- a/framework/test/base.py
++++ b/framework/test/base.py
+@@ -24,6 +24,7 @@
+ """ Module provides a base class for Tests """
+
+ import abc
++import collections
+ import copy
+ import errno
+ import itertools
+@@ -97,6 +98,8 @@ def is_crash_returncode(returncode):
+         return returncode < 0
+
+
++TestPlaceholder = collections.namedtuple('TestPlaceholder', ['test_class', 'test_name'])
++
+ class Test(metaclass=abc.ABCMeta):
+     """ Abstract base class for Test classes
+
+diff --git a/framework/test/deqp.py b/framework/test/deqp.py
+index 849ffbd96..ccfeaeff2 100644
+--- a/framework/test/deqp.py
++++ b/framework/test/deqp.py
+@@ -26,7 +26,7 @@ import subprocess
+ from framework import core, grouptools, exceptions
+ from framework import options
+ from framework.profile import TestProfile
+-from framework.test.base import Test, is_crash_returncode, TestRunError
++from framework.test.base import Test, is_crash_returncode, TestRunError, TestPlaceholder
+
+ __all__ = [
+     'DEQPBaseTest',
+@@ -56,7 +56,7 @@ def make_profile(test_list, test_class):
+     for testname in test_list:
+         # deqp uses '.' as the testgroup separator.
+         piglit_name = testname.replace('.', grouptools.SEPARATOR)
+-        profile.test_list[piglit_name] = test_class(testname)
++        profile.test_list[piglit_name] = TestPlaceholder(test_class, testname)
+
+     return profile
+
+--
+2.50.1
diff --git a/meta-ti-test/recipes-graphics/piglit/piglit_%.bbappend b/meta-ti-test/recipes-graphics/piglit/piglit_%.bbappend
new file mode 100644
index 00000000..d93e5d48
--- /dev/null
+++ b/meta-ti-test/recipes-graphics/piglit/piglit_%.bbappend
@@ -0,0 +1,4 @@
+PIGLIT_TI = ""
+PIGLIT_TI:ti-soc = "piglit-ti.inc"
+
+require ${PIGLIT_TI}
