ProgramD3D: Move some common code into a Metadata class.
This metadata class captures some of our commonly referenced but also
complex flats into a shared place. We can then re-use them in the
semantic code, the DynamicHLSL linking code, and the program code.
Refactoring patch only.
BUG=angleproject:1202
Change-Id: I8b6088cfa5488c5173a6f06c15abab5a4ead4cb8
Reviewed-on: https://chromium-review.googlesource.com/311700
Tryjob-Request: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
index 0640407..8f5f006 100644
--- a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -444,14 +444,13 @@
bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
const gl::Program::Data &programData,
+ const ProgramD3DMetadata &programMetadata,
InfoLog &infoLog,
unsigned int registerCount,
std::string *pixelHLSL,
std::string *vertexHLSL,
const std::vector<PackedVarying> &packedVaryings,
- std::vector<D3DVarying> *d3dVaryingsOut,
- std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
- bool *outUsesFragDepth) const
+ std::vector<D3DVarying> *d3dVaryingsOut) const
{
ASSERT(pixelHLSL->empty() && vertexHLSL->empty());
@@ -461,15 +460,12 @@
const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(fragmentShaderGL);
const int shaderModel = mRenderer->getMajorShaderModel();
- bool usesMRT = fragmentShader->usesMultipleRenderTargets();
- bool usesFragCoord = fragmentShader->usesFragCoord();
+ bool usesFragCoord = programMetadata.usesFragCoord();
bool usesPointCoord = fragmentShader->usesPointCoord();
bool usesPointSize = vertexShader->usesPointSize();
bool useInstancedPointSpriteEmulation =
- usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
- bool insertDummyPointCoordValue = !usesPointSize && usesPointCoord && shaderModel >= 4;
- bool addPointCoord =
- (useInstancedPointSpriteEmulation && usesPointCoord) || insertDummyPointCoordValue;
+ programMetadata.usesPointSize() &&
+ mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
// Validation done in the compiler
ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData());
@@ -478,19 +474,6 @@
const unsigned int registersNeeded =
registerCount + (usesFragCoord ? 1u : 0u) + (usesPointCoord ? 1u : 0u);
- // Two cases when writing to gl_FragColor and using ESSL 1.0:
- // - with a 3.0 context, the output color is copied to channel 0
- // - with a 2.0 context, the output color is broadcast to all channels
- const bool broadcast = (fragmentShader->usesFragColor() && data.clientVersion < 3);
- const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1);
-
- // gl_Position only needs to be outputted from the vertex shader if transform feedback is
- // active. This isn't supported on D3D11 Feature Level 9_3, so we don't output gl_Position from
- // the vertex shader in this case. This saves us 1 output vector.
- bool outputPositionFromVS = !(shaderModel >= 4 && mRenderer->getShaderModelSuffix() != "");
-
- int shaderVersion = vertexShaderGL->getShaderVersion();
-
if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
{
infoLog << "No varying registers left to support gl_FragCoord/gl_PointCoord";
@@ -504,9 +487,8 @@
// PS_INPUT of the generated pixel shader. The Geometry Shader point sprite implementation needs
// gl_PointSize to be in VS_OUTPUT and GS_INPUT. Instanced point sprites doesn't need
// gl_PointSize in VS_OUTPUT.
- const SemanticInfo &vertexSemantics = GetSemanticInfo(
- SHADER_VERTEX, shaderModel, registerCount, outputPositionFromVS, usesFragCoord,
- addPointCoord, (!useInstancedPointSpriteEmulation && usesPointSize));
+ const SemanticInfo &vertexSemantics =
+ GetSemanticInfo(SHADER_VERTEX, programMetadata, registerCount);
storeUserVaryings(packedVaryings, usesPointSize, d3dVaryingsOut);
storeBuiltinVaryings(vertexSemantics, d3dVaryingsOut);
@@ -545,7 +527,7 @@
<< "\n"
<< " VS_OUTPUT output;\n";
- if (outputPositionFromVS)
+ if (vertexSemantics.glPosition.enabled)
{
vertexStream << " output.gl_Position = gl_Position;\n";
}
@@ -614,7 +596,7 @@
"gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * "
"output.dx_Position.w;\n";
- if (usesPointCoord)
+ if (programMetadata.usesPointCoord())
{
vertexStream << "\n"
<< " output.gl_PointCoord = input.spriteTexCoord;\n";
@@ -624,7 +606,7 @@
// Renderers that enable instanced pointsprite emulation require the vertex shader output member
// gl_PointCoord to be set to a default value if used without gl_PointSize. 0.5,0.5 is the same
// default value used in the generated pixel shader.
- if (insertDummyPointCoordValue)
+ if (programMetadata.usesInsertedPointCoordValue())
{
ASSERT(!useInstancedPointSpriteEmulation);
vertexStream << "\n"
@@ -638,57 +620,13 @@
std::stringstream pixelStream;
pixelStream << fragmentShaderGL->getTranslatedSource();
- const SemanticInfo &pixelSemantics = GetSemanticInfo(
- SHADER_PIXEL, shaderModel, registerCount, outputPositionFromVS, usesFragCoord,
- usesPointCoord, (!useInstancedPointSpriteEmulation && usesPointSize));
+ const SemanticInfo &pixelSemantics =
+ GetSemanticInfo(SHADER_PIXEL, programMetadata, registerCount);
pixelStream << "struct PS_INPUT\n";
generateVaryingLinkHLSL(*data.caps, usesPointSize, pixelSemantics, packedVaryings, pixelStream);
pixelStream << "\n";
- if (shaderVersion < 300)
- {
- for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets;
- renderTargetIndex++)
- {
- PixelShaderOutputVariable outputKeyVariable;
- outputKeyVariable.type = GL_FLOAT_VEC4;
- outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex);
- outputKeyVariable.source =
- broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]";
- outputKeyVariable.outputIndex = renderTargetIndex;
-
- outPixelShaderKey->push_back(outputKeyVariable);
- }
-
- *outUsesFragDepth = fragmentShader->usesFragDepth();
- }
- else
- {
- const auto &shaderOutputVars = fragmentShaderGL->getActiveOutputVariables();
-
- for (auto outputPair : programData.getOutputVariables())
- {
- const VariableLocation &outputLocation = outputPair.second;
- const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
- const std::string &variableName = "out_" + outputLocation.name;
- const std::string &elementString =
- (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
-
- ASSERT(outputVariable.staticUse);
-
- PixelShaderOutputVariable outputKeyVariable;
- outputKeyVariable.type = outputVariable.type;
- outputKeyVariable.name = variableName + elementString;
- outputKeyVariable.source = variableName + ArrayString(outputLocation.element);
- outputKeyVariable.outputIndex = outputPair.first;
-
- outPixelShaderKey->push_back(outputKeyVariable);
- }
-
- *outUsesFragDepth = false;
- }
-
pixelStream << PIXEL_OUTPUT_STUB_STRING + "\n";
if (fragmentShader->usesFrontFacing())
@@ -830,6 +768,7 @@
std::string DynamicHLSL::generateGeometryShaderPreamble(
const gl::Data &data,
const gl::Program::Data &programData,
+ const ProgramD3DMetadata &programMetadata,
unsigned int registerCount,
const std::vector<PackedVarying> &packedVaryings) const
{
@@ -844,14 +783,12 @@
ASSERT(vertexShader && fragmentShader);
bool usesFragCoord = fragmentShader->usesFragCoord();
- bool usesPointCoord = fragmentShader->usesPointCoord();
bool usesPointSize = vertexShader->usesPointSize();
- const SemanticInfo &inSemantics = GetSemanticInfo(
- SHADER_VERTEX, majorShaderModel, registerCount, true, usesFragCoord, false, usesPointSize);
+ const SemanticInfo &inSemantics =
+ GetSemanticInfo(SHADER_VERTEX, programMetadata, registerCount);
const SemanticInfo &outSemantics =
- GetSemanticInfo(SHADER_GEOMETRY, majorShaderModel, registerCount, true, usesFragCoord,
- usesPointCoord, usesPointSize);
+ GetSemanticInfo(SHADER_GEOMETRY, programMetadata, registerCount);
std::stringstream preambleStream;
@@ -1085,4 +1022,58 @@
// No conversion necessary
return attribString;
}
+
+void DynamicHLSL::getPixelShaderOutputKey(const gl::Data &data,
+ const gl::Program::Data &programData,
+ const ProgramD3DMetadata &metadata,
+ std::vector<PixelShaderOutputVariable> *outPixelShaderKey)
+{
+ // Two cases when writing to gl_FragColor and using ESSL 1.0:
+ // - with a 3.0 context, the output color is copied to channel 0
+ // - with a 2.0 context, the output color is broadcast to all channels
+ bool broadcast = metadata.usesBroadcast(data);
+ const unsigned int numRenderTargets =
+ (broadcast || metadata.usesMultipleFragmentOuts() ? data.caps->maxDrawBuffers : 1);
+
+ if (metadata.getMajorShaderVersion() < 300)
+ {
+ for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets;
+ renderTargetIndex++)
+ {
+ PixelShaderOutputVariable outputKeyVariable;
+ outputKeyVariable.type = GL_FLOAT_VEC4;
+ outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex);
+ outputKeyVariable.source =
+ broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]";
+ outputKeyVariable.outputIndex = renderTargetIndex;
+
+ outPixelShaderKey->push_back(outputKeyVariable);
+ }
+ }
+ else
+ {
+ const auto &shaderOutputVars =
+ metadata.getFragmentShader()->getData().getActiveOutputVariables();
+
+ for (auto outputPair : programData.getOutputVariables())
+ {
+ const VariableLocation &outputLocation = outputPair.second;
+ const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
+ const std::string &variableName = "out_" + outputLocation.name;
+ const std::string &elementString =
+ (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
+
+ ASSERT(outputVariable.staticUse);
+
+ PixelShaderOutputVariable outputKeyVariable;
+ outputKeyVariable.type = outputVariable.type;
+ outputKeyVariable.name = variableName + elementString;
+ outputKeyVariable.source = variableName + ArrayString(outputLocation.element);
+ outputKeyVariable.outputIndex = outputPair.first;
+
+ outPixelShaderKey->push_back(outputKeyVariable);
+ }
+ }
+}
+
} // namespace rx