Commit 2c2a7b29 by Alexis Hetu Committed by Alexis Hétu

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/4151Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 2cb618d6
...@@ -87,7 +87,7 @@ enum ...@@ -87,7 +87,7 @@ enum
MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = MAX_UNIFORM_BLOCKS_COMPONENTS + 4 * FRAGMENT_UNIFORM_VECTORS, 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_COMBINED_VERTEX_UNIFORM_COMPONENTS = MAX_UNIFORM_BLOCKS_COMPONENTS + 4 * VERTEX_UNIFORM_VECTORS,
MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4, 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, MAX_CLIP_PLANES = 6,
RENDERTARGETS = 4, RENDERTARGETS = 4,
}; };
......
...@@ -3038,8 +3038,8 @@ void Context::applyShaders() ...@@ -3038,8 +3038,8 @@ void Context::applyShaders()
mAppliedProgramSerial = programObject->getSerial(); mAppliedProgramSerial = programObject->getSerial();
} }
programObject->applyUniformBuffers(mState.uniformBuffers);
programObject->applyUniforms(); programObject->applyUniforms();
programObject->applyUniformBuffers();
} }
void Context::applyTextures() void Context::applyTextures()
......
...@@ -62,9 +62,16 @@ namespace es2 ...@@ -62,9 +62,16 @@ namespace es2
const BlockInfo &blockInfo) const BlockInfo &blockInfo)
: type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo) : type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo)
{ {
int bytes = UniformTypeSize(type) * size(); if(blockInfo.index == -1)
data = new unsigned char[bytes]; {
memset(data, 0, bytes); int bytes = UniformTypeSize(type) * size();
data = new unsigned char[bytes];
memset(data, 0, bytes);
}
else
{
data = nullptr;
}
dirty = true; dirty = true;
psRegisterIndex = -1; psRegisterIndex = -1;
...@@ -1065,7 +1072,7 @@ namespace es2 ...@@ -1065,7 +1072,7 @@ namespace es2
Uniform *targetUniform = uniforms[uniformIndex[location].index]; Uniform *targetUniform = uniforms[uniformIndex[location].index];
if(targetUniform->dirty) if(targetUniform->dirty && (targetUniform->blockInfo.index == -1))
{ {
int size = targetUniform->size(); int size = targetUniform->size();
GLfloat *f = (GLfloat*)targetUniform->data; GLfloat *f = (GLfloat*)targetUniform->data;
...@@ -1125,25 +1132,26 @@ namespace es2 ...@@ -1125,25 +1132,26 @@ namespace es2
} }
} }
void Program::applyUniformBuffers() void Program::applyUniformBuffers(gl::BindingPointer<Buffer>* uniformBuffers)
{ {
GLint vertexUniformBuffers[IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS]; GLint vertexUniformBuffers[IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS];
GLint fragmentUniformBuffers[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++) for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
{ {
UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex]; UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
// Unnecessary to apply an unreferenced standard or shared UBO // Unnecessary to apply an unreferenced standard or shared UBO
if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader()) if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())
...@@ -1151,20 +1159,26 @@ namespace es2 ...@@ -1151,20 +1159,26 @@ namespace es2
continue; continue;
} }
GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
if(uniformBlock.isReferencedByVertexShader()) if(uniformBlock.isReferencedByVertexShader())
{ {
unsigned int registerIndex = uniformBlock.vsRegisterIndex; vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding;
ASSERT(vertexUniformBuffers[registerIndex] == -1);
vertexUniformBuffers[registerIndex] = blockBinding;
} }
if(uniformBlock.isReferencedByFragmentShader()) if(uniformBlock.isReferencedByFragmentShader())
{ {
unsigned int registerIndex = uniformBlock.psRegisterIndex; fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding;
ASSERT(fragmentUniformBuffers[registerIndex] == -1);
fragmentUniformBuffers[registerIndex] = 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() bool Program::linkVaryings()
......
...@@ -167,7 +167,7 @@ namespace es2 ...@@ -167,7 +167,7 @@ namespace es2
void dirtyAllUniforms(); void dirtyAllUniforms();
void applyUniforms(); void applyUniforms();
void applyUniformBuffers(); void applyUniformBuffers(gl::BindingPointer<Buffer>* uniformBuffers);
void link(); void link();
bool isLinked() const; bool isLinked() const;
......
...@@ -136,6 +136,32 @@ namespace sw ...@@ -136,6 +136,32 @@ namespace sw
else ASSERT(false); 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) void PixelProcessor::setRenderTarget(int index, Surface *renderTarget)
{ {
context->renderTarget[index] = renderTarget; context->renderTarget[index] = renderTarget;
......
...@@ -191,6 +191,10 @@ namespace sw ...@@ -191,6 +191,10 @@ namespace sw
virtual void setIntegerConstant(unsigned int index, const int value[4]); virtual void setIntegerConstant(unsigned int index, const int value[4]);
virtual void setBooleanConstant(unsigned int index, int boolean); 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 setRenderTarget(int index, Surface *renderTarget);
virtual void setDepthStencil(Surface *depthStencil); virtual void setDepthStencil(Surface *depthStencil);
...@@ -299,6 +303,8 @@ namespace sw ...@@ -299,6 +303,8 @@ namespace sw
float4 c[FRAGMENT_UNIFORM_VECTORS]; float4 c[FRAGMENT_UNIFORM_VECTORS];
int4 i[16]; int4 i[16];
bool b[16]; bool b[16];
Resource* uniformBuffer[MAX_UNIFORM_BUFFER_BINDINGS];
int uniformBufferOffset[MAX_UNIFORM_BUFFER_BINDINGS];
// Other semi-constants // Other semi-constants
Stencil stencil; Stencil stencil;
......
...@@ -382,6 +382,8 @@ namespace sw ...@@ -382,6 +382,8 @@ namespace sw
memcpy(&data->ps.b, PixelProcessor::b, sizeof(bool) * draw->psDirtyConstB); memcpy(&data->ps.b, PixelProcessor::b, sizeof(bool) * draw->psDirtyConstB);
draw->psDirtyConstB = 0; draw->psDirtyConstB = 0;
} }
PixelProcessor::lockUniformBuffers(data->ps.u);
} }
if(context->pixelShaderVersion() <= 0x0104) if(context->pixelShaderVersion() <= 0x0104)
...@@ -434,6 +436,8 @@ namespace sw ...@@ -434,6 +436,8 @@ namespace sw
{ {
data->instanceID = context->instanceID; data->instanceID = context->instanceID;
} }
VertexProcessor::lockUniformBuffers(data->vs.u);
} }
else else
{ {
...@@ -954,6 +958,9 @@ namespace sw ...@@ -954,6 +958,9 @@ namespace sw
draw.indexBuffer->unlock(); draw.indexBuffer->unlock();
} }
PixelProcessor::unlockUniformBuffers();
VertexProcessor::unlockUniformBuffers();
draw.vertexRoutine->unbind(); draw.vertexRoutine->unbind();
draw.setupRoutine->unbind(); draw.setupRoutine->unbind();
draw.pixelRoutine->unbind(); draw.pixelRoutine->unbind();
......
...@@ -121,6 +121,7 @@ namespace sw ...@@ -121,6 +121,7 @@ namespace sw
struct VS struct VS
{ {
float4 c[VERTEX_UNIFORM_VECTORS + 1]; // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0} 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]; int4 i[16];
bool b[16]; bool b[16];
}; };
...@@ -129,6 +130,7 @@ namespace sw ...@@ -129,6 +130,7 @@ namespace sw
{ {
word4 cW[8][4]; word4 cW[8][4];
float4 c[FRAGMENT_UNIFORM_VECTORS]; float4 c[FRAGMENT_UNIFORM_VECTORS];
byte* u[MAX_UNIFORM_BUFFER_BINDINGS];
int4 i[16]; int4 i[16];
bool b[16]; bool b[16];
}; };
......
...@@ -157,6 +157,32 @@ namespace sw ...@@ -157,6 +157,32 @@ namespace sw
else ASSERT(false); 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) void VertexProcessor::setModelMatrix(const Matrix &M, int i)
{ {
if(i < 12) if(i < 12)
......
...@@ -185,6 +185,10 @@ namespace sw ...@@ -185,6 +185,10 @@ namespace sw
virtual void setIntegerConstant(unsigned int index, const int integer[4]); virtual void setIntegerConstant(unsigned int index, const int integer[4]);
virtual void setBooleanConstant(unsigned int index, int boolean); 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 // Transformations
virtual void setModelMatrix(const Matrix &M, int i = 0); virtual void setModelMatrix(const Matrix &M, int i = 0);
virtual void setViewMatrix(const Matrix &V); virtual void setViewMatrix(const Matrix &V);
...@@ -269,6 +273,8 @@ namespace sw ...@@ -269,6 +273,8 @@ namespace sw
float4 c[VERTEX_UNIFORM_VECTORS + 1]; // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0} float4 c[VERTEX_UNIFORM_VECTORS + 1]; // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}
int4 i[16]; int4 i[16];
bool b[16]; bool b[16];
Resource* uniformBuffer[MAX_UNIFORM_BUFFER_BINDINGS];
int uniformBufferOffset[MAX_UNIFORM_BUFFER_BINDINGS];
PointSprite point; PointSprite point;
FixedFunction ff; FixedFunction ff;
......
...@@ -743,7 +743,7 @@ namespace sw ...@@ -743,7 +743,7 @@ namespace sw
} }
else else
{ {
Int a = relativeAddress(src); Int a = relativeAddress(src, src.bufferIndex);
reg = r[i + a]; reg = r[i + a];
} }
...@@ -756,7 +756,7 @@ namespace sw ...@@ -756,7 +756,7 @@ namespace sw
} }
else else
{ {
Int a = relativeAddress(src); Int a = relativeAddress(src, src.bufferIndex);
reg = v[i + a]; reg = v[i + a];
} }
...@@ -800,7 +800,7 @@ namespace sw ...@@ -800,7 +800,7 @@ namespace sw
} }
else else
{ {
Int a = relativeAddress(src); Int a = relativeAddress(src, src.bufferIndex);
reg = oC[i + a]; reg = oC[i + a];
} }
...@@ -858,6 +858,23 @@ namespace sw ...@@ -858,6 +858,23 @@ namespace sw
return mod; 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 PixelProgram::readConstant(const Src &src, unsigned int offset)
{ {
Vector4f c; Vector4f c;
...@@ -865,7 +882,7 @@ namespace sw ...@@ -865,7 +882,7 @@ namespace sw
if(src.rel.type == Shader::PARAMETER_VOID) // Not relative 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.x = c.x.xxxx;
c.y = c.y.yyyy; c.y = c.y.yyyy;
...@@ -897,7 +914,7 @@ namespace sw ...@@ -897,7 +914,7 @@ namespace sw
{ {
Int loopCounter = aL[loopDepth]; 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.x = c.x.xxxx;
c.y = c.y.yyyy; c.y = c.y.yyyy;
...@@ -906,9 +923,9 @@ namespace sw ...@@ -906,9 +923,9 @@ namespace sw
} }
else 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.x = c.x.xxxx;
c.y = c.y.yyyy; c.y = c.y.yyyy;
...@@ -919,7 +936,7 @@ namespace sw ...@@ -919,7 +936,7 @@ namespace sw
return c; return c;
} }
Int PixelProgram::relativeAddress(const Shader::Parameter &var) Int PixelProgram::relativeAddress(const Shader::Parameter &var, int bufferIndex)
{ {
ASSERT(var.rel.deterministic); ASSERT(var.rel.deterministic);
...@@ -937,7 +954,7 @@ namespace sw ...@@ -937,7 +954,7 @@ namespace sw
} }
else if(var.rel.type == Shader::PARAMETER_CONST) 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; return Extract(c, 0) * var.rel.scale;
} }
......
...@@ -88,7 +88,9 @@ namespace sw ...@@ -88,7 +88,9 @@ namespace sw
Vector4f fetchRegisterF(const Src &src, unsigned int offset = 0); Vector4f fetchRegisterF(const Src &src, unsigned int offset = 0);
Vector4f readConstant(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); Float4 linearToSRGB(const Float4 &x);
......
...@@ -455,7 +455,7 @@ namespace sw ...@@ -455,7 +455,7 @@ namespace sw
struct SourceParameter : Parameter struct SourceParameter : Parameter
{ {
SourceParameter() : swizzle(0xE4), modifier(MODIFIER_NONE) SourceParameter() : swizzle(0xE4), modifier(MODIFIER_NONE), bufferIndex(-1)
{ {
} }
...@@ -465,6 +465,7 @@ namespace sw ...@@ -465,6 +465,7 @@ namespace sw
unsigned int swizzle : 8; unsigned int swizzle : 8;
Modifier modifier : 8; Modifier modifier : 8;
int bufferIndex : 8;
}; };
struct Instruction struct Instruction
......
...@@ -659,7 +659,7 @@ namespace sw ...@@ -659,7 +659,7 @@ namespace sw
} }
else else
{ {
reg = r[i + relativeAddress(src)]; reg = r[i + relativeAddress(src, src.bufferIndex)];
} }
break; break;
case Shader::PARAMETER_CONST: case Shader::PARAMETER_CONST:
...@@ -672,7 +672,7 @@ namespace sw ...@@ -672,7 +672,7 @@ namespace sw
} }
else else
{ {
reg = v[i + relativeAddress(src)]; reg = v[i + relativeAddress(src, src.bufferIndex)];
} }
break; break;
case Shader::PARAMETER_VOID: return r[0]; // Dummy case Shader::PARAMETER_VOID: return r[0]; // Dummy
...@@ -704,7 +704,7 @@ namespace sw ...@@ -704,7 +704,7 @@ namespace sw
} }
else else
{ {
reg = o[i + relativeAddress(src)]; reg = o[i + relativeAddress(src, src.bufferIndex)];
} }
break; break;
case Shader::PARAMETER_MISCTYPE: case Shader::PARAMETER_MISCTYPE:
...@@ -760,6 +760,23 @@ namespace sw ...@@ -760,6 +760,23 @@ namespace sw
return mod; 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 VertexProgram::readConstant(const Src &src, unsigned int offset)
{ {
Vector4f c; Vector4f c;
...@@ -767,7 +784,7 @@ namespace sw ...@@ -767,7 +784,7 @@ namespace sw
if(src.rel.type == Shader::PARAMETER_VOID) // Not relative 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.x = c.x.xxxx;
c.y = c.y.yyyy; c.y = c.y.yyyy;
...@@ -799,7 +816,7 @@ namespace sw ...@@ -799,7 +816,7 @@ namespace sw
{ {
Int loopCounter = aL[loopDepth]; 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.x = c.x.xxxx;
c.y = c.y.yyyy; c.y = c.y.yyyy;
...@@ -810,7 +827,9 @@ namespace sw ...@@ -810,7 +827,9 @@ namespace sw
{ {
if(src.rel.deterministic) 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); c.x = c.y = c.z = c.w = *Pointer<Float4>(data + OFFSET(DrawData,vs.c[i]) + a * 16);
...@@ -830,7 +849,7 @@ namespace sw ...@@ -830,7 +849,7 @@ namespace sw
case Shader::PARAMETER_TEMP: a = r[src.rel.index][component]; break; 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_INPUT: a = v[src.rel.index][component]; break;
case Shader::PARAMETER_OUTPUT: a = o[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); default: ASSERT(false);
} }
...@@ -843,10 +862,10 @@ namespace sw ...@@ -843,10 +862,10 @@ namespace sw
Int index2 = Extract(index, 2); Int index2 = Extract(index, 2);
Int index3 = Extract(index, 3); Int index3 = Extract(index, 3);
c.x = *Pointer<Float4>(data + OFFSET(DrawData,vs.c) + index0 * 16, 16); c.x = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index0), 16);
c.y = *Pointer<Float4>(data + OFFSET(DrawData,vs.c) + index1 * 16, 16); c.y = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index1), 16);
c.z = *Pointer<Float4>(data + OFFSET(DrawData,vs.c) + index2 * 16, 16); c.z = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index2), 16);
c.w = *Pointer<Float4>(data + OFFSET(DrawData,vs.c) + index3 * 16, 16); c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index3), 16);
transpose4x4(c.x, c.y, c.z, c.w); transpose4x4(c.x, c.y, c.z, c.w);
} }
...@@ -855,7 +874,7 @@ namespace sw ...@@ -855,7 +874,7 @@ namespace sw
return c; return c;
} }
Int VertexProgram::relativeAddress(const Shader::Parameter &var) Int VertexProgram::relativeAddress(const Shader::Parameter &var, int bufferIndex)
{ {
ASSERT(var.rel.deterministic); ASSERT(var.rel.deterministic);
...@@ -873,7 +892,7 @@ namespace sw ...@@ -873,7 +892,7 @@ namespace sw
} }
else if(var.rel.type == Shader::PARAMETER_CONST) 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; return Extract(c, 0) * var.rel.scale;
} }
......
...@@ -65,7 +65,9 @@ namespace sw ...@@ -65,7 +65,9 @@ namespace sw
Vector4f fetchRegisterF(const Src &src, unsigned int offset = 0); Vector4f fetchRegisterF(const Src &src, unsigned int offset = 0);
Vector4f readConstant(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); Int4 enableMask(const Shader::Instruction *instruction);
void M3X2(Vector4f &dst, Vector4f &src0, Src &src1); void M3X2(Vector4f &dst, Vector4f &src0, Src &src1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment