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
{
if(type == D3DQUERYTYPE_OCCLUSION)
{
query = new sw::Query();
query = new sw::Query(sw::Query::FRAGMENTS_PASSED);
}
else
{
......
......@@ -39,8 +39,19 @@ void Query::begin()
{
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)
{
return error(GL_OUT_OF_MEMORY);
......
......@@ -39,8 +39,22 @@ void Query::begin()
{
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)
{
return error(GL_OUT_OF_MEMORY);
......@@ -51,7 +65,18 @@ void Query::begin()
mQuery->begin();
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()
......@@ -65,8 +90,19 @@ void Query::end()
mQuery->end();
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;
mResult = GL_FALSE;
}
......@@ -105,17 +141,17 @@ GLboolean Query::testQuery()
{
if(!mQuery->building && mQuery->reference == 0)
{
unsigned int numPixels = mQuery->data;
unsigned int resultSum = mQuery->data;
mStatus = GL_TRUE;
switch(mType)
{
case GL_ANY_SAMPLES_PASSED_EXT:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
mResult = (resultSum > 0) ? GL_TRUE : GL_FALSE;
break;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
UNIMPLEMENTED();
mResult = resultSum;
break;
default:
ASSERT(false);
......
......@@ -297,6 +297,8 @@ namespace sw
instanceID = 0;
occlusionEnabled = false;
transformFeedbackQueryEnabled = false;
transformFeedbackEnabled = false;
pointSpriteEnable = false;
pointScaleEnable = false;
......
......@@ -492,6 +492,8 @@ namespace sw
bool colorVertexEnable;
bool occlusionEnabled;
bool transformFeedbackQueryEnabled;
bool transformFeedbackEnabled;
// Pixel processor states
bool rasterizerDiscard;
......
......@@ -303,12 +303,17 @@ namespace sw
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++)
{
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;
......@@ -881,12 +886,6 @@ namespace sw
pixelProgress[cluster].processedPrimitives = primitive + count;
if(pixelProgress[cluster].processedPrimitives >= draw.count)
{
pixelProgress[cluster].drawCall++;
pixelProgress[cluster].processedPrimitives = 0;
}
int ref = atomicDecrement(&primitiveProgress[unit].references);
if(ref == 0)
......@@ -911,9 +910,19 @@ namespace sw
{
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);
......@@ -972,6 +981,12 @@ namespace sw
}
}
if(pixelProgress[cluster].processedPrimitives >= draw.count)
{
pixelProgress[cluster].drawCall++;
pixelProgress[cluster].processedPrimitives = 0;
}
pixelProgress[cluster].executing = false;
}
......
......@@ -86,11 +86,10 @@ namespace sw
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()
......@@ -107,6 +106,8 @@ namespace sw
bool building;
volatile int reference;
volatile unsigned int data;
const Type type;
};
struct DrawData
......
......@@ -642,6 +642,16 @@ namespace sw
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)
{
updateTransform();
......@@ -873,6 +883,9 @@ namespace sw
state.superSampling = context->getSuperSampleCount() > 1;
state.multiSampling = context->getMultiSampleCount() > 1;
state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
state.transformFeedbackEnabled = context->transformFeedbackEnabled;
for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
{
state.input[i].type = context->input[i].type;
......
......@@ -69,6 +69,8 @@ namespace sw
bool localViewerActive : 1;
bool pointSizeActive : 1;
bool pointScaleActive : 1;
bool transformFeedbackQueryEnabled : 1;
uint64_t transformFeedbackEnabled : 64;
bool preTransformed : 1;
bool superSampling : 1;
......@@ -259,6 +261,9 @@ namespace sw
virtual void setPointScaleB(float pointScaleB);
virtual void setPointScaleC(float pointScaleC);
virtual void setTransformFeedbackQueryEnabled(bool enable);
virtual void enableTransformFeedback(uint64_t enable);
protected:
const Matrix &getModelTransform(int i);
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