Renderer side code to lock/unlock transform feedback data
Added variables and function calls to lock/unlock transform
feedback data used for reading the selected transform
feedback varying variables out of the vertex shader.
Also fixed uniform buffer unlocking potential race condition.
Change-Id: I98790fc36fdf8674506d924b2f21b3e68892811a
Reviewed-on: https://swiftshader-review.googlesource.com/5060
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp
index f736233..02d4c56 100644
--- a/src/Renderer/PixelProcessor.cpp
+++ b/src/Renderer/PixelProcessor.cpp
@@ -58,6 +58,12 @@
return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
}
+ PixelProcessor::UniformBufferInfo::UniformBufferInfo()
+ {
+ buffer = nullptr;
+ offset = 0;
+ }
+
PixelProcessor::PixelProcessor(Context *context) : context(context)
{
setGlobalMipmapBias(0.0f); // Round to highest LOD [0.5, 1.0]: -0.5
@@ -66,11 +72,6 @@
routineCache = 0;
setRoutineCacheSize(1024);
-
- for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
- {
- uniformBuffer[i] = nullptr;
- }
}
PixelProcessor::~PixelProcessor()
@@ -143,27 +144,16 @@
void PixelProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
{
- uniformBuffer[index] = buffer;
- uniformBufferOffset[index] = offset;
+ uniformBufferInfo[index].buffer = buffer;
+ uniformBufferInfo[index].offset = offset;
}
- void PixelProcessor::lockUniformBuffers(byte** u)
+ void PixelProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
{
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;
- }
+ u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
+ uniformBuffers[i] = uniformBufferInfo[i].buffer;
}
}
diff --git a/src/Renderer/PixelProcessor.hpp b/src/Renderer/PixelProcessor.hpp
index 2308d8f..571e860 100644
--- a/src/Renderer/PixelProcessor.hpp
+++ b/src/Renderer/PixelProcessor.hpp
@@ -192,8 +192,7 @@
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 lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);
virtual void setRenderTarget(int index, Surface *renderTarget);
virtual void setDepthBuffer(Surface *depthBuffer);
@@ -304,8 +303,6 @@
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;
@@ -314,6 +311,15 @@
Factor factor;
private:
+ struct UniformBufferInfo
+ {
+ UniformBufferInfo();
+
+ Resource* buffer;
+ int offset;
+ };
+ UniformBufferInfo uniformBufferInfo[MAX_UNIFORM_BUFFER_BINDINGS];
+
void setFogRanges(float start, float end);
Context *const context;
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index a5e8760..71c50e9 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -388,7 +388,14 @@
draw->psDirtyConstB = 0;
}
- PixelProcessor::lockUniformBuffers(data->ps.u);
+ PixelProcessor::lockUniformBuffers(data->ps.u, draw->pUniformBuffers);
+ }
+ else
+ {
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
+ {
+ draw->pUniformBuffers[i] = nullptr;
+ }
}
if(context->pixelShaderVersion() <= 0x0104)
@@ -442,7 +449,8 @@
data->instanceID = context->instanceID;
}
- VertexProcessor::lockUniformBuffers(data->vs.u);
+ VertexProcessor::lockUniformBuffers(data->vs.u, draw->vUniformBuffers);
+ VertexProcessor::lockTransformFeedbackBuffers(data->vs.t, data->vs.reg, data->vs.row, data->vs.col, data->vs.str, draw->transformFeedbackBuffers);
}
else
{
@@ -451,6 +459,16 @@
draw->vsDirtyConstF = VERTEX_UNIFORM_VECTORS + 1;
draw->vsDirtyConstI = 16;
draw->vsDirtyConstB = 16;
+
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
+ {
+ draw->vUniformBuffers[i] = nullptr;
+ }
+
+ for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; i++)
+ {
+ draw->transformFeedbackBuffers[i] = nullptr;
+ }
}
if(pixelState.stencilActive)
@@ -981,8 +999,25 @@
draw.indexBuffer->unlock();
}
- PixelProcessor::unlockUniformBuffers();
- VertexProcessor::unlockUniformBuffers();
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
+ {
+ if(draw.pUniformBuffers[i])
+ {
+ draw.pUniformBuffers[i]->unlock();
+ }
+ if(draw.vUniformBuffers[i])
+ {
+ draw.vUniformBuffers[i]->unlock();
+ }
+ }
+
+ for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; i++)
+ {
+ if(draw.transformFeedbackBuffers[i])
+ {
+ draw.transformFeedbackBuffers[i]->unlock();
+ }
+ }
draw.vertexRoutine->unbind();
draw.setupRoutine->unbind();
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index 3f0c931..e0b9141 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -123,6 +123,11 @@
{
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];
+ byte* t[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];
+ unsigned int reg[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Offset used when reading from registers, in components
+ unsigned int row[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of rows to read
+ unsigned int col[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of columns to read
+ unsigned int str[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of components between each varying in output buffer
int4 i[16];
bool b[16];
};
@@ -222,6 +227,9 @@
Surface *depthBuffer;
Surface *stencilBuffer;
Resource *texture[TOTAL_IMAGE_UNITS];
+ Resource* pUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
+ Resource* vUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
+ Resource* transformFeedbackBuffers[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];
int vsDirtyConstF;
int vsDirtyConstI;
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp
index 01f6f14..24f40cc 100644
--- a/src/Renderer/VertexProcessor.cpp
+++ b/src/Renderer/VertexProcessor.cpp
@@ -63,11 +63,6 @@
VertexProcessor::TransformFeedbackInfo::TransformFeedbackInfo()
{
- clear();
- }
-
- void VertexProcessor::TransformFeedbackInfo::clear()
- {
buffer = nullptr;
offset = 0;
reg = 0;
@@ -76,6 +71,12 @@
stride = 0;
}
+ VertexProcessor::UniformBufferInfo::UniformBufferInfo()
+ {
+ buffer = nullptr;
+ offset = 0;
+ }
+
VertexProcessor::VertexProcessor(Context *context) : context(context)
{
for(int i = 0; i < 12; i++)
@@ -116,11 +117,6 @@
routineCache = 0;
setRoutineCacheSize(1024);
-
- for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
- {
- uniformBuffer[i] = nullptr;
- }
}
VertexProcessor::~VertexProcessor()
@@ -179,27 +175,16 @@
void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
{
- uniformBuffer[index] = buffer;
- uniformBufferOffset[index] = offset;
+ uniformBufferInfo[index].buffer = buffer;
+ uniformBufferInfo[index].offset = offset;
}
- void VertexProcessor::lockUniformBuffers(byte** u)
+ void VertexProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
{
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;
- }
+ u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
+ uniformBuffers[i] = uniformBufferInfo[i].buffer;
}
}
@@ -213,11 +198,12 @@
transformFeedbackInfo[index].stride = stride;
}
- void VertexProcessor::lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s)
+ void VertexProcessor::lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[])
{
for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
{
t[i] = transformFeedbackInfo[i].buffer ? static_cast<byte*>(transformFeedbackInfo[i].buffer->lock(PUBLIC, PRIVATE)) + transformFeedbackInfo[i].offset : nullptr;
+ transformFeedbackBuffers[i] = transformFeedbackInfo[i].buffer;
v[i] = transformFeedbackInfo[i].reg;
r[i] = transformFeedbackInfo[i].row;
c[i] = transformFeedbackInfo[i].col;
@@ -225,18 +211,6 @@
}
}
- void VertexProcessor::unlockTransformFeedbackBuffers()
- {
- for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
- {
- if(transformFeedbackInfo[i].buffer)
- {
- transformFeedbackInfo[i].buffer->unlock();
- }
- transformFeedbackInfo[i].clear();
- }
- }
-
void VertexProcessor::setModelMatrix(const Matrix &M, int i)
{
if(i < 12)
diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp
index 9fb400a..1f1ccb7 100644
--- a/src/Renderer/VertexProcessor.hpp
+++ b/src/Renderer/VertexProcessor.hpp
@@ -188,12 +188,10 @@
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();
+ virtual void lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);
virtual void setTransformFeedbackBuffer(int index, sw::Resource* transformFeedbackBuffer, int offset, unsigned int reg, unsigned int row, unsigned int col, size_t stride);
- virtual void lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s);
- virtual void unlockTransformFeedbackBuffers();
+ virtual void lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[]);
// Transformations
virtual void setModelMatrix(const Matrix &M, int i = 0);
@@ -282,18 +280,23 @@
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;
private:
- void updateTransform();
+ struct UniformBufferInfo
+ {
+ UniformBufferInfo();
+
+ Resource* buffer;
+ int offset;
+ };
+ UniformBufferInfo uniformBufferInfo[MAX_UNIFORM_BUFFER_BINDINGS];
+
struct TransformFeedbackInfo
{
TransformFeedbackInfo();
- void clear();
Resource* buffer;
int offset;
@@ -304,6 +307,7 @@
};
TransformFeedbackInfo transformFeedbackInfo[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];
+ void updateTransform();
void setTransform(const Matrix &M, int i);
void setCameraTransform(const Matrix &M, int i);
void setNormalTransform(const Matrix &M, int i);