Commit 16116cb5 by Alexis Hetu Committed by Alexis Hétu

Transform feedback query implementation

This is a first implementation of the transform feedback primitives written query. It passes available related dEQP tests (more tests will be available when transform feedback is fully implemented). Change-Id: Iaee97e3e2e853174b7f22836f72dabede1ed04c1 Reviewed-on: https://swiftshader-review.googlesource.com/4912Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent b0f247f5
...@@ -24,7 +24,7 @@ namespace D3D9 ...@@ -24,7 +24,7 @@ namespace D3D9
{ {
if(type == D3DQUERYTYPE_OCCLUSION) if(type == D3DQUERYTYPE_OCCLUSION)
{ {
query = new sw::Query(); query = new sw::Query(sw::Query::FRAGMENTS_PASSED);
} }
else else
{ {
......
...@@ -39,8 +39,19 @@ void Query::begin() ...@@ -39,8 +39,19 @@ void Query::begin()
{ {
if(mQuery == NULL) if(mQuery == NULL)
{ {
mQuery = new sw::Query(); sw::Query::Type type;
switch(mType)
{
case GL_ANY_SAMPLES_PASSED:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
type = sw::Query::FRAGMENTS_PASSED;
break;
default:
ASSERT(false);
}
mQuery = new sw::Query(type);
if(!mQuery) if(!mQuery)
{ {
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
......
...@@ -39,8 +39,22 @@ void Query::begin() ...@@ -39,8 +39,22 @@ void Query::begin()
{ {
if(mQuery == NULL) if(mQuery == NULL)
{ {
mQuery = new sw::Query(); sw::Query::Type type;
switch(mType)
{
case GL_ANY_SAMPLES_PASSED_EXT:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
type = sw::Query::FRAGMENTS_PASSED;
break;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
type = sw::Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
break;
default:
ASSERT(false);
}
mQuery = new sw::Query(type);
if(!mQuery) if(!mQuery)
{ {
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
...@@ -51,7 +65,18 @@ void Query::begin() ...@@ -51,7 +65,18 @@ void Query::begin()
mQuery->begin(); mQuery->begin();
device->addQuery(mQuery); device->addQuery(mQuery);
device->setOcclusionEnabled(true); switch(mType)
{
case GL_ANY_SAMPLES_PASSED_EXT:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
device->setOcclusionEnabled(true);
break;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
device->setTransformFeedbackQueryEnabled(true);
break;
default:
ASSERT(false);
}
} }
void Query::end() void Query::end()
...@@ -65,8 +90,19 @@ void Query::end() ...@@ -65,8 +90,19 @@ void Query::end()
mQuery->end(); mQuery->end();
device->removeQuery(mQuery); device->removeQuery(mQuery);
device->setOcclusionEnabled(false); switch(mType)
{
case GL_ANY_SAMPLES_PASSED_EXT:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
device->setOcclusionEnabled(false);
break;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
device->setTransformFeedbackQueryEnabled(false);
break;
default:
ASSERT(false);
}
mStatus = GL_FALSE; mStatus = GL_FALSE;
mResult = GL_FALSE; mResult = GL_FALSE;
} }
...@@ -105,17 +141,17 @@ GLboolean Query::testQuery() ...@@ -105,17 +141,17 @@ GLboolean Query::testQuery()
{ {
if(!mQuery->building && mQuery->reference == 0) if(!mQuery->building && mQuery->reference == 0)
{ {
unsigned int numPixels = mQuery->data; unsigned int resultSum = mQuery->data;
mStatus = GL_TRUE; mStatus = GL_TRUE;
switch(mType) switch(mType)
{ {
case GL_ANY_SAMPLES_PASSED_EXT: case GL_ANY_SAMPLES_PASSED_EXT:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; mResult = (resultSum > 0) ? GL_TRUE : GL_FALSE;
break; break;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
UNIMPLEMENTED(); mResult = resultSum;
break; break;
default: default:
ASSERT(false); ASSERT(false);
......
...@@ -297,6 +297,8 @@ namespace sw ...@@ -297,6 +297,8 @@ namespace sw
instanceID = 0; instanceID = 0;
occlusionEnabled = false; occlusionEnabled = false;
transformFeedbackQueryEnabled = false;
transformFeedbackEnabled = false;
pointSpriteEnable = false; pointSpriteEnable = false;
pointScaleEnable = false; pointScaleEnable = false;
......
...@@ -492,6 +492,8 @@ namespace sw ...@@ -492,6 +492,8 @@ namespace sw
bool colorVertexEnable; bool colorVertexEnable;
bool occlusionEnabled; bool occlusionEnabled;
bool transformFeedbackQueryEnabled;
bool transformFeedbackEnabled;
// Pixel processor states // Pixel processor states
bool rasterizerDiscard; bool rasterizerDiscard;
......
...@@ -303,12 +303,17 @@ namespace sw ...@@ -303,12 +303,17 @@ namespace sw
if(queries.size() != 0) if(queries.size() != 0)
{ {
draw->queries = new std::list<Query*>();
bool includePrimitivesWrittenQueries = vertexState.transformFeedbackQueryEnabled && vertexState.transformFeedbackEnabled;
for(std::list<Query*>::iterator query = queries.begin(); query != queries.end(); query++) for(std::list<Query*>::iterator query = queries.begin(); query != queries.end(); query++)
{ {
atomicIncrement(&(*query)->reference); Query* q = *query;
if(includePrimitivesWrittenQueries || (q->type != Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN))
{
atomicIncrement(&(q->reference));
draw->queries->push_back(q);
}
} }
draw->queries = new std::list<Query*>(queries);
} }
draw->drawType = drawType; draw->drawType = drawType;
...@@ -881,12 +886,6 @@ namespace sw ...@@ -881,12 +886,6 @@ namespace sw
pixelProgress[cluster].processedPrimitives = primitive + count; pixelProgress[cluster].processedPrimitives = primitive + count;
if(pixelProgress[cluster].processedPrimitives >= draw.count)
{
pixelProgress[cluster].drawCall++;
pixelProgress[cluster].processedPrimitives = 0;
}
int ref = atomicDecrement(&primitiveProgress[unit].references); int ref = atomicDecrement(&primitiveProgress[unit].references);
if(ref == 0) if(ref == 0)
...@@ -911,9 +910,19 @@ namespace sw ...@@ -911,9 +910,19 @@ namespace sw
{ {
Query *query = *q; Query *query = *q;
for(int cluster = 0; cluster < clusterCount; cluster++) switch(query->type)
{ {
atomicAdd((volatile int*)&query->data, data.occlusion[cluster]); case Query::FRAGMENTS_PASSED:
for(int cluster = 0; cluster < clusterCount; cluster++)
{
atomicAdd((volatile int*)&query->data, data.occlusion[cluster]);
}
break;
case Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
atomicAdd((volatile int*)&query->data, pixelProgress[cluster].processedPrimitives);
break;
default:
break;
} }
atomicDecrement(&query->reference); atomicDecrement(&query->reference);
...@@ -972,6 +981,12 @@ namespace sw ...@@ -972,6 +981,12 @@ namespace sw
} }
} }
if(pixelProgress[cluster].processedPrimitives >= draw.count)
{
pixelProgress[cluster].drawCall++;
pixelProgress[cluster].processedPrimitives = 0;
}
pixelProgress[cluster].executing = false; pixelProgress[cluster].executing = false;
} }
......
...@@ -86,11 +86,10 @@ namespace sw ...@@ -86,11 +86,10 @@ namespace sw
struct Query struct Query
{ {
Query() enum Type { FRAGMENTS_PASSED, TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN };
Query(Type type) : building(false), reference(0), data(0), type(type)
{ {
building = false;
reference = 0;
data = 0;
} }
void begin() void begin()
...@@ -107,6 +106,8 @@ namespace sw ...@@ -107,6 +106,8 @@ namespace sw
bool building; bool building;
volatile int reference; volatile int reference;
volatile unsigned int data; volatile unsigned int data;
const Type type;
}; };
struct DrawData struct DrawData
......
...@@ -642,6 +642,16 @@ namespace sw ...@@ -642,6 +642,16 @@ namespace sw
point.pointScaleC = pointScaleC; point.pointScaleC = pointScaleC;
} }
void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
{
context->transformFeedbackQueryEnabled = enable;
}
void VertexProcessor::enableTransformFeedback(uint64_t enable)
{
context->transformFeedbackEnabled = enable;
}
const Matrix &VertexProcessor::getModelTransform(int i) const Matrix &VertexProcessor::getModelTransform(int i)
{ {
updateTransform(); updateTransform();
...@@ -873,6 +883,9 @@ namespace sw ...@@ -873,6 +883,9 @@ namespace sw
state.superSampling = context->getSuperSampleCount() > 1; state.superSampling = context->getSuperSampleCount() > 1;
state.multiSampling = context->getMultiSampleCount() > 1; state.multiSampling = context->getMultiSampleCount() > 1;
state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
state.transformFeedbackEnabled = context->transformFeedbackEnabled;
for(int i = 0; i < VERTEX_ATTRIBUTES; i++) for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
{ {
state.input[i].type = context->input[i].type; state.input[i].type = context->input[i].type;
......
...@@ -69,6 +69,8 @@ namespace sw ...@@ -69,6 +69,8 @@ namespace sw
bool localViewerActive : 1; bool localViewerActive : 1;
bool pointSizeActive : 1; bool pointSizeActive : 1;
bool pointScaleActive : 1; bool pointScaleActive : 1;
bool transformFeedbackQueryEnabled : 1;
uint64_t transformFeedbackEnabled : 64;
bool preTransformed : 1; bool preTransformed : 1;
bool superSampling : 1; bool superSampling : 1;
...@@ -259,6 +261,9 @@ namespace sw ...@@ -259,6 +261,9 @@ namespace sw
virtual void setPointScaleB(float pointScaleB); virtual void setPointScaleB(float pointScaleB);
virtual void setPointScaleC(float pointScaleC); virtual void setPointScaleC(float pointScaleC);
virtual void setTransformFeedbackQueryEnabled(bool enable);
virtual void enableTransformFeedback(uint64_t enable);
protected: protected:
const Matrix &getModelTransform(int i); const Matrix &getModelTransform(int i);
const Matrix &getViewTransform(); const Matrix &getViewTransform();
......
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