Commit e39a3f0a by Jamie Madill

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: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 7824b609
...@@ -29,6 +29,8 @@ class ShaderImpl : angle::NonCopyable ...@@ -29,6 +29,8 @@ class ShaderImpl : angle::NonCopyable
virtual std::string getDebugInfo() const = 0; virtual std::string getDebugInfo() const = 0;
const gl::Shader::Data &getData() const { return mData; }
protected: protected:
const gl::Shader::Data &mData; const gl::Shader::Data &mData;
}; };
......
...@@ -444,14 +444,13 @@ void DynamicHLSL::storeUserVaryings(const std::vector<PackedVarying> &packedVary ...@@ -444,14 +444,13 @@ void DynamicHLSL::storeUserVaryings(const std::vector<PackedVarying> &packedVary
bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
const gl::Program::Data &programData, const gl::Program::Data &programData,
const ProgramD3DMetadata &programMetadata,
InfoLog &infoLog, InfoLog &infoLog,
unsigned int registerCount, unsigned int registerCount,
std::string *pixelHLSL, std::string *pixelHLSL,
std::string *vertexHLSL, std::string *vertexHLSL,
const std::vector<PackedVarying> &packedVaryings, const std::vector<PackedVarying> &packedVaryings,
std::vector<D3DVarying> *d3dVaryingsOut, std::vector<D3DVarying> *d3dVaryingsOut) const
std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const
{ {
ASSERT(pixelHLSL->empty() && vertexHLSL->empty()); ASSERT(pixelHLSL->empty() && vertexHLSL->empty());
...@@ -461,15 +460,12 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -461,15 +460,12 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(fragmentShaderGL); const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(fragmentShaderGL);
const int shaderModel = mRenderer->getMajorShaderModel(); const int shaderModel = mRenderer->getMajorShaderModel();
bool usesMRT = fragmentShader->usesMultipleRenderTargets(); bool usesFragCoord = programMetadata.usesFragCoord();
bool usesFragCoord = fragmentShader->usesFragCoord();
bool usesPointCoord = fragmentShader->usesPointCoord(); bool usesPointCoord = fragmentShader->usesPointCoord();
bool usesPointSize = vertexShader->usesPointSize(); bool usesPointSize = vertexShader->usesPointSize();
bool useInstancedPointSpriteEmulation = bool useInstancedPointSpriteEmulation =
usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation; programMetadata.usesPointSize() &&
bool insertDummyPointCoordValue = !usesPointSize && usesPointCoord && shaderModel >= 4; mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
bool addPointCoord =
(useInstancedPointSpriteEmulation && usesPointCoord) || insertDummyPointCoordValue;
// Validation done in the compiler // Validation done in the compiler
ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData()); ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData());
...@@ -478,19 +474,6 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -478,19 +474,6 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
const unsigned int registersNeeded = const unsigned int registersNeeded =
registerCount + (usesFragCoord ? 1u : 0u) + (usesPointCoord ? 1u : 0u); 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) if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
{ {
infoLog << "No varying registers left to support gl_FragCoord/gl_PointCoord"; infoLog << "No varying registers left to support gl_FragCoord/gl_PointCoord";
...@@ -504,9 +487,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -504,9 +487,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
// PS_INPUT of the generated pixel shader. The Geometry Shader point sprite implementation needs // 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 to be in VS_OUTPUT and GS_INPUT. Instanced point sprites doesn't need
// gl_PointSize in VS_OUTPUT. // gl_PointSize in VS_OUTPUT.
const SemanticInfo &vertexSemantics = GetSemanticInfo( const SemanticInfo &vertexSemantics =
SHADER_VERTEX, shaderModel, registerCount, outputPositionFromVS, usesFragCoord, GetSemanticInfo(SHADER_VERTEX, programMetadata, registerCount);
addPointCoord, (!useInstancedPointSpriteEmulation && usesPointSize));
storeUserVaryings(packedVaryings, usesPointSize, d3dVaryingsOut); storeUserVaryings(packedVaryings, usesPointSize, d3dVaryingsOut);
storeBuiltinVaryings(vertexSemantics, d3dVaryingsOut); storeBuiltinVaryings(vertexSemantics, d3dVaryingsOut);
...@@ -545,7 +527,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -545,7 +527,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
<< "\n" << "\n"
<< " VS_OUTPUT output;\n"; << " VS_OUTPUT output;\n";
if (outputPositionFromVS) if (vertexSemantics.glPosition.enabled)
{ {
vertexStream << " output.gl_Position = gl_Position;\n"; vertexStream << " output.gl_Position = gl_Position;\n";
} }
...@@ -614,7 +596,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -614,7 +596,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
"gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * " "gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * "
"output.dx_Position.w;\n"; "output.dx_Position.w;\n";
if (usesPointCoord) if (programMetadata.usesPointCoord())
{ {
vertexStream << "\n" vertexStream << "\n"
<< " output.gl_PointCoord = input.spriteTexCoord;\n"; << " output.gl_PointCoord = input.spriteTexCoord;\n";
...@@ -624,7 +606,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -624,7 +606,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
// Renderers that enable instanced pointsprite emulation require the vertex shader output member // 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 // 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. // default value used in the generated pixel shader.
if (insertDummyPointCoordValue) if (programMetadata.usesInsertedPointCoordValue())
{ {
ASSERT(!useInstancedPointSpriteEmulation); ASSERT(!useInstancedPointSpriteEmulation);
vertexStream << "\n" vertexStream << "\n"
...@@ -638,57 +620,13 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -638,57 +620,13 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
std::stringstream pixelStream; std::stringstream pixelStream;
pixelStream << fragmentShaderGL->getTranslatedSource(); pixelStream << fragmentShaderGL->getTranslatedSource();
const SemanticInfo &pixelSemantics = GetSemanticInfo( const SemanticInfo &pixelSemantics =
SHADER_PIXEL, shaderModel, registerCount, outputPositionFromVS, usesFragCoord, GetSemanticInfo(SHADER_PIXEL, programMetadata, registerCount);
usesPointCoord, (!useInstancedPointSpriteEmulation && usesPointSize));
pixelStream << "struct PS_INPUT\n"; pixelStream << "struct PS_INPUT\n";
generateVaryingLinkHLSL(*data.caps, usesPointSize, pixelSemantics, packedVaryings, pixelStream); generateVaryingLinkHLSL(*data.caps, usesPointSize, pixelSemantics, packedVaryings, pixelStream);
pixelStream << "\n"; 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"; pixelStream << PIXEL_OUTPUT_STUB_STRING + "\n";
if (fragmentShader->usesFrontFacing()) if (fragmentShader->usesFrontFacing())
...@@ -830,6 +768,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -830,6 +768,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
std::string DynamicHLSL::generateGeometryShaderPreamble( std::string DynamicHLSL::generateGeometryShaderPreamble(
const gl::Data &data, const gl::Data &data,
const gl::Program::Data &programData, const gl::Program::Data &programData,
const ProgramD3DMetadata &programMetadata,
unsigned int registerCount, unsigned int registerCount,
const std::vector<PackedVarying> &packedVaryings) const const std::vector<PackedVarying> &packedVaryings) const
{ {
...@@ -844,14 +783,12 @@ std::string DynamicHLSL::generateGeometryShaderPreamble( ...@@ -844,14 +783,12 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(
ASSERT(vertexShader && fragmentShader); ASSERT(vertexShader && fragmentShader);
bool usesFragCoord = fragmentShader->usesFragCoord(); bool usesFragCoord = fragmentShader->usesFragCoord();
bool usesPointCoord = fragmentShader->usesPointCoord();
bool usesPointSize = vertexShader->usesPointSize(); bool usesPointSize = vertexShader->usesPointSize();
const SemanticInfo &inSemantics = GetSemanticInfo( const SemanticInfo &inSemantics =
SHADER_VERTEX, majorShaderModel, registerCount, true, usesFragCoord, false, usesPointSize); GetSemanticInfo(SHADER_VERTEX, programMetadata, registerCount);
const SemanticInfo &outSemantics = const SemanticInfo &outSemantics =
GetSemanticInfo(SHADER_GEOMETRY, majorShaderModel, registerCount, true, usesFragCoord, GetSemanticInfo(SHADER_GEOMETRY, programMetadata, registerCount);
usesPointCoord, usesPointSize);
std::stringstream preambleStream; std::stringstream preambleStream;
...@@ -1085,4 +1022,58 @@ std::string DynamicHLSL::generateAttributeConversionHLSL( ...@@ -1085,4 +1022,58 @@ std::string DynamicHLSL::generateAttributeConversionHLSL(
// No conversion necessary // No conversion necessary
return attribString; 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 } // namespace rx
...@@ -36,6 +36,7 @@ struct Data; ...@@ -36,6 +36,7 @@ struct Data;
namespace rx namespace rx
{ {
struct PackedVarying; struct PackedVarying;
class ProgramD3DMetadata;
struct SemanticInfo; struct SemanticInfo;
class ShaderD3D; class ShaderD3D;
...@@ -63,18 +64,18 @@ class DynamicHLSL : angle::NonCopyable ...@@ -63,18 +64,18 @@ class DynamicHLSL : angle::NonCopyable
const std::vector<GLenum> &outputLayout) const; const std::vector<GLenum> &outputLayout) const;
bool generateShaderLinkHLSL(const gl::Data &data, bool generateShaderLinkHLSL(const gl::Data &data,
const gl::Program::Data &programData, const gl::Program::Data &programData,
const ProgramD3DMetadata &programMetadata,
gl::InfoLog &infoLog, gl::InfoLog &infoLog,
unsigned int registerCount, unsigned int registerCount,
std::string *pixelHLSL, std::string *pixelHLSL,
std::string *vertexHLSL, std::string *vertexHLSL,
const std::vector<PackedVarying> &packedVaryings, const std::vector<PackedVarying> &packedVaryings,
std::vector<D3DVarying> *d3dVaryingsOut, std::vector<D3DVarying> *d3dVaryingsOut) const;
std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const;
std::string generateGeometryShaderPreamble( std::string generateGeometryShaderPreamble(
const gl::Data &data, const gl::Data &data,
const gl::Program::Data &programData, const gl::Program::Data &programData,
const ProgramD3DMetadata &programMetadata,
unsigned int registers, unsigned int registers,
const std::vector<PackedVarying> &packedVaryings) const; const std::vector<PackedVarying> &packedVaryings) const;
...@@ -83,6 +84,11 @@ class DynamicHLSL : angle::NonCopyable ...@@ -83,6 +84,11 @@ class DynamicHLSL : angle::NonCopyable
const gl::Program::Data &programData, const gl::Program::Data &programData,
const std::string &preambleString) const; const std::string &preambleString) const;
void getPixelShaderOutputKey(const gl::Data &data,
const gl::Program::Data &programData,
const ProgramD3DMetadata &metadata,
std::vector<PixelShaderOutputVariable> *outPixelShaderKey);
private: private:
RendererD3D *const mRenderer; RendererD3D *const mRenderer;
......
...@@ -363,6 +363,98 @@ D3DVarying::D3DVarying(const std::string &name, ...@@ -363,6 +363,98 @@ D3DVarying::D3DVarying(const std::string &name,
{ {
} }
// ProgramD3DMetadata Implementation
ProgramD3DMetadata::ProgramD3DMetadata(int rendererMajorShaderModel,
const std::string &shaderModelSuffix,
bool usesInstancedPointSpriteEmulation,
const ShaderD3D *vertexShader,
const ShaderD3D *fragmentShader)
: mRendererMajorShaderModel(rendererMajorShaderModel),
mShaderModelSuffix(shaderModelSuffix),
mUsesInstancedPointSpriteEmulation(usesInstancedPointSpriteEmulation),
mVertexShader(vertexShader),
mFragmentShader(fragmentShader)
{
}
int ProgramD3DMetadata::getRendererMajorShaderModel() const
{
return mRendererMajorShaderModel;
}
bool ProgramD3DMetadata::usesBroadcast(const gl::Data &data) const
{
return (mFragmentShader->usesFragColor() && data.clientVersion < 3);
}
bool ProgramD3DMetadata::usesFragDepth(const gl::Program::Data &programData) const
{
// TODO(jmadill): Rename this or check if we need it for version 300
return (getMajorShaderVersion() < 300 && mFragmentShader->usesFragDepth());
}
bool ProgramD3DMetadata::usesPointCoord() const
{
return mFragmentShader->usesPointCoord();
}
bool ProgramD3DMetadata::usesFragCoord() const
{
return mFragmentShader->usesFragCoord();
}
bool ProgramD3DMetadata::usesPointSize() const
{
return mVertexShader->usesPointSize();
}
bool ProgramD3DMetadata::usesInsertedPointCoordValue() const
{
return !usesPointSize() && usesPointCoord() && mRendererMajorShaderModel >= 4;
}
bool ProgramD3DMetadata::addsPointCoordToVertexShader() const
{
// Instanced PointSprite emulation requires that gl_PointCoord is present in the vertex shader
// VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader.
// GeometryShader PointSprite emulation does not require this additional entry because the
// GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the
// 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.
return (mUsesInstancedPointSpriteEmulation && usesPointCoord()) ||
usesInsertedPointCoordValue();
}
bool ProgramD3DMetadata::usesTransformFeedbackGLPosition() const
{
// 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.
return !(mRendererMajorShaderModel >= 4 && mShaderModelSuffix != "");
}
bool ProgramD3DMetadata::usesSystemValuePointSize() const
{
return !mUsesInstancedPointSpriteEmulation && usesPointSize();
}
bool ProgramD3DMetadata::usesMultipleFragmentOuts() const
{
return mFragmentShader->usesMultipleRenderTargets();
}
GLint ProgramD3DMetadata::getMajorShaderVersion() const
{
return mVertexShader->getData().getShaderVersion();
}
const ShaderD3D *ProgramD3DMetadata::getFragmentShader() const
{
return mFragmentShader;
}
// ProgramD3D Implementation // ProgramD3D Implementation
ProgramD3D::VertexExecutable::VertexExecutable(const gl::InputLayout &inputLayout, ProgramD3D::VertexExecutable::VertexExecutable(const gl::InputLayout &inputLayout,
...@@ -1268,15 +1360,21 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog) ...@@ -1268,15 +1360,21 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
ProgramD3DMetadata metadata(mRenderer->getMajorShaderModel(), mRenderer->getShaderModelSuffix(),
usesInstancedPointSpriteEmulation(), vertexShaderD3D,
fragmentShaderD3D);
std::vector<D3DVarying> d3dVaryings; std::vector<D3DVarying> d3dVaryings;
if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, infoLog, registerCount, &mPixelHLSL, if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, metadata, infoLog, registerCount,
&mVertexHLSL, packedVaryings, &d3dVaryings, &mPixelHLSL, &mVertexHLSL, packedVaryings,
&mPixelShaderKey, &mUsesFragDepth)) &d3dVaryings))
{ {
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
mUsesPointSize = vertexShaderD3D->usesPointSize(); mUsesPointSize = vertexShaderD3D->usesPointSize();
mDynamicHLSL->getPixelShaderOutputKey(data, mData, metadata, &mPixelShaderKey);
mUsesFragDepth = metadata.usesFragDepth(mData);
// Cache if we use flat shading // Cache if we use flat shading
for (const auto &varying : packedVaryings) for (const auto &varying : packedVaryings)
...@@ -1291,7 +1389,7 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog) ...@@ -1291,7 +1389,7 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
if (mRenderer->getMajorShaderModel() >= 4) if (mRenderer->getMajorShaderModel() >= 4)
{ {
mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble( mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
data, mData, registerCount, packedVaryings); data, mData, metadata, registerCount, packedVaryings);
} }
initSemanticIndex(); initSemanticIndex();
......
...@@ -102,6 +102,37 @@ struct D3DVarying ...@@ -102,6 +102,37 @@ struct D3DVarying
unsigned int semanticIndexCount; unsigned int semanticIndexCount;
}; };
class ProgramD3DMetadata : angle::NonCopyable
{
public:
ProgramD3DMetadata(int rendererMajorShaderModel,
const std::string &shaderModelSuffix,
bool usesInstancedPointSpriteEmulation,
const ShaderD3D *vertexShader,
const ShaderD3D *fragmentShader);
int getRendererMajorShaderModel() const;
bool usesBroadcast(const gl::Data &data) const;
bool usesFragDepth(const gl::Program::Data &programData) const;
bool usesPointCoord() const;
bool usesFragCoord() const;
bool usesPointSize() const;
bool usesInsertedPointCoordValue() const;
bool addsPointCoordToVertexShader() const;
bool usesTransformFeedbackGLPosition() const;
bool usesSystemValuePointSize() const;
bool usesMultipleFragmentOuts() const;
GLint getMajorShaderVersion() const;
const ShaderD3D *getFragmentShader() const;
private:
const int mRendererMajorShaderModel;
const std::string mShaderModelSuffix;
const bool mUsesInstancedPointSpriteEmulation;
const ShaderD3D *mVertexShader;
const ShaderD3D *mFragmentShader;
};
class ProgramD3D : public ProgramImpl class ProgramD3D : public ProgramImpl
{ {
public: public:
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "common/utilities.h" #include "common/utilities.h"
#include "compiler/translator/blocklayoutHLSL.h" #include "compiler/translator/blocklayoutHLSL.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h"
namespace rx namespace rx
{ {
...@@ -361,19 +362,21 @@ bool PackVaryings(const gl::Caps &caps, ...@@ -361,19 +362,21 @@ bool PackVaryings(const gl::Caps &caps,
} }
SemanticInfo GetSemanticInfo(ShaderType shaderType, SemanticInfo GetSemanticInfo(ShaderType shaderType,
int majorShaderModel, const ProgramD3DMetadata &programMetadata,
unsigned int startRegisters, unsigned int startRegisters)
bool position,
bool fragCoord,
bool pointCoord,
bool pointSize)
{ {
SemanticInfo info; int majorShaderModel = programMetadata.getRendererMajorShaderModel();
bool hlsl4 = (majorShaderModel >= 4); bool position = programMetadata.usesTransformFeedbackGLPosition();
const std::string &varyingSemantic = GetVaryingSemantic(majorShaderModel, pointSize); bool fragCoord = programMetadata.usesFragCoord();
bool pointCoord = shaderType == SHADER_VERTEX ? programMetadata.addsPointCoordToVertexShader()
: programMetadata.usesPointCoord();
bool pointSize = programMetadata.usesSystemValuePointSize();
bool hlsl4 = (majorShaderModel >= 4);
const std::string &userSemantic = GetVaryingSemantic(majorShaderModel, pointSize);
unsigned int reservedRegisterIndex = startRegisters; unsigned int reservedRegisterIndex = startRegisters;
SemanticInfo info;
if (hlsl4) if (hlsl4)
{ {
info.dxPosition.enableSystem("SV_Position"); info.dxPosition.enableSystem("SV_Position");
...@@ -389,12 +392,12 @@ SemanticInfo GetSemanticInfo(ShaderType shaderType, ...@@ -389,12 +392,12 @@ SemanticInfo GetSemanticInfo(ShaderType shaderType,
if (position) if (position)
{ {
info.glPosition.enable(varyingSemantic, reservedRegisterIndex++); info.glPosition.enable(userSemantic, reservedRegisterIndex++);
} }
if (fragCoord) if (fragCoord)
{ {
info.glFragCoord.enable(varyingSemantic, reservedRegisterIndex++); info.glFragCoord.enable(userSemantic, reservedRegisterIndex++);
} }
if (pointCoord) if (pointCoord)
...@@ -403,7 +406,7 @@ SemanticInfo GetSemanticInfo(ShaderType shaderType, ...@@ -403,7 +406,7 @@ SemanticInfo GetSemanticInfo(ShaderType shaderType,
// In D3D11 we manually compute gl_PointCoord in the GS. // In D3D11 we manually compute gl_PointCoord in the GS.
if (hlsl4) if (hlsl4)
{ {
info.glPointCoord.enable(varyingSemantic, reservedRegisterIndex++); info.glPointCoord.enable(userSemantic, reservedRegisterIndex++);
} }
else else
{ {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
namespace rx namespace rx
{ {
class ProgramD3DMetadata;
struct PackedVarying struct PackedVarying
{ {
...@@ -119,12 +120,8 @@ struct SemanticInfo final ...@@ -119,12 +120,8 @@ struct SemanticInfo final
}; };
SemanticInfo GetSemanticInfo(ShaderType shaderType, SemanticInfo GetSemanticInfo(ShaderType shaderType,
int majorShaderModel, const ProgramD3DMetadata &programMetadata,
unsigned int startRegisters, unsigned int startRegisters);
bool position,
bool fragCoord,
bool pointCoord,
bool pointSize);
} // namespace rx } // namespace rx
......
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