Commit 4e31ad55 by Jamie Madill

D3D11: Add dynamic geometry shaders.

The geometry shader we want will depend on our current draw mode, and if we're using flat shading in the shader. Without flat shading, we'll still be using them only for point sprites, but for other primitive types with flat shading enabled, we'll be using them to correct the provoking vertex order with D3D11. Note: no new features in this CL, those are turned on in follow-ups. BUG=angleproject:754 Change-Id: Iabf13ffd582f5a7200ee0df5aa9c3671aa7b6ed4 Reviewed-on: https://chromium-review.googlesource.com/309154Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 76f8fa66
...@@ -70,9 +70,9 @@ void SafeDelete(T*& resource) ...@@ -70,9 +70,9 @@ void SafeDelete(T*& resource)
template <typename T> template <typename T>
void SafeDeleteContainer(T& resource) void SafeDeleteContainer(T& resource)
{ {
for (typename T::iterator i = resource.begin(); i != resource.end(); i++) for (auto &element : resource)
{ {
SafeDelete(*i); SafeDelete(element);
} }
resource.clear(); resource.clear();
} }
......
...@@ -256,12 +256,14 @@ DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer) ...@@ -256,12 +256,14 @@ DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer)
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading
// Language 1.00 rev. 17] appendix A section 7 page 111 // Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful // Returns the number of used varying registers, or -1 if unsuccesful
int DynamicHLSL::packVaryings(const gl::Caps &caps, bool DynamicHLSL::packVaryings(const gl::Caps &caps,
InfoLog &infoLog, InfoLog &infoLog,
std::vector<PackedVarying> *packedVaryings, std::vector<PackedVarying> *packedVaryings,
const std::vector<std::string> &transformFeedbackVaryings) const std::vector<std::string> &transformFeedbackVaryings,
unsigned int *registerCountOut)
{ {
VaryingPacking packing = {}; VaryingPacking packing = {};
*registerCountOut = 0;
std::set<std::string> uniqueVaryingNames; std::set<std::string> uniqueVaryingNames;
...@@ -284,7 +286,7 @@ int DynamicHLSL::packVaryings(const gl::Caps &caps, ...@@ -284,7 +286,7 @@ int DynamicHLSL::packVaryings(const gl::Caps &caps,
else else
{ {
infoLog << "Could not pack varying " << varying.name; infoLog << "Could not pack varying " << varying.name;
return -1; return false;
} }
} }
...@@ -308,7 +310,7 @@ int DynamicHLSL::packVaryings(const gl::Caps &caps, ...@@ -308,7 +310,7 @@ int DynamicHLSL::packVaryings(const gl::Caps &caps,
if (!PackVarying(&packedVarying, caps.maxVaryingVectors, packing)) if (!PackVarying(&packedVarying, caps.maxVaryingVectors, packing))
{ {
infoLog << "Could not pack varying " << varying.name; infoLog << "Could not pack varying " << varying.name;
return -1; return false;
} }
found = true; found = true;
...@@ -320,23 +322,21 @@ int DynamicHLSL::packVaryings(const gl::Caps &caps, ...@@ -320,23 +322,21 @@ int DynamicHLSL::packVaryings(const gl::Caps &caps,
{ {
infoLog << "Transform feedback varying " << transformFeedbackVaryingName infoLog << "Transform feedback varying " << transformFeedbackVaryingName
<< " does not exist in the vertex shader."; << " does not exist in the vertex shader.";
return -1; return false;
} }
} }
} }
// Return the number of used registers // Return the number of used registers
int registers = 0;
for (GLuint r = 0; r < caps.maxVaryingVectors; r++) for (GLuint r = 0; r < caps.maxVaryingVectors; r++)
{ {
if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3]) if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
{ {
registers++; (*registerCountOut)++;
} }
} }
return registers; return true;
} }
std::string DynamicHLSL::generateVaryingHLSL(const gl::Caps &caps, std::string DynamicHLSL::generateVaryingHLSL(const gl::Caps &caps,
...@@ -639,7 +639,7 @@ struct DynamicHLSL::SemanticInfo ...@@ -639,7 +639,7 @@ struct DynamicHLSL::SemanticInfo
BuiltinInfo glPointSize; BuiltinInfo glPointSize;
}; };
DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(unsigned int startRegisters,
bool position, bool position,
bool fragCoord, bool fragCoord,
bool pointCoord, bool pointCoord,
...@@ -650,7 +650,7 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, ...@@ -650,7 +650,7 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters,
bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4); bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4);
const std::string &varyingSemantic = getVaryingSemantic(pointSize); const std::string &varyingSemantic = getVaryingSemantic(pointSize);
int reservedRegisterIndex = startRegisters; unsigned int reservedRegisterIndex = startRegisters;
if (hlsl4) if (hlsl4)
{ {
...@@ -783,7 +783,7 @@ void DynamicHLSL::storeUserLinkedVaryings(const std::vector<PackedVarying> &pack ...@@ -783,7 +783,7 @@ void DynamicHLSL::storeUserLinkedVaryings(const std::vector<PackedVarying> &pack
bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
const gl::Program::Data &programData, const gl::Program::Data &programData,
InfoLog &infoLog, InfoLog &infoLog,
int registers, 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,
...@@ -813,7 +813,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -813,7 +813,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData()); ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData());
// Write the HLSL input/output declarations // Write the HLSL input/output declarations
const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0); const unsigned int registersNeeded =
registerCount + (usesFragCoord ? 1u : 0u) + (usesPointCoord ? 1u : 0u);
// Two cases when writing to gl_FragColor and using ESSL 1.0: // 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 3.0 context, the output color is copied to channel 0
...@@ -844,7 +845,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -844,7 +845,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
// 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 = const SemanticInfo &vertexSemantics =
getSemanticInfo(registers, outputPositionFromVS, usesFragCoord, addPointCoord, getSemanticInfo(registerCount, outputPositionFromVS, usesFragCoord, addPointCoord,
(!useInstancedPointSpriteEmulation && usesPointSize), false); (!useInstancedPointSpriteEmulation && usesPointSize), false);
storeUserLinkedVaryings(packedVaryings, usesPointSize, linkedVaryings); storeUserLinkedVaryings(packedVaryings, usesPointSize, linkedVaryings);
...@@ -988,7 +989,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -988,7 +989,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
pixelStream << fragmentShaderGL->getTranslatedSource(); pixelStream << fragmentShaderGL->getTranslatedSource();
const SemanticInfo &pixelSemantics = const SemanticInfo &pixelSemantics =
getSemanticInfo(registers, outputPositionFromVS, usesFragCoord, usesPointCoord, getSemanticInfo(registerCount, outputPositionFromVS, usesFragCoord, usesPointCoord,
(!useInstancedPointSpriteEmulation && usesPointSize), true); (!useInstancedPointSpriteEmulation && usesPointSize), true);
pixelStream << "struct PS_INPUT\n" << generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) pixelStream << "struct PS_INPUT\n" << generateVaryingLinkHLSL(pixelSemantics, varyingHLSL)
...@@ -1191,35 +1192,76 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -1191,35 +1192,76 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
return true; return true;
} }
std::string DynamicHLSL::generateGeometryShaderHLSL( std::string DynamicHLSL::generateGeometryShaderPreamble(
gl::PrimitiveType primitiveType,
const gl::Data &data, const gl::Data &data,
const gl::Program::Data &programData, const gl::Program::Data &programData,
int registers, unsigned int registerCount,
const std::vector<PackedVarying> &packedVaryings) const const std::vector<PackedVarying> &packedVaryings) const
{ {
ASSERT(registers >= 0); ASSERT(registerCount >= 0 && registerCount <= data.caps->maxVaryingVectors);
ASSERT(mRenderer->getMajorShaderModel() >= 4); ASSERT(mRenderer->getMajorShaderModel() >= 4);
// Must be called during link, not from a binary load.
const ShaderD3D *vertexShader = GetImplAs<ShaderD3D>(programData.getAttachedVertexShader()); const ShaderD3D *vertexShader = GetImplAs<ShaderD3D>(programData.getAttachedVertexShader());
const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(programData.getAttachedFragmentShader()); const ShaderD3D *fragmentShader = GetImplAs<ShaderD3D>(programData.getAttachedFragmentShader());
ASSERT(vertexShader && fragmentShader);
bool usesFragCoord = fragmentShader->usesFragCoord(); bool usesFragCoord = fragmentShader->usesFragCoord();
bool usesPointCoord = fragmentShader->usesPointCoord(); bool usesPointCoord = fragmentShader->usesPointCoord();
bool usesPointSize = vertexShader->usesPointSize(); bool usesPointSize = vertexShader->usesPointSize();
const SemanticInfo &inSemantics = const SemanticInfo &inSemantics =
getSemanticInfo(registers, true, usesFragCoord, false, usesPointSize, false); getSemanticInfo(registerCount, true, usesFragCoord, false, usesPointSize, false);
const SemanticInfo &outSemantics = const SemanticInfo &outSemantics =
getSemanticInfo(registers, true, usesFragCoord, usesPointCoord, usesPointSize, false); getSemanticInfo(registerCount, true, usesFragCoord, usesPointCoord, usesPointSize, false);
const std::string &varyingHLSL = generateVaryingHLSL(*data.caps, packedVaryings, usesPointSize);
std::string inLinkHLSL = generateVaryingLinkHLSL(inSemantics, varyingHLSL);
std::string outLinkHLSL = generateVaryingLinkHLSL(outSemantics, varyingHLSL);
std::stringstream preambleStream;
preambleStream << "struct GS_INPUT\n" << inLinkHLSL << "\n"
<< "struct GS_OUTPUT\n" << outLinkHLSL << "\n"
<< "void copyVertex(inout GS_OUTPUT output, GS_INPUT input)\n"
<< "{\n"
<< " output.gl_Position = input.gl_Position;\n";
if (usesPointSize)
{
preambleStream << " output.gl_PointSize = input.gl_PointSize;\n";
}
for (unsigned int r = 0; r < registerCount; ++r)
{
preambleStream << " output.v" << r << " = input.v" << r << ";\n";
}
if (usesFragCoord)
{
preambleStream << " output.gl_FragCoord = input.gl_FragCoord;\n";
}
// Only write the dx_Position if we aren't using point sprites
preambleStream << "#ifndef ANGLE_POINT_SPRITE_SHADER\n"
<< " output.dx_Position = input.dx_Position;\n"
<< "#endif // ANGLE_POINT_SPRITE_SHADER\n"
<< "}\n";
return preambleStream.str();
}
std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveType,
const gl::Data &data,
const gl::Program::Data &programData,
const std::string &preambleString) const
{
ASSERT(mRenderer->getMajorShaderModel() >= 4);
std::stringstream shaderStream; std::stringstream shaderStream;
const bool pointSprites = (primitiveType == PRIMITIVE_POINTS); const bool pointSprites = (primitiveType == PRIMITIVE_POINTS);
const bool usesPointCoord = preambleString.find("gl_PointCoord") != std::string::npos;
std::string varyingHLSL = generateVaryingHLSL(*data.caps, packedVaryings, usesPointSize);
std::string inLinkHLSL = generateVaryingLinkHLSL(inSemantics, varyingHLSL);
std::string outLinkHLSL = generateVaryingLinkHLSL(outSemantics, varyingHLSL);
const char *inputPT = nullptr; const char *inputPT = nullptr;
const char *outputPT = nullptr; const char *outputPT = nullptr;
...@@ -1260,7 +1302,9 @@ std::string DynamicHLSL::generateGeometryShaderHLSL( ...@@ -1260,7 +1302,9 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(
if (pointSprites) if (pointSprites)
{ {
shaderStream << "uniform float4 dx_ViewCoords : register(c1);\n" shaderStream << "#define ANGLE_POINT_SPRITE_SHADER\n"
"\n"
"uniform float4 dx_ViewCoords : register(c1);\n"
"\n" "\n"
"static float2 pointSpriteCorners[] = \n" "static float2 pointSpriteCorners[] = \n"
"{\n" "{\n"
...@@ -1286,9 +1330,7 @@ std::string DynamicHLSL::generateGeometryShaderHLSL( ...@@ -1286,9 +1330,7 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(
<< "\n"; << "\n";
} }
shaderStream << "struct GS_INPUT\n" << inLinkHLSL << "\n" shaderStream << preambleString << "\n"
<< "struct GS_OUTPUT\n" << outLinkHLSL << "\n"
<< "\n"
<< "[maxvertexcount(" << maxVertexOutput << ")]\n" << "[maxvertexcount(" << maxVertexOutput << ")]\n"
<< "void main(" << inputPT << " GS_INPUT input[" << inputSize << "]," << "void main(" << inputPT << " GS_INPUT input[" << inputSize << "],"
" inout " " inout "
...@@ -1296,37 +1338,19 @@ std::string DynamicHLSL::generateGeometryShaderHLSL( ...@@ -1296,37 +1338,19 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(
<< "{\n" << "{\n"
<< " GS_OUTPUT output = (GS_OUTPUT)0;\n"; << " GS_OUTPUT output = (GS_OUTPUT)0;\n";
for (int vid = 0; vid < inputSize; ++vid) for (int vertexIndex = 0; vertexIndex < inputSize; ++vertexIndex)
{ {
shaderStream << " output.gl_Position = input[" << vid << "].gl_Position;\n"; shaderStream << " copyVertex(output, input[" << vertexIndex << "]);\n";
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) if (!pointSprites)
{ {
ASSERT(inputSize == maxVertexOutput); ASSERT(inputSize == maxVertexOutput);
shaderStream << " output.dx_Position = input[" << vid << "].dx_Position;\n" shaderStream << " outStream.Append(output);\n";
<< " outStream.Append(output);\n";
} }
} }
if (pointSprites) if (pointSprites)
{ {
ASSERT(usesPointSize);
shaderStream << "\n" shaderStream << "\n"
" float4 dx_Position = input[0].dx_Position;\n" " float4 dx_Position = input[0].dx_Position;\n"
" float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, " " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, "
......
...@@ -74,10 +74,11 @@ class DynamicHLSL : angle::NonCopyable ...@@ -74,10 +74,11 @@ class DynamicHLSL : angle::NonCopyable
public: public:
explicit DynamicHLSL(RendererD3D *const renderer); explicit DynamicHLSL(RendererD3D *const renderer);
int packVaryings(const gl::Caps &caps, bool packVaryings(const gl::Caps &caps,
gl::InfoLog &infoLog, gl::InfoLog &infoLog,
std::vector<PackedVarying> *packedVaryings, std::vector<PackedVarying> *packedVaryings,
const std::vector<std::string> &transformFeedbackVaryings); const std::vector<std::string> &transformFeedbackVaryings,
unsigned int *registerCountOut);
std::string generateVertexShaderForInputLayout( std::string generateVertexShaderForInputLayout(
const std::string &sourceShader, const std::string &sourceShader,
const gl::InputLayout &inputLayout, const gl::InputLayout &inputLayout,
...@@ -90,7 +91,7 @@ class DynamicHLSL : angle::NonCopyable ...@@ -90,7 +91,7 @@ class DynamicHLSL : angle::NonCopyable
bool generateShaderLinkHLSL(const gl::Data &data, bool generateShaderLinkHLSL(const gl::Data &data,
const gl::Program::Data &programData, const gl::Program::Data &programData,
gl::InfoLog &infoLog, gl::InfoLog &infoLog,
int registers, 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,
...@@ -98,19 +99,24 @@ class DynamicHLSL : angle::NonCopyable ...@@ -98,19 +99,24 @@ class DynamicHLSL : angle::NonCopyable
std::vector<PixelShaderOutputVariable> *outPixelShaderKey, std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const; bool *outUsesFragDepth) const;
std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType, std::string generateGeometryShaderPreamble(
const gl::Data &data, const gl::Data &data,
const gl::Program::Data &programData, const gl::Program::Data &programData,
int registers, unsigned int registers,
const std::vector<PackedVarying> &packedVaryings) const; const std::vector<PackedVarying> &packedVaryings) const;
std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType,
const gl::Data &data,
const gl::Program::Data &programData,
const std::string &preambleString) const;
private: private:
RendererD3D *const mRenderer; RendererD3D *const mRenderer;
struct SemanticInfo; struct SemanticInfo;
std::string getVaryingSemantic(bool pointSize) const; std::string getVaryingSemantic(bool pointSize) const;
SemanticInfo getSemanticInfo(int startRegisters, SemanticInfo getSemanticInfo(unsigned int startRegisters,
bool position, bool position,
bool fragCoord, bool fragCoord,
bool pointCoord, bool pointCoord,
......
...@@ -260,6 +260,35 @@ bool ExpandMatrix(T *target, ...@@ -260,6 +260,35 @@ bool ExpandMatrix(T *target,
return dirty; return dirty;
} }
gl::PrimitiveType GetGeometryShaderTypeFromDrawMode(GLenum drawMode)
{
switch (drawMode)
{
// Uses the point sprite geometry shader.
case GL_POINTS:
return gl::PRIMITIVE_POINTS;
// All line drawing uses the same geometry shader.
case GL_LINES:
case GL_LINE_STRIP:
case GL_LINE_LOOP:
return gl::PRIMITIVE_LINES;
// The triangle fan primitive is emulated with strips in D3D11.
case GL_TRIANGLES:
case GL_TRIANGLE_FAN:
return gl::PRIMITIVE_TRIANGLES;
// Special case for triangle strips.
case GL_TRIANGLE_STRIP:
return gl::PRIMITIVE_TRIANGLE_STRIP;
default:
UNREACHABLE();
return gl::PRIMITIVE_TYPE_MAX;
}
}
} // anonymous namespace } // anonymous namespace
D3DUniform::D3DUniform(GLenum typeIn, D3DUniform::D3DUniform(GLenum typeIn,
...@@ -380,7 +409,7 @@ ProgramD3D::ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer) ...@@ -380,7 +409,7 @@ ProgramD3D::ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer)
: ProgramImpl(data), : ProgramImpl(data),
mRenderer(renderer), mRenderer(renderer),
mDynamicHLSL(NULL), mDynamicHLSL(NULL),
mGeometryExecutable(NULL), mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX, nullptr),
mUsesPointSize(false), mUsesPointSize(false),
mVertexUniformStorage(NULL), mVertexUniformStorage(NULL),
mFragmentUniformStorage(NULL), mFragmentUniformStorage(NULL),
...@@ -663,6 +692,8 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -663,6 +692,8 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex); stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
} }
stream->readString(&mGeometryShaderPreamble);
const unsigned char *binary = reinterpret_cast<const unsigned char *>(stream->data()); const unsigned char *binary = reinterpret_cast<const unsigned char *>(stream->data());
const unsigned int vertexShaderCount = stream->readInt<unsigned int>(); const unsigned int vertexShaderCount = stream->readInt<unsigned int>();
...@@ -741,21 +772,29 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -741,21 +772,29 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
stream->skip(pixelShaderSize); stream->skip(pixelShaderSize);
} }
for (unsigned int geometryExeIndex = 0; geometryExeIndex < gl::PRIMITIVE_TYPE_MAX;
++geometryExeIndex)
{
unsigned int geometryShaderSize = stream->readInt<unsigned int>(); unsigned int geometryShaderSize = stream->readInt<unsigned int>();
if (geometryShaderSize == 0)
if (geometryShaderSize > 0)
{ {
mGeometryExecutables[geometryExeIndex] = nullptr;
continue;
}
const unsigned char *geometryShaderFunction = binary + stream->offset(); const unsigned char *geometryShaderFunction = binary + stream->offset();
gl::Error error = mRenderer->loadExecutable( bool splitAttribs = (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS);
geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY,
mTransformFeedbackLinkedVaryings, gl::Error error =
(mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), &mGeometryExecutable); mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY,
mTransformFeedbackLinkedVaryings, splitAttribs,
&mGeometryExecutables[geometryExeIndex]);
if (error.isError()) if (error.isError())
{ {
return LinkResult(false, error); return LinkResult(false, error);
} }
if (!mGeometryExecutable) if (!mGeometryExecutables[geometryExeIndex])
{ {
infoLog << "Could not create geometry shader."; infoLog << "Could not create geometry shader.";
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
...@@ -856,6 +895,8 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) ...@@ -856,6 +895,8 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
stream->writeInt(variable.outputIndex); stream->writeInt(variable.outputIndex);
} }
stream->writeString(mGeometryShaderPreamble);
stream->writeInt(mVertexExecutables.size()); stream->writeInt(mVertexExecutables.size());
for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size();
vertexExecutableIndex++) vertexExecutableIndex++)
...@@ -897,14 +938,17 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) ...@@ -897,14 +938,17 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
stream->writeBytes(pixelBlob, pixelShaderSize); stream->writeBytes(pixelBlob, pixelShaderSize);
} }
size_t geometryShaderSize = for (const ShaderExecutableD3D *geometryExe : mGeometryExecutables)
(mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; {
stream->writeInt(geometryShaderSize); if (geometryExe == nullptr)
if (mGeometryExecutable != NULL && geometryShaderSize > 0)
{ {
const uint8_t *geometryBlob = mGeometryExecutable->getFunction(); stream->writeInt(0);
stream->writeBytes(geometryBlob, geometryShaderSize); continue;
}
size_t geometryShaderSize = geometryExe->getLength();
stream->writeInt(geometryShaderSize);
stream->writeBytes(geometryExe->getFunction(), geometryShaderSize);
} }
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
...@@ -1034,10 +1078,48 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::InputLayout &i ...@@ -1034,10 +1078,48 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::InputLayout &i
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Data &data,
gl::InfoLog &infoLog, GLenum drawMode,
int registers, ShaderExecutableD3D **outExecutable,
const std::vector<PackedVarying> &packedVaryings) gl::InfoLog *infoLog)
{
gl::PrimitiveType geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
if (mGeometryExecutables[geometryShaderType] != nullptr)
{
if (outExecutable)
{
*outExecutable = mGeometryExecutables[geometryShaderType];
}
return gl::Error(GL_NO_ERROR);
}
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
geometryShaderType, data, mData, mGeometryShaderPreamble);
gl::InfoLog tempInfoLog;
gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
gl::Error error = mRenderer->compileToExecutable(
*currentInfoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
(mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), D3DCompilerWorkarounds(),
&mGeometryExecutables[geometryShaderType]);
if (!infoLog && error.isError())
{
std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
tempInfoLog.getLog(static_cast<GLsizei>(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]);
ERR("Error compiling dynamic geometry executable:\n%s\n", &tempCharBuffer[0]);
}
if (outExecutable)
{
*outExecutable = mGeometryExecutables[geometryShaderType];
}
return error;
}
LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::InfoLog &infoLog)
{ {
const gl::InputLayout &defaultInputLayout = const gl::InputLayout &defaultInputLayout =
GetDefaultInputLayoutFromShader(mData.getAttachedVertexShader()); GetDefaultInputLayoutFromShader(mData.getAttachedVertexShader());
...@@ -1058,19 +1140,10 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, ...@@ -1058,19 +1140,10 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data,
return LinkResult(false, error); return LinkResult(false, error);
} }
// Auto-generate the geometry shader here, if we expect to be using point rendering in D3D11.
if (usesGeometryShader()) if (usesGeometryShader())
{ {
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL( getGeometryExecutableForPrimitiveType(data, GL_POINTS, nullptr, &infoLog);
gl::PRIMITIVE_POINTS, data, mData, registers, packedVaryings);
error = mRenderer->compileToExecutable(
infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
(mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
D3DCompilerWorkarounds(), &mGeometryExecutable);
if (error.isError())
{
return LinkResult(false, error);
}
} }
#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED #if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
...@@ -1099,7 +1172,7 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, ...@@ -1099,7 +1172,7 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data,
#endif #endif
bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable &&
(!usesGeometryShader() || mGeometryExecutable)); (!usesGeometryShader() || mGeometryExecutables[gl::PRIMITIVE_POINTS]));
return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR)); return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
} }
...@@ -1142,16 +1215,15 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog) ...@@ -1142,16 +1215,15 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
MergeVaryings(*vertexShader, *fragmentShader, mData.getTransformFeedbackVaryingNames()); MergeVaryings(*vertexShader, *fragmentShader, mData.getTransformFeedbackVaryingNames());
// Map the varyings to the register file // Map the varyings to the register file
int registers = mDynamicHLSL->packVaryings(*data.caps, infoLog, &packedVaryings, unsigned int registerCount = 0;
mData.getTransformFeedbackVaryingNames()); if (!mDynamicHLSL->packVaryings(*data.caps, infoLog, &packedVaryings,
mData.getTransformFeedbackVaryingNames(), &registerCount))
if (registers < 0)
{ {
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
std::vector<gl::LinkedVarying> linkedVaryings; std::vector<gl::LinkedVarying> linkedVaryings;
if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, infoLog, registers, &mPixelHLSL, if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, infoLog, registerCount, &mPixelHLSL,
&mVertexHLSL, packedVaryings, &linkedVaryings, &mVertexHLSL, packedVaryings, &linkedVaryings,
&mPixelShaderKey, &mUsesFragDepth)) &mPixelShaderKey, &mUsesFragDepth))
{ {
...@@ -1160,13 +1232,19 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog) ...@@ -1160,13 +1232,19 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
mUsesPointSize = vertexShaderD3D->usesPointSize(); mUsesPointSize = vertexShaderD3D->usesPointSize();
if (mRenderer->getMajorShaderModel() >= 4)
{
mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
data, mData, registerCount, packedVaryings);
}
initSemanticIndex(); initSemanticIndex();
defineUniformsAndAssignRegisters(); defineUniformsAndAssignRegisters();
gatherTransformFeedbackVaryings(linkedVaryings); gatherTransformFeedbackVaryings(linkedVaryings);
LinkResult result = compileProgramExecutables(data, infoLog, registers, packedVaryings); LinkResult result = compileProgramExecutables(data, infoLog);
if (result.error.isError() || !result.linkSuccess) if (result.error.isError() || !result.linkSuccess)
{ {
infoLog << "Failed to create D3D shaders."; infoLog << "Failed to create D3D shaders.";
...@@ -1849,7 +1927,11 @@ void ProgramD3D::reset() ...@@ -1849,7 +1927,11 @@ void ProgramD3D::reset()
{ {
SafeDeleteContainer(mVertexExecutables); SafeDeleteContainer(mVertexExecutables);
SafeDeleteContainer(mPixelExecutables); SafeDeleteContainer(mPixelExecutables);
SafeDelete(mGeometryExecutable);
for (auto &element : mGeometryExecutables)
{
SafeDelete(element);
}
mVertexHLSL.clear(); mVertexHLSL.clear();
mVertexWorkarounds = D3DCompilerWorkarounds(); mVertexWorkarounds = D3DCompilerWorkarounds();
...@@ -1877,6 +1959,8 @@ void ProgramD3D::reset() ...@@ -1877,6 +1959,8 @@ void ProgramD3D::reset()
std::fill(mAttributesByLayout, mAttributesByLayout + ArraySize(mAttributesByLayout), -1); std::fill(mAttributesByLayout, mAttributesByLayout + ArraySize(mAttributesByLayout), -1);
mTransformFeedbackLinkedVaryings.clear(); mTransformFeedbackLinkedVaryings.clear();
mGeometryShaderPreamble.clear();
} }
unsigned int ProgramD3D::getSerial() const unsigned int ProgramD3D::getSerial() const
......
...@@ -113,7 +113,10 @@ class ProgramD3D : public ProgramImpl ...@@ -113,7 +113,10 @@ class ProgramD3D : public ProgramImpl
gl::Error getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout, gl::Error getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout,
ShaderExecutableD3D **outExectuable, ShaderExecutableD3D **outExectuable,
gl::InfoLog *infoLog); gl::InfoLog *infoLog);
ShaderExecutableD3D *getGeometryExecutable() const { return mGeometryExecutable; } gl::Error getGeometryExecutableForPrimitiveType(const gl::Data &data,
GLenum drawMode,
ShaderExecutableD3D **outExecutable,
gl::InfoLog *infoLog);
LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override; LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
...@@ -278,10 +281,7 @@ class ProgramD3D : public ProgramImpl ...@@ -278,10 +281,7 @@ class ProgramD3D : public ProgramImpl
const GLfloat *value, const GLfloat *value,
GLenum targetUniformType); GLenum targetUniformType);
LinkResult compileProgramExecutables(const gl::Data &data, LinkResult compileProgramExecutables(const gl::Data &data, gl::InfoLog &infoLog);
gl::InfoLog &infoLog,
int registers,
const std::vector<PackedVarying> &packedVaryings);
void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings); void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings);
D3DUniform *getD3DUniformByName(const std::string &name); D3DUniform *getD3DUniformByName(const std::string &name);
...@@ -301,7 +301,7 @@ class ProgramD3D : public ProgramImpl ...@@ -301,7 +301,7 @@ class ProgramD3D : public ProgramImpl
std::vector<VertexExecutable *> mVertexExecutables; std::vector<VertexExecutable *> mVertexExecutables;
std::vector<PixelExecutable *> mPixelExecutables; std::vector<PixelExecutable *> mPixelExecutables;
ShaderExecutableD3D *mGeometryExecutable; std::vector<ShaderExecutableD3D *> mGeometryExecutables;
std::string mVertexHLSL; std::string mVertexHLSL;
D3DCompilerWorkarounds mVertexWorkarounds; D3DCompilerWorkarounds mVertexWorkarounds;
...@@ -311,6 +311,11 @@ class ProgramD3D : public ProgramImpl ...@@ -311,6 +311,11 @@ class ProgramD3D : public ProgramImpl
bool mUsesFragDepth; bool mUsesFragDepth;
std::vector<PixelShaderOutputVariable> mPixelShaderKey; std::vector<PixelShaderOutputVariable> mPixelShaderKey;
// Common code for all dynamic geometry shaders. Consists mainly of the GS input and output
// structures, built from the linked varying info. We store the string itself instead of the
// packed varyings for simplicity.
std::string mGeometryShaderPreamble;
bool mUsesPointSize; bool mUsesPointSize;
UniformStorageD3D *mVertexUniformStorage; UniformStorageD3D *mVertexUniformStorage;
......
...@@ -195,7 +195,7 @@ gl::Error RendererD3D::genericDrawElements(const gl::Data &data, ...@@ -195,7 +195,7 @@ gl::Error RendererD3D::genericDrawElements(const gl::Data &data,
return error; return error;
} }
error = applyShaders(data); error = applyShaders(data, mode);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -270,7 +270,7 @@ gl::Error RendererD3D::genericDrawArrays(const gl::Data &data, ...@@ -270,7 +270,7 @@ gl::Error RendererD3D::genericDrawArrays(const gl::Data &data,
return error; return error;
} }
error = applyShaders(data); error = applyShaders(data, mode);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -436,13 +436,13 @@ gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode) ...@@ -436,13 +436,13 @@ gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode)
} }
// Applies the shaders and shader constants to the Direct3D device // Applies the shaders and shader constants to the Direct3D device
gl::Error RendererD3D::applyShaders(const gl::Data &data) gl::Error RendererD3D::applyShaders(const gl::Data &data, GLenum drawMode)
{ {
gl::Program *program = data.state->getProgram(); gl::Program *program = data.state->getProgram();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
programD3D->updateCachedInputLayout(*data.state); programD3D->updateCachedInputLayout(*data.state);
gl::Error error = applyShadersImpl(data); gl::Error error = applyShadersImpl(data, drawMode);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -242,7 +242,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -242,7 +242,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
protected: protected:
virtual bool getLUID(LUID *adapterLuid) const = 0; virtual bool getLUID(LUID *adapterLuid) const = 0;
virtual gl::Error applyShadersImpl(const gl::Data &data) = 0; virtual gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) = 0;
void cleanup(); void cleanup();
...@@ -296,7 +296,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -296,7 +296,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport); gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport);
gl::Error applyState(const gl::Data &data, GLenum drawMode); gl::Error applyState(const gl::Data &data, GLenum drawMode);
gl::Error applyShaders(const gl::Data &data); gl::Error applyShaders(const gl::Data &data, GLenum drawMode);
gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType, gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType,
const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount); const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount);
gl::Error applyTextures(const gl::Data &data); gl::Error applyTextures(const gl::Data &data);
......
...@@ -1711,7 +1711,15 @@ gl::Error Renderer11::drawArraysImpl(const gl::Data &data, ...@@ -1711,7 +1711,15 @@ gl::Error Renderer11::drawArraysImpl(const gl::Data &data,
mDeviceContext->PSSetShader(pixelShader, NULL, 0); mDeviceContext->PSSetShader(pixelShader, NULL, 0);
// Retrieve the point sprite geometry shader // Retrieve the point sprite geometry shader
rx::ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable(); rx::ShaderExecutableD3D *geometryExe = nullptr;
error = programD3D->getGeometryExecutableForPrimitiveType(data, mode, &geometryExe,
nullptr);
if (error.isError())
{
return error;
}
ID3D11GeometryShader *geometryShader = (geometryExe ? GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : NULL); ID3D11GeometryShader *geometryShader = (geometryExe ? GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : NULL);
mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader); mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader);
ASSERT(geometryShader); ASSERT(geometryShader);
...@@ -2045,7 +2053,7 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * ...@@ -2045,7 +2053,7 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer11::applyShadersImpl(const gl::Data &data) gl::Error Renderer11::applyShadersImpl(const gl::Data &data, GLenum drawMode)
{ {
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram()); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
const auto &inputLayout = programD3D->getCachedInputLayout(); const auto &inputLayout = programD3D->getCachedInputLayout();
...@@ -2065,7 +2073,13 @@ gl::Error Renderer11::applyShadersImpl(const gl::Data &data) ...@@ -2065,7 +2073,13 @@ gl::Error Renderer11::applyShadersImpl(const gl::Data &data)
return error; return error;
} }
ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable(); ShaderExecutableD3D *geometryExe = nullptr;
error =
programD3D->getGeometryExecutableForPrimitiveType(data, drawMode, &geometryExe, nullptr);
if (error.isError())
{
return error;
}
ID3D11VertexShader *vertexShader = (vertexExe ? GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : NULL); ID3D11VertexShader *vertexShader = (vertexExe ? GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : NULL);
...@@ -2083,7 +2097,7 @@ gl::Error Renderer11::applyShadersImpl(const gl::Data &data) ...@@ -2083,7 +2097,7 @@ gl::Error Renderer11::applyShadersImpl(const gl::Data &data)
{ {
geometryShader = (vertexExe ? GetAs<ShaderExecutable11>(vertexExe)->getStreamOutShader() : NULL); geometryShader = (vertexExe ? GetAs<ShaderExecutable11>(vertexExe)->getStreamOutShader() : NULL);
} }
else if (mCurRasterState.pointDrawMode) else
{ {
geometryShader = (geometryExe ? GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : NULL); geometryShader = (geometryExe ? GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : NULL);
} }
......
...@@ -132,7 +132,6 @@ class Renderer11 : public RendererD3D ...@@ -132,7 +132,6 @@ class Renderer11 : public RendererD3D
virtual bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize); virtual bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
gl::Error applyUniforms(const ProgramD3D &programD3D, gl::Error applyUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray) override; const std::vector<D3DUniform *> &uniformArray) override;
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo); virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo);
...@@ -269,7 +268,7 @@ class Renderer11 : public RendererD3D ...@@ -269,7 +268,7 @@ class Renderer11 : public RendererD3D
protected: protected:
void createAnnotator() override; void createAnnotator() override;
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override;
gl::Error applyShadersImpl(const gl::Data &data) override; gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override;
private: private:
gl::Error drawArraysImpl(const gl::Data &data, gl::Error drawArraysImpl(const gl::Data &data,
......
...@@ -1862,7 +1862,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou ...@@ -1862,7 +1862,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer9::applyShadersImpl(const gl::Data &data) gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/)
{ {
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram()); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
const auto &inputLayout = programD3D->getCachedInputLayout(); const auto &inputLayout = programD3D->getCachedInputLayout();
......
...@@ -235,7 +235,7 @@ class Renderer9 : public RendererD3D ...@@ -235,7 +235,7 @@ class Renderer9 : public RendererD3D
protected: protected:
void createAnnotator() override; void createAnnotator() override;
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override;
gl::Error applyShadersImpl(const gl::Data &data) override; gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override;
private: private:
gl::Error drawArraysImpl(const gl::Data &data, gl::Error drawArraysImpl(const gl::Data &data,
......
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