Skip to content

Commit c1a48db

Browse files
wRosieYiyun Wang
authored andcommitted
Add RGBA format to TextureType
1 parent 6dc7fb4 commit c1a48db

File tree

15 files changed

+130
-30
lines changed

15 files changed

+130
-30
lines changed

docs/api/python/frozen/pyopencolorio_gpushaderdesc.rst

Lines changed: 3 additions & 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.
@@ -477,6 +477,8 @@
477477
.. py:property:: Texture3D.interpolation
478478
:module: PyOpenColorIO.GpuShaderDesc
479479

480+
.. py:property:: Texture3D.channel
481+
:module: PyOpenColorIO.GpuShaderDesc
480482

481483
.. py:property:: Texture3D.samplerName
482484
:module: PyOpenColorIO.GpuShaderDesc

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.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,28 @@ std::string getMatrixValues(const T * mtx, GpuLanguage lang, bool transpose)
222222
return vals;
223223
}
224224

225+
226+
void RGBtoRGBATexture(const float* lutValues, int valueCount, std::vector<float>& float4AdaptedLutValues){
227+
if(valueCount % 3 != 0)
228+
throw Exception("Value count should be divisible by 3.");
229+
230+
valueCount = valueCount * 4 / 3;
231+
if(lutValues != nullptr)
232+
{
233+
float4AdaptedLutValues.resize(valueCount);
234+
const float *rgbLutValuesIt = lutValues;
235+
float *rgbaLutValuesIt = float4AdaptedLutValues.data();
236+
const float *end = rgbaLutValuesIt + valueCount;
237+
238+
while(rgbaLutValuesIt != end) {
239+
*rgbaLutValuesIt++ = *rgbLutValuesIt++;
240+
*rgbaLutValuesIt++ = *rgbLutValuesIt++;
241+
*rgbaLutValuesIt++ = *rgbLutValuesIt++;
242+
*rgbaLutValuesIt++ = 1.0f;
243+
}
244+
}
245+
}
246+
225247
GpuShaderText::GpuShaderLine::GpuShaderLine(GpuShaderText * text)
226248
: m_text(text)
227249
{

src/OpenColorIO/GpuShaderUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ 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 RGBtoRGBATexture(const float* lutValues, int valueCount, std::vector<float>& float4AdaptedLutValues);
265+
263266
} // namespace OCIO_NAMESPACE
264267

265268
#endif

src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,27 +155,51 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
155155
const unsigned long length = lutData->getArray().getLength();
156156
const unsigned long width = std::min(length, defaultMaxWidth);
157157
const unsigned long height = (length / defaultMaxWidth) + 1;
158-
const unsigned long numChannels = lutData->getArray().getNumColorComponents();
158+
unsigned long numChannels = lutData->getArray().getNumColorComponents();
159159

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-
163+
164164
const bool singleChannel = (numChannels == 1);
165165

166+
// When shader language is metal, we want to return a texture in
167+
// RGBA format instead of RGB.
168+
if (shaderCreator ->getLanguage() == GPU_LANGUAGE_MSL_2_0 && numChannels == 3)
169+
{
170+
numChannels = 4;
171+
}
172+
166173
// Adjust LUT texture to allow for correct 2d linear interpolation, if needed.
167174

168175
std::vector<float> values;
169176
values.reserve(width * height * numChannels);
170177

171-
if (singleChannel) // i.e. numChannels == 1.
178+
GpuShaderCreator::TextureType channel = GpuShaderCreator::TEXTURE_RED_CHANNEL;
179+
switch (numChannels)
172180
{
181+
case 1:
173182
CreatePaddedRedChannel(width, height, lutData->getArray().getValues(), values);
174-
}
175-
else
176-
{
183+
channel = GpuShaderCreator::TEXTURE_RED_CHANNEL;
184+
break;
185+
case 3:
177186
CreatePaddedLutChannels(width, height, lutData->getArray().getValues(), values);
187+
channel = GpuShaderCreator::TEXTURE_RGB_CHANNEL;
188+
break;
189+
case 4: {
190+
std::vector<float> paddedChannels;
191+
values.reserve(width * height * 3);
192+
CreatePaddedLutChannels(width, height, lutData->getArray().getValues(), paddedChannels);
193+
// Insert a place holder alpha channel with value of 1. This is to support RGBA
194+
// texture format for Metal shading language.
195+
RGBtoRGBATexture(paddedChannels.data(), width * height * 3, values);
196+
channel = GpuShaderCreator::TEXTURE_RGBA_CHANNEL;
197+
break;
178198
}
199+
default:
200+
throw Exception("Invalid number of texture channels.");
201+
break;
202+
}
179203

180204
// Register the RGB LUT.
181205

@@ -203,8 +227,7 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
203227
GpuShaderText::getSamplerName(name).c_str(),
204228
width,
205229
height,
206-
singleChannel ? GpuShaderCreator::TEXTURE_RED_CHANNEL
207-
: GpuShaderCreator::TEXTURE_RGB_CHANNEL,
230+
channel,
208231
dimensions,
209232
lutData->getConcreteInterpolation(),
210233
&values[0]);

src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp

Lines changed: 22 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,30 @@ 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+
unsigned edgelen = lutData->getGridSize();
43+
std::vector<float> float4AdaptedLutValues;
44+
RGBtoRGBATexture(&lutData->getArray()[0], 3*edgelen*edgelen*edgelen, float4AdaptedLutValues);
45+
46+
shaderCreator->add3DTexture(name.c_str(),
4347
GpuShaderText::getSamplerName(name).c_str(),
44-
lutData->getGridSize(),
48+
edgelen,
49+
GpuShaderCreator::TEXTURE_RGBA_CHANNEL,
4550
samplerInterpolation,
46-
&lutData->getArray()[0]);
51+
float4AdaptedLutValues.data());
52+
}
53+
else
54+
{
55+
// All other languages
56+
// (Using CacheID here to potentially allow reuse of existing textures.)
57+
shaderCreator->add3DTexture(name.c_str(),
58+
GpuShaderText::getSamplerName(name).c_str(),
59+
lutData->getGridSize(),
60+
GpuShaderCreator::TEXTURE_RGB_CHANNEL,
61+
samplerInterpolation,
62+
&lutData->getArray()[0]);
63+
}
4764

4865
{
4966
GpuShaderText ss(shaderCreator->getLanguage());

src/bindings/python/PyGpuShaderDesc.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct Texture3D
3838
std::string m_textureName;
3939
std::string m_samplerName;
4040
unsigned m_edgelen;
41+
GpuShaderDesc::TextureType m_channel;
4142
Interpolation m_interpolation;
4243
GpuShaderDescRcPtr m_shaderDesc;
4344
int m_index;
@@ -129,6 +130,9 @@ void bindPyGpuShaderDesc(py::module & m)
129130
case GpuShaderDesc::TEXTURE_RGB_CHANNEL:
130131
numChannels = 3;
131132
break;
133+
case GpuShaderDesc::TEXTURE_RGBA_CHANNEL:
134+
numChannels = 4;
135+
break;
132136
default:
133137
throw Exception("Error: Unsupported texture type");
134138
}
@@ -160,6 +164,7 @@ void bindPyGpuShaderDesc(py::module & m)
160164
const std::string & textureName,
161165
const std::string & samplerName,
162166
unsigned edgelen,
167+
GpuShaderDesc::TextureType channel,
163168
Interpolation interpolation,
164169
const py::buffer & values)
165170
{
@@ -172,10 +177,11 @@ void bindPyGpuShaderDesc(py::module & m)
172177
self->add3DTexture(textureName.c_str(),
173178
samplerName.c_str(),
174179
edgelen,
180+
channel,
175181
interpolation,
176182
static_cast<float *>(info.ptr));
177183
},
178-
"textureName"_a, "samplerName"_a, "edgeLen"_a, "interpolation"_a, "values"_a,
184+
"textureName"_a, "samplerName"_a, "edgeLen"_a, "channel"_a, "interpolation"_a, "values"_a,
179185
DOC(GpuShaderCreator, add3DTexture))
180186
.def("get3DTextures", [](GpuShaderDescRcPtr & self)
181187
{
@@ -266,6 +272,9 @@ void bindPyGpuShaderDesc(py::module & m)
266272
case GpuShaderDesc::TEXTURE_RGB_CHANNEL:
267273
numChannels = 3;
268274
break;
275+
case GpuShaderDesc::TEXTURE_RGBA_CHANNEL:
276+
numChannels = 4;
277+
break;
269278
default:
270279
throw Exception("Error: Unsupported texture type");
271280
}
@@ -323,6 +332,7 @@ void bindPyGpuShaderDesc(py::module & m)
323332
.def_readonly("textureName", &Texture3D::m_textureName)
324333
.def_readonly("samplerName", &Texture3D::m_samplerName)
325334
.def_readonly("edgeLen", &Texture3D::m_edgelen)
335+
.def_readonly("channel", &Texture3D::m_channel)
326336
.def_readonly("interpolation", &Texture3D::m_interpolation)
327337
.def("getValues", [](Texture3D & self)
328338
{
@@ -350,10 +360,11 @@ void bindPyGpuShaderDesc(py::module & m)
350360
const char * textureName = nullptr;
351361
const char * samplerName = nullptr;
352362
unsigned edgelen;
363+
GpuShaderDesc::TextureType channel;
353364
Interpolation interpolation;
354-
it.m_obj->get3DTexture(i, textureName, samplerName, edgelen, interpolation);
365+
it.m_obj->get3DTexture(i, textureName, samplerName, edgelen, channel, interpolation);
355366

356-
return { textureName, samplerName, edgelen, interpolation, it.m_obj, i };
367+
return { textureName, samplerName, edgelen, channel, interpolation, it.m_obj, i };
357368
})
358369
.def("__iter__", [](Texture3DIterator & it) -> Texture3DIterator &
359370
{
@@ -366,10 +377,11 @@ void bindPyGpuShaderDesc(py::module & m)
366377
const char * textureName = nullptr;
367378
const char * samplerName = nullptr;
368379
unsigned edgelen;
380+
GpuShaderDesc::TextureType channel;
369381
Interpolation interpolation;
370-
it.m_obj->get3DTexture(i, textureName, samplerName, edgelen, interpolation);
382+
it.m_obj->get3DTexture(i, textureName, samplerName, edgelen, channel, interpolation);
371383

372-
return { textureName, samplerName, edgelen, interpolation, it.m_obj, i };
384+
return { textureName, samplerName, edgelen, channel, interpolation, it.m_obj, i };
373385
});
374386
}
375387

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::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

0 commit comments

Comments
 (0)