Commit 41ac68e7 by Martin Radev Committed by Commit Bot

Select viewport index in GS for multi-view instanced rendering

The patch extends the OutputHLSL and DynamicHLSL translators to select the viewport index in the geometry shader and propagate the ViewID variable to the fragment shader. BUG=angleproject:2062 TEST=angle_end2end_tests Change-Id: I9e344a7521e2e1137e6eb38d0bfecea8bece778f Reviewed-on: https://chromium-review.googlesource.com/608967 Commit-Queue: Martin Radev <mradev@nvidia.com> Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent e86db0c1
...@@ -113,6 +113,9 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -113,6 +113,9 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
mUsesFrontFacing = false; mUsesFrontFacing = false;
mUsesPointSize = false; mUsesPointSize = false;
mUsesInstanceID = false; mUsesInstanceID = false;
mHasMultiviewExtensionEnabled = IsExtensionEnabled(mExtensionBehavior, "GL_OVR_multiview") ||
IsExtensionEnabled(mExtensionBehavior, "GL_OVR_multiview2");
mUsesViewID = false;
mUsesVertexID = false; mUsesVertexID = false;
mUsesFragDepth = false; mUsesFragDepth = false;
mUsesNumWorkGroups = false; mUsesNumWorkGroups = false;
...@@ -708,6 +711,16 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built ...@@ -708,6 +711,16 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
out << "#define GL_USES_POINT_SIZE\n"; out << "#define GL_USES_POINT_SIZE\n";
} }
if (mHasMultiviewExtensionEnabled)
{
out << "#define GL_ANGLE_MULTIVIEW_ENABLED\n";
}
if (mUsesViewID)
{
out << "#define GL_USES_VIEW_ID\n";
}
if (mUsesFragDepth) if (mUsesFragDepth)
{ {
out << "#define GL_USES_FRAG_DEPTH\n"; out << "#define GL_USES_FRAG_DEPTH\n";
...@@ -804,6 +817,10 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) ...@@ -804,6 +817,10 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
{ {
mReferencedVaryings[name] = node; mReferencedVaryings[name] = node;
out << Decorate(name); out << Decorate(name);
if (name == "ViewID_OVR")
{
mUsesViewID = true;
}
} }
else if (qualifier == EvqFragmentOut) else if (qualifier == EvqFragmentOut)
{ {
......
...@@ -171,6 +171,8 @@ class OutputHLSL : public TIntermTraverser ...@@ -171,6 +171,8 @@ class OutputHLSL : public TIntermTraverser
bool mUsesFrontFacing; bool mUsesFrontFacing;
bool mUsesPointSize; bool mUsesPointSize;
bool mUsesInstanceID; bool mUsesInstanceID;
bool mHasMultiviewExtensionEnabled;
bool mUsesViewID;
bool mUsesVertexID; bool mUsesVertexID;
bool mUsesFragDepth; bool mUsesFragDepth;
bool mUsesNumWorkGroups; bool mUsesNumWorkGroups;
......
...@@ -379,6 +379,18 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking, ...@@ -379,6 +379,18 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking,
hlslStream << " float gl_PointSize : " << builtins.glPointSize.str() << ";\n"; hlslStream << " float gl_PointSize : " << builtins.glPointSize.str() << ";\n";
} }
if (builtins.glViewIDOVR.enabled)
{
hlslStream << " nointerpolation uint gl_ViewID_OVR : " << builtins.glViewIDOVR.str()
<< ";\n";
}
if (builtins.glViewportIndex.enabled)
{
hlslStream << " nointerpolation uint gl_ViewportIndex : "
<< builtins.glViewportIndex.str() << ";\n";
}
std::string varyingSemantic = std::string varyingSemantic =
GetVaryingSemantic(mRenderer->getMajorShaderModel(), programUsesPointSize); GetVaryingSemantic(mRenderer->getMajorShaderModel(), programUsesPointSize);
...@@ -483,6 +495,11 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context, ...@@ -483,6 +495,11 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
vertexStream << " output.gl_Position = gl_Position;\n"; vertexStream << " output.gl_Position = gl_Position;\n";
} }
if (vertexBuiltins.glViewIDOVR.enabled)
{
vertexStream << " output.gl_ViewID_OVR = _ViewID_OVR;\n";
}
// On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust. // On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust.
if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
{ {
...@@ -642,6 +659,11 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context, ...@@ -642,6 +659,11 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
<< "{\n"; << "{\n";
} }
if (pixelBuiltins.glViewIDOVR.enabled)
{
pixelStream << " _ViewID_OVR = input.gl_ViewID_OVR;\n";
}
if (pixelBuiltins.glFragCoord.enabled) if (pixelBuiltins.glFragCoord.enabled)
{ {
pixelStream << " float rhw = 1.0 / input.gl_FragCoord.w;\n"; pixelStream << " float rhw = 1.0 / input.gl_FragCoord.w;\n";
...@@ -872,7 +894,8 @@ std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::Context *contex ...@@ -872,7 +894,8 @@ std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::Context *contex
} }
std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &varyingPacking, std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &varyingPacking,
const BuiltinVaryingsD3D &builtinsD3D) const const BuiltinVaryingsD3D &builtinsD3D,
const bool hasANGLEMultiviewEnabled) const
{ {
ASSERT(mRenderer->getMajorShaderModel() >= 4); ASSERT(mRenderer->getMajorShaderModel() >= 4);
...@@ -919,6 +942,15 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va ...@@ -919,6 +942,15 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
<< "#endif // ANGLE_POINT_SPRITE_SHADER\n" << "#endif // ANGLE_POINT_SPRITE_SHADER\n"
<< "}\n"; << "}\n";
if (builtinsD3D[SHADER_GEOMETRY].glViewportIndex.enabled && hasANGLEMultiviewEnabled)
{
preambleStream << "\n"
<< "void selectView(inout GS_OUTPUT output, GS_INPUT input)\n"
<< "{\n"
<< " output.gl_ViewportIndex = input.gl_ViewID_OVR;\n"
<< "}\n";
}
return preambleStream.str(); return preambleStream.str();
} }
...@@ -926,13 +958,15 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT ...@@ -926,13 +958,15 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT
const gl::ContextState &data, const gl::ContextState &data,
const gl::ProgramState &programData, const gl::ProgramState &programData,
const bool useViewScale, const bool useViewScale,
const bool hasANGLEMultiviewEnabled,
const bool pointSpriteEmulation,
const std::string &preambleString) const const std::string &preambleString) const
{ {
ASSERT(mRenderer->getMajorShaderModel() >= 4); ASSERT(mRenderer->getMajorShaderModel() >= 4);
std::stringstream shaderStream; std::stringstream shaderStream;
const bool pointSprites = (primitiveType == PRIMITIVE_POINTS); const bool pointSprites = (primitiveType == PRIMITIVE_POINTS) && pointSpriteEmulation;
const bool usesPointCoord = preambleString.find("gl_PointCoord") != std::string::npos; const bool usesPointCoord = preambleString.find("gl_PointCoord") != std::string::npos;
const char *inputPT = nullptr; const char *inputPT = nullptr;
...@@ -944,9 +978,19 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT ...@@ -944,9 +978,19 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT
{ {
case PRIMITIVE_POINTS: case PRIMITIVE_POINTS:
inputPT = "point"; inputPT = "point";
outputPT = "Triangle";
inputSize = 1; inputSize = 1;
maxVertexOutput = 4;
if (pointSprites)
{
outputPT = "Triangle";
maxVertexOutput = 4;
}
else
{
outputPT = "Point";
maxVertexOutput = 1;
}
break; break;
case PRIMITIVE_LINES: case PRIMITIVE_LINES:
...@@ -1034,7 +1078,10 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT ...@@ -1034,7 +1078,10 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT
{ {
shaderStream << " copyVertex(output, input[" << vertexIndex shaderStream << " copyVertex(output, input[" << vertexIndex
<< "], input[lastVertexIndex]);\n"; << "], input[lastVertexIndex]);\n";
if (hasANGLEMultiviewEnabled)
{
shaderStream << " selectView(output, input[" << vertexIndex << "]);\n";
}
if (!pointSprites) if (!pointSprites)
{ {
ASSERT(inputSize == maxVertexOutput); ASSERT(inputSize == maxVertexOutput);
...@@ -1253,6 +1300,21 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType, ...@@ -1253,6 +1300,21 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
} }
} }
if (shaderType == SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled())
{
builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
}
if (shaderType == SHADER_PIXEL && metadata.usesViewID())
{
builtins->glViewIDOVR.enableSystem("SV_ViewportArrayIndex");
}
if (shaderType == SHADER_GEOMETRY && metadata.hasANGLEMultiviewEnabled())
{
builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex");
}
// 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 (metadata.usesSystemValuePointSize() && if (metadata.usesSystemValuePointSize() &&
(shaderType != SHADER_PIXEL || metadata.getRendererMajorShaderModel() >= 4)) (shaderType != SHADER_PIXEL || metadata.getRendererMajorShaderModel() >= 4))
......
...@@ -76,6 +76,8 @@ struct BuiltinInfo ...@@ -76,6 +76,8 @@ struct BuiltinInfo
BuiltinVarying glFragCoord; BuiltinVarying glFragCoord;
BuiltinVarying glPointCoord; BuiltinVarying glPointCoord;
BuiltinVarying glPointSize; BuiltinVarying glPointSize;
BuiltinVarying glViewIDOVR;
BuiltinVarying glViewportIndex;
}; };
inline std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize) inline std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize)
...@@ -128,12 +130,15 @@ class DynamicHLSL : angle::NonCopyable ...@@ -128,12 +130,15 @@ class DynamicHLSL : angle::NonCopyable
const gl::ProgramState &programData) const; const gl::ProgramState &programData) const;
std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking, std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking,
const BuiltinVaryingsD3D &builtinsD3D) const; const BuiltinVaryingsD3D &builtinsD3D,
const bool hasANGLEMultiviewEnabled) const;
std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType, std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType,
const gl::ContextState &data, const gl::ContextState &data,
const gl::ProgramState &programData, const gl::ProgramState &programData,
const bool useViewScale, const bool useViewScale,
const bool hasANGLEMultiviewEnabled,
const bool pointSpriteEmulation,
const std::string &preambleString) const; const std::string &preambleString) const;
void getPixelShaderOutputKey(const gl::ContextState &data, void getPixelShaderOutputKey(const gl::ContextState &data,
......
...@@ -343,6 +343,8 @@ ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer, ...@@ -343,6 +343,8 @@ ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer,
mUsesInstancedPointSpriteEmulation( mUsesInstancedPointSpriteEmulation(
renderer->getWorkarounds().useInstancedPointSpriteEmulation), renderer->getWorkarounds().useInstancedPointSpriteEmulation),
mUsesViewScale(renderer->presentPathFastEnabled()), mUsesViewScale(renderer->presentPathFastEnabled()),
mHasANGLEMultiviewEnabled(vertexShader->hasANGLEMultiviewEnabled()),
mUsesViewID(fragmentShader->usesViewID()),
mVertexShader(vertexShader), mVertexShader(vertexShader),
mFragmentShader(fragmentShader) mFragmentShader(fragmentShader)
{ {
...@@ -390,6 +392,16 @@ bool ProgramD3DMetadata::usesViewScale() const ...@@ -390,6 +392,16 @@ bool ProgramD3DMetadata::usesViewScale() const
return mUsesViewScale; return mUsesViewScale;
} }
bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const
{
return mHasANGLEMultiviewEnabled;
}
bool ProgramD3DMetadata::usesViewID() const
{
return mUsesViewID;
}
bool ProgramD3DMetadata::addsPointCoordToVertexShader() const bool ProgramD3DMetadata::addsPointCoordToVertexShader() const
{ {
// PointSprite emulation requiress that gl_PointCoord is present in the vertex shader // PointSprite emulation requiress that gl_PointCoord is present in the vertex shader
...@@ -549,14 +561,22 @@ bool ProgramD3D::usesPointSpriteEmulation() const ...@@ -549,14 +561,22 @@ bool ProgramD3D::usesPointSpriteEmulation() const
return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
} }
bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const
{
return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation();
}
bool ProgramD3D::usesGeometryShader(GLenum drawMode) const bool ProgramD3D::usesGeometryShader(GLenum drawMode) const
{ {
if (mHasANGLEMultiviewEnabled)
{
return true;
}
if (drawMode != GL_POINTS) if (drawMode != GL_POINTS)
{ {
return mUsesFlatInterpolation; return mUsesFlatInterpolation;
} }
return usesGeometryShaderForPointSpriteEmulation();
return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation();
} }
bool ProgramD3D::usesInstancedPointSpriteEmulation() const bool ProgramD3D::usesInstancedPointSpriteEmulation() const
...@@ -843,6 +863,8 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -843,6 +863,8 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
stream->readBytes(reinterpret_cast<unsigned char *>(&mPixelWorkarounds), stream->readBytes(reinterpret_cast<unsigned char *>(&mPixelWorkarounds),
sizeof(angle::CompilerWorkaroundsD3D)); sizeof(angle::CompilerWorkaroundsD3D));
stream->readBool(&mUsesFragDepth); stream->readBool(&mUsesFragDepth);
stream->readBool(&mHasANGLEMultiviewEnabled);
stream->readBool(&mUsesViewID);
stream->readBool(&mUsesPointSize); stream->readBool(&mUsesPointSize);
stream->readBool(&mUsesFlatInterpolation); stream->readBool(&mUsesFlatInterpolation);
...@@ -1066,6 +1088,8 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1066,6 +1088,8 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
stream->writeBytes(reinterpret_cast<unsigned char *>(&mPixelWorkarounds), stream->writeBytes(reinterpret_cast<unsigned char *>(&mPixelWorkarounds),
sizeof(angle::CompilerWorkaroundsD3D)); sizeof(angle::CompilerWorkaroundsD3D));
stream->writeInt(mUsesFragDepth); stream->writeInt(mUsesFragDepth);
stream->writeInt(mHasANGLEMultiviewEnabled);
stream->writeInt(mUsesViewID);
stream->writeInt(mUsesPointSize); stream->writeInt(mUsesPointSize);
stream->writeInt(mUsesFlatInterpolation); stream->writeInt(mUsesFlatInterpolation);
...@@ -1269,6 +1293,7 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextSta ...@@ -1269,6 +1293,7 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextSta
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL( std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
geometryShaderType, data, mState, mRenderer->presentPathFastEnabled(), geometryShaderType, data, mState, mRenderer->presentPathFastEnabled(),
mHasANGLEMultiviewEnabled, usesGeometryShaderForPointSpriteEmulation(),
mGeometryShaderPreamble); mGeometryShaderPreamble);
gl::InfoLog tempInfoLog; gl::InfoLog tempInfoLog;
...@@ -1558,6 +1583,8 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1558,6 +1583,8 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context,
mUsesPointSize = vertexShaderD3D->usesPointSize(); mUsesPointSize = vertexShaderD3D->usesPointSize();
mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey); mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
mUsesFragDepth = metadata.usesFragDepth(); mUsesFragDepth = metadata.usesFragDepth();
mUsesViewID = metadata.usesViewID();
mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled();
// Cache if we use flat shading // Cache if we use flat shading
mUsesFlatInterpolation = mUsesFlatInterpolation =
...@@ -1566,8 +1593,8 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1566,8 +1593,8 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context,
if (mRenderer->getMajorShaderModel() >= 4) if (mRenderer->getMajorShaderModel() >= 4)
{ {
mGeometryShaderPreamble = mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
mDynamicHLSL->generateGeometryShaderPreamble(packing, builtins); packing, builtins, mHasANGLEMultiviewEnabled);
} }
initAttribLocationsToD3DSemantic(context); initAttribLocationsToD3DSemantic(context);
...@@ -2330,6 +2357,8 @@ void ProgramD3D::reset() ...@@ -2330,6 +2357,8 @@ void ProgramD3D::reset()
mPixelHLSL.clear(); mPixelHLSL.clear();
mPixelWorkarounds = angle::CompilerWorkaroundsD3D(); mPixelWorkarounds = angle::CompilerWorkaroundsD3D();
mUsesFragDepth = false; mUsesFragDepth = false;
mHasANGLEMultiviewEnabled = false;
mUsesViewID = false;
mPixelShaderKey.clear(); mPixelShaderKey.clear();
mUsesPointSize = false; mUsesPointSize = false;
mUsesFlatInterpolation = false; mUsesFlatInterpolation = false;
......
...@@ -122,6 +122,8 @@ class ProgramD3DMetadata final : angle::NonCopyable ...@@ -122,6 +122,8 @@ class ProgramD3DMetadata final : angle::NonCopyable
bool usesPointSize() const; bool usesPointSize() const;
bool usesInsertedPointCoordValue() const; bool usesInsertedPointCoordValue() const;
bool usesViewScale() const; bool usesViewScale() const;
bool hasANGLEMultiviewEnabled() const;
bool usesViewID() const;
bool addsPointCoordToVertexShader() const; bool addsPointCoordToVertexShader() const;
bool usesTransformFeedbackGLPosition() const; bool usesTransformFeedbackGLPosition() const;
bool usesSystemValuePointSize() const; bool usesSystemValuePointSize() const;
...@@ -134,6 +136,8 @@ class ProgramD3DMetadata final : angle::NonCopyable ...@@ -134,6 +136,8 @@ class ProgramD3DMetadata final : angle::NonCopyable
const std::string mShaderModelSuffix; const std::string mShaderModelSuffix;
const bool mUsesInstancedPointSpriteEmulation; const bool mUsesInstancedPointSpriteEmulation;
const bool mUsesViewScale; const bool mUsesViewScale;
const bool mHasANGLEMultiviewEnabled;
const bool mUsesViewID;
const ShaderD3D *mVertexShader; const ShaderD3D *mVertexShader;
const ShaderD3D *mFragmentShader; const ShaderD3D *mFragmentShader;
}; };
...@@ -156,6 +160,7 @@ class ProgramD3D : public ProgramImpl ...@@ -156,6 +160,7 @@ class ProgramD3D : public ProgramImpl
bool usesPointSize() const { return mUsesPointSize; } bool usesPointSize() const { return mUsesPointSize; }
bool usesPointSpriteEmulation() const; bool usesPointSpriteEmulation() const;
bool usesGeometryShader(GLenum drawMode) const; bool usesGeometryShader(GLenum drawMode) const;
bool usesGeometryShaderForPointSpriteEmulation() const;
bool usesInstancedPointSpriteEmulation() const; bool usesInstancedPointSpriteEmulation() const;
gl::LinkResult load(const gl::Context *context, gl::LinkResult load(const gl::Context *context,
...@@ -398,6 +403,8 @@ class ProgramD3D : public ProgramImpl ...@@ -398,6 +403,8 @@ class ProgramD3D : public ProgramImpl
std::string mPixelHLSL; std::string mPixelHLSL;
angle::CompilerWorkaroundsD3D mPixelWorkarounds; angle::CompilerWorkaroundsD3D mPixelWorkarounds;
bool mUsesFragDepth; bool mUsesFragDepth;
bool mHasANGLEMultiviewEnabled;
bool mUsesViewID;
std::vector<PixelShaderOutputVariable> mPixelShaderKey; std::vector<PixelShaderOutputVariable> mPixelShaderKey;
// Common code for all dynamic geometry shaders. Consists mainly of the GS input and output // Common code for all dynamic geometry shaders. Consists mainly of the GS input and output
......
...@@ -9,11 +9,12 @@ ...@@ -9,11 +9,12 @@
#include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/ShaderD3D.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Compiler.h" #include "libANGLE/Compiler.h"
#include "libANGLE/Shader.h" #include "libANGLE/Shader.h"
#include "libANGLE/features.h" #include "libANGLE/features.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/ProgramD3D.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
// Definitions local to the translation unit // Definitions local to the translation unit
namespace namespace
...@@ -43,7 +44,9 @@ const char *GetShaderTypeString(GLenum type) ...@@ -43,7 +44,9 @@ const char *GetShaderTypeString(GLenum type)
namespace rx namespace rx
{ {
ShaderD3D::ShaderD3D(const gl::ShaderState &data, const angle::WorkaroundsD3D &workarounds) ShaderD3D::ShaderD3D(const gl::ShaderState &data,
const angle::WorkaroundsD3D &workarounds,
const gl::Extensions &extensions)
: ShaderImpl(data), mAdditionalOptions(0) : ShaderImpl(data), mAdditionalOptions(0)
{ {
uncompile(); uncompile();
...@@ -70,6 +73,10 @@ ShaderD3D::ShaderD3D(const gl::ShaderState &data, const angle::WorkaroundsD3D &w ...@@ -70,6 +73,10 @@ ShaderD3D::ShaderD3D(const gl::ShaderState &data, const angle::WorkaroundsD3D &w
{ {
mAdditionalOptions |= SH_EMULATE_ISNAN_FLOAT_FUNCTION; mAdditionalOptions |= SH_EMULATE_ISNAN_FLOAT_FUNCTION;
} }
if (extensions.multiview)
{
mAdditionalOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;
}
} }
ShaderD3D::~ShaderD3D() ShaderD3D::~ShaderD3D()
...@@ -102,6 +109,8 @@ void ShaderD3D::uncompile() ...@@ -102,6 +109,8 @@ void ShaderD3D::uncompile()
mUsesPointCoord = false; mUsesPointCoord = false;
mUsesDepthRange = false; mUsesDepthRange = false;
mUsesFragDepth = false; mUsesFragDepth = false;
mHasANGLEMultiviewEnabled = false;
mUsesViewID = false;
mUsesDiscardRewriting = false; mUsesDiscardRewriting = false;
mUsesNestedBreak = false; mUsesNestedBreak = false;
mRequiresIEEEStrictCompiling = false; mRequiresIEEEStrictCompiling = false;
...@@ -201,6 +210,9 @@ bool ShaderD3D::postTranslateCompile(gl::Compiler *compiler, std::string *infoLo ...@@ -201,6 +210,9 @@ bool ShaderD3D::postTranslateCompile(gl::Compiler *compiler, std::string *infoLo
mUsesPointCoord = translatedSource.find("GL_USES_POINT_COORD") != std::string::npos; mUsesPointCoord = translatedSource.find("GL_USES_POINT_COORD") != std::string::npos;
mUsesDepthRange = translatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos; mUsesDepthRange = translatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos;
mUsesFragDepth = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos; mUsesFragDepth = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos;
mHasANGLEMultiviewEnabled =
translatedSource.find("GL_ANGLE_MULTIVIEW_ENABLED") != std::string::npos;
mUsesViewID = translatedSource.find("GL_USES_VIEW_ID") != std::string::npos;
mUsesDiscardRewriting = mUsesDiscardRewriting =
translatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos; translatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos;
mUsesNestedBreak = translatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos; mUsesNestedBreak = translatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos;
......
...@@ -19,6 +19,11 @@ struct CompilerWorkaroundsD3D; ...@@ -19,6 +19,11 @@ struct CompilerWorkaroundsD3D;
struct WorkaroundsD3D; struct WorkaroundsD3D;
} }
namespace gl
{
struct Extensions;
}
namespace rx namespace rx
{ {
class DynamicHLSL; class DynamicHLSL;
...@@ -28,7 +33,9 @@ struct D3DUniform; ...@@ -28,7 +33,9 @@ struct D3DUniform;
class ShaderD3D : public ShaderImpl class ShaderD3D : public ShaderImpl
{ {
public: public:
ShaderD3D(const gl::ShaderState &data, const angle::WorkaroundsD3D &workarounds); ShaderD3D(const gl::ShaderState &data,
const angle::WorkaroundsD3D &workarounds,
const gl::Extensions &extensions);
virtual ~ShaderD3D(); virtual ~ShaderD3D();
// ShaderImpl implementation // ShaderImpl implementation
...@@ -60,6 +67,8 @@ class ShaderD3D : public ShaderImpl ...@@ -60,6 +67,8 @@ class ShaderD3D : public ShaderImpl
bool usesPointCoord() const { return mUsesPointCoord; } bool usesPointCoord() const { return mUsesPointCoord; }
bool usesDepthRange() const { return mUsesDepthRange; } bool usesDepthRange() const { return mUsesDepthRange; }
bool usesFragDepth() const { return mUsesFragDepth; } bool usesFragDepth() const { return mUsesFragDepth; }
bool usesViewID() const { return mUsesViewID; }
bool hasANGLEMultiviewEnabled() const { return mHasANGLEMultiviewEnabled; }
ShShaderOutput getCompilerOutputType() const; ShShaderOutput getCompilerOutputType() const;
...@@ -73,6 +82,8 @@ class ShaderD3D : public ShaderImpl ...@@ -73,6 +82,8 @@ class ShaderD3D : public ShaderImpl
bool mUsesPointCoord; bool mUsesPointCoord;
bool mUsesDepthRange; bool mUsesDepthRange;
bool mUsesFragDepth; bool mUsesFragDepth;
bool mHasANGLEMultiviewEnabled;
bool mUsesViewID;
bool mUsesDiscardRewriting; bool mUsesDiscardRewriting;
bool mUsesNestedBreak; bool mUsesNestedBreak;
bool mRequiresIEEEStrictCompiling; bool mRequiresIEEEStrictCompiling;
......
...@@ -57,7 +57,7 @@ CompilerImpl *Context11::createCompiler() ...@@ -57,7 +57,7 @@ CompilerImpl *Context11::createCompiler()
ShaderImpl *Context11::createShader(const gl::ShaderState &data) ShaderImpl *Context11::createShader(const gl::ShaderState &data)
{ {
return new ShaderD3D(data, mRenderer->getWorkarounds()); return new ShaderD3D(data, mRenderer->getWorkarounds(), mRenderer->getNativeExtensions());
} }
ProgramImpl *Context11::createProgram(const gl::ProgramState &data) ProgramImpl *Context11::createProgram(const gl::ProgramState &data)
......
...@@ -48,7 +48,7 @@ CompilerImpl *Context9::createCompiler() ...@@ -48,7 +48,7 @@ CompilerImpl *Context9::createCompiler()
ShaderImpl *Context9::createShader(const gl::ShaderState &data) ShaderImpl *Context9::createShader(const gl::ShaderState &data)
{ {
return new ShaderD3D(data, mRenderer->getWorkarounds()); return new ShaderD3D(data, mRenderer->getWorkarounds(), mRenderer->getNativeExtensions());
} }
ProgramImpl *Context9::createProgram(const gl::ProgramState &data) ProgramImpl *Context9::createProgram(const gl::ProgramState &data)
......
...@@ -238,6 +238,12 @@ class MultiviewSideBySideOcclusionQueryTest : public MultiviewSideBySideRenderTe ...@@ -238,6 +238,12 @@ class MultiviewSideBySideOcclusionQueryTest : public MultiviewSideBySideRenderTe
} }
}; };
class MultiviewProgramGenerationTest : public MultiviewSideBySideRenderTest
{
protected:
MultiviewProgramGenerationTest() {}
};
// The test verifies that glDraw*Indirect: // The test verifies that glDraw*Indirect:
// 1) generates an INVALID_OPERATION error if the number of views in the draw framebuffer is greater // 1) generates an INVALID_OPERATION error if the number of views in the draw framebuffer is greater
// than 1. // than 1.
...@@ -993,7 +999,112 @@ TEST_P(MultiviewSideBySideOcclusionQueryTest, OcclusionQueryOnlyRightVisible) ...@@ -993,7 +999,112 @@ TEST_P(MultiviewSideBySideOcclusionQueryTest, OcclusionQueryOnlyRightVisible)
EXPECT_GL_TRUE(result); EXPECT_GL_TRUE(result);
} }
// Test that a simple multi-view program which doesn't use gl_ViewID_OVR in neither VS nor FS
// compiles and links without an error.
TEST_P(MultiviewProgramGenerationTest, SimpleProgram)
{
if (!requestMultiviewExtension())
{
return;
}
const std::string vsSource =
"#version 300 es\n"
"#extension GL_OVR_multiview : require\n"
"layout(num_views = 2) in;\n"
"void main()\n"
"{\n"
"}\n";
const std::string fsSource =
"#version 300 es\n"
"#extension GL_OVR_multiview : require\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
"}\n";
ANGLE_GL_PROGRAM(program, vsSource, fsSource);
glUseProgram(program);
EXPECT_GL_NO_ERROR();
}
// Test that a simple multi-view program which uses gl_ViewID_OVR only in VS compiles and links
// without an error.
TEST_P(MultiviewProgramGenerationTest, UseViewIDInVertexShader)
{
if (!requestMultiviewExtension())
{
return;
}
const std::string vsSource =
"#version 300 es\n"
"#extension GL_OVR_multiview2 : require\n"
"layout(num_views = 2) in;\n"
"void main()\n"
"{\n"
" if (gl_ViewID_OVR == 0u) {\n"
" gl_Position = vec4(1,0,0,1);\n"
" } else {\n"
" gl_Position = vec4(-1,0,0,1);\n"
" }\n"
"}\n";
const std::string fsSource =
"#version 300 es\n"
"#extension GL_OVR_multiview2 : require\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
"}\n";
ANGLE_GL_PROGRAM(program, vsSource, fsSource);
glUseProgram(program);
EXPECT_GL_NO_ERROR();
}
// Test that a simple multi-view program which uses gl_ViewID_OVR only in FS compiles and links
// without an error.
TEST_P(MultiviewProgramGenerationTest, UseViewIDInFragmentShader)
{
if (!requestMultiviewExtension())
{
return;
}
const std::string vsSource =
"#version 300 es\n"
"#extension GL_OVR_multiview2 : require\n"
"layout(num_views = 2) in;\n"
"void main()\n"
"{\n"
"}\n";
const std::string fsSource =
"#version 300 es\n"
"#extension GL_OVR_multiview2 : require\n"
"precision mediump float;\n"
"out vec4 col;\n"
"void main()\n"
"{\n"
" if (gl_ViewID_OVR == 0u) {\n"
" col = vec4(1,0,0,1);\n"
" } else {\n"
" col = vec4(-1,0,0,1);\n"
" }\n"
"}\n";
ANGLE_GL_PROGRAM(program, vsSource, fsSource);
glUseProgram(program);
EXPECT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST(MultiviewDrawValidationTest, ES31_OPENGL()); ANGLE_INSTANTIATE_TEST(MultiviewDrawValidationTest, ES31_OPENGL());
ANGLE_INSTANTIATE_TEST(MultiviewSideBySideRenderDualViewTest, ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(MultiviewSideBySideRenderDualViewTest, ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(MultiviewSideBySideRenderTest, ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(MultiviewSideBySideRenderTest, ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(MultiviewSideBySideOcclusionQueryTest, ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(MultiviewSideBySideOcclusionQueryTest, ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(MultiviewProgramGenerationTest, ES3_OPENGL(), ES3_D3D11());
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