Commit 3e14e2b1 by Jamie Madill

D3D11: Fix basic provoking vertex flat shading cases.

The enables geometry shaders that correct for the flat shading on provoking vertexes. It does not fix it for triangle strips, or in conjunction with primitive restart (which is not yet implemented in D3D11). Also ensure we do not regress with flat shading enabled and transform feedback. In cases where we use flat shading, do a double draw call, first with an untransformed vertex stream, and no geometry shader, then with the geometry shader enabled. This also fixes the dEQP fragment output tests with ints. BUG=angleproject:754 Change-Id: Ib37e8ec32d19db17ea5d4dc88158cdae0c956bfc Reviewed-on: https://chromium-review.googlesource.com/309155 Tryjob-Request: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent f4b2c4fd
...@@ -760,12 +760,12 @@ struct DynamicHLSL::SemanticInfo ...@@ -760,12 +760,12 @@ struct DynamicHLSL::SemanticInfo
BuiltinInfo glPointSize; BuiltinInfo glPointSize;
}; };
DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(unsigned int startRegisters, DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(ShaderType shaderType,
unsigned int startRegisters,
bool position, bool position,
bool fragCoord, bool fragCoord,
bool pointCoord, bool pointCoord,
bool pointSize, bool pointSize) const
bool pixelShader) const
{ {
SemanticInfo info; SemanticInfo info;
bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4); bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4);
...@@ -777,7 +777,7 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(unsigned int startRegiste ...@@ -777,7 +777,7 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(unsigned int startRegiste
{ {
info.dxPosition.enableSystem("SV_Position"); info.dxPosition.enableSystem("SV_Position");
} }
else if (pixelShader) else if (shaderType == SHADER_PIXEL)
{ {
info.dxPosition.enableSystem("VPOS"); info.dxPosition.enableSystem("VPOS");
} }
...@@ -811,7 +811,7 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(unsigned int startRegiste ...@@ -811,7 +811,7 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(unsigned int startRegiste
} }
// Special case: do not include PSIZE semantic in HLSL 3 pixel shaders // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders
if (pointSize && (!pixelShader || hlsl4)) if (pointSize && (shaderType != SHADER_PIXEL || hlsl4))
{ {
info.glPointSize.enableSystem("PSIZE"); info.glPointSize.enableSystem("PSIZE");
} }
...@@ -964,8 +964,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -964,8 +964,8 @@ 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(registerCount, outputPositionFromVS, usesFragCoord, addPointCoord, getSemanticInfo(SHADER_VERTEX, registerCount, outputPositionFromVS, usesFragCoord,
(!useInstancedPointSpriteEmulation && usesPointSize), false); addPointCoord, (!useInstancedPointSpriteEmulation && usesPointSize));
storeUserLinkedVaryings(packedVaryings, usesPointSize, linkedVaryings); storeUserLinkedVaryings(packedVaryings, usesPointSize, linkedVaryings);
storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings); storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings);
...@@ -1098,8 +1098,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -1098,8 +1098,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
pixelStream << fragmentShaderGL->getTranslatedSource(); pixelStream << fragmentShaderGL->getTranslatedSource();
const SemanticInfo &pixelSemantics = const SemanticInfo &pixelSemantics =
getSemanticInfo(registerCount, outputPositionFromVS, usesFragCoord, usesPointCoord, getSemanticInfo(SHADER_PIXEL, registerCount, outputPositionFromVS, usesFragCoord,
(!useInstancedPointSpriteEmulation && usesPointSize), true); 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);
...@@ -1305,9 +1305,9 @@ std::string DynamicHLSL::generateGeometryShaderPreamble( ...@@ -1305,9 +1305,9 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(
bool usesPointSize = vertexShader->usesPointSize(); bool usesPointSize = vertexShader->usesPointSize();
const SemanticInfo &inSemantics = const SemanticInfo &inSemantics =
getSemanticInfo(registerCount, true, usesFragCoord, false, usesPointSize, false); getSemanticInfo(SHADER_VERTEX, registerCount, true, usesFragCoord, false, usesPointSize);
const SemanticInfo &outSemantics = const SemanticInfo &outSemantics = getSemanticInfo(
getSemanticInfo(registerCount, true, usesFragCoord, usesPointCoord, usesPointSize, false); SHADER_GEOMETRY, registerCount, true, usesFragCoord, usesPointCoord, usesPointSize);
std::stringstream preambleStream; std::stringstream preambleStream;
...@@ -1317,10 +1317,11 @@ std::string DynamicHLSL::generateGeometryShaderPreamble( ...@@ -1317,10 +1317,11 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(
<< "struct GS_OUTPUT\n"; << "struct GS_OUTPUT\n";
generateVaryingLinkHLSL(*data.caps, usesPointSize, outSemantics, packedVaryings, generateVaryingLinkHLSL(*data.caps, usesPointSize, outSemantics, packedVaryings,
preambleStream); preambleStream);
preambleStream << "\n" preambleStream
<< "void copyVertex(inout GS_OUTPUT output, GS_INPUT input)\n" << "\n"
<< "{\n" << "void copyVertex(inout GS_OUTPUT output, GS_INPUT input, GS_INPUT flatinput)\n"
<< " output.gl_Position = input.gl_Position;\n"; << "{\n"
<< " output.gl_Position = input.gl_Position;\n";
if (usesPointSize) if (usesPointSize)
{ {
...@@ -1329,9 +1330,14 @@ std::string DynamicHLSL::generateGeometryShaderPreamble( ...@@ -1329,9 +1330,14 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(
for (const PackedVaryingRegister &varyingRegister : PackedVaryingIterator(packedVaryings)) for (const PackedVaryingRegister &varyingRegister : PackedVaryingIterator(packedVaryings))
{ {
const sh::Varying &varying = *packedVaryings[varyingRegister.varyingIndex].varying;
unsigned int registerIndex = varyingRegister.registerIndex(*data.caps, packedVaryings); unsigned int registerIndex = varyingRegister.registerIndex(*data.caps, packedVaryings);
preambleStream << " output.v" << registerIndex << " = "; preambleStream << " output.v" << registerIndex << " = ";
if (varying.interpolation == sh::INTERPOLATION_FLAT)
{
preambleStream << "flat";
}
preambleStream << "input.v" << registerIndex << "; \n"; preambleStream << "input.v" << registerIndex << "; \n";
} }
...@@ -1436,9 +1442,11 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT ...@@ -1436,9 +1442,11 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT
<< "{\n" << "{\n"
<< " GS_OUTPUT output = (GS_OUTPUT)0;\n"; << " GS_OUTPUT output = (GS_OUTPUT)0;\n";
int flatVertexIndex = inputSize - 1;
for (int vertexIndex = 0; vertexIndex < inputSize; ++vertexIndex) for (int vertexIndex = 0; vertexIndex < inputSize; ++vertexIndex)
{ {
shaderStream << " copyVertex(output, input[" << vertexIndex << "]);\n"; shaderStream << " copyVertex(output, input[" << vertexIndex << "], input["
<< flatVertexIndex << "]);\n";
if (!pointSprites) if (!pointSprites)
{ {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libANGLE/Constants.h" #include "libANGLE/Constants.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace sh namespace sh
{ {
...@@ -35,7 +36,6 @@ struct Data; ...@@ -35,7 +36,6 @@ struct Data;
namespace rx namespace rx
{ {
class RendererD3D;
class ShaderD3D; class ShaderD3D;
struct PixelShaderOutputVariable struct PixelShaderOutputVariable
...@@ -116,12 +116,12 @@ class DynamicHLSL : angle::NonCopyable ...@@ -116,12 +116,12 @@ class DynamicHLSL : angle::NonCopyable
struct SemanticInfo; struct SemanticInfo;
std::string getVaryingSemantic(bool programUsesPointSize) const; std::string getVaryingSemantic(bool programUsesPointSize) const;
SemanticInfo getSemanticInfo(unsigned int startRegisters, SemanticInfo getSemanticInfo(ShaderType shaderType,
unsigned int startRegisters,
bool position, bool position,
bool fragCoord, bool fragCoord,
bool pointCoord, bool pointCoord,
bool pointSize, bool pointSize) const;
bool pixelShader) const;
void generateVaryingLinkHLSL(const gl::Caps &caps, void generateVaryingLinkHLSL(const gl::Caps &caps,
bool programUsesPointSize, bool programUsesPointSize,
const SemanticInfo &info, const SemanticInfo &info,
......
...@@ -411,6 +411,7 @@ ProgramD3D::ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer) ...@@ -411,6 +411,7 @@ ProgramD3D::ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer)
mDynamicHLSL(NULL), mDynamicHLSL(NULL),
mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX, nullptr), mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX, nullptr),
mUsesPointSize(false), mUsesPointSize(false),
mUsesFlatInterpolation(false),
mVertexUniformStorage(NULL), mVertexUniformStorage(NULL),
mFragmentUniformStorage(NULL), mFragmentUniformStorage(NULL),
mUsedVertexSamplerRange(0), mUsedVertexSamplerRange(0),
...@@ -432,8 +433,13 @@ bool ProgramD3D::usesPointSpriteEmulation() const ...@@ -432,8 +433,13 @@ bool ProgramD3D::usesPointSpriteEmulation() const
return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
} }
bool ProgramD3D::usesGeometryShader() const bool ProgramD3D::usesGeometryShader(GLenum drawMode) const
{ {
if (drawMode != GL_POINTS)
{
return mUsesFlatInterpolation;
}
return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation(); return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation();
} }
...@@ -680,6 +686,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -680,6 +686,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
sizeof(D3DCompilerWorkarounds)); sizeof(D3DCompilerWorkarounds));
stream->readBool(&mUsesFragDepth); stream->readBool(&mUsesFragDepth);
stream->readBool(&mUsesPointSize); stream->readBool(&mUsesPointSize);
stream->readBool(&mUsesFlatInterpolation);
const size_t pixelShaderKeySize = stream->readInt<unsigned int>(); const size_t pixelShaderKeySize = stream->readInt<unsigned int>();
mPixelShaderKey.resize(pixelShaderKeySize); mPixelShaderKey.resize(pixelShaderKeySize);
...@@ -882,6 +889,7 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) ...@@ -882,6 +889,7 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
sizeof(D3DCompilerWorkarounds)); sizeof(D3DCompilerWorkarounds));
stream->writeInt(mUsesFragDepth); stream->writeInt(mUsesFragDepth);
stream->writeInt(mUsesPointSize); stream->writeInt(mUsesPointSize);
stream->writeInt(mUsesFlatInterpolation);
const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey; const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
stream->writeInt(pixelShaderKey.size()); stream->writeInt(pixelShaderKey.size());
...@@ -1083,6 +1091,18 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Data &data ...@@ -1083,6 +1091,18 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Data &data
ShaderExecutableD3D **outExecutable, ShaderExecutableD3D **outExecutable,
gl::InfoLog *infoLog) gl::InfoLog *infoLog)
{ {
if (outExecutable)
{
*outExecutable = nullptr;
}
// We only uses a geometry shader for point sprite emulation, or for fixing the provoking
// vertex problem. Otherwise, return a null shader.
if (drawMode != GL_POINTS && !mUsesFlatInterpolation)
{
return gl::Error(GL_NO_ERROR);
}
gl::PrimitiveType geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode); gl::PrimitiveType geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
if (mGeometryExecutables[geometryShaderType] != nullptr) if (mGeometryExecutables[geometryShaderType] != nullptr)
...@@ -1141,7 +1161,7 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::InfoL ...@@ -1141,7 +1161,7 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::InfoL
} }
// Auto-generate the geometry shader here, if we expect to be using point rendering in D3D11. // Auto-generate the geometry shader here, if we expect to be using point rendering in D3D11.
if (usesGeometryShader()) if (usesGeometryShader(GL_POINTS))
{ {
getGeometryExecutableForPrimitiveType(data, GL_POINTS, nullptr, &infoLog); getGeometryExecutableForPrimitiveType(data, GL_POINTS, nullptr, &infoLog);
} }
...@@ -1171,8 +1191,9 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::InfoL ...@@ -1171,8 +1191,9 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::InfoL
} }
#endif #endif
bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && bool linkSuccess =
(!usesGeometryShader() || mGeometryExecutables[gl::PRIMITIVE_POINTS])); (defaultVertexExecutable && defaultPixelExecutable &&
(!usesGeometryShader(GL_POINTS) || mGeometryExecutables[gl::PRIMITIVE_POINTS]));
return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR)); return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
} }
...@@ -1232,6 +1253,16 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog) ...@@ -1232,6 +1253,16 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
mUsesPointSize = vertexShaderD3D->usesPointSize(); mUsesPointSize = vertexShaderD3D->usesPointSize();
// Cache if we use flat shading
for (const auto &varying : packedVaryings)
{
if (varying.varying->interpolation == sh::INTERPOLATION_FLAT)
{
mUsesFlatInterpolation = true;
break;
}
}
if (mRenderer->getMajorShaderModel() >= 4) if (mRenderer->getMajorShaderModel() >= 4)
{ {
mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble( mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
...@@ -1351,11 +1382,11 @@ void ProgramD3D::initializeUniformStorage() ...@@ -1351,11 +1382,11 @@ void ProgramD3D::initializeUniformStorage()
mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u); mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
} }
gl::Error ProgramD3D::applyUniforms() gl::Error ProgramD3D::applyUniforms(GLenum drawMode)
{ {
updateSamplerMapping(); updateSamplerMapping();
gl::Error error = mRenderer->applyUniforms(*this, mD3DUniforms); gl::Error error = mRenderer->applyUniforms(*this, drawMode, mD3DUniforms);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -1941,6 +1972,7 @@ void ProgramD3D::reset() ...@@ -1941,6 +1972,7 @@ void ProgramD3D::reset()
mUsesFragDepth = false; mUsesFragDepth = false;
mPixelShaderKey.clear(); mPixelShaderKey.clear();
mUsesPointSize = false; mUsesPointSize = false;
mUsesFlatInterpolation = false;
SafeDeleteContainer(mD3DUniforms); SafeDeleteContainer(mD3DUniforms);
mD3DUniformBlocks.clear(); mD3DUniformBlocks.clear();
......
...@@ -99,7 +99,7 @@ class ProgramD3D : public ProgramImpl ...@@ -99,7 +99,7 @@ class ProgramD3D : public ProgramImpl
bool usesPointSize() const { return mUsesPointSize; } bool usesPointSize() const { return mUsesPointSize; }
bool usesPointSpriteEmulation() const; bool usesPointSpriteEmulation() const;
bool usesGeometryShader() const; bool usesGeometryShader(GLenum drawMode) const;
bool usesInstancedPointSpriteEmulation() const; bool usesInstancedPointSpriteEmulation() const;
LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream); LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
...@@ -126,7 +126,7 @@ class ProgramD3D : public ProgramImpl ...@@ -126,7 +126,7 @@ class ProgramD3D : public ProgramImpl
sh::BlockMemberInfo *memberInfoOut) const override; sh::BlockMemberInfo *memberInfoOut) const override;
void initializeUniformStorage(); void initializeUniformStorage();
gl::Error applyUniforms(); gl::Error applyUniforms(GLenum drawMode);
gl::Error applyUniformBuffers(const gl::Data &data); gl::Error applyUniformBuffers(const gl::Data &data);
void dirtyAllUniforms(); void dirtyAllUniforms();
...@@ -317,6 +317,7 @@ class ProgramD3D : public ProgramImpl ...@@ -317,6 +317,7 @@ class ProgramD3D : public ProgramImpl
std::string mGeometryShaderPreamble; std::string mGeometryShaderPreamble;
bool mUsesPointSize; bool mUsesPointSize;
bool mUsesFlatInterpolation;
UniformStorageD3D *mVertexUniformStorage; UniformStorageD3D *mVertexUniformStorage;
UniformStorageD3D *mFragmentUniformStorage; UniformStorageD3D *mFragmentUniformStorage;
......
...@@ -290,7 +290,7 @@ gl::Error RendererD3D::genericDrawArrays(const gl::Data &data, ...@@ -290,7 +290,7 @@ gl::Error RendererD3D::genericDrawArrays(const gl::Data &data,
if (!skipDraw(data, mode)) if (!skipDraw(data, mode))
{ {
error = drawArraysImpl(data, mode, count, instances, usesPointSize); error = drawArraysImpl(data, mode, count, instances);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -448,7 +448,7 @@ gl::Error RendererD3D::applyShaders(const gl::Data &data, GLenum drawMode) ...@@ -448,7 +448,7 @@ gl::Error RendererD3D::applyShaders(const gl::Data &data, GLenum drawMode)
return error; return error;
} }
return programD3D->applyUniforms(); return programD3D->applyUniforms(drawMode);
} }
// For each Direct3D sampler of either the pixel or vertex stage, // For each Direct3D sampler of either the pixel or vertex stage,
......
...@@ -161,6 +161,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -161,6 +161,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0; virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0;
virtual gl::Error applyUniforms(const ProgramD3D &programD3D, virtual gl::Error applyUniforms(const ProgramD3D &programD3D,
GLenum drawMode,
const std::vector<D3DUniform *> &uniformArray) = 0; const std::vector<D3DUniform *> &uniformArray) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0;
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo) = 0; virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo) = 0;
...@@ -277,8 +278,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -277,8 +278,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
virtual gl::Error drawArraysImpl(const gl::Data &data, virtual gl::Error drawArraysImpl(const gl::Data &data,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
GLsizei instances, GLsizei instances) = 0;
bool usesPointSize) = 0;
virtual gl::Error drawElementsImpl(GLenum mode, virtual gl::Error drawElementsImpl(GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
......
...@@ -1672,18 +1672,17 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) ...@@ -1672,18 +1672,17 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
gl::Error Renderer11::drawArraysImpl(const gl::Data &data, gl::Error Renderer11::drawArraysImpl(const gl::Data &data,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
GLsizei instances, GLsizei instances)
bool usesPointSize)
{ {
bool useInstancedPointSpriteEmulation = usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation; ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
if (mode == GL_POINTS && data.state->isTransformFeedbackActiveUnpaused())
{
// Since point sprites are generated with a geometry shader, too many vertices will
// be written if transform feedback is active. To work around this, draw only the points
// with the stream out shader and no pixel shader to feed the stream out buffers and then
// draw again with the point sprite geometry shader to rasterize the point sprites.
mDeviceContext->PSSetShader(NULL, NULL, 0); if (programD3D->usesGeometryShader(mode) && data.state->isTransformFeedbackActiveUnpaused())
{
// Since we use a geometry if-and-only-if we rewrite vertex streams, transform feedback
// won't get the correct output. To work around this, draw with *only* the stream out
// first (no pixel shader) to feed the stream out buffers and then draw again with the
// geometry shader + pixel shader to rasterize the primitives.
mDeviceContext->PSSetShader(nullptr, nullptr, 0);
if (instances > 0) if (instances > 0)
{ {
...@@ -1694,77 +1693,80 @@ gl::Error Renderer11::drawArraysImpl(const gl::Data &data, ...@@ -1694,77 +1693,80 @@ gl::Error Renderer11::drawArraysImpl(const gl::Data &data,
mDeviceContext->Draw(count, 0); mDeviceContext->Draw(count, 0);
} }
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram()); rx::ShaderExecutableD3D *pixelExe = nullptr;
rx::ShaderExecutableD3D *pixelExe = NULL;
gl::Error error = programD3D->getPixelExecutableForFramebuffer(data.state->getDrawFramebuffer(), &pixelExe); gl::Error error = programD3D->getPixelExecutableForFramebuffer(data.state->getDrawFramebuffer(), &pixelExe);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
// Skip this step if we're doing rasterizer discard. // Skip the draw call if rasterizer discard is enabled (or no fragment shader).
if (pixelExe && !data.state->getRasterizerState().rasterizerDiscard && usesPointSize) if (!pixelExe || data.state->getRasterizerState().rasterizerDiscard)
{ {
ID3D11PixelShader *pixelShader = GetAs<ShaderExecutable11>(pixelExe)->getPixelShader(); return gl::Error(GL_NO_ERROR);
ASSERT(reinterpret_cast<uintptr_t>(pixelShader) == mAppliedPixelShader); }
mDeviceContext->PSSetShader(pixelShader, NULL, 0);
// Retrieve the point sprite geometry shader ID3D11PixelShader *pixelShader = GetAs<ShaderExecutable11>(pixelExe)->getPixelShader();
rx::ShaderExecutableD3D *geometryExe = nullptr; ASSERT(reinterpret_cast<uintptr_t>(pixelShader) == mAppliedPixelShader);
mDeviceContext->PSSetShader(pixelShader, NULL, 0);
error = programD3D->getGeometryExecutableForPrimitiveType(data, mode, &geometryExe, // Retrieve the geometry shader.
nullptr); rx::ShaderExecutableD3D *geometryExe = nullptr;
if (error.isError()) error =
{ programD3D->getGeometryExecutableForPrimitiveType(data, mode, &geometryExe, nullptr);
return error; if (error.isError())
} {
return error;
}
ID3D11GeometryShader *geometryShader = (geometryExe ? GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : NULL); ID3D11GeometryShader *geometryShader =
mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader); (geometryExe ? GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : NULL);
ASSERT(geometryShader); mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader);
mDeviceContext->GSSetShader(geometryShader, NULL, 0); ASSERT(geometryShader);
mDeviceContext->GSSetShader(geometryShader, NULL, 0);
if (instances > 0) if (instances > 0)
{ {
mDeviceContext->DrawInstanced(count, instances, 0, 0); mDeviceContext->DrawInstanced(count, instances, 0, 0);
} }
else else
{ {
mDeviceContext->Draw(count, 0); mDeviceContext->Draw(count, 0);
}
} }
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
else if (mode == GL_LINE_LOOP)
if (mode == GL_LINE_LOOP)
{ {
return drawLineLoop(count, GL_NONE, NULL, 0, NULL); return drawLineLoop(count, GL_NONE, NULL, 0, NULL);
} }
else if (mode == GL_TRIANGLE_FAN)
if (mode == GL_TRIANGLE_FAN)
{ {
return drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); return drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances);
} }
else if (instances > 0)
if (instances > 0)
{ {
mDeviceContext->DrawInstanced(count, instances, 0, 0); mDeviceContext->DrawInstanced(count, instances, 0, 0);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
bool useInstancedPointSpriteEmulation =
programD3D->usesPointSize() && getWorkarounds().useInstancedPointSpriteEmulation;
// If the shader is writing to gl_PointSize, then pointsprites are being rendered.
// Emulating instanced point sprites for FL9_3 requires the topology to be
// D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
if (mode == GL_POINTS && useInstancedPointSpriteEmulation)
{
mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
}
else else
{ {
// If the shader is writing to gl_PointSize, then pointsprites are being rendered. mDeviceContext->Draw(count, 0);
// Emulating instanced point sprites for FL9_3 requires the topology to be
// D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
if (mode == GL_POINTS && useInstancedPointSpriteEmulation)
{
mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
}
else
{
mDeviceContext->Draw(count, 0);
}
return gl::Error(GL_NO_ERROR);
} }
return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer11::drawElementsImpl(GLenum mode, gl::Error Renderer11::drawElementsImpl(GLenum mode,
...@@ -2134,6 +2136,7 @@ gl::Error Renderer11::applyShadersImpl(const gl::Data &data, GLenum drawMode) ...@@ -2134,6 +2136,7 @@ gl::Error Renderer11::applyShadersImpl(const gl::Data &data, GLenum drawMode)
} }
gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
GLenum drawMode,
const std::vector<D3DUniform *> &uniformArray) const std::vector<D3DUniform *> &uniformArray)
{ {
unsigned int totalRegisterCountVS = 0; unsigned int totalRegisterCountVS = 0;
...@@ -2293,7 +2296,7 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, ...@@ -2293,7 +2296,7 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
} }
// GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
if (programD3D.usesGeometryShader()) if (programD3D.usesGeometryShader(drawMode))
{ {
// needed for the point sprite geometry shader // needed for the point sprite geometry shader
if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS) if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
......
...@@ -133,6 +133,7 @@ class Renderer11 : public RendererD3D ...@@ -133,6 +133,7 @@ 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,
GLenum drawMode,
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);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo); virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo);
...@@ -274,8 +275,7 @@ class Renderer11 : public RendererD3D ...@@ -274,8 +275,7 @@ class Renderer11 : public RendererD3D
gl::Error drawArraysImpl(const gl::Data &data, gl::Error drawArraysImpl(const gl::Data &data,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
GLsizei instances, GLsizei instances) override;
bool usesPointSize) override;
gl::Error drawElementsImpl(GLenum mode, gl::Error drawElementsImpl(GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
......
...@@ -1485,8 +1485,7 @@ void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) ...@@ -1485,8 +1485,7 @@ void Renderer9::applyTransformFeedbackBuffers(const gl::State& state)
gl::Error Renderer9::drawArraysImpl(const gl::Data &data, gl::Error Renderer9::drawArraysImpl(const gl::Data &data,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
GLsizei instances, GLsizei instances)
bool usesPointSize)
{ {
ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); ASSERT(!data.state->isTransformFeedbackActiveUnpaused());
...@@ -1914,6 +1913,7 @@ gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/) ...@@ -1914,6 +1913,7 @@ gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/)
} }
gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D,
GLenum /*drawMode*/,
const std::vector<D3DUniform *> &uniformArray) const std::vector<D3DUniform *> &uniformArray)
{ {
for (const D3DUniform *targetUniform : uniformArray) for (const D3DUniform *targetUniform : uniformArray)
......
...@@ -110,6 +110,7 @@ class Renderer9 : public RendererD3D ...@@ -110,6 +110,7 @@ class Renderer9 : public RendererD3D
gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorAttachment,
const gl::FramebufferAttachment *depthStencilAttachment); const gl::FramebufferAttachment *depthStencilAttachment);
gl::Error applyUniforms(const ProgramD3D &programD3D, gl::Error applyUniforms(const ProgramD3D &programD3D,
GLenum drawMode,
const std::vector<D3DUniform *> &uniformArray) override; const std::vector<D3DUniform *> &uniformArray) override;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo); virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo);
...@@ -241,8 +242,7 @@ class Renderer9 : public RendererD3D ...@@ -241,8 +242,7 @@ class Renderer9 : public RendererD3D
gl::Error drawArraysImpl(const gl::Data &data, gl::Error drawArraysImpl(const gl::Data &data,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
GLsizei instances, GLsizei instances) override;
bool usesPointSize) override;
gl::Error drawElementsImpl(GLenum mode, gl::Error drawElementsImpl(GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
......
...@@ -957,100 +957,6 @@ ...@@ -957,100 +957,6 @@
1099 WIN : dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2x2 = FAIL 1099 WIN : dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2x2 = FAIL
1099 WIN : dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2 = FAIL 1099 WIN : dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2 = FAIL
1099 WIN : dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2x2 = FAIL 1099 WIN : dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2x2 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.basic.int.* = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.basic.uint.* = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.array.int.* = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.array.uint.* = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.0 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.1 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.2 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.4 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.5 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.6 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.7 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.8 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.9 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.10 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.11 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.12 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.13 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.15 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.16 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.17 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.18 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.19 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.20 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.21 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.22 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.24 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.25 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.27 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.28 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.29 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.30 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.31 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.32 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.33 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.34 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.35 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.36 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.37 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.38 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.39 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.40 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.41 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.42 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.43 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.44 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.45 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.47 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.49 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.50 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.51 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.52 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.53 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.54 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.55 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.56 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.57 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.58 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.59 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.60 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.61 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.62 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.63 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.64 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.66 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.67 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.68 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.69 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.70 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.71 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.72 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.75 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.76 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.77 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.78 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.79 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.80 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.82 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.83 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.84 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.85 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.86 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.87 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.88 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.89 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.90 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.91 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.92 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.93 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.94 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.95 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.96 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.97 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.98 = FAIL
1100 WIN : dEQP-GLES3.functional.fragment_out.random.99 = FAIL
1101 WIN : dEQP-GLES3.functional.rasterization.flatshading.triangles = FAIL 1101 WIN : dEQP-GLES3.functional.rasterization.flatshading.triangles = FAIL
1101 WIN : dEQP-GLES3.functional.rasterization.flatshading.triangle_strip = FAIL 1101 WIN : dEQP-GLES3.functional.rasterization.flatshading.triangle_strip = FAIL
1101 WIN : dEQP-GLES3.functional.rasterization.flatshading.triangle_fan = FAIL 1101 WIN : dEQP-GLES3.functional.rasterization.flatshading.triangle_fan = FAIL
......
...@@ -125,13 +125,6 @@ class ProvokingVertexTest : public ANGLETest ...@@ -125,13 +125,6 @@ class ProvokingVertexTest : public ANGLETest
// Test drawing a simple triangle with flat shading, and different valued vertices. // Test drawing a simple triangle with flat shading, and different valued vertices.
TEST_P(ProvokingVertexTest, FlatTriangle) TEST_P(ProvokingVertexTest, FlatTriangle)
{ {
// TODO(jmadill): Implement on the D3D back-end.
if (isD3D11())
{
std::cout << "Test disabled on D3D11." << std::endl;
return;
}
GLint vertexData[] = {1, 2, 3, 1, 2, 3}; GLint vertexData[] = {1, 2, 3, 1, 2, 3};
glVertexAttribIPointer(mIntAttribLocation, 1, GL_INT, 0, vertexData); glVertexAttribIPointer(mIntAttribLocation, 1, GL_INT, 0, vertexData);
...@@ -147,13 +140,6 @@ TEST_P(ProvokingVertexTest, FlatTriangle) ...@@ -147,13 +140,6 @@ TEST_P(ProvokingVertexTest, FlatTriangle)
// Ensure that any provoking vertex shenanigans still gives correct vertex streams. // Ensure that any provoking vertex shenanigans still gives correct vertex streams.
TEST_P(ProvokingVertexTest, FlatTriWithTransformFeedback) TEST_P(ProvokingVertexTest, FlatTriWithTransformFeedback)
{ {
// TODO(jmadill): Implement on the D3D back-end.
if (isD3D11())
{
std::cout << "Test disabled on D3D11." << std::endl;
return;
}
glGenTransformFeedbacks(1, &mTransformFeedback); glGenTransformFeedbacks(1, &mTransformFeedback);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback); glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback);
...@@ -190,13 +176,6 @@ TEST_P(ProvokingVertexTest, FlatTriWithTransformFeedback) ...@@ -190,13 +176,6 @@ TEST_P(ProvokingVertexTest, FlatTriWithTransformFeedback)
// Test drawing a simple line with flat shading, and different valued vertices. // Test drawing a simple line with flat shading, and different valued vertices.
TEST_P(ProvokingVertexTest, FlatLine) TEST_P(ProvokingVertexTest, FlatLine)
{ {
// TODO(jmadill): Implement on the D3D back-end.
if (isD3D11())
{
std::cout << "Test disabled on D3D11." << std::endl;
return;
}
GLfloat halfPixel = 1.0f / static_cast<GLfloat>(getWindowWidth()); GLfloat halfPixel = 1.0f / static_cast<GLfloat>(getWindowWidth());
GLint vertexData[] = {1, 2}; GLint vertexData[] = {1, 2};
......
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