Implement flat and centroid interpolation in HLSL.

TRAC #22857 Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2154 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 7bc65f2e
......@@ -196,7 +196,8 @@ void OutputHLSL::header()
const TString &name = varying->second->getSymbol();
// Program linking depends on this exact format
varyings += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
varyings += "static " + interpolationString(type.getQualifier()) + " " + typeString(type) + " " +
decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
}
for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
......@@ -2547,6 +2548,26 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
return qualifierString(qualifier) + " " + typeString(type) + " " + name + arrayString(type);
}
TString OutputHLSL::interpolationString(TQualifier qualifier)
{
switch(qualifier)
{
case EvqVaryingIn: return "";
case EvqInvariantVaryingIn: return "";
case EvqSmoothIn: return "linear";
case EvqFlatIn: return "nointerpolation";
case EvqCentroidIn: return "centroid";
case EvqVaryingOut: return "";
case EvqInvariantVaryingOut: return "";
case EvqSmoothOut: return "linear";
case EvqFlatOut: return "nointerpolation";
case EvqCentroidOut: return "centroid";
default: UNREACHABLE();
}
return "";
}
TString OutputHLSL::qualifierString(TQualifier qualifier)
{
switch(qualifier)
......
......@@ -36,6 +36,7 @@ class OutputHLSL : public TIntermTraverser
TString typeString(const TType &type);
TString textureString(const TType &type);
TString interpolationString(TQualifier qualifier);
static TString qualifierString(TQualifier qualifier);
static TString arrayString(const TType &type);
static TString initializer(const TType &type);
......
......@@ -929,7 +929,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
{
if (output->name == input->name)
{
if (output->type != input->type || output->size != input->size)
if (output->type != input->type || output->size != input->size || output->interpolation != input->interpolation)
{
infoLog.append("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
......
......@@ -273,17 +273,31 @@ void Shader::parseVaryings()
while(true)
{
char varyingType[256];
char varyingName[256];
char string1[256];
char string2[256];
char string3[256];
int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
int matches = sscanf(input, "static %255s %255s %255s", string1, string2, string3);
if (matches != 2)
char *interpolation = "linear"; // Default
char *type = string1;
char *name = string2;
if (matches == 0)
{
break;
}
else if (matches == 3)
{
if (string3[0] != '=') // Explicit interpolation qualifier
{
type = string2;
name = string3;
}
}
else UNREACHABLE();
char *array = strstr(varyingName, "[");
char *array = strstr(name, "[");
int size = 1;
if (array)
......@@ -292,7 +306,7 @@ void Shader::parseVaryings()
*array = '\0';
}
mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
mVaryings.push_back(Varying(parseInterpolation(interpolation), parseType(type), name, size, array != NULL));
input = strstr(input, ";") + 2;
}
......@@ -409,6 +423,25 @@ void Shader::compileToHLSL(void *compiler)
}
}
Interpolation Shader::parseInterpolation(const std::string &type)
{
if (type == "linear")
{
return Smooth;
}
else if (type == "centroid")
{
return Centroid;
}
else if (type == "nointerpolation")
{
return Flat;
}
else UNREACHABLE();
return Smooth;
}
GLenum Shader::parseType(const std::string &type)
{
if (type == "float")
......
......@@ -31,13 +31,21 @@ namespace gl
{
class ResourceManager;
enum Interpolation
{
Smooth,
Centroid,
Flat
};
struct Varying
{
Varying(GLenum type, const std::string &name, int size, bool array)
: type(type), name(name), size(size), array(array), reg(-1), col(-1)
Varying(Interpolation interpolation, GLenum type, const std::string &name, int size, bool array)
: interpolation(interpolation), type(type), name(name), size(size), array(array), reg(-1), col(-1)
{
}
Interpolation interpolation;
GLenum type;
std::string name;
int size; // Number of 'type' elements
......@@ -92,6 +100,7 @@ class Shader
void getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer);
static Interpolation parseInterpolation(const std::string &type);
static GLenum parseType(const std::string &type);
static bool compareVarying(const Varying &x, const Varying &y);
......
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