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/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;
}