Commit c1d4e550 by Martin Radev Committed by Commit Bot

D3D11: Select view in vertex shader

View selection can happen in the vertex shader through the optional feature VPAndRTArrayIndexFromAnyShaderFeedingRasterizer. BUG=angleproject:2062 TEST=angle_end2end_tests Change-Id: Iaf65685e04f828b0936295fea867f6f6cbe69bee Reviewed-on: https://chromium-review.googlesource.com/628419 Commit-Queue: Martin Radev <mradev@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 630d558f
...@@ -107,6 +107,11 @@ struct WorkaroundsD3D ...@@ -107,6 +107,11 @@ struct WorkaroundsD3D
// for buffer data. // for buffer data.
// D3D11-only workaround. See http://crbug.com/593024. // D3D11-only workaround. See http://crbug.com/593024.
bool useSystemMemoryForConstantBuffers = false; bool useSystemMemoryForConstantBuffers = false;
// This workaround is for the ANGLE_multiview extension. If enabled the viewport or render
// target slice will be selected in the geometry shader stage. The workaround flag is added to
// make it possible to select the code path in end2end and performance tests.
bool selectViewInGeometryShader = false;
}; };
} // namespace angle } // namespace angle
......
...@@ -507,7 +507,18 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context, ...@@ -507,7 +507,18 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
if (vertexBuiltins.glViewIDOVR.enabled) if (vertexBuiltins.glViewIDOVR.enabled)
{ {
vertexStream << " output.gl_ViewID_OVR = _ViewID_OVR;\n"; vertexStream << " output.gl_ViewID_OVR = _ViewID_OVR;\n";
}
if (programMetadata.hasANGLEMultiviewEnabled() && programMetadata.canSelectViewInVertexShader())
{
ASSERT(vertexBuiltins.glViewportIndex.enabled && vertexBuiltins.glLayer.enabled);
vertexStream << " if (multiviewSelectViewportIndex)\n"
<< " {\n"
<< " output.gl_ViewportIndex = _ViewID_OVR;\n"
<< " } else {\n"
<< " output.gl_ViewportIndex = 0;\n"
<< " output.gl_Layer = _ViewID_OVR;\n"
<< " }\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.
...@@ -906,7 +917,8 @@ std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::Context *contex ...@@ -906,7 +917,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 BuiltinVaryingsD3D &builtinsD3D,
const bool hasANGLEMultiviewEnabled) const const bool hasANGLEMultiviewEnabled,
const bool selectViewInVS) const
{ {
ASSERT(mRenderer->getMajorShaderModel() >= 4); ASSERT(mRenderer->getMajorShaderModel() >= 4);
...@@ -932,6 +944,21 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va ...@@ -932,6 +944,21 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
preambleStream << " output.gl_PointSize = input.gl_PointSize;\n"; preambleStream << " output.gl_PointSize = input.gl_PointSize;\n";
} }
if (hasANGLEMultiviewEnabled)
{
preambleStream << " output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n";
if (selectViewInVS)
{
ASSERT(builtinsD3D[SHADER_GEOMETRY].glViewportIndex.enabled &&
builtinsD3D[SHADER_GEOMETRY].glLayer.enabled);
// If the view is already selected in the VS, then we just pass the gl_ViewportIndex and
// gl_Layer to the output.
preambleStream << " output.gl_ViewportIndex = input.gl_ViewportIndex;\n"
<< " output.gl_Layer = input.gl_Layer;\n";
}
}
for (const PackedVaryingRegister &varyingRegister : varyingPacking.getRegisterList()) for (const PackedVaryingRegister &varyingRegister : varyingPacking.getRegisterList())
{ {
preambleStream << " output.v" << varyingRegister.semanticIndex << " = "; preambleStream << " output.v" << varyingRegister.semanticIndex << " = ";
...@@ -953,7 +980,7 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va ...@@ -953,7 +980,7 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
<< "#endif // ANGLE_POINT_SPRITE_SHADER\n" << "#endif // ANGLE_POINT_SPRITE_SHADER\n"
<< "}\n"; << "}\n";
if (hasANGLEMultiviewEnabled) if (hasANGLEMultiviewEnabled && !selectViewInVS)
{ {
ASSERT(builtinsD3D[SHADER_GEOMETRY].glViewportIndex.enabled && ASSERT(builtinsD3D[SHADER_GEOMETRY].glViewportIndex.enabled &&
builtinsD3D[SHADER_GEOMETRY].glLayer.enabled); builtinsD3D[SHADER_GEOMETRY].glLayer.enabled);
...@@ -966,7 +993,6 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va ...@@ -966,7 +993,6 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
preambleStream << "\n" preambleStream << "\n"
<< "void selectView(inout GS_OUTPUT output, GS_INPUT input)\n" << "void selectView(inout GS_OUTPUT output, GS_INPUT input)\n"
<< "{\n" << "{\n"
<< " output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n"
<< " if (multiviewSelectViewportIndex)\n" << " if (multiviewSelectViewportIndex)\n"
<< " {\n" << " {\n"
<< " output.gl_ViewportIndex = input.gl_ViewID_OVR;\n" << " output.gl_ViewportIndex = input.gl_ViewID_OVR;\n"
...@@ -985,6 +1011,7 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT ...@@ -985,6 +1011,7 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT
const gl::ProgramState &programData, const gl::ProgramState &programData,
const bool useViewScale, const bool useViewScale,
const bool hasANGLEMultiviewEnabled, const bool hasANGLEMultiviewEnabled,
const bool selectViewInVS,
const bool pointSpriteEmulation, const bool pointSpriteEmulation,
const std::string &preambleString) const const std::string &preambleString) const
{ {
...@@ -1120,7 +1147,7 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT ...@@ -1120,7 +1147,7 @@ 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) if (hasANGLEMultiviewEnabled && !selectViewInVS)
{ {
shaderStream << " selectView(output, input[" << vertexIndex << "]);\n"; shaderStream << " selectView(output, input[" << vertexIndex << "]);\n";
} }
...@@ -1345,6 +1372,11 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType, ...@@ -1345,6 +1372,11 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
if (shaderType == SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled()) if (shaderType == SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled())
{ {
builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++); builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
if (metadata.canSelectViewInVertexShader())
{
builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex");
builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex");
}
} }
if (shaderType == SHADER_PIXEL && metadata.hasANGLEMultiviewEnabled()) if (shaderType == SHADER_PIXEL && metadata.hasANGLEMultiviewEnabled())
......
...@@ -132,13 +132,15 @@ class DynamicHLSL : angle::NonCopyable ...@@ -132,13 +132,15 @@ class DynamicHLSL : angle::NonCopyable
std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking, std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking,
const BuiltinVaryingsD3D &builtinsD3D, const BuiltinVaryingsD3D &builtinsD3D,
const bool hasANGLEMultiviewEnabled) const; const bool hasANGLEMultiviewEnabled,
const bool selectViewInVS) 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 hasANGLEMultiviewEnabled,
const bool selectViewInVS,
const bool pointSpriteEmulation, const bool pointSpriteEmulation,
const std::string &preambleString) const; const std::string &preambleString) const;
......
...@@ -377,6 +377,7 @@ ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer, ...@@ -377,6 +377,7 @@ ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer,
mUsesViewScale(renderer->presentPathFastEnabled()), mUsesViewScale(renderer->presentPathFastEnabled()),
mHasANGLEMultiviewEnabled(vertexShader->hasANGLEMultiviewEnabled()), mHasANGLEMultiviewEnabled(vertexShader->hasANGLEMultiviewEnabled()),
mUsesViewID(fragmentShader->usesViewID()), mUsesViewID(fragmentShader->usesViewID()),
mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()),
mVertexShader(vertexShader), mVertexShader(vertexShader),
mFragmentShader(fragmentShader) mFragmentShader(fragmentShader)
{ {
...@@ -434,6 +435,11 @@ bool ProgramD3DMetadata::usesViewID() const ...@@ -434,6 +435,11 @@ bool ProgramD3DMetadata::usesViewID() const
return mUsesViewID; return mUsesViewID;
} }
bool ProgramD3DMetadata::canSelectViewInVertexShader() const
{
return mCanSelectViewInVertexShader;
}
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
...@@ -601,7 +607,7 @@ bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const ...@@ -601,7 +607,7 @@ bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const
bool ProgramD3D::usesGeometryShader(GLenum drawMode) const bool ProgramD3D::usesGeometryShader(GLenum drawMode) const
{ {
if (mHasANGLEMultiviewEnabled) if (mHasANGLEMultiviewEnabled && !mRenderer->canSelectViewInVertexShader())
{ {
return true; return true;
} }
...@@ -1322,8 +1328,8 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextSta ...@@ -1322,8 +1328,8 @@ 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(), mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(),
mGeometryShaderPreamble); usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble);
gl::InfoLog tempInfoLog; gl::InfoLog tempInfoLog;
gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
...@@ -1623,7 +1629,8 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1623,7 +1629,8 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context,
if (mRenderer->getMajorShaderModel() >= 4) if (mRenderer->getMajorShaderModel() >= 4)
{ {
mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble( mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
packing, builtins, mHasANGLEMultiviewEnabled); packing, builtins, mHasANGLEMultiviewEnabled,
metadata.canSelectViewInVertexShader());
} }
initAttribLocationsToD3DSemantic(context); initAttribLocationsToD3DSemantic(context);
......
...@@ -130,6 +130,7 @@ class ProgramD3DMetadata final : angle::NonCopyable ...@@ -130,6 +130,7 @@ class ProgramD3DMetadata final : angle::NonCopyable
bool usesViewScale() const; bool usesViewScale() const;
bool hasANGLEMultiviewEnabled() const; bool hasANGLEMultiviewEnabled() const;
bool usesViewID() const; bool usesViewID() const;
bool canSelectViewInVertexShader() const;
bool addsPointCoordToVertexShader() const; bool addsPointCoordToVertexShader() const;
bool usesTransformFeedbackGLPosition() const; bool usesTransformFeedbackGLPosition() const;
bool usesSystemValuePointSize() const; bool usesSystemValuePointSize() const;
...@@ -144,6 +145,7 @@ class ProgramD3DMetadata final : angle::NonCopyable ...@@ -144,6 +145,7 @@ class ProgramD3DMetadata final : angle::NonCopyable
const bool mUsesViewScale; const bool mUsesViewScale;
const bool mHasANGLEMultiviewEnabled; const bool mHasANGLEMultiviewEnabled;
const bool mUsesViewID; const bool mUsesViewID;
const bool mCanSelectViewInVertexShader;
const ShaderD3D *mVertexShader; const ShaderD3D *mVertexShader;
const ShaderD3D *mFragmentShader; const ShaderD3D *mFragmentShader;
}; };
......
...@@ -331,6 +331,8 @@ class RendererD3D : public BufferFactoryD3D ...@@ -331,6 +331,8 @@ class RendererD3D : public BufferFactoryD3D
Serial generateSerial(); Serial generateSerial();
virtual bool canSelectViewInVertexShader() const = 0;
protected: protected:
virtual bool getLUID(LUID *adapterLuid) const = 0; virtual bool getLUID(LUID *adapterLuid) const = 0;
virtual void generateCaps(gl::Caps *outCaps, virtual void generateCaps(gl::Caps *outCaps,
......
...@@ -450,6 +450,7 @@ Renderer11::Renderer11(egl::Display *display) ...@@ -450,6 +450,7 @@ Renderer11::Renderer11(egl::Display *display)
mRenderer11DeviceCaps.supportsClearView = false; mRenderer11DeviceCaps.supportsClearView = false;
mRenderer11DeviceCaps.supportsConstantBufferOffsets = false; mRenderer11DeviceCaps.supportsConstantBufferOffsets = false;
mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader = false;
mRenderer11DeviceCaps.supportsDXGI1_2 = false; mRenderer11DeviceCaps.supportsDXGI1_2 = false;
mRenderer11DeviceCaps.B5G6R5support = 0; mRenderer11DeviceCaps.B5G6R5support = 0;
mRenderer11DeviceCaps.B4G4R4A4support = 0; mRenderer11DeviceCaps.B4G4R4A4support = 0;
...@@ -921,6 +922,18 @@ void Renderer11::populateRenderer11DeviceCaps() ...@@ -921,6 +922,18 @@ void Renderer11::populateRenderer11DeviceCaps()
} }
} }
if (mDeviceContext3)
{
D3D11_FEATURE_DATA_D3D11_OPTIONS3 d3d11Options3;
HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &d3d11Options3,
sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS3));
if (SUCCEEDED(result))
{
mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader =
(d3d11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer == TRUE);
}
}
if (getWorkarounds().disableB5G6R5Support) if (getWorkarounds().disableB5G6R5Support)
{ {
mRenderer11DeviceCaps.B5G6R5support = 0; mRenderer11DeviceCaps.B5G6R5support = 0;
...@@ -4477,4 +4490,10 @@ gl::Error Renderer11::clearRenderTarget(RenderTargetD3D *renderTarget, ...@@ -4477,4 +4490,10 @@ gl::Error Renderer11::clearRenderTarget(RenderTargetD3D *renderTarget,
return gl::NoError(); return gl::NoError();
} }
bool Renderer11::canSelectViewInVertexShader() const
{
return !getWorkarounds().selectViewInGeometryShader &&
getRenderer11DeviceCaps().supportsVpRtIndexWriteFromVertexShader;
}
} // namespace rx } // namespace rx
...@@ -49,6 +49,8 @@ struct Renderer11DeviceCaps ...@@ -49,6 +49,8 @@ struct Renderer11DeviceCaps
bool supportsDXGI1_2; // Support for DXGI 1.2 bool supportsDXGI1_2; // Support for DXGI 1.2
bool supportsClearView; // Support for ID3D11DeviceContext1::ClearView bool supportsClearView; // Support for ID3D11DeviceContext1::ClearView
bool supportsConstantBufferOffsets; // Support for Constant buffer offset bool supportsConstantBufferOffsets; // Support for Constant buffer offset
bool supportsVpRtIndexWriteFromVertexShader; // VP/RT can be selected in the Vertex Shader
// stage.
UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM
UINT B5G6R5maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B5G6R5_UNORM UINT B5G6R5maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B5G6R5_UNORM
UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM
...@@ -463,6 +465,8 @@ class Renderer11 : public RendererD3D ...@@ -463,6 +465,8 @@ class Renderer11 : public RendererD3D
const float clearDepthValue, const float clearDepthValue,
const unsigned int clearStencilValue) override; const unsigned int clearStencilValue) override;
bool canSelectViewInVertexShader() const override;
private: private:
gl::Error drawArraysImpl(const gl::Context *context, gl::Error drawArraysImpl(const gl::Context *context,
GLenum mode, GLenum mode,
......
...@@ -2084,6 +2084,11 @@ angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps ...@@ -2084,6 +2084,11 @@ angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps
workarounds.emulateTinyStencilTextures = false; workarounds.emulateTinyStencilTextures = false;
} }
// If the VPAndRTArrayIndexFromAnyShaderFeedingRasterizer feature is not available, we have to
// select the viewport / RT array index in the geometry shader.
workarounds.selectViewInGeometryShader =
(deviceCaps.supportsVpRtIndexWriteFromVertexShader == false);
// Call platform hooks for testing overrides. // Call platform hooks for testing overrides.
auto *platform = ANGLEPlatformCurrent(); auto *platform = ANGLEPlatformCurrent();
platform->overrideWorkaroundsD3D(platform, &workarounds); platform->overrideWorkaroundsD3D(platform, &workarounds);
......
...@@ -398,6 +398,8 @@ class Renderer9 : public RendererD3D ...@@ -398,6 +398,8 @@ class Renderer9 : public RendererD3D
const float clearDepthValue, const float clearDepthValue,
const unsigned int clearStencilValue) override; const unsigned int clearStencilValue) override;
bool canSelectViewInVertexShader() const override { return false; }
private: private:
gl::Error drawArraysImpl(const gl::ContextState &data, gl::Error drawArraysImpl(const gl::ContextState &data,
GLenum mode, GLenum mode,
......
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