Skip to content

Commit f1da843

Browse files
author
Yiyun Wang
committed
First draft
1 parent 6dc7fb4 commit f1da843

File tree

13 files changed

+108
-25
lines changed

13 files changed

+108
-25
lines changed

docs/api/python/frozen/pyopencolorio_gpushaderdesc.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195
:module: PyOpenColorIO
196196

197197

198-
.. py:method:: GpuShaderDesc.add3DTexture(self: PyOpenColorIO.GpuShaderDesc, textureName: str, samplerName: str, edgeLen: int, interpolation: PyOpenColorIO.Interpolation, values: buffer) -> None
198+
.. py:method:: GpuShaderDesc.add3DTexture(self: PyOpenColorIO.GpuShaderDesc, textureName: str, samplerName: str, edgeLen: int, channel: PyOpenColorIO.GpuShaderCreator.TextureType, interpolation: PyOpenColorIO.Interpolation, values: buffer) -> None
199199
:module: PyOpenColorIO
200200

201201
Add a 3D texture with RGB channel type.

include/OpenColorIO/OpenColorIO.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3267,7 +3267,8 @@ class OCIOEXPORT GpuShaderCreator
32673267
enum TextureType
32683268
{
32693269
TEXTURE_RED_CHANNEL, ///< Only need a red channel texture
3270-
TEXTURE_RGB_CHANNEL ///< Need a RGB texture
3270+
TEXTURE_RGB_CHANNEL, ///< Need a RGB texture
3271+
TEXTURE_RGBA_CHANNEL ///< Need a RGBA texture
32713272
};
32723273

32733274
/**
@@ -3304,6 +3305,7 @@ class OCIOEXPORT GpuShaderCreator
33043305
virtual void add3DTexture(const char * textureName,
33053306
const char * samplerName,
33063307
unsigned edgelen,
3308+
TextureType channel,
33073309
Interpolation interpolation,
33083310
const float * values) = 0;
33093311

@@ -3551,6 +3553,7 @@ class OCIOEXPORT GpuShaderDesc : public GpuShaderCreator
35513553
const char *& textureName,
35523554
const char *& samplerName,
35533555
unsigned & edgelen,
3556+
TextureType& channel,
35543557
Interpolation & interpolation) const = 0;
35553558
virtual void get3DTextureValues(unsigned index, const float *& values) const = 0;
35563559

src/OpenColorIO/GpuShader.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ class PrivateImpl
246246
void add3DTexture(const char * textureName,
247247
const char * samplerName,
248248
unsigned edgelen,
249+
GenericGpuShaderDesc::TextureType channel,
249250
Interpolation interpolation,
250251
const float * values)
251252
{
@@ -258,7 +259,7 @@ class PrivateImpl
258259
}
259260

260261
Texture t(textureName, samplerName, edgelen, edgelen, edgelen,
261-
GpuShaderDesc::TEXTURE_RGB_CHANNEL, 3,
262+
channel, 3,
262263
interpolation, values);
263264
m_textures3D.push_back(t);
264265
}
@@ -267,6 +268,7 @@ class PrivateImpl
267268
const char *& textureName,
268269
const char *& samplerName,
269270
unsigned & edgelen,
271+
GenericGpuShaderDesc::TextureType& channel,
270272
Interpolation & interpolation) const
271273
{
272274
if(index >= m_textures3D.size())
@@ -281,6 +283,7 @@ class PrivateImpl
281283
textureName = t.m_textureName.c_str();
282284
samplerName = t.m_samplerName.c_str();
283285
edgelen = t.m_width;
286+
channel = t.m_type;
284287
interpolation = t.m_interp;
285288
}
286289

@@ -520,19 +523,21 @@ unsigned GenericGpuShaderDesc::getNum3DTextures() const noexcept
520523
void GenericGpuShaderDesc::add3DTexture(const char * textureName,
521524
const char * samplerName,
522525
unsigned edgelen,
526+
TextureType channel,
523527
Interpolation interpolation,
524528
const float * values)
525529
{
526-
getImplGeneric()->add3DTexture(textureName, samplerName, edgelen, interpolation, values);
530+
getImplGeneric()->add3DTexture(textureName, samplerName, edgelen, channel, interpolation, values);
527531
}
528532

529533
void GenericGpuShaderDesc::get3DTexture(unsigned index,
530534
const char *& textureName,
531535
const char *& samplerName,
532536
unsigned & edgelen,
537+
TextureType & channel,
533538
Interpolation & interpolation) const
534539
{
535-
getImplGeneric()->get3DTexture(index, textureName, samplerName, edgelen, interpolation);
540+
getImplGeneric()->get3DTexture(index, textureName, samplerName, edgelen, channel, interpolation);
536541
}
537542

538543
void GenericGpuShaderDesc::get3DTextureValues(unsigned index, const float *& values) const

src/OpenColorIO/GpuShader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,14 @@ class GenericGpuShaderDesc : public GpuShaderDesc
7171
void add3DTexture(const char * textureName,
7272
const char * samplerName,
7373
unsigned edgelen,
74+
TextureType channel,
7475
Interpolation interpolation,
7576
const float * values) override;
7677
void get3DTexture(unsigned index,
7778
const char *& textureName,
7879
const char *& samplerName,
7980
unsigned & edgelen,
81+
TextureType& channel,
8082
Interpolation & interpolation) const override;
8183
void get3DTextureValues(unsigned index, const float *& value) const override;
8284

src/OpenColorIO/GpuShaderUtils.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,29 @@ void AddLinToLogShader(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & st
260260
// Convert "grading log" values to scene-linear.
261261
void AddLogToLinShader(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & st);
262262

263+
// Texture converter from RGB to RGBA
264+
void RGB_to_RGBA(const float* lutValues, int valueCount, std::vector<float>& float4AdaptedLutValues)
265+
{
266+
if(valueCount % 3 != 0)
267+
throw Exception("Value count should be divisible by 3.");
268+
269+
valueCount = valueCount * 4 / 3;
270+
if(lutValues != nullptr)
271+
{
272+
float4AdaptedLutValues.resize(valueCount);
273+
const float *rgbLutValuesIt = lutValues;
274+
float *rgbaLutValuesIt = float4AdaptedLutValues.data();
275+
const float *end = rgbaLutValuesIt + valueCount;
276+
277+
while(rgbaLutValuesIt != end) {
278+
*rgbaLutValuesIt++ = *rgbLutValuesIt++;
279+
*rgbaLutValuesIt++ = *rgbLutValuesIt++;
280+
*rgbaLutValuesIt++ = *rgbLutValuesIt++;
281+
*rgbaLutValuesIt++ = 1.0f;
282+
}
283+
}
284+
}
285+
263286
} // namespace OCIO_NAMESPACE
264287

265288
#endif

src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,22 +160,42 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
160160
// Note: The 1D LUT needs a GPU texture for the Look-up table implementation.
161161
// However, the texture type & content may vary based on the number of channels
162162
// i.e. when all channels are identical a F32 Red GPU texture is enough.
163-
164-
const bool singleChannel = (numChannels == 1);
163+
164+
// When shader language is metal, we want to return a texture in
165+
// RGBA format instead of RGB.
166+
if (shaderCreator ->getLanguage() == GPU_LANGUAGE_MSL_2_0 && numChannels == 3)
167+
{
168+
numChannels = 4;
169+
}
165170

166171
// Adjust LUT texture to allow for correct 2d linear interpolation, if needed.
167172

168173
std::vector<float> values;
169174
values.reserve(width * height * numChannels);
170175

171-
if (singleChannel) // i.e. numChannels == 1.
176+
GpuShaderCreator::TextureType channel;
177+
switch (numChannels)
172178
{
179+
case 1:
173180
CreatePaddedRedChannel(width, height, lutData->getArray().getValues(), values);
174-
}
175-
else
176-
{
181+
channel = GpuShaderCreator::TEXTURE_RED_CHANNEL;
182+
break;
183+
case 3:
177184
CreatePaddedLutChannels(width, height, lutData->getArray().getValues(), values);
178-
}
185+
channel = GpuShaderCreator::TEXTURE_RGB_CHANNEL;
186+
break;
187+
case 4:
188+
std::vector<float> paddedChannels;
189+
values.reserve(width * height * 3);
190+
CreatePaddedLutChannels(width, height, lutData->getArray().getValues(), paddedChannels);
191+
// Insert a place holder alpha channel with value of 1. This is to support RGBA
192+
// texture format for Metal shading language.
193+
RGB_to_RGBA(paddedChannels, width * height * 3, values)
194+
channel = GpuShaderCreator::TEXTURE_RGBA_CHANNEL;
195+
break;
196+
default:
197+
break;
198+
}
179199

180200
// Register the RGB LUT.
181201

@@ -203,8 +223,7 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
203223
GpuShaderText::getSamplerName(name).c_str(),
204224
width,
205225
height,
206-
singleChannel ? GpuShaderCreator::TEXTURE_RED_CHANNEL
207-
: GpuShaderCreator::TEXTURE_RGB_CHANNEL,
226+
channel,
208227
dimensions,
209228
lutData->getConcreteInterpolation(),
210229
&values[0]);

src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "ops/lut3d/Lut3DOpGPU.h"
1111
#include "utils/StringUtils.h"
1212

13-
1413
namespace OCIO_NAMESPACE
1514
{
1615

@@ -38,12 +37,35 @@ void GetLut3DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, ConstLut3DO
3837
{
3938
samplerInterpolation = INTERP_NEAREST;
4039
}
41-
// (Using CacheID here to potentially allow reuse of existing textures.)
42-
shaderCreator->add3DTexture(name.c_str(),
40+
41+
if(shaderCreator->getLanguage() == GPU_LANGUAGE_MSL_2_0){
42+
43+
if(values.size() % 3 != 0) {
44+
throw Exception("3D LUT value count should be divisible by 3.");
45+
}
46+
47+
unsigned edgelen = lutData->getGridSize();
48+
std::vector<float> float4AdaptedLutValues;
49+
RGB_to_RGBA(&lutData->getArray()[0], 3*edgelen*edgelen*edgelen, float4AdaptedLutValues);
50+
51+
shaderCreator->add3DTexture(name.c_str(),
4352
GpuShaderText::getSamplerName(name).c_str(),
44-
lutData->getGridSize(),
53+
edgelen,
54+
GpuShaderCreator::TEXTURE_RGBA_CHANNEL,
4555
samplerInterpolation,
46-
&lutData->getArray()[0]);
56+
float4AdaptedLutValues.data());
57+
}
58+
else
59+
{
60+
// All other languages
61+
// (Using CacheID here to potentially allow reuse of existing textures.)
62+
shaderCreator->add3DTexture(name.c_str(),
63+
GpuShaderText::getSamplerName(name).c_str(),
64+
lutData->getGridSize(),
65+
GpuShaderCreator::TEXTURE_RGB_CHANNEL,
66+
samplerInterpolation,
67+
&lutData->getArray()[0]);
68+
}
4769

4870
{
4971
GpuShaderText ss(shaderCreator->getLanguage());

src/bindings/python/PyGpuShaderDesc.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ void bindPyGpuShaderDesc(py::module & m)
160160
const std::string & textureName,
161161
const std::string & samplerName,
162162
unsigned edgelen,
163+
GpuShaderDesc::TextureType channel,
163164
Interpolation interpolation,
164165
const py::buffer & values)
165166
{
@@ -172,10 +173,11 @@ void bindPyGpuShaderDesc(py::module & m)
172173
self->add3DTexture(textureName.c_str(),
173174
samplerName.c_str(),
174175
edgelen,
176+
channel,
175177
interpolation,
176178
static_cast<float *>(info.ptr));
177179
},
178-
"textureName"_a, "samplerName"_a, "edgeLen"_a, "interpolation"_a, "values"_a,
180+
"textureName"_a, "samplerName"_a, "edgeLen"_a, "channel"_a, "interpolation"_a, "values"_a,
179181
DOC(GpuShaderCreator, add3DTexture))
180182
.def("get3DTextures", [](GpuShaderDescRcPtr & self)
181183
{

src/libutils/oglapphelpers/glsl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,9 @@ void OpenGLBuilder::allocateAllTextures(unsigned startIndex)
319319
const char * textureName = nullptr;
320320
const char * samplerName = nullptr;
321321
unsigned edgelen = 0;
322+
GpuShaderCreator:: TextureType channel = GpuShaderCreator::TextureType::TEXTURE_RGB_CHANNEL;
322323
Interpolation interpolation = INTERP_LINEAR;
323-
m_shaderDesc->get3DTexture(idx, textureName, samplerName, edgelen, interpolation);
324+
m_shaderDesc->get3DTexture(idx, textureName, samplerName, edgelen, channel, interpolation);
324325

325326
if(!textureName || !*textureName
326327
|| !samplerName || !*samplerName

src/libutils/oglapphelpers/metalapp.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,10 @@ vertex VertexOut ColorCorrectionVS(unsigned int vId [[ vertex_id ]])
264264
const char* textureName;
265265
const char* samplerName;
266266
unsigned int edgeLen;
267+
TextureType channel;
267268
Interpolation interpolation;
268269

269-
shaderDesc->get3DTexture(i, textureName, samplerName, edgeLen, interpolation);
270+
shaderDesc->get3DTexture(i, textureName, samplerName, edgeLen, channel, interpolation);
270271

271272
main << ", texture3d<float> "
272273
<< textureName

0 commit comments

Comments
 (0)