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
virtual std::string getDebugInfo() const = 0;
const gl::Shader::Data &getData() const { return mData; }
protected:
const gl::Shader::Data &mData;
};
......
......@@ -36,6 +36,7 @@ struct Data;
namespace rx
{
struct PackedVarying;
class ProgramD3DMetadata;
struct SemanticInfo;
class ShaderD3D;
......@@ -63,18 +64,18 @@ class DynamicHLSL : angle::NonCopyable
const std::vector<GLenum> &outputLayout) const;
bool generateShaderLinkHLSL(const gl::Data &data,
const gl::Program::Data &programData,
const ProgramD3DMetadata &programMetadata,
gl::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;
std::string generateGeometryShaderPreamble(
const gl::Data &data,
const gl::Program::Data &programData,
const ProgramD3DMetadata &programMetadata,
unsigned int registers,
const std::vector<PackedVarying> &packedVaryings) const;
......@@ -83,6 +84,11 @@ class DynamicHLSL : angle::NonCopyable
const gl::Program::Data &programData,
const std::string &preambleString) const;
void getPixelShaderOutputKey(const gl::Data &data,
const gl::Program::Data &programData,
const ProgramD3DMetadata &metadata,
std::vector<PixelShaderOutputVariable> *outPixelShaderKey);
private:
RendererD3D *const mRenderer;
......
......@@ -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::VertexExecutable::VertexExecutable(const gl::InputLayout &inputLayout,
......@@ -1268,15 +1360,21 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
ProgramD3DMetadata metadata(mRenderer->getMajorShaderModel(), mRenderer->getShaderModelSuffix(),
usesInstancedPointSpriteEmulation(), vertexShaderD3D,
fragmentShaderD3D);
std::vector<D3DVarying> d3dVaryings;
if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, infoLog, registerCount, &mPixelHLSL,
&mVertexHLSL, packedVaryings, &d3dVaryings,
&mPixelShaderKey, &mUsesFragDepth))
if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, metadata, infoLog, registerCount,
&mPixelHLSL, &mVertexHLSL, packedVaryings,
&d3dVaryings))
{
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUsesPointSize = vertexShaderD3D->usesPointSize();
mDynamicHLSL->getPixelShaderOutputKey(data, mData, metadata, &mPixelShaderKey);
mUsesFragDepth = metadata.usesFragDepth(mData);
// Cache if we use flat shading
for (const auto &varying : packedVaryings)
......@@ -1291,7 +1389,7 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
if (mRenderer->getMajorShaderModel() >= 4)
{
mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
data, mData, registerCount, packedVaryings);
data, mData, metadata, registerCount, packedVaryings);
}
initSemanticIndex();
......
......@@ -102,6 +102,37 @@ struct D3DVarying
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
{
public:
......
......@@ -13,6 +13,7 @@
#include "common/utilities.h"
#include "compiler/translator/blocklayoutHLSL.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h"
namespace rx
{
......@@ -361,19 +362,21 @@ bool PackVaryings(const gl::Caps &caps,
}
SemanticInfo GetSemanticInfo(ShaderType shaderType,
int majorShaderModel,
unsigned int startRegisters,
bool position,
bool fragCoord,
bool pointCoord,
bool pointSize)
const ProgramD3DMetadata &programMetadata,
unsigned int startRegisters)
{
SemanticInfo info;
bool hlsl4 = (majorShaderModel >= 4);
const std::string &varyingSemantic = GetVaryingSemantic(majorShaderModel, pointSize);
int majorShaderModel = programMetadata.getRendererMajorShaderModel();
bool position = programMetadata.usesTransformFeedbackGLPosition();
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;
SemanticInfo info;
if (hlsl4)
{
info.dxPosition.enableSystem("SV_Position");
......@@ -389,12 +392,12 @@ SemanticInfo GetSemanticInfo(ShaderType shaderType,
if (position)
{
info.glPosition.enable(varyingSemantic, reservedRegisterIndex++);
info.glPosition.enable(userSemantic, reservedRegisterIndex++);
}
if (fragCoord)
{
info.glFragCoord.enable(varyingSemantic, reservedRegisterIndex++);
info.glFragCoord.enable(userSemantic, reservedRegisterIndex++);
}
if (pointCoord)
......@@ -403,7 +406,7 @@ SemanticInfo GetSemanticInfo(ShaderType shaderType,
// In D3D11 we manually compute gl_PointCoord in the GS.
if (hlsl4)
{
info.glPointCoord.enable(varyingSemantic, reservedRegisterIndex++);
info.glPointCoord.enable(userSemantic, reservedRegisterIndex++);
}
else
{
......
......@@ -15,6 +15,7 @@
namespace rx
{
class ProgramD3DMetadata;
struct PackedVarying
{
......@@ -119,12 +120,8 @@ struct SemanticInfo final
};
SemanticInfo GetSemanticInfo(ShaderType shaderType,
int majorShaderModel,
unsigned int startRegisters,
bool position,
bool fragCoord,
bool pointCoord,
bool pointSize);
const ProgramD3DMetadata &programMetadata,
unsigned int startRegisters);
} // 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