Commit 12b00506 by Alexis Hetu Committed by Nicolas Capens

Implement flat interpolation qualifier support.

By default vertex shader outputs/fragment shader inputs are smoothly interpolated. The 'flat' keyword can be used to change the interpolation to "flat", which basically means that no interpolation is performed. "flat" is the only interpolation qualifier accepted for integer types. This change fixes all shaders/precision dEQP tests as well as a few fragment output integer format types related tests. Change-Id: Ic64b0ec40c705d885c255b3b671cf7460965dfee Reviewed-on: https://swiftshader-review.googlesource.com/5390Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent e3c87461
...@@ -2568,6 +2568,12 @@ namespace glsl ...@@ -2568,6 +2568,12 @@ namespace glsl
return sw::Shader::PARAMETER_VOID; return sw::Shader::PARAMETER_VOID;
} }
bool OutputASM::hasFlatQualifier(TIntermTyped *operand)
{
const TQualifier qualifier = operand->getQualifier();
return qualifier == EvqFlat || qualifier == EvqFlatOut || qualifier == EvqFlatIn;
}
unsigned int OutputASM::registerIndex(TIntermTyped *operand) unsigned int OutputASM::registerIndex(TIntermTyped *operand)
{ {
if(isSamplerRegister(operand)) if(isSamplerRegister(operand))
...@@ -2778,10 +2784,12 @@ namespace glsl ...@@ -2778,10 +2784,12 @@ namespace glsl
{ {
for(int i = 0; i < varying->totalRegisterCount(); i++) for(int i = 0; i < varying->totalRegisterCount(); i++)
{ {
if(componentCount >= 1) pixelShader->semantic[var + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i); bool flat = hasFlatQualifier(varying);
if(componentCount >= 2) pixelShader->semantic[var + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
if(componentCount >= 3) pixelShader->semantic[var + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i); if(componentCount >= 1) pixelShader->semantic[var + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
if(componentCount >= 4) pixelShader->semantic[var + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i); if(componentCount >= 2) pixelShader->semantic[var + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
if(componentCount >= 3) pixelShader->semantic[var + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
if(componentCount >= 4) pixelShader->semantic[var + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
} }
} }
} }
......
...@@ -275,6 +275,7 @@ namespace glsl ...@@ -275,6 +275,7 @@ namespace glsl
void assignLvalue(TIntermTyped *dst, TIntermTyped *src); void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node); int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
sw::Shader::ParameterType registerType(TIntermTyped *operand); sw::Shader::ParameterType registerType(TIntermTyped *operand);
bool hasFlatQualifier(TIntermTyped *operand);
unsigned int registerIndex(TIntermTyped *operand); unsigned int registerIndex(TIntermTyped *operand);
int writeMask(TIntermTyped *destination, int index = 0); int writeMask(TIntermTyped *destination, int index = 0);
int readSwizzle(TIntermTyped *argument, int size); int readSwizzle(TIntermTyped *argument, int size);
......
...@@ -1332,10 +1332,12 @@ namespace es2 ...@@ -1332,10 +1332,12 @@ namespace es2
for(int i = 0; i < registers; i++) for(int i = 0; i < registers; i++)
{ {
if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i); bool flat = pixelBinary->semantic[in + i][0].flat;
if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i); if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i); if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
} }
} }
else // Vertex varying is declared but not written to else // Vertex varying is declared but not written to
......
...@@ -1075,14 +1075,16 @@ namespace sw ...@@ -1075,14 +1075,16 @@ namespace sw
{ {
for(int component = 0; component < 4; component++) for(int component = 0; component < 4; component++)
{ {
if(context->pixelShader->semantic[interpolant][component].active()) const Shader::Semantic &semantic = context->pixelShader->semantic[interpolant][component];
if(semantic.active())
{ {
bool flat = point; bool flat = point;
switch(context->pixelShader->semantic[interpolant][component].usage) switch(semantic.usage)
{ {
case Shader::USAGE_TEXCOORD: flat = point && !sprite; break; case Shader::USAGE_TEXCOORD: flat = point && !sprite; break;
case Shader::USAGE_COLOR: flat = flatShading; break; case Shader::USAGE_COLOR: flat = semantic.flat || flatShading; break;
} }
state.interpolant[interpolant].component |= 1 << component; state.interpolant[interpolant].component |= 1 << component;
......
...@@ -129,13 +129,14 @@ namespace sw ...@@ -129,13 +129,14 @@ namespace sw
for(int component = 0; component < 4; component++) for(int component = 0; component < 4; component++)
{ {
int project = context->isProjectionComponent(interpolant - 2, component) ? 1 : 0; int project = context->isProjectionComponent(interpolant - 2, component) ? 1 : 0;
const Shader::Semantic& semantic = context->pixelShader->semantic[interpolant][component - project];
if(context->pixelShader->semantic[interpolant][component - project].active()) if(semantic.active())
{ {
int input = interpolant; int input = interpolant;
for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++) for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
{ {
if(context->pixelShader->semantic[interpolant][component - project] == context->vertexShader->output[i][component - project]) if(semantic == context->vertexShader->output[i][component - project])
{ {
input = i; input = i;
break; break;
...@@ -144,10 +145,10 @@ namespace sw ...@@ -144,10 +145,10 @@ namespace sw
bool flat = point; bool flat = point;
switch(context->pixelShader->semantic[interpolant][component - project].usage) switch(semantic.usage)
{ {
case Shader::USAGE_TEXCOORD: flat = point && !sprite; break; case Shader::USAGE_TEXCOORD: flat = point && !sprite; break;
case Shader::USAGE_COLOR: flat = flatShading; break; case Shader::USAGE_COLOR: flat = semantic.flat || flatShading; break;
} }
state.gradient[interpolant][component].attribute = input; state.gradient[interpolant][component].attribute = input;
...@@ -162,19 +163,19 @@ namespace sw ...@@ -162,19 +163,19 @@ namespace sw
{ {
for(int component = 0; component < 4; component++) for(int component = 0; component < 4; component++)
{ {
int index = context->pixelShader->semantic[interpolant][component].index; const Shader::Semantic& semantic = context->pixelShader->semantic[interpolant][component];
switch(context->pixelShader->semantic[interpolant][component].usage) switch(semantic.usage)
{ {
case 0xFF: case 0xFF:
break; break;
case Shader::USAGE_TEXCOORD: case Shader::USAGE_TEXCOORD:
state.gradient[interpolant][component].attribute = T0 + index; state.gradient[interpolant][component].attribute = T0 + semantic.index;
state.gradient[interpolant][component].flat = point && !sprite; state.gradient[interpolant][component].flat = semantic.flat || (point && !sprite);
break; break;
case Shader::USAGE_COLOR: case Shader::USAGE_COLOR:
state.gradient[interpolant][component].attribute = C0 + index; state.gradient[interpolant][component].attribute = C0 + semantic.index;
state.gradient[interpolant][component].flat = flatShading; state.gradient[interpolant][component].flat = semantic.flat || flatShading;
break; break;
default: default:
ASSERT(false); ASSERT(false);
......
...@@ -572,7 +572,7 @@ namespace sw ...@@ -572,7 +572,7 @@ namespace sw
struct Semantic struct Semantic
{ {
Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF) : usage(usage), index(index), centroid(false) Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF, bool flat = false) : usage(usage), index(index), centroid(false), flat(flat)
{ {
} }
...@@ -589,6 +589,7 @@ namespace sw ...@@ -589,6 +589,7 @@ namespace sw
unsigned char usage; unsigned char usage;
unsigned char index; unsigned char index;
bool centroid; bool centroid;
bool flat;
}; };
void optimize(); void optimize();
......
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