Passing uniform buffers to the vertex/pixel programs
This cl contains the necessary changes to make uniform buffers
usable in shaders. A few things to note:
- Uniform buffers can be set, but nothing will attempt to access
them in this cl.
- While the 'index' of uniforms is expressed in terms of registers,
uniform buffer 'index' is expressed in bytes in both PixelProgram
and VertexProgram. This is necessary because of packing which can
potentially put some variables in the middle of registers.
Technically, std140 always packs variables in multiples of byte4,
but other future layouts may not, so using bytes as the unit is
more future proof.
- The above mentioned 'index' will have to be computed in OutputASM
and extra operations will need to be added (to fetch a row from a
row major matrix, for example).
Change-Id: I636cc4bdc6fe90d6f5697e735f4288f48d18a75b
Reviewed-on: https://swiftshader-review.googlesource.com/4151
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Main/Config.hpp b/src/Main/Config.hpp
index d1fd218..ed3a72c 100644
--- a/src/Main/Config.hpp
+++ b/src/Main/Config.hpp
@@ -87,7 +87,7 @@
MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = MAX_UNIFORM_BLOCKS_COMPONENTS + 4 * FRAGMENT_UNIFORM_VECTORS,
MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = MAX_UNIFORM_BLOCKS_COMPONENTS + 4 * VERTEX_UNIFORM_VECTORS,
MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4,
- MAX_UNIFORM_BUFFER_BINDINGS = 36,
+ MAX_UNIFORM_BUFFER_BINDINGS = 36, // Limited to 127 by SourceParameter.bufferIndex in Shader.hpp
MAX_CLIP_PLANES = 6,
RENDERTARGETS = 4,
};
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 7bce0a1..af69141 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3038,8 +3038,8 @@
mAppliedProgramSerial = programObject->getSerial();
}
+ programObject->applyUniformBuffers(mState.uniformBuffers);
programObject->applyUniforms();
- programObject->applyUniformBuffers();
}
void Context::applyTextures()
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index e3dcd5a..28b5571 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -62,9 +62,16 @@
const BlockInfo &blockInfo)
: type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo)
{
- int bytes = UniformTypeSize(type) * size();
- data = new unsigned char[bytes];
- memset(data, 0, bytes);
+ if(blockInfo.index == -1)
+ {
+ int bytes = UniformTypeSize(type) * size();
+ data = new unsigned char[bytes];
+ memset(data, 0, bytes);
+ }
+ else
+ {
+ data = nullptr;
+ }
dirty = true;
psRegisterIndex = -1;
@@ -1065,7 +1072,7 @@
Uniform *targetUniform = uniforms[uniformIndex[location].index];
- if(targetUniform->dirty)
+ if(targetUniform->dirty && (targetUniform->blockInfo.index == -1))
{
int size = targetUniform->size();
GLfloat *f = (GLfloat*)targetUniform->data;
@@ -1125,25 +1132,26 @@
}
}
- void Program::applyUniformBuffers()
+ void Program::applyUniformBuffers(gl::BindingPointer<Buffer>* uniformBuffers)
{
GLint vertexUniformBuffers[IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS];
GLint fragmentUniformBuffers[IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS];
- for(unsigned int registerIndex = 0; registerIndex < IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; ++registerIndex)
+ for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; ++bufferBindingIndex)
{
- vertexUniformBuffers[registerIndex] = -1;
+ vertexUniformBuffers[bufferBindingIndex] = -1;
}
- for(unsigned int registerIndex = 0; registerIndex < IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; ++registerIndex)
+ for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; ++bufferBindingIndex)
{
- fragmentUniformBuffers[registerIndex] = -1;
+ fragmentUniformBuffers[bufferBindingIndex] = -1;
}
+ int vertexUniformBufferIndex = 0;
+ int fragmentUniformBufferIndex = 0;
for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
{
UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
- GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
// Unnecessary to apply an unreferenced standard or shared UBO
if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())
@@ -1151,20 +1159,26 @@
continue;
}
+ GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
+
if(uniformBlock.isReferencedByVertexShader())
{
- unsigned int registerIndex = uniformBlock.vsRegisterIndex;
- ASSERT(vertexUniformBuffers[registerIndex] == -1);
- vertexUniformBuffers[registerIndex] = blockBinding;
+ vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding;
}
if(uniformBlock.isReferencedByFragmentShader())
{
- unsigned int registerIndex = uniformBlock.psRegisterIndex;
- ASSERT(fragmentUniformBuffers[registerIndex] == -1);
- fragmentUniformBuffers[registerIndex] = blockBinding;
+ fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding;
}
}
+
+ for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; ++bufferBindingIndex)
+ {
+ int index = vertexUniformBuffers[bufferBindingIndex];
+ device->VertexProcessor::setUniformBuffer(bufferBindingIndex, (index != -1) ? uniformBuffers[index]->getResource() : nullptr, 0);
+ index = fragmentUniformBuffers[bufferBindingIndex];
+ device->PixelProcessor::setUniformBuffer(bufferBindingIndex, (index != -1) ? uniformBuffers[index]->getResource() : nullptr, 0);
+ }
}
bool Program::linkVaryings()
diff --git a/src/OpenGL/libGLESv2/Program.h b/src/OpenGL/libGLESv2/Program.h
index 23076c2..86a861e 100644
--- a/src/OpenGL/libGLESv2/Program.h
+++ b/src/OpenGL/libGLESv2/Program.h
@@ -167,7 +167,7 @@
void dirtyAllUniforms();
void applyUniforms();
- void applyUniformBuffers();
+ void applyUniformBuffers(gl::BindingPointer<Buffer>* uniformBuffers);
void link();
bool isLinked() const;
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp
index d157f51..4162598 100644
--- a/src/Renderer/PixelProcessor.cpp
+++ b/src/Renderer/PixelProcessor.cpp
@@ -136,6 +136,32 @@
else ASSERT(false);
}
+ void PixelProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
+ {
+ uniformBuffer[index] = buffer;
+ uniformBufferOffset[index] = offset;
+ }
+
+ void PixelProcessor::lockUniformBuffers(byte** u)
+ {
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
+ {
+ u[i] = uniformBuffer[i] ? static_cast<byte*>(uniformBuffer[i]->lock(PUBLIC, PRIVATE)) + uniformBufferOffset[i] : nullptr;
+ }
+ }
+
+ void PixelProcessor::unlockUniformBuffers()
+ {
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
+ {
+ if(uniformBuffer[i])
+ {
+ uniformBuffer[i]->unlock();
+ uniformBuffer[i] = nullptr;
+ }
+ }
+ }
+
void PixelProcessor::setRenderTarget(int index, Surface *renderTarget)
{
context->renderTarget[index] = renderTarget;
diff --git a/src/Renderer/PixelProcessor.hpp b/src/Renderer/PixelProcessor.hpp
index 9efc234..9c80c67 100644
--- a/src/Renderer/PixelProcessor.hpp
+++ b/src/Renderer/PixelProcessor.hpp
@@ -191,6 +191,10 @@
virtual void setIntegerConstant(unsigned int index, const int value[4]);
virtual void setBooleanConstant(unsigned int index, int boolean);
+ virtual void setUniformBuffer(int index, sw::Resource* buffer, int offset);
+ virtual void lockUniformBuffers(byte** u);
+ virtual void unlockUniformBuffers();
+
virtual void setRenderTarget(int index, Surface *renderTarget);
virtual void setDepthStencil(Surface *depthStencil);
@@ -299,6 +303,8 @@
float4 c[FRAGMENT_UNIFORM_VECTORS];
int4 i[16];
bool b[16];
+ Resource* uniformBuffer[MAX_UNIFORM_BUFFER_BINDINGS];
+ int uniformBufferOffset[MAX_UNIFORM_BUFFER_BINDINGS];
// Other semi-constants
Stencil stencil;
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index 52589d2..ca5e67a 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -382,6 +382,8 @@
memcpy(&data->ps.b, PixelProcessor::b, sizeof(bool) * draw->psDirtyConstB);
draw->psDirtyConstB = 0;
}
+
+ PixelProcessor::lockUniformBuffers(data->ps.u);
}
if(context->pixelShaderVersion() <= 0x0104)
@@ -434,6 +436,8 @@
{
data->instanceID = context->instanceID;
}
+
+ VertexProcessor::lockUniformBuffers(data->vs.u);
}
else
{
@@ -954,6 +958,9 @@
draw.indexBuffer->unlock();
}
+ PixelProcessor::unlockUniformBuffers();
+ VertexProcessor::unlockUniformBuffers();
+
draw.vertexRoutine->unbind();
draw.setupRoutine->unbind();
draw.pixelRoutine->unbind();
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index 28afc42..a818eaa 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -121,6 +121,7 @@
struct VS
{
float4 c[VERTEX_UNIFORM_VECTORS + 1]; // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}
+ byte* u[MAX_UNIFORM_BUFFER_BINDINGS];
int4 i[16];
bool b[16];
};
@@ -129,6 +130,7 @@
{
word4 cW[8][4];
float4 c[FRAGMENT_UNIFORM_VECTORS];
+ byte* u[MAX_UNIFORM_BUFFER_BINDINGS];
int4 i[16];
bool b[16];
};
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp
index 80539dc..c1e19da 100644
--- a/src/Renderer/VertexProcessor.cpp
+++ b/src/Renderer/VertexProcessor.cpp
@@ -157,6 +157,32 @@
else ASSERT(false);
}
+ void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
+ {
+ uniformBuffer[index] = buffer;
+ uniformBufferOffset[index] = offset;
+ }
+
+ void VertexProcessor::lockUniformBuffers(byte** u)
+ {
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
+ {
+ u[i] = uniformBuffer[i] ? static_cast<byte*>(uniformBuffer[i]->lock(PUBLIC, PRIVATE)) + uniformBufferOffset[i] : nullptr;
+ }
+ }
+
+ void VertexProcessor::unlockUniformBuffers()
+ {
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
+ {
+ if(uniformBuffer[i])
+ {
+ uniformBuffer[i]->unlock();
+ uniformBuffer[i] = nullptr;
+ }
+ }
+ }
+
void VertexProcessor::setModelMatrix(const Matrix &M, int i)
{
if(i < 12)
diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp
index d379304..a8ddf1a 100644
--- a/src/Renderer/VertexProcessor.hpp
+++ b/src/Renderer/VertexProcessor.hpp
@@ -185,6 +185,10 @@
virtual void setIntegerConstant(unsigned int index, const int integer[4]);
virtual void setBooleanConstant(unsigned int index, int boolean);
+ virtual void setUniformBuffer(int index, sw::Resource* uniformBuffer, int offset);
+ virtual void lockUniformBuffers(byte** u);
+ virtual void unlockUniformBuffers();
+
// Transformations
virtual void setModelMatrix(const Matrix &M, int i = 0);
virtual void setViewMatrix(const Matrix &V);
@@ -269,6 +273,8 @@
float4 c[VERTEX_UNIFORM_VECTORS + 1]; // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}
int4 i[16];
bool b[16];
+ Resource* uniformBuffer[MAX_UNIFORM_BUFFER_BINDINGS];
+ int uniformBufferOffset[MAX_UNIFORM_BUFFER_BINDINGS];
PointSprite point;
FixedFunction ff;
diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp
index 9fec0b3..8f56c06 100644
--- a/src/Shader/PixelProgram.cpp
+++ b/src/Shader/PixelProgram.cpp
@@ -743,7 +743,7 @@
}
else
{
- Int a = relativeAddress(src);
+ Int a = relativeAddress(src, src.bufferIndex);
reg = r[i + a];
}
@@ -756,7 +756,7 @@
}
else
{
- Int a = relativeAddress(src);
+ Int a = relativeAddress(src, src.bufferIndex);
reg = v[i + a];
}
@@ -800,7 +800,7 @@
}
else
{
- Int a = relativeAddress(src);
+ Int a = relativeAddress(src, src.bufferIndex);
reg = oC[i + a];
}
@@ -858,6 +858,23 @@
return mod;
}
+ RValue<Pointer<Byte>> PixelProgram::uniformAddress(int bufferIndex, unsigned int index)
+ {
+ if(bufferIndex == -1)
+ {
+ return data + OFFSET(DrawData, ps.c[index]);
+ }
+ else
+ {
+ return *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, ps.u[bufferIndex])) + index;
+ }
+ }
+
+ RValue<Pointer<Byte>> PixelProgram::uniformAddress(int bufferIndex, unsigned int index, Int& offset)
+ {
+ return uniformAddress(bufferIndex, index) + offset * sizeof(float4);
+ }
+
Vector4f PixelProgram::readConstant(const Src &src, unsigned int offset)
{
Vector4f c;
@@ -865,7 +882,7 @@
if(src.rel.type == Shader::PARAMETER_VOID) // Not relative
{
- c.x = c.y = c.z = c.w = *Pointer<Float4>(data + OFFSET(DrawData, ps.c[i]));
+ c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i));
c.x = c.x.xxxx;
c.y = c.y.yyyy;
@@ -897,7 +914,7 @@
{
Int loopCounter = aL[loopDepth];
- c.x = c.y = c.z = c.w = *Pointer<Float4>(data + OFFSET(DrawData, ps.c[i]) + loopCounter * 16);
+ c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, loopCounter));
c.x = c.x.xxxx;
c.y = c.y.yyyy;
@@ -906,9 +923,9 @@
}
else
{
- Int a = relativeAddress(src);
+ Int a = relativeAddress(src, src.bufferIndex);
- c.x = c.y = c.z = c.w = *Pointer<Float4>(data + OFFSET(DrawData, ps.c[i]) + a * 16);
+ c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, a));
c.x = c.x.xxxx;
c.y = c.y.yyyy;
@@ -919,7 +936,7 @@
return c;
}
- Int PixelProgram::relativeAddress(const Shader::Parameter &var)
+ Int PixelProgram::relativeAddress(const Shader::Parameter &var, int bufferIndex)
{
ASSERT(var.rel.deterministic);
@@ -937,7 +954,7 @@
}
else if(var.rel.type == Shader::PARAMETER_CONST)
{
- RValue<Int4> c = *Pointer<Int4>(data + OFFSET(DrawData, ps.c[var.rel.index]));
+ RValue<Int4> c = *Pointer<Int4>(uniformAddress(bufferIndex, var.rel.index));
return Extract(c, 0) * var.rel.scale;
}
diff --git a/src/Shader/PixelProgram.hpp b/src/Shader/PixelProgram.hpp
index ffef0ac..ab69b62 100644
--- a/src/Shader/PixelProgram.hpp
+++ b/src/Shader/PixelProgram.hpp
@@ -88,7 +88,9 @@
Vector4f fetchRegisterF(const Src &src, unsigned int offset = 0);
Vector4f readConstant(const Src &src, unsigned int offset = 0);
- Int relativeAddress(const Shader::Parameter &var);
+ RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);
+ RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset);
+ Int relativeAddress(const Shader::Parameter &var, int bufferIndex = -1);
Float4 linearToSRGB(const Float4 &x);
diff --git a/src/Shader/Shader.hpp b/src/Shader/Shader.hpp
index fa77394..03b95dc 100644
--- a/src/Shader/Shader.hpp
+++ b/src/Shader/Shader.hpp
@@ -455,7 +455,7 @@
struct SourceParameter : Parameter
{
- SourceParameter() : swizzle(0xE4), modifier(MODIFIER_NONE)
+ SourceParameter() : swizzle(0xE4), modifier(MODIFIER_NONE), bufferIndex(-1)
{
}
@@ -465,6 +465,7 @@
unsigned int swizzle : 8;
Modifier modifier : 8;
+ int bufferIndex : 8;
};
struct Instruction
diff --git a/src/Shader/VertexProgram.cpp b/src/Shader/VertexProgram.cpp
index 1999efe..97e335f 100644
--- a/src/Shader/VertexProgram.cpp
+++ b/src/Shader/VertexProgram.cpp
@@ -659,7 +659,7 @@
}
else
{
- reg = r[i + relativeAddress(src)];
+ reg = r[i + relativeAddress(src, src.bufferIndex)];
}
break;
case Shader::PARAMETER_CONST:
@@ -672,7 +672,7 @@
}
else
{
- reg = v[i + relativeAddress(src)];
+ reg = v[i + relativeAddress(src, src.bufferIndex)];
}
break;
case Shader::PARAMETER_VOID: return r[0]; // Dummy
@@ -704,7 +704,7 @@
}
else
{
- reg = o[i + relativeAddress(src)];
+ reg = o[i + relativeAddress(src, src.bufferIndex)];
}
break;
case Shader::PARAMETER_MISCTYPE:
@@ -760,6 +760,23 @@
return mod;
}
+ RValue<Pointer<Byte>> VertexProgram::uniformAddress(int bufferIndex, unsigned int index)
+ {
+ if(bufferIndex == -1)
+ {
+ return data + OFFSET(DrawData, vs.c[index]);
+ }
+ else
+ {
+ return *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, vs.u[bufferIndex])) + index;
+ }
+ }
+
+ RValue<Pointer<Byte>> VertexProgram::uniformAddress(int bufferIndex, unsigned int index, Int& offset)
+ {
+ return uniformAddress(bufferIndex, index) + offset * sizeof(float4);
+ }
+
Vector4f VertexProgram::readConstant(const Src &src, unsigned int offset)
{
Vector4f c;
@@ -767,7 +784,7 @@
if(src.rel.type == Shader::PARAMETER_VOID) // Not relative
{
- c.x = c.y = c.z = c.w = *Pointer<Float4>(data + OFFSET(DrawData,vs.c[i]));
+ c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i));
c.x = c.x.xxxx;
c.y = c.y.yyyy;
@@ -799,7 +816,7 @@
{
Int loopCounter = aL[loopDepth];
- c.x = c.y = c.z = c.w = *Pointer<Float4>(data + OFFSET(DrawData,vs.c[i]) + loopCounter * 16);
+ c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, loopCounter));
c.x = c.x.xxxx;
c.y = c.y.yyyy;
@@ -810,7 +827,9 @@
{
if(src.rel.deterministic)
{
- Int a = relativeAddress(src);
+ Int a = relativeAddress(src, src.bufferIndex);
+
+ c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, a));
c.x = c.y = c.z = c.w = *Pointer<Float4>(data + OFFSET(DrawData,vs.c[i]) + a * 16);
@@ -830,7 +849,7 @@
case Shader::PARAMETER_TEMP: a = r[src.rel.index][component]; break;
case Shader::PARAMETER_INPUT: a = v[src.rel.index][component]; break;
case Shader::PARAMETER_OUTPUT: a = o[src.rel.index][component]; break;
- case Shader::PARAMETER_CONST: a = *Pointer<Float>(data + OFFSET(DrawData,vs.c[src.rel.index][component])); break;
+ case Shader::PARAMETER_CONST: a = *Pointer<Float>(uniformAddress(src.bufferIndex, src.rel.index) + component * sizeof(float)); break;
default: ASSERT(false);
}
@@ -843,10 +862,10 @@
Int index2 = Extract(index, 2);
Int index3 = Extract(index, 3);
- c.x = *Pointer<Float4>(data + OFFSET(DrawData,vs.c) + index0 * 16, 16);
- c.y = *Pointer<Float4>(data + OFFSET(DrawData,vs.c) + index1 * 16, 16);
- c.z = *Pointer<Float4>(data + OFFSET(DrawData,vs.c) + index2 * 16, 16);
- c.w = *Pointer<Float4>(data + OFFSET(DrawData,vs.c) + index3 * 16, 16);
+ c.x = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index0), 16);
+ c.y = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index1), 16);
+ c.z = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index2), 16);
+ c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index3), 16);
transpose4x4(c.x, c.y, c.z, c.w);
}
@@ -855,7 +874,7 @@
return c;
}
- Int VertexProgram::relativeAddress(const Shader::Parameter &var)
+ Int VertexProgram::relativeAddress(const Shader::Parameter &var, int bufferIndex)
{
ASSERT(var.rel.deterministic);
@@ -873,7 +892,7 @@
}
else if(var.rel.type == Shader::PARAMETER_CONST)
{
- RValue<Int4> c = *Pointer<Int4>(data + OFFSET(DrawData, vs.c[var.rel.index]));
+ RValue<Int4> c = *Pointer<Int4>(uniformAddress(bufferIndex, var.rel.index));
return Extract(c, 0) * var.rel.scale;
}
diff --git a/src/Shader/VertexProgram.hpp b/src/Shader/VertexProgram.hpp
index 8cacf31..1819d91 100644
--- a/src/Shader/VertexProgram.hpp
+++ b/src/Shader/VertexProgram.hpp
@@ -65,7 +65,9 @@
Vector4f fetchRegisterF(const Src &src, unsigned int offset = 0);
Vector4f readConstant(const Src &src, unsigned int offset = 0);
- Int relativeAddress(const Shader::Parameter &var);
+ RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);
+ RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset);
+ Int relativeAddress(const Shader::Parameter &var, int bufferIndex = -1);
Int4 enableMask(const Shader::Instruction *instruction);
void M3X2(Vector4f &dst, Vector4f &src0, Src &src1);