Commit 76f8fa66 by Jamie Madill

Refactor Geometry Shader support to enable pass-through.

This should be a refactoring change only. The new code is exercised in follow-up CLs. BUG=angleproject:754 Change-Id: I99285e1e7772cae467013102f25c911ebc9f54a9 Reviewed-on: https://chromium-review.googlesource.com/309153Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 1cc10903
......@@ -15,6 +15,30 @@
namespace gl
{
PrimitiveType GetPrimitiveType(GLenum drawMode)
{
switch (drawMode)
{
case GL_POINTS:
return PRIMITIVE_POINTS;
case GL_LINES:
return PRIMITIVE_LINES;
case GL_LINE_STRIP:
return PRIMITIVE_LINE_STRIP;
case GL_LINE_LOOP:
return PRIMITIVE_LINE_LOOP;
case GL_TRIANGLES:
return PRIMITIVE_TRIANGLES;
case GL_TRIANGLE_STRIP:
return PRIMITIVE_TRIANGLE_STRIP;
case GL_TRIANGLE_FAN:
return PRIMITIVE_TRIANGLE_FAN;
default:
UNREACHABLE();
return PRIMITIVE_TYPE_MAX;
}
}
SamplerState::SamplerState()
: minFilter(GL_NEAREST_MIPMAP_LINEAR),
magFilter(GL_LINEAR),
......
......@@ -24,6 +24,20 @@ class Program;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
enum PrimitiveType
{
PRIMITIVE_POINTS,
PRIMITIVE_LINES,
PRIMITIVE_LINE_STRIP,
PRIMITIVE_LINE_LOOP,
PRIMITIVE_TRIANGLES,
PRIMITIVE_TRIANGLE_STRIP,
PRIMITIVE_TRIANGLE_FAN,
PRIMITIVE_TYPE_MAX,
};
PrimitiveType GetPrimitiveType(GLenum drawMode);
enum SamplerType
{
SAMPLER_PIXEL,
......
......@@ -229,6 +229,6 @@ VertexFormatType GetVertexFormatType(const VertexAttribute &attrib);
VertexFormatType GetVertexFormatType(const VertexAttribute &attrib, GLenum currentValueType);
const VertexFormat &GetVertexFormatFromType(VertexFormatType vertexFormatType);
}
} // namespace gl
#endif // LIBANGLE_FORMATUTILS_H_
......@@ -1192,108 +1192,167 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
}
std::string DynamicHLSL::generateGeometryShaderHLSL(
gl::PrimitiveType primitiveType,
const gl::Data &data,
const gl::Program::Data &programData,
int registers,
const ShaderD3D *fragmentShader,
const std::vector<PackedVarying> &packedVaryings) const
{
// for now we only handle point sprite emulation
ASSERT(mRenderer->getMajorShaderModel() >= 4);
return generatePointSpriteHLSL(data, registers, fragmentShader, packedVaryings);
}
std::string DynamicHLSL::generatePointSpriteHLSL(
const gl::Data &data,
int registers,
const ShaderD3D *fragmentShader,
const std::vector<PackedVarying> &packedVaryings) const
{
ASSERT(registers >= 0);
ASSERT(mRenderer->getMajorShaderModel() >= 4);
const ShaderD3D *vertexShader = GetImplAs<ShaderD3D>(programData.getAttachedVertexShader());
const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(programData.getAttachedFragmentShader());
bool usesFragCoord = fragmentShader->usesFragCoord();
bool usesPointCoord = fragmentShader->usesPointCoord();
std::stringstream shaderStream;
bool usesPointSize = vertexShader->usesPointSize();
const SemanticInfo &inSemantics =
getSemanticInfo(registers, true, usesFragCoord, false, true, false);
getSemanticInfo(registers, true, usesFragCoord, false, usesPointSize, false);
const SemanticInfo &outSemantics =
getSemanticInfo(registers, true, usesFragCoord, usesPointCoord, true, false);
getSemanticInfo(registers, true, usesFragCoord, usesPointCoord, usesPointSize, false);
std::stringstream shaderStream;
const bool pointSprites = (primitiveType == PRIMITIVE_POINTS);
// If we're generating the geometry shader, we assume the vertex shader uses point size.
std::string varyingHLSL = generateVaryingHLSL(*data.caps, packedVaryings, true);
std::string varyingHLSL = generateVaryingHLSL(*data.caps, packedVaryings, usesPointSize);
std::string inLinkHLSL = generateVaryingLinkHLSL(inSemantics, varyingHLSL);
std::string outLinkHLSL = generateVaryingLinkHLSL(outSemantics, varyingHLSL);
shaderStream
<< "uniform float4 dx_ViewCoords : register(c1);\n"
<< "\n"
<< "struct GS_INPUT\n" << inLinkHLSL << "\n"
<< "struct GS_OUTPUT\n" << outLinkHLSL << "\n"
<< "\n"
<< "static float2 pointSpriteCorners[] = \n"
<< "{\n"
<< " float2( 0.5f, -0.5f),\n"
<< " float2( 0.5f, 0.5f),\n"
<< " float2(-0.5f, -0.5f),\n"
<< " float2(-0.5f, 0.5f)\n"
<< "};\n"
<< "\n"
<< "static float2 pointSpriteTexcoords[] = \n"
<< "{\n"
<< " float2(1.0f, 1.0f),\n"
<< " float2(1.0f, 0.0f),\n"
<< " float2(0.0f, 1.0f),\n"
<< " float2(0.0f, 0.0f)\n"
<< "};\n"
<< "\n"
<< "static float minPointSize = " << static_cast<int>(data.caps->minAliasedPointSize)
<< ".0f;\n"
<< "static float maxPointSize = " << static_cast<int>(data.caps->maxAliasedPointSize)
<< ".0f;\n"
<< "\n"
<< "[maxvertexcount(4)]\n"
<< "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
<< "{\n"
<< " GS_OUTPUT output = (GS_OUTPUT)0;\n"
<< " output.gl_Position = input[0].gl_Position;\n"
<< " output.gl_PointSize = input[0].gl_PointSize;\n";
for (int r = 0; r < registers; r++)
const char *inputPT = nullptr;
const char *outputPT = nullptr;
int inputSize = 0;
int maxVertexOutput = 0;
switch (primitiveType)
{
shaderStream << " output.v" << r << " = input[0].v" << r << ";\n";
case PRIMITIVE_POINTS:
inputPT = "point";
outputPT = "Triangle";
inputSize = 1;
maxVertexOutput = 4;
break;
case PRIMITIVE_LINES:
case PRIMITIVE_LINE_STRIP:
case PRIMITIVE_LINE_LOOP:
inputPT = "line";
outputPT = "Line";
inputSize = 2;
maxVertexOutput = 2;
break;
case PRIMITIVE_TRIANGLES:
case PRIMITIVE_TRIANGLE_STRIP:
case PRIMITIVE_TRIANGLE_FAN:
inputPT = "triangle";
outputPT = "Triangle";
inputSize = 3;
maxVertexOutput = 3;
break;
default:
UNREACHABLE();
break;
}
if (usesFragCoord)
if (pointSprites)
{
shaderStream << " output.gl_FragCoord = input[0].gl_FragCoord;\n";
shaderStream << "uniform float4 dx_ViewCoords : register(c1);\n"
"\n"
"static float2 pointSpriteCorners[] = \n"
"{\n"
" float2( 0.5f, -0.5f),\n"
" float2( 0.5f, 0.5f),\n"
" float2(-0.5f, -0.5f),\n"
" float2(-0.5f, 0.5f)\n"
"};\n"
"\n"
"static float2 pointSpriteTexcoords[] = \n"
"{\n"
" float2(1.0f, 1.0f),\n"
" float2(1.0f, 0.0f),\n"
" float2(0.0f, 1.0f),\n"
" float2(0.0f, 0.0f)\n"
"};\n"
"\n"
"static float minPointSize = "
<< static_cast<int>(data.caps->minAliasedPointSize)
<< ".0f;\n"
"static float maxPointSize = "
<< static_cast<int>(data.caps->maxAliasedPointSize) << ".0f;\n"
<< "\n";
}
shaderStream
<< " \n"
<< " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n"
<< " float4 dx_Position = input[0].dx_Position;\n"
<< " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * "
"dx_Position.w;\n";
shaderStream << "struct GS_INPUT\n" << inLinkHLSL << "\n"
<< "struct GS_OUTPUT\n" << outLinkHLSL << "\n"
<< "\n"
<< "[maxvertexcount(" << maxVertexOutput << ")]\n"
<< "void main(" << inputPT << " GS_INPUT input[" << inputSize << "],"
" inout "
<< outputPT << "Stream<GS_OUTPUT> outStream)\n"
<< "{\n"
<< " GS_OUTPUT output = (GS_OUTPUT)0;\n";
for (int corner = 0; corner < 4; corner++)
for (int vid = 0; vid < inputSize; ++vid)
{
shaderStream << " \n"
<< " output.dx_Position = dx_Position + float4(pointSpriteCorners["
<< corner << "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
shaderStream << " output.gl_Position = input[" << vid << "].gl_Position;\n";
if (usesPointCoord)
if (usesPointSize)
{
shaderStream << " output.gl_PointSize = input[" << vid << "].gl_PointSize;\n";
}
for (int r = 0; r < registers; ++r)
{
shaderStream << " output.v" << r << " = input[" << vid << "].v" << r << ";\n";
}
if (usesFragCoord)
{
shaderStream << " output.gl_FragCoord = input[" << vid << "].gl_FragCoord;\n";
}
if (!pointSprites)
{
shaderStream << " output.gl_PointCoord = pointSpriteTexcoords[" << corner << "];\n";
ASSERT(inputSize == maxVertexOutput);
shaderStream << " output.dx_Position = input[" << vid << "].dx_Position;\n"
<< " outStream.Append(output);\n";
}
}
if (pointSprites)
{
ASSERT(usesPointSize);
shaderStream << "\n"
" float4 dx_Position = input[0].dx_Position;\n"
" float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, "
"maxPointSize);\n"
" float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / "
"dx_ViewCoords.y) * dx_Position.w;\n";
for (int corner = 0; corner < 4; corner++)
{
shaderStream << "\n"
" output.dx_Position = dx_Position + float4(pointSpriteCorners["
<< corner << "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
shaderStream << " outStream.Append(output);\n";
if (usesPointCoord)
{
shaderStream << " output.gl_PointCoord = pointSpriteTexcoords[" << corner
<< "];\n";
}
shaderStream << " outStream.Append(output);\n";
}
}
shaderStream << " \n"
<< " outStream.RestartStrip();\n"
<< "}\n";
" outStream.RestartStrip();\n"
"}\n";
return shaderStream.str();
}
......
......@@ -98,9 +98,10 @@ class DynamicHLSL : angle::NonCopyable
std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const;
std::string generateGeometryShaderHLSL(const gl::Data &data,
std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType,
const gl::Data &data,
const gl::Program::Data &programData,
int registers,
const ShaderD3D *fragmentShader,
const std::vector<PackedVarying> &packedVaryings) const;
private:
......@@ -125,10 +126,6 @@ class DynamicHLSL : angle::NonCopyable
std::vector<gl::LinkedVarying> *linkedVaryings) const;
void storeBuiltinLinkedVaryings(const SemanticInfo &info,
std::vector<gl::LinkedVarying> *linkedVaryings) const;
std::string generatePointSpriteHLSL(const gl::Data &data,
int registers,
const ShaderD3D *fragmentShader,
const std::vector<PackedVarying> &packedVaryings) const;
// Prepend an underscore
static std::string decorateVariable(const std::string &name);
......
......@@ -1039,8 +1039,6 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data,
int registers,
const std::vector<PackedVarying> &packedVaryings)
{
const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(mData.getAttachedFragmentShader());
const gl::InputLayout &defaultInputLayout =
GetDefaultInputLayoutFromShader(mData.getAttachedVertexShader());
ShaderExecutableD3D *defaultVertexExecutable = NULL;
......@@ -1063,7 +1061,7 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data,
if (usesGeometryShader())
{
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
data, registers, fragmentShaderD3D, packedVaryings);
gl::PRIMITIVE_POINTS, data, mData, registers, packedVaryings);
error = mRenderer->compileToExecutable(
infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
......@@ -1077,7 +1075,6 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data,
#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mData.getAttachedVertexShader());
if (usesGeometryShader() && mGeometryExecutable)
{
// Geometry shaders are currently only used internally, so there is no corresponding shader
......@@ -1095,6 +1092,8 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data,
if (defaultPixelExecutable)
{
const ShaderD3D *fragmentShaderD3D =
GetImplAs<ShaderD3D>(mData.getAttachedFragmentShader());
fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo());
}
#endif
......
......@@ -35,7 +35,7 @@ class ShaderD3D : public ShaderImpl
void uncompile();
unsigned int getUniformRegister(const std::string &uniformName) const;
unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
void appendDebugInfo(const std::string &info) { mDebugInfo += info; }
void appendDebugInfo(const std::string &info) const { mDebugInfo += info; }
void generateWorkarounds(D3DCompilerWorkarounds *workarounds) const;
......@@ -68,7 +68,7 @@ class ShaderD3D : public ShaderImpl
bool mRequiresIEEEStrictCompiling;
ShShaderOutput mCompilerOutputType;
std::string mDebugInfo;
mutable std::string mDebugInfo;
std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
};
......
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