Files
OpenColorIO/tests/python/GpuShaderDescTest.py
929d5364c4 Exposed option to allow/disallow 1D texture GPU resources for 1D LUTs. (#1762)
* Exposed option to allow/disallow 1D texture GPU resources for 1D LUTs.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* New API to get or add 1D LUT textures with the specified dimensions.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Fix errors relevealed by CIS related to texture dimension API change.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Update gpu shader tests away from now deprecated get/add texture functions.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Converted deprecated get/add texture functions from pure virtual to virtual.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Commenting out unused parameters on deprecated functions to mitigate warnings.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Addressing review notes.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Updated python addTexture/getTextures test with latest interface.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Further update python and metal samples to new texture dimensions API.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Improvements: moved default deprecated implementations to base classes, avoided asserts, fixed typo and naming.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Follow spacing/formatting convention arguments.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Removed the original addTexture and getTexture methods.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

---------

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>
Co-authored-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
2023-08-26 00:27:14 -04:00

211 lines
8.3 KiB
Python

# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenColorIO Project.
import unittest
import logging
logger = logging.getLogger(__name__)
try:
import numpy as np
except ImportError:
logger.warning(
"NumPy could not be imported. "
"Test case will lack significant coverage!"
)
np = None
import PyOpenColorIO as OCIO
from UnitTestUtils import STRING_TYPES
class GpuShaderDescTest(unittest.TestCase):
def test_shader_creator_interface(self):
desc = OCIO.GpuShaderDesc.CreateShaderDesc()
desc.setLanguage(OCIO.GPU_LANGUAGE_GLSL_1_3)
self.assertEqual(OCIO.GPU_LANGUAGE_GLSL_1_3, desc.getLanguage())
desc.setFunctionName("foo123")
self.assertEqual("foo123", desc.getFunctionName())
desc.finalize()
self.assertEqual("glsl_1.3 foo123 ocio outColor 0 6001c324468d497f99aa06d3014798d8",
desc.getCacheID())
def test_uniform(self):
# Test dynamic exposure and gamma
config = OCIO.Config()
tr = OCIO.ExposureContrastTransform(dynamicExposure=True,
dynamicGamma=True)
proc = config.getProcessor(tr)
desc = OCIO.GpuShaderDesc.CreateShaderDesc()
gpu_proc = proc.getDefaultGPUProcessor()
gpu_proc.extractGpuShaderInfo(desc)
uniforms = desc.getUniforms()
self.assertEqual(len(uniforms), 2)
self.assertEqual(uniforms[0][0], "ocio_exposure_contrast_exposureVal")
self.assertEqual(uniforms[0][1].type, OCIO.UNIFORM_DOUBLE)
self.assertEqual(uniforms[0][1].getDouble(), 0.0)
self.assertEqual(uniforms[1][0], "ocio_exposure_contrast_gammaVal")
self.assertEqual(uniforms[1][1].type, OCIO.UNIFORM_DOUBLE)
self.assertEqual(uniforms[1][1].getDouble(), 1.0)
# Can dynamically modify uniforms
dyn_exposure = desc.getDynamicProperty(OCIO.DYNAMIC_PROPERTY_EXPOSURE)
dyn_exposure.setDouble(2.0)
self.assertEqual(uniforms[0][1].getDouble(), 2.0)
dyn_gamma = desc.getDynamicProperty(OCIO.DYNAMIC_PROPERTY_GAMMA)
dyn_gamma.setDouble(0.5)
self.assertEqual(uniforms[1][1].getDouble(), 0.5)
# Uniforms are present in shader src
text = desc.getShaderText()
self.assertEqual(text.count("uniform float"), 2)
# Iterates uniform name and data
for name, uniform_data in uniforms:
self.assertIsInstance(name, STRING_TYPES)
self.assertIsInstance(uniform_data, OCIO.GpuShaderDesc.UniformData)
def test_vector_uniform(self):
if not np:
logger.warning("NumPy not found. Skipping test!")
return
# Test dynamic GradingRGBCurve
a_curve = OCIO.GradingBSplineCurve([1.0, 2.0, 3.0, 4.0])
rgb_curve = OCIO.GradingRGBCurve(a_curve, a_curve, a_curve, a_curve)
tr = OCIO.GradingRGBCurveTransform(values=rgb_curve,
dynamic=True)
config = OCIO.Config()
proc = config.getProcessor(tr)
desc = OCIO.GpuShaderDesc.CreateShaderDesc()
gpu_proc = proc.getDefaultGPUProcessor()
gpu_proc.extractGpuShaderInfo(desc)
uniforms = desc.getUniforms()
self.assertEqual(len(uniforms), 5)
self.assertEqual(uniforms[0][0], "ocio_grading_rgbcurve_knotsOffsets")
self.assertEqual(uniforms[0][1].type, OCIO.UNIFORM_VECTOR_INT)
vector_int = uniforms[0][1].getVectorInt()
self.assertTrue(isinstance(vector_int, np.ndarray))
self.assertEqual(vector_int.dtype, np.intc)
self.assertTrue(np.array_equal(
vector_int,
np.array([0, 2, 2, 2, 4, 2, 6, 2],
dtype=np.intc))
)
self.assertEqual(uniforms[1][0], "ocio_grading_rgbcurve_knots")
self.assertEqual(uniforms[1][1].type, OCIO.UNIFORM_VECTOR_FLOAT)
vector_float = uniforms[1][1].getVectorFloat()
self.assertTrue(isinstance(vector_float, np.ndarray))
self.assertEqual(vector_float.dtype, np.float32)
self.assertTrue(np.array_equal(
vector_float,
np.array([1.0, 3.0, 1.0, 3.0, 1.0, 3.0, 1.0, 3.0],
dtype=np.float32))
)
# Can dynamically modify uniforms
b_curve = OCIO.GradingBSplineCurve([5.0, 6.0, 7.0, 8.0])
dyn_rgb_curve = desc.getDynamicProperty(
OCIO.DYNAMIC_PROPERTY_GRADING_RGBCURVE
)
dyn_rgb_curve.setGradingRGBCurve(
OCIO.GradingRGBCurve(b_curve, b_curve, b_curve, b_curve)
)
self.assertTrue(np.array_equal(
uniforms[1][1].getVectorFloat(),
np.array([5.0, 7.0, 5.0, 7.0, 5.0, 7.0, 5.0, 7.0],
dtype=np.float32))
)
def test_texture(self):
# Test addTexture() & getTextures().
if not np:
logger.warning("NumPy not found. Skipping test!")
return
desc = OCIO.GpuShaderDesc.CreateShaderDesc()
buf = np.array([0,0.1,0.2,0.3,0.4,0.5]).astype(np.float32)
desc.addTexture('tex', 'sampler', 2, 3,
OCIO.GpuShaderDesc.TEXTURE_RED_CHANNEL,
OCIO.GpuShaderDesc.TEXTURE_2D,
OCIO.INTERP_DEFAULT, buf)
desc.addTexture(textureName='tex2', samplerName='sampler2', width=3, height=2,
channel=OCIO.GpuShaderDesc.TEXTURE_RED_CHANNEL,
dimensions=OCIO.GpuShaderDesc.TEXTURE_2D,
interpolation=OCIO.INTERP_DEFAULT, values=buf)
textures = desc.getTextures()
self.assertEqual(len(textures), 2)
t1 = next(textures)
self.assertEqual(t1.textureName, 'tex')
self.assertEqual(t1.samplerName, 'sampler')
self.assertEqual(t1.width, 2)
self.assertEqual(t1.height, 3)
self.assertEqual(t1.channel, OCIO.GpuShaderDesc.TEXTURE_RED_CHANNEL)
self.assertEqual(t1.interpolation, OCIO.INTERP_DEFAULT)
v1 = t1.getValues()
self.assertEqual(len(v1), 6)
self.assertEqual(v1[0], np.float32(0))
self.assertEqual(v1[1], np.float32(0.1))
self.assertEqual(v1[2], np.float32(0.2))
self.assertEqual(v1[3], np.float32(0.3))
self.assertEqual(v1[4], np.float32(0.4))
self.assertEqual(v1[5], np.float32(0.5))
t2 = next(textures)
self.assertEqual(t2.textureName, 'tex2')
self.assertEqual(t2.samplerName, 'sampler2')
self.assertEqual(t2.width, 3)
self.assertEqual(t2.height, 2)
self.assertEqual(t2.channel, OCIO.GpuShaderDesc.TEXTURE_RED_CHANNEL)
self.assertEqual(t2.interpolation, OCIO.INTERP_DEFAULT)
v2 = t2.getValues()
self.assertEqual(len(v2), 6)
self.assertEqual(v2[0], np.float32(0))
self.assertEqual(v2[1], np.float32(0.1))
self.assertEqual(v2[2], np.float32(0.2))
self.assertEqual(v2[3], np.float32(0.3))
self.assertEqual(v2[4], np.float32(0.4))
self.assertEqual(v2[5], np.float32(0.5))
def test_texture_3d(self):
# Test add3DTexture() & get3DTextures().
if not np:
logger.warning("NumPy not found. Skipping test!")
return
desc = OCIO.GpuShaderDesc.CreateShaderDesc()
buf = np.linspace(0, 1, num=8*3).astype(np.float32)
bufTest1 = buf[3]
desc.add3DTexture('tex', 'sampler', 2,
OCIO.INTERP_DEFAULT, buf)
buf = np.linspace(0, 1, num=27*3).astype(np.float32)
bufTest2 = buf[42]
desc.add3DTexture('tex2', 'sampler2', 3,
OCIO.INTERP_DEFAULT, buf)
textures = desc.get3DTextures()
self.assertEqual(len(textures), 2)
t1 = next(textures)
self.assertEqual(t1.textureName, 'tex')
self.assertEqual(t1.samplerName, 'sampler')
self.assertEqual(t1.edgeLen, 2)
self.assertEqual(t1.interpolation, OCIO.INTERP_DEFAULT)
v1 = t1.getValues()
self.assertEqual(len(v1), 3*8)
self.assertEqual(v1[3], bufTest1)
t2 = next(textures)
self.assertEqual(t2.textureName, 'tex2')
self.assertEqual(t2.samplerName, 'sampler2')
self.assertEqual(t2.edgeLen, 3)
self.assertEqual(t2.interpolation, OCIO.INTERP_DEFAULT)
v2 = t2.getValues()
self.assertEqual(len(v2), 3*27)
self.assertEqual(v2[42], bufTest2)