* 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>
211 lines
8.3 KiB
Python
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)
|