Commit 8664b063 by Jamie Madill

Add logic for dynamic converstion of int to float vertex data.

We can use the format tables and input layout to determine when we need to generate conversion code in the vertex shader. BUG=angle:560 Change-Id: Ib64fb16823bf78ed6432fba283b0d24bcb673a76 Reviewed-on: https://chromium-review.googlesource.com/185195Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent c5ede1a7
...@@ -14,58 +14,70 @@ ...@@ -14,58 +14,70 @@
#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/Renderer.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/formatutils.h"
#include "compiler/translator/HLSLLayoutEncoder.h" #include "compiler/translator/HLSLLayoutEncoder.h"
static std::string Str(int i)
{
char buffer[20];
snprintf(buffer, sizeof(buffer), "%d", i);
return buffer;
}
namespace gl_d3d namespace gl_d3d
{ {
std::string TypeString(GLenum type) std::string HLSLComponentTypeString(GLenum componentType)
{ {
switch (type) switch (componentType)
{ {
case GL_FLOAT: return "float"; case GL_UNSIGNED_INT: return "uint";
case GL_FLOAT_VEC2: return "float2"; case GL_INT: return "int";
case GL_FLOAT_VEC3: return "float3"; case GL_UNSIGNED_NORMALIZED:
case GL_FLOAT_VEC4: return "float4"; case GL_SIGNED_NORMALIZED:
case GL_INT: return "int"; case GL_FLOAT: return "float";
case GL_INT_VEC2: return "int2"; default: UNREACHABLE(); return "not-component-type";
case GL_INT_VEC3: return "int3";
case GL_INT_VEC4: return "int4";
case GL_UNSIGNED_INT: return "uint";
case GL_UNSIGNED_INT_VEC2: return "uint2";
case GL_UNSIGNED_INT_VEC3: return "uint3";
case GL_UNSIGNED_INT_VEC4: return "uint4";
case GL_FLOAT_MAT2: return "float2x2";
case GL_FLOAT_MAT3: return "float3x3";
case GL_FLOAT_MAT4: return "float4x4";
case GL_FLOAT_MAT2x3: return "float2x3";
case GL_FLOAT_MAT3x2: return "float3x2";
case GL_FLOAT_MAT2x4: return "float2x4";
case GL_FLOAT_MAT4x2: return "float4x2";
case GL_FLOAT_MAT3x4: return "float3x4";
case GL_FLOAT_MAT4x3: return "float4x3";
default: UNREACHABLE(); return "invalid-gl-type";
} }
} }
std::string HLSLComponentTypeString(GLenum componentType, int componentCount)
{
return HLSLComponentTypeString(componentType) + (componentCount > 1 ? Str(componentCount) : "");
} }
namespace gl std::string HLSLMatrixTypeString(GLenum type)
{ {
switch (type)
{
case GL_FLOAT_MAT2: return "float2x2";
case GL_FLOAT_MAT3: return "float3x3";
case GL_FLOAT_MAT4: return "float4x4";
case GL_FLOAT_MAT2x3: return "float2x3";
case GL_FLOAT_MAT3x2: return "float3x2";
case GL_FLOAT_MAT2x4: return "float2x4";
case GL_FLOAT_MAT4x2: return "float4x2";
case GL_FLOAT_MAT3x4: return "float3x4";
case GL_FLOAT_MAT4x3: return "float4x3";
default: UNREACHABLE(); return "not-matrix-type";
}
}
static std::string Str(int i) std::string HLSLTypeString(GLenum type)
{ {
char buffer[20]; if (gl::IsMatrixType(type))
snprintf(buffer, sizeof(buffer), "%d", i); {
return buffer; return HLSLMatrixTypeString(type);
}
return HLSLComponentTypeString(gl::UniformComponentType(type), gl::UniformComponentCount(type));
} }
static std::string ArrayString(int i)
{
return "[" + Str(i) + "]";
} }
namespace gl
{
std::string ArrayString(unsigned int i) std::string ArrayString(unsigned int i)
{ {
return (i == GL_INVALID_INDEX ? "" : "[" + Str(i) + "]"); return (i == GL_INVALID_INDEX ? "" : "[" + Str(i) + "]");
...@@ -259,9 +271,10 @@ std::string DynamicHLSL::generateVaryingHLSL(FragmentShader *fragmentShader, con ...@@ -259,9 +271,10 @@ std::string DynamicHLSL::generateVaryingHLSL(FragmentShader *fragmentShader, con
std::string n = Str(varying->registerIndex + elementIndex * variableRows + row); std::string n = Str(varying->registerIndex + elementIndex * variableRows + row);
// matrices within structs are not transposed, hence we do not use the special struct prefix "rm" // matrices within structs are not transposed, hence we do not use the special struct prefix "rm"
std::string typeString = varying->isStruct() ? "_" + varying->structName : GLenum componentType = gl::UniformComponentType(transposedType);
gl_d3d::TypeString(UniformComponentType(transposedType)) + Str(VariableColumnCount(transposedType)); int columnCount = gl::VariableColumnCount(transposedType);
std::string componentTypeString = gl_d3d::HLSLComponentTypeString(componentType, columnCount);
std::string typeString = (varying->isStruct() ? "_" + varying->structName : componentTypeString);
varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n"; varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n";
} }
} }
...@@ -282,14 +295,24 @@ std::string DynamicHLSL::generateInputLayoutHLSL(const VertexFormat inputLayout[ ...@@ -282,14 +295,24 @@ std::string DynamicHLSL::generateInputLayoutHLSL(const VertexFormat inputLayout[
int semanticIndex = 0; int semanticIndex = 0;
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
const sh::Attribute &attribute = shaderAttributes[attributeIndex]; const VertexFormat &vertexFormat = inputLayout[attributeIndex];
const sh::Attribute &shaderAttribute = shaderAttributes[attributeIndex];
if (!attribute.name.empty()) if (!shaderAttribute.name.empty())
{ {
vertexHLSL += " " + gl_d3d::TypeString(TransposeMatrixType(attribute.type)) + " "; if (IsMatrixType(shaderAttribute.type))
vertexHLSL += decorateAttribute(attribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n"; {
// Matrix types are always transposed
vertexHLSL += " " + gl_d3d::HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
}
else
{
GLenum componentType = mRenderer->getVertexComponentType(vertexFormat);
vertexHLSL += " " + gl_d3d::HLSLComponentTypeString(componentType, UniformComponentCount(shaderAttribute.type));
}
semanticIndex += AttributeRegisterCount(attribute.type); vertexHLSL += " " + decorateAttribute(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
semanticIndex += AttributeRegisterCount(shaderAttribute.type);
} }
} }
...@@ -300,13 +323,26 @@ std::string DynamicHLSL::generateInputLayoutHLSL(const VertexFormat inputLayout[ ...@@ -300,13 +323,26 @@ std::string DynamicHLSL::generateInputLayoutHLSL(const VertexFormat inputLayout[
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
const sh::ShaderVariable &attribute = shaderAttributes[attributeIndex]; const VertexFormat &vertexFormat = inputLayout[attributeIndex];
const sh::Attribute &shaderAttribute = shaderAttributes[attributeIndex];
if (!attribute.name.empty()) if (!shaderAttribute.name.empty())
{ {
vertexHLSL += " " + decorateAttribute(attribute.name) + " = "; vertexHLSL += " " + decorateAttribute(shaderAttribute.name) + " = ";
vertexHLSL += generateAttributeConversionHLSL(inputLayout[attributeIndex], attribute);
vertexHLSL += "(input." + decorateAttribute(attribute.name) + ");\n"; // Mismatched vertex attribute to vertex input may result in an undefined
// data reinterpretation (eg for pure integer->float, float->pure integer)
// TODO: issue warning with gl debug info extension, when supported
if ((mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0)
{
vertexHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute);
}
else
{
vertexHLSL += "input." + decorateAttribute(shaderAttribute.name);
}
vertexHLSL += ";\n";
} }
} }
...@@ -581,7 +617,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const ...@@ -581,7 +617,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element)); const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
pixelHLSL += " " + gl_d3d::TypeString(outputVariable.type) + pixelHLSL += " " + gl_d3d::HLSLTypeString(outputVariable.type) +
" out_" + outputLocation.name + elementString + " out_" + outputLocation.name + elementString +
" : " + targetSemantic + Str(locationIt->first) + ";\n"; " : " + targetSemantic + Str(locationIt->first) + ";\n";
} }
...@@ -904,16 +940,32 @@ std::string DynamicHLSL::decorateAttribute(const std::string &name) ...@@ -904,16 +940,32 @@ std::string DynamicHLSL::decorateAttribute(const std::string &name)
std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const
{ {
std::string attribString = "input." + decorateAttribute(shaderAttrib.name);
// Matrix // Matrix
if (IsMatrixType(shaderAttrib.type)) if (IsMatrixType(shaderAttrib.type))
{ {
return "transpose"; return "transpose(" + attribString + ")";
} }
// TODO: un-normalized integer data GLenum shaderComponentType = UniformComponentType(shaderAttrib.type);
int shaderComponentCount = UniformComponentCount(shaderAttrib.type);
std::string padString = "";
// Perform integer to float conversion (if necessary)
bool requiresTypeConversion = (shaderComponentType == GL_FLOAT && vertexFormat.mType != GL_FLOAT);
// TODO: normalization for 32-bit integer formats
ASSERT(!requiresTypeConversion || !vertexFormat.mNormalized);
if (requiresTypeConversion || !padString.empty())
{
return "float" + Str(shaderComponentCount) + "(" + attribString + padString + ")";
}
// No conversion necessary // No conversion necessary
return ""; return attribString;
} }
} }
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