Commit 4e619f58 by Martin Radev Committed by Commit Bot

Add branch for viewport or layer selection in VS

The patch extends the behavior of SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER so that either the viewport or layer is selected based on the value of the internal uniform variable MultiviewRenderPath. BUG=angleproject:2062 TEST=angle_end2end_tests TEST=angle_unittests Change-Id: Ia311b12b1fed642dac78eba8732e2535242f34fd Reviewed-on: https://chromium-review.googlesource.com/615260 Commit-Queue: Martin Radev <mradev@nvidia.com> Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 3dfaf265
...@@ -234,8 +234,9 @@ const ShCompileOptions SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW = UINT64_C ...@@ -234,8 +234,9 @@ const ShCompileOptions SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW = UINT64_C
// With the flag enabled the GLSL/ESSL vertex shader is modified to include code for viewport // With the flag enabled the GLSL/ESSL vertex shader is modified to include code for viewport
// selection in the following way: // selection in the following way:
// - Code to enable the extension NV_viewport_array2 is included. // - Code to enable the extension NV_viewport_array2 is included.
// - Code to select the viewport index is included at the beginning of main after ViewID_OVR's // - Code to select the viewport index or layer is inserted at the beginning of main after
// initialization: gl_ViewportIndex = int(ViewID_OVR) // ViewID_OVR's initialization.
// - A declaration of the uniform multiviewBaseViewLayerIndex.
// Note: The SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW flag also has to be enabled to have the // Note: The SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW flag also has to be enabled to have the
// temporary variable ViewID_OVR declared and initialized. // temporary variable ViewID_OVR declared and initialized.
const ShCompileOptions SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER = UINT64_C(1) << 34; const ShCompileOptions SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER = UINT64_C(1) << 34;
......
...@@ -576,6 +576,7 @@ enum TQualifier ...@@ -576,6 +576,7 @@ enum TQualifier
// GLSL ES 3.1 extension OES_geometry_shader qualifiers // GLSL ES 3.1 extension OES_geometry_shader qualifiers
EvqGeometryIn, EvqGeometryIn,
EvqGeometryOut, EvqGeometryOut,
EvqLayer, // gl_Layer
// end of list // end of list
EvqLast EvqLast
...@@ -807,6 +808,7 @@ inline const char *getQualifierString(TQualifier q) ...@@ -807,6 +808,7 @@ inline const char *getQualifierString(TQualifier q)
case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT"; case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT";
case EvqViewIDOVR: return "ViewIDOVR"; case EvqViewIDOVR: return "ViewIDOVR";
case EvqViewportIndex: return "ViewportIndex"; case EvqViewportIndex: return "ViewportIndex";
case EvqLayer: return "Layer";
case EvqLastFragColor: return "LastFragColor"; case EvqLastFragColor: return "LastFragColor";
case EvqLastFragData: return "LastFragData"; case EvqLastFragData: return "LastFragData";
case EvqSmoothOut: return "smooth out"; case EvqSmoothOut: return "smooth out";
......
...@@ -109,23 +109,50 @@ void DeclareGlobalVariable(TIntermBlock *root, TIntermTyped *typedNode) ...@@ -109,23 +109,50 @@ void DeclareGlobalVariable(TIntermBlock *root, TIntermTyped *typedNode)
globalSequence->insert(globalSequence->begin(), declaration); globalSequence->insert(globalSequence->begin(), declaration);
} }
// Adds the expression gl_ViewportIndex = int(ViewID_OVR) to the end of the initializers' sequence. // Adds a branch to write int(ViewID_OVR) to either gl_ViewportIndex or gl_Layer. The branch is
void SelectViewportIndexInVertexShader(TIntermTyped *viewIDSymbol, TIntermSequence *initializers) // added to the end of the initializers' sequence.
void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
TIntermTyped *multiviewBaseViewLayerIndexSymbol,
TIntermSequence *initializers)
{ {
// Create a gl_ViewportIndex node.
TIntermSymbol *viewportIndexSymbol =
new TIntermSymbol(0, "gl_ViewportIndex", TType(EbtInt, EbpHigh, EvqViewportIndex));
// Create an int(ViewID_OVR) node. // Create an int(ViewID_OVR) node.
TIntermSequence *viewIDSymbolCastArguments = new TIntermSequence(); TIntermSequence *viewIDSymbolCastArguments = new TIntermSequence();
viewIDSymbolCastArguments->push_back(viewIDSymbol); viewIDSymbolCastArguments->push_back(viewIDSymbol);
TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor( TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor(
TType(EbtInt, EbpHigh, EvqTemporary), viewIDSymbolCastArguments); TType(EbtInt, EbpHigh, EvqTemporary), viewIDSymbolCastArguments);
// Create a gl_ViewportIndex = int(ViewID_OVR) node. // Create a gl_ViewportIndex node.
TIntermBinary *viewIDInitializer = TIntermSymbol *viewportIndexSymbol =
new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt); new TIntermSymbol(0, "gl_ViewportIndex", TType(EbtInt, EbpHigh, EvqViewportIndex));
initializers->push_back(viewIDInitializer);
// Create a { gl_ViewportIndex = int(ViewID_OVR) } node.
TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock();
viewportIndexInitializerInBlock->appendStatement(
new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt));
// Create a gl_Layer node.
TIntermSymbol *layerSymbol = new TIntermSymbol(0, "gl_Layer", TType(EbtInt, EbpHigh, EvqLayer));
// Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node
TIntermBinary *sumOfViewIDAndBaseViewIndex =
new TIntermBinary(EOpAdd, viewIDAsInt->deepCopy(), multiviewBaseViewLayerIndexSymbol);
// Create a { gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex } node.
TIntermBlock *layerInitializerInBlock = new TIntermBlock();
layerInitializerInBlock->appendStatement(
new TIntermBinary(EOpAssign, layerSymbol, sumOfViewIDAndBaseViewIndex));
// Create a node to compare whether the base view index uniform is less than zero.
TIntermBinary *multiviewBaseViewLayerIndexZeroComparison =
new TIntermBinary(EOpLessThan, multiviewBaseViewLayerIndexSymbol->deepCopy(),
CreateZeroNode(TType(EbtInt, EbpHigh, EvqConst)));
// Create an if-else statement to select the code path.
TIntermIfElse *multiviewBranch =
new TIntermIfElse(multiviewBaseViewLayerIndexZeroComparison,
viewportIndexInitializerInBlock, layerInitializerInBlock);
initializers->push_back(multiviewBranch);
} }
} // namespace } // namespace
...@@ -162,15 +189,24 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root, ...@@ -162,15 +189,24 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// The AST transformation which adds the expression to select the viewport index should // The AST transformation which adds the expression to select the viewport index should
// be done only for the GLSL and ESSL output. // be done only for the GLSL and ESSL output.
const bool selectViewport = const bool selectView = (compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u;
(compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u; // Assert that if the view is selected in the vertex shader, then the output is
// Assert that if the viewport is selected in the vertex shader, then the output is
// either GLSL or ESSL. // either GLSL or ESSL.
ASSERT(!selectViewport || IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput)); ASSERT(!selectView || IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput));
if (selectViewport) if (selectView)
{ {
// Setting a value to gl_ViewportIndex should happen after ViewID_OVR's initialization. // Add a uniform to switch between side-by-side and layered rendering.
SelectViewportIndexInVertexShader(viewIDSymbol->deepCopy(), initializers); TIntermSymbol *multiviewBaseViewLayerIndexSymbol =
new TIntermSymbol(symbolTable->nextUniqueId(), "multiviewBaseViewLayerIndex",
TType(EbtInt, EbpHigh, EvqUniform));
multiviewBaseViewLayerIndexSymbol->setInternal(true);
DeclareGlobalVariable(root, multiviewBaseViewLayerIndexSymbol);
// Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
// initialization.
SelectViewIndexInVertexShader(viewIDSymbol->deepCopy(),
multiviewBaseViewLayerIndexSymbol->deepCopy(),
initializers);
} }
// Insert initializers at the beginning of main(). // Insert initializers at the beginning of main().
......
...@@ -14,8 +14,14 @@ ...@@ -14,8 +14,14 @@
// - Add initializers of ViewID_OVR and InstanceID to the beginning of the body of main. The pass // - Add initializers of ViewID_OVR and InstanceID to the beginning of the body of main. The pass
// should be executed before any variables get collected so that usage of gl_InstanceID is recorded. // should be executed before any variables get collected so that usage of gl_InstanceID is recorded.
// - If the output is ESSL or GLSL and the SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is // - If the output is ESSL or GLSL and the SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is
// enabled, the expression "gl_ViewportIndex = int(ViewID_OVR)" is added after ViewID and InstanceID // enabled, the expression
// are initialized. // "if (multiviewBaseViewLayerIndex < 0) {
// gl_ViewportIndex = int(ViewID_OVR);
// } else {
// gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex;
// }"
// is added after ViewID and InstanceID are initialized. Also, MultiviewRenderPath is added as a
// uniform.
// //
#ifndef COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_ #ifndef COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
......
...@@ -483,6 +483,16 @@ GLenum FramebufferState::getMultiviewLayout() const ...@@ -483,6 +483,16 @@ GLenum FramebufferState::getMultiviewLayout() const
return attachment->getMultiviewLayout(); return attachment->getMultiviewLayout();
} }
int FramebufferState::getBaseViewIndex() const
{
const FramebufferAttachment *attachment = getFirstNonNullAttachment();
if (attachment == nullptr)
{
return GL_NONE;
}
return attachment->getBaseViewIndex();
}
Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id) Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id)
: mState(caps), : mState(caps),
mImpl(factory->createFramebuffer(mState)), mImpl(factory->createFramebuffer(mState)),
...@@ -1652,6 +1662,11 @@ GLsizei Framebuffer::getNumViews() const ...@@ -1652,6 +1662,11 @@ GLsizei Framebuffer::getNumViews() const
return mState.getNumViews(); return mState.getNumViews();
} }
GLint Framebuffer::getBaseViewIndex() const
{
return mState.getBaseViewIndex();
}
const std::vector<Offset> *Framebuffer::getViewportOffsets() const const std::vector<Offset> *Framebuffer::getViewportOffsets() const
{ {
return mState.getViewportOffsets(); return mState.getViewportOffsets();
......
...@@ -95,6 +95,7 @@ class FramebufferState final : angle::NonCopyable ...@@ -95,6 +95,7 @@ class FramebufferState final : angle::NonCopyable
GLenum getMultiviewLayout() const; GLenum getMultiviewLayout() const;
GLsizei getNumViews() const; GLsizei getNumViews() const;
const std::vector<Offset> *getViewportOffsets() const; const std::vector<Offset> *getViewportOffsets() const;
GLint getBaseViewIndex() const;
private: private:
friend class Framebuffer; friend class Framebuffer;
...@@ -185,6 +186,7 @@ class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver ...@@ -185,6 +186,7 @@ class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver
const FramebufferAttachment *getAttachment(GLenum attachment) const; const FramebufferAttachment *getAttachment(GLenum attachment) const;
GLenum getMultiviewLayout() const; GLenum getMultiviewLayout() const;
GLsizei getNumViews() const; GLsizei getNumViews() const;
GLint getBaseViewIndex() const;
const std::vector<Offset> *getViewportOffsets() const; const std::vector<Offset> *getViewportOffsets() const;
size_t getDrawbufferStateCount() const; size_t getDrawbufferStateCount() const;
......
...@@ -280,6 +280,9 @@ class ProgramState final : angle::NonCopyable ...@@ -280,6 +280,9 @@ class ProgramState final : angle::NonCopyable
GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
GLuint getAttributeLocation(const std::string &name) const; GLuint getAttributeLocation(const std::string &name) const;
int getNumViews() const { return mNumViews; }
bool usesMultiview() const { return mNumViews != -1; }
private: private:
friend class MemoryProgramCache; friend class MemoryProgramCache;
friend class Program; friend class Program;
...@@ -537,8 +540,8 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -537,8 +540,8 @@ class Program final : angle::NonCopyable, public LabeledObject
const Bindings &getUniformLocationBindings() const { return mUniformLocationBindings; } const Bindings &getUniformLocationBindings() const { return mUniformLocationBindings; }
const Bindings &getFragmentInputBindings() const { return mFragmentInputBindings; } const Bindings &getFragmentInputBindings() const { return mFragmentInputBindings; }
int getNumViews() const { return mState.mNumViews; } int getNumViews() const { return mState.getNumViews(); }
bool usesMultiview() const { return mState.mNumViews != -1; } bool usesMultiview() const { return mState.usesMultiview(); }
private: private:
~Program(); ~Program();
......
...@@ -95,12 +95,14 @@ void BindFramebufferAttachment(const FunctionsGL *functions, ...@@ -95,12 +95,14 @@ void BindFramebufferAttachment(const FunctionsGL *functions,
void RetrieveMultiviewFieldsFromAttachment(const gl::FramebufferAttachment *attachment, void RetrieveMultiviewFieldsFromAttachment(const gl::FramebufferAttachment *attachment,
const std::vector<gl::Offset> **viewportOffsets, const std::vector<gl::Offset> **viewportOffsets,
GLenum *multiviewLayout) GLenum *multiviewLayout,
int *baseViewIndex)
{ {
if (attachment) if (attachment)
{ {
*viewportOffsets = &attachment->getMultiviewViewportOffsets(); *viewportOffsets = &attachment->getMultiviewViewportOffsets();
*multiviewLayout = attachment->getMultiviewLayout(); *multiviewLayout = attachment->getMultiviewLayout();
*baseViewIndex = attachment->getBaseViewIndex();
} }
} }
...@@ -596,6 +598,7 @@ void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::Dir ...@@ -596,6 +598,7 @@ void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::Dir
const std::vector<gl::Offset> *attachmentViewportOffsets = nullptr; const std::vector<gl::Offset> *attachmentViewportOffsets = nullptr;
GLenum multiviewLayout = GL_NONE; GLenum multiviewLayout = GL_NONE;
int baseViewIndex = -1;
bool isAttachmentModified = false; bool isAttachmentModified = false;
for (auto dirtyBit : dirtyBits) for (auto dirtyBit : dirtyBits)
...@@ -606,14 +609,16 @@ void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::Dir ...@@ -606,14 +609,16 @@ void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::Dir
BindFramebufferAttachment(mFunctions, GL_DEPTH_ATTACHMENT, BindFramebufferAttachment(mFunctions, GL_DEPTH_ATTACHMENT,
mState.getDepthAttachment()); mState.getDepthAttachment());
RetrieveMultiviewFieldsFromAttachment(mState.getDepthAttachment(), RetrieveMultiviewFieldsFromAttachment(mState.getDepthAttachment(),
&attachmentViewportOffsets, &multiviewLayout); &attachmentViewportOffsets, &multiviewLayout,
&baseViewIndex);
isAttachmentModified = true; isAttachmentModified = true;
break; break;
case Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT: case Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
BindFramebufferAttachment(mFunctions, GL_STENCIL_ATTACHMENT, BindFramebufferAttachment(mFunctions, GL_STENCIL_ATTACHMENT,
mState.getStencilAttachment()); mState.getStencilAttachment());
RetrieveMultiviewFieldsFromAttachment(mState.getStencilAttachment(), RetrieveMultiviewFieldsFromAttachment(mState.getStencilAttachment(),
&attachmentViewportOffsets, &multiviewLayout); &attachmentViewportOffsets, &multiviewLayout,
&baseViewIndex);
isAttachmentModified = true; isAttachmentModified = true;
break; break;
case Framebuffer::DIRTY_BIT_DRAW_BUFFERS: case Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
...@@ -654,7 +659,8 @@ void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::Dir ...@@ -654,7 +659,8 @@ void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::Dir
static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + index), static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + index),
mState.getColorAttachment(index)); mState.getColorAttachment(index));
RetrieveMultiviewFieldsFromAttachment(mState.getColorAttachment(index), RetrieveMultiviewFieldsFromAttachment(mState.getColorAttachment(index),
&attachmentViewportOffsets, &multiviewLayout); &attachmentViewportOffsets, &multiviewLayout,
&baseViewIndex);
isAttachmentModified = true; isAttachmentModified = true;
break; break;
} }
...@@ -674,6 +680,9 @@ void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::Dir ...@@ -674,6 +680,9 @@ void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::Dir
mStateManager->setViewportOffsets( mStateManager->setViewportOffsets(
FramebufferAttachment::GetDefaultViewportOffsetVector()); FramebufferAttachment::GetDefaultViewportOffsetVector());
} }
mStateManager->updateMultiviewBaseViewLayerIndexUniform(context->getGLState().getProgram(),
getState());
} }
} }
......
...@@ -35,6 +35,7 @@ ProgramGL::ProgramGL(const gl::ProgramState &data, ...@@ -35,6 +35,7 @@ ProgramGL::ProgramGL(const gl::ProgramState &data,
mWorkarounds(workarounds), mWorkarounds(workarounds),
mStateManager(stateManager), mStateManager(stateManager),
mEnablePathRendering(enablePathRendering), mEnablePathRendering(enablePathRendering),
mMultiviewBaseViewLayerIndexUniformLocation(-1),
mProgramID(0) mProgramID(0)
{ {
ASSERT(mFunctions); ASSERT(mFunctions);
...@@ -590,6 +591,8 @@ void ProgramGL::preLink() ...@@ -590,6 +591,8 @@ void ProgramGL::preLink()
mUniformRealLocationMap.clear(); mUniformRealLocationMap.clear();
mUniformBlockRealLocationMap.clear(); mUniformBlockRealLocationMap.clear();
mPathRenderingFragmentInputs.clear(); mPathRenderingFragmentInputs.clear();
mMultiviewBaseViewLayerIndexUniformLocation = -1;
} }
bool ProgramGL::checkLinkStatus(gl::InfoLog &infoLog) bool ProgramGL::checkLinkStatus(gl::InfoLog &infoLog)
...@@ -658,6 +661,13 @@ void ProgramGL::postLink() ...@@ -658,6 +661,13 @@ void ProgramGL::postLink()
mUniformRealLocationMap[uniformLocation] = realLocation; mUniformRealLocationMap[uniformLocation] = realLocation;
} }
if (mState.usesMultiview())
{
mMultiviewBaseViewLayerIndexUniformLocation =
mFunctions->getUniformLocation(mProgramID, "webgl_angle_multiviewBaseViewLayerIndex");
ASSERT(mMultiviewBaseViewLayerIndexUniformLocation != -1);
}
// Discover CHROMIUM_path_rendering fragment inputs if enabled. // Discover CHROMIUM_path_rendering fragment inputs if enabled.
if (!mEnablePathRendering) if (!mEnablePathRendering)
return; return;
...@@ -724,4 +734,23 @@ void ProgramGL::postLink() ...@@ -724,4 +734,23 @@ void ProgramGL::postLink()
} }
} }
void ProgramGL::enableSideBySideRenderingPath() const
{
ASSERT(mState.usesMultiview());
ASSERT(mMultiviewBaseViewLayerIndexUniformLocation != -1);
ASSERT(mFunctions->programUniform1i != nullptr);
mFunctions->programUniform1i(mProgramID, mMultiviewBaseViewLayerIndexUniformLocation, -1);
}
void ProgramGL::enableLayeredRenderingPath(int baseViewIndex) const
{
ASSERT(mState.usesMultiview());
ASSERT(mMultiviewBaseViewLayerIndexUniformLocation != -1);
ASSERT(mFunctions->programUniform1i != nullptr);
mFunctions->programUniform1i(mProgramID, mMultiviewBaseViewLayerIndexUniformLocation,
baseViewIndex);
}
} // namespace rx } // namespace rx
...@@ -78,6 +78,9 @@ class ProgramGL : public ProgramImpl ...@@ -78,6 +78,9 @@ class ProgramGL : public ProgramImpl
GLuint getProgramID() const; GLuint getProgramID() const;
void enableSideBySideRenderingPath() const;
void enableLayeredRenderingPath(int baseViewIndex) const;
private: private:
void preLink(); void preLink();
bool checkLinkStatus(gl::InfoLog &infoLog); bool checkLinkStatus(gl::InfoLog &infoLog);
...@@ -102,6 +105,7 @@ class ProgramGL : public ProgramImpl ...@@ -102,6 +105,7 @@ class ProgramGL : public ProgramImpl
std::vector<PathRenderingFragmentInput> mPathRenderingFragmentInputs; std::vector<PathRenderingFragmentInput> mPathRenderingFragmentInputs;
bool mEnablePathRendering; bool mEnablePathRendering;
GLint mMultiviewBaseViewLayerIndexUniformLocation;
GLuint mProgramID; GLuint mProgramID;
}; };
......
...@@ -1885,8 +1885,13 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -1885,8 +1885,13 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
// TODO(jmadill): implement this // TODO(jmadill): implement this
break; break;
case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
{
// TODO(jmadill): implement this // TODO(jmadill): implement this
updateMultiviewBaseViewLayerIndexUniform(
state.getProgram(),
state.getDrawFramebuffer()->getImplementation()->getState());
break; break;
}
case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING: case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
// TODO(jmadill): implement this // TODO(jmadill): implement this
break; break;
...@@ -1902,6 +1907,9 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -1902,6 +1907,9 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
// TODO(jmadill): implement this // TODO(jmadill): implement this
propagateNumViewsToVAO(state.getProgram(), propagateNumViewsToVAO(state.getProgram(),
GetImplAs<VertexArrayGL>(state.getVertexArray())); GetImplAs<VertexArrayGL>(state.getVertexArray()));
updateMultiviewBaseViewLayerIndexUniform(
state.getProgram(),
state.getDrawFramebuffer()->getImplementation()->getState());
break; break;
case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE: case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
// TODO(jmadill): implement this // TODO(jmadill): implement this
...@@ -2159,4 +2167,25 @@ void StateManagerGL::propagateNumViewsToVAO(const gl::Program *program, VertexAr ...@@ -2159,4 +2167,25 @@ void StateManagerGL::propagateNumViewsToVAO(const gl::Program *program, VertexAr
vao->applyNumViewsToDivisor(programNumViews); vao->applyNumViewsToDivisor(programNumViews);
} }
} }
void StateManagerGL::updateMultiviewBaseViewLayerIndexUniform(
const gl::Program *program,
const gl::FramebufferState &drawFramebufferState) const
{
if (mIsMultiviewEnabled && program != nullptr && program->usesMultiview())
{
const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
switch (drawFramebufferState.getMultiviewLayout())
{
case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
programGL->enableSideBySideRenderingPath();
break;
case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
programGL->enableLayeredRenderingPath(drawFramebufferState.getBaseViewIndex());
break;
default:
break;
}
}
}
} }
...@@ -22,6 +22,7 @@ namespace gl ...@@ -22,6 +22,7 @@ namespace gl
struct Caps; struct Caps;
class ContextState; class ContextState;
class State; class State;
class FramebufferState;
} }
namespace rx namespace rx
...@@ -180,6 +181,10 @@ class StateManagerGL final : angle::NonCopyable ...@@ -180,6 +181,10 @@ class StateManagerGL final : angle::NonCopyable
void syncState(const gl::Context *context, const gl::State::DirtyBits &glDirtyBits); void syncState(const gl::Context *context, const gl::State::DirtyBits &glDirtyBits);
void updateMultiviewBaseViewLayerIndexUniform(
const gl::Program *program,
const gl::FramebufferState &drawFramebufferState) const;
private: private:
// Set state that's common among draw commands and compute invocations. // Set state that's common among draw commands and compute invocations.
void setGenericShaderState(const gl::Context *context); void setGenericShaderState(const gl::Context *context);
......
...@@ -931,4 +931,34 @@ TEST_F(WEBGLMultiviewVertexShaderOutputCodeTest, GlViewportIndexIsSet) ...@@ -931,4 +931,34 @@ TEST_F(WEBGLMultiviewVertexShaderOutputCodeTest, GlViewportIndexIsSet)
EXPECT_LT(viewIDOVRAssignmentLoc, glViewportIndexAssignmentLoc); EXPECT_LT(viewIDOVRAssignmentLoc, glViewportIndexAssignmentLoc);
} }
// The test checks that the layer is selected after the initialization of ViewID_OVR for
// GLSL and ESSL ouputs.
TEST_F(WEBGLMultiviewVertexShaderOutputCodeTest, GlLayerIsSet)
{
const std::string &shaderString =
"#version 300 es\n"
"#extension GL_OVR_multiview : require\n"
"layout(num_views = 3) in;\n"
"void main()\n"
"{\n"
"}\n";
compile(shaderString, SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |
SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER);
const char glLayerAssignment[] =
"gl_Layer = (int(webgl_angle_ViewID_OVR) + webgl_angle_multiviewBaseViewLayerIndex)";
// Check that the layer is selected.
EXPECT_TRUE(foundInAllGLSLCode(glLayerAssignment));
// Setting gl_Layer must happen after ViewID_OVR's initialization.
const char viewIDOVRAssignment[] = "webgl_angle_ViewID_OVR = (uint(gl_InstanceID) % 3u)";
size_t viewIDOVRAssignmentLoc = findInCode(SH_GLSL_COMPATIBILITY_OUTPUT, viewIDOVRAssignment);
size_t glLayerAssignmentLoc = findInCode(SH_GLSL_COMPATIBILITY_OUTPUT, glLayerAssignment);
EXPECT_LT(viewIDOVRAssignmentLoc, glLayerAssignmentLoc);
viewIDOVRAssignmentLoc = findInCode(SH_ESSL_OUTPUT, viewIDOVRAssignment);
glLayerAssignmentLoc = findInCode(SH_ESSL_OUTPUT, glLayerAssignment);
EXPECT_LT(viewIDOVRAssignmentLoc, glLayerAssignmentLoc);
}
} // namespace } // namespace
\ No newline at end of file
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