Commit c5ede1a7 by Jamie Madill

Add logic for inserting vertex conversion code in HLSL.

The patch refactors the vertex input HLSL to allow for dynamic conversion in the future. Using a placehold keyword, the code replaces that stub with the vertex input conversion logic. BUG=angle:560 Change-Id: I100c50cb4decd45b0f0c10d7c2c22583368b773e Reviewed-on: https://chromium-review.googlesource.com/185194Reviewed-by: 's avatarNicolas Capens <nicolascapens@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 2c7d84ac
......@@ -71,6 +71,8 @@ std::string ArrayString(unsigned int i)
return (i == GL_INVALID_INDEX ? "" : "[" + Str(i) + "]");
}
const std::string DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
DynamicHLSL::DynamicHLSL(rx::Renderer *const renderer)
: mRenderer(renderer)
{
......@@ -270,6 +272,49 @@ std::string DynamicHLSL::generateVaryingHLSL(FragmentShader *fragmentShader, con
return varyingHLSL;
}
std::string DynamicHLSL::generateInputLayoutHLSL(const VertexFormat inputLayout[], const sh::Attribute shaderAttributes[]) const
{
std::string vertexHLSL;
vertexHLSL += "struct VS_INPUT\n"
"{\n";
int semanticIndex = 0;
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const sh::Attribute &attribute = shaderAttributes[attributeIndex];
if (!attribute.name.empty())
{
vertexHLSL += " " + gl_d3d::TypeString(TransposeMatrixType(attribute.type)) + " ";
vertexHLSL += decorateAttribute(attribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
semanticIndex += AttributeRegisterCount(attribute.type);
}
}
vertexHLSL += "};\n"
"\n"
"void initAttributes(VS_INPUT input)\n"
"{\n";
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const sh::ShaderVariable &attribute = shaderAttributes[attributeIndex];
if (!attribute.name.empty())
{
vertexHLSL += " " + decorateAttribute(attribute.name) + " = ";
vertexHLSL += generateAttributeConversionHLSL(inputLayout[attributeIndex], attribute);
vertexHLSL += "(input." + decorateAttribute(attribute.name) + ");\n";
}
}
vertexHLSL += "}\n";
return vertexHLSL;
}
bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const sh::ShaderVariable *packing[][4],
std::string& pixelHLSL, std::string& vertexHLSL,
FragmentShader *fragmentShader, VertexShader *vertexShader,
......@@ -341,23 +386,10 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
}
}
vertexHLSL += "struct VS_INPUT\n"
"{\n";
// Add stub string to be replaced when shader is dynamically defined by its layout
vertexHLSL += "\n" + VERTEX_ATTRIBUTE_STUB_STRING + "\n";
int semanticIndex = 0;
const std::vector<sh::Attribute> &activeAttributes = vertexShader->mActiveAttributes;
for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
const sh::Attribute &attribute = activeAttributes[attributeIndex];
vertexHLSL += " " + gl_d3d::TypeString(TransposeMatrixType(attribute.type)) + " ";
vertexHLSL += decorateAttribute(attribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
semanticIndex += AttributeRegisterCount(attribute.type);
}
vertexHLSL += "};\n"
"\n"
"struct VS_OUTPUT\n"
vertexHLSL += "struct VS_OUTPUT\n"
"{\n";
if (shaderModel < 4)
......@@ -385,20 +417,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
vertexHLSL += "};\n"
"\n"
"VS_OUTPUT main(VS_INPUT input)\n"
"{\n";
for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
vertexHLSL += " " + decorateAttribute(attribute.name) + " = ";
if (IsMatrixType(attribute.type)) // Matrix
{
vertexHLSL += "transpose";
}
vertexHLSL += "(input." + decorateAttribute(attribute.name) + ");\n";
}
"{\n"
" initAttributes(input);\n";
if (shaderModel >= 4)
{
......@@ -882,4 +902,18 @@ std::string DynamicHLSL::decorateAttribute(const std::string &name)
return name;
}
std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const
{
// Matrix
if (IsMatrixType(shaderAttrib.type))
{
return "transpose";
}
// TODO: un-normalized integer data
// No conversion necessary
return "";
}
}
......@@ -14,6 +14,7 @@
namespace sh
{
struct ShaderVariable;
struct Attribute;
}
namespace rx
......@@ -28,6 +29,8 @@ class InfoLog;
class FragmentShader;
class VertexShader;
struct VariableLocation;
class VertexAttribute;
struct VertexFormat;
class DynamicHLSL
{
......@@ -35,6 +38,7 @@ class DynamicHLSL
explicit DynamicHLSL(rx::Renderer *const renderer);
int packVaryings(InfoLog &infoLog, const sh::ShaderVariable *packing[][4], FragmentShader *fragmentShader);
std::string generateInputLayoutHLSL(const VertexFormat inputLayout[], const sh::Attribute shaderAttributes[]) const;
bool generateShaderLinkHLSL(InfoLog &infoLog, int registers, const sh::ShaderVariable *packing[][4],
std::string& pixelHLSL, std::string& vertexHLSL,
FragmentShader *fragmentShader, VertexShader *vertexShader,
......@@ -42,6 +46,8 @@ class DynamicHLSL
std::string generateGeometryShaderHLSL(int registers, const sh::ShaderVariable *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
static const std::string VERTEX_ATTRIBUTE_STUB_STRING;
private:
DISALLOW_COPY_AND_ASSIGN(DynamicHLSL);
......@@ -53,6 +59,8 @@ class DynamicHLSL
// Prepend an underscore
static std::string decorateAttribute(const std::string &name);
std::string generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const;
};
// Utility method shared between ProgramBinary and DynamicHLSL
......
......@@ -192,9 +192,17 @@ rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const Ver
}
}
// Generate new dynamic layout with attribute conversions
const std::string &layoutHLSL = mDynamicHLSL->generateInputLayoutHLSL(inputLayout, mShaderAttributes);
// Generate new shader source by replacing the attributes stub with the defined input layout
std::string vertexHLSL = mVertexHLSL;
size_t insertPos = vertexHLSL.find(DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING);
vertexHLSL.replace(insertPos, DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING.length(), layoutHLSL);
// Generate new vertex executable
InfoLog tempInfoLog;
rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, mVertexHLSL.c_str(), rx::SHADER_VERTEX, mVertexWorkarounds);
rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX, mVertexWorkarounds);
if (!vertexExecutable)
{
......
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