Commit 796df76c by shrekshao Committed by Commit Bot

MultiDraw Refactor

Refactor MultiDraw* from general Context to different ContextImpl. Move general multiDraw code to renderer_utils.cpp. Bug: angleproject:3402 Change-Id: I85cb4b781afa2b3a8beb382a9c735910057f2ebe Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2268580 Commit-Queue: Shrek Shao <shrekshao@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent ba584cf7
...@@ -3575,7 +3575,7 @@ void Context::updateCaps() ...@@ -3575,7 +3575,7 @@ void Context::updateCaps()
mStateCache.initialize(this); mStateCache.initialize(this);
} }
bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const
{ {
return (instanceCount == 0) || noopDraw(mode, count); return (instanceCount == 0) || noopDraw(mode, count);
} }
...@@ -5631,37 +5631,7 @@ void Context::multiDrawArrays(PrimitiveMode mode, ...@@ -5631,37 +5631,7 @@ void Context::multiDrawArrays(PrimitiveMode mode,
GLsizei drawcount) GLsizei drawcount)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw(mode)); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Program *programObject = mState.getLinkedProgram(this); ANGLE_CONTEXT_TRY(mImplementation->multiDrawArrays(this, mode, firsts, counts, drawcount));
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
if (hasDrawID)
{
for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
{
if (noopDraw(mode, counts[drawID]))
{
continue;
}
programObject->setDrawIDUniform(drawID);
ANGLE_CONTEXT_TRY(
mImplementation->drawArrays(this, mode, firsts[drawID], counts[drawID]));
MarkTransformFeedbackBufferUsage(this, counts[drawID], 1);
MarkShaderStorageBufferUsage(this);
}
}
else
{
for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
{
if (noopDraw(mode, counts[drawID]))
{
continue;
}
ANGLE_CONTEXT_TRY(
mImplementation->drawArrays(this, mode, firsts[drawID], counts[drawID]));
MarkTransformFeedbackBufferUsage(this, counts[drawID], 1);
MarkShaderStorageBufferUsage(this);
}
}
} }
void Context::multiDrawArraysInstanced(PrimitiveMode mode, void Context::multiDrawArraysInstanced(PrimitiveMode mode,
...@@ -5671,37 +5641,8 @@ void Context::multiDrawArraysInstanced(PrimitiveMode mode, ...@@ -5671,37 +5641,8 @@ void Context::multiDrawArraysInstanced(PrimitiveMode mode,
GLsizei drawcount) GLsizei drawcount)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw(mode)); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Program *programObject = mState.getLinkedProgram(this); ANGLE_CONTEXT_TRY(mImplementation->multiDrawArraysInstanced(this, mode, firsts, counts,
const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); instanceCounts, drawcount));
if (hasDrawID)
{
for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
{
if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
{
continue;
}
programObject->setDrawIDUniform(drawID);
ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstanced(
this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID]));
MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]);
MarkShaderStorageBufferUsage(this);
}
}
else
{
for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
{
if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
{
continue;
}
ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstanced(
this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID]));
MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]);
MarkShaderStorageBufferUsage(this);
}
}
} }
void Context::multiDrawElements(PrimitiveMode mode, void Context::multiDrawElements(PrimitiveMode mode,
...@@ -5711,35 +5652,8 @@ void Context::multiDrawElements(PrimitiveMode mode, ...@@ -5711,35 +5652,8 @@ void Context::multiDrawElements(PrimitiveMode mode,
GLsizei drawcount) GLsizei drawcount)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw(mode)); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Program *programObject = mState.getLinkedProgram(this);
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
if (hasDrawID)
{
for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
{
if (noopDraw(mode, counts[drawID]))
{
continue;
}
programObject->setDrawIDUniform(drawID);
ANGLE_CONTEXT_TRY( ANGLE_CONTEXT_TRY(
mImplementation->drawElements(this, mode, counts[drawID], type, indices[drawID])); mImplementation->multiDrawElements(this, mode, counts, type, indices, drawcount));
MarkShaderStorageBufferUsage(this);
}
}
else
{
for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
{
if (noopDraw(mode, counts[drawID]))
{
continue;
}
ANGLE_CONTEXT_TRY(
mImplementation->drawElements(this, mode, counts[drawID], type, indices[drawID]));
MarkShaderStorageBufferUsage(this);
}
}
} }
void Context::multiDrawElementsInstanced(PrimitiveMode mode, void Context::multiDrawElementsInstanced(PrimitiveMode mode,
...@@ -5750,77 +5664,10 @@ void Context::multiDrawElementsInstanced(PrimitiveMode mode, ...@@ -5750,77 +5664,10 @@ void Context::multiDrawElementsInstanced(PrimitiveMode mode,
GLsizei drawcount) GLsizei drawcount)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw(mode)); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Program *programObject = mState.getLinkedProgram(this); ANGLE_CONTEXT_TRY(mImplementation->multiDrawElementsInstanced(this, mode, counts, type, indices,
const bool hasDrawID = programObject && programObject->hasDrawIDUniform(); instanceCounts, drawcount));
if (hasDrawID)
{
for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
{
if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
{
continue;
}
programObject->setDrawIDUniform(drawID);
ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstanced(
this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID]));
MarkShaderStorageBufferUsage(this);
}
}
else
{
for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
{
if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
{
continue;
}
ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstanced(
this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID]));
MarkShaderStorageBufferUsage(this);
}
}
} }
namespace
{
// RAII object making sure reset uniforms is called no matter whether there's an error in draw calls
class ResetBaseVertexBaseInstance : angle::NonCopyable
{
public:
ResetBaseVertexBaseInstance(Program *programObject,
bool resetBaseVertex,
bool resetBaseInstance)
: mProgramObject(programObject),
mResetBaseVertex(resetBaseVertex),
mResetBaseInstance(resetBaseInstance)
{}
~ResetBaseVertexBaseInstance()
{
if (mProgramObject)
{
// Reset emulated uniforms to zero to avoid affecting other draw calls
if (mResetBaseVertex)
{
mProgramObject->setBaseVertexUniform(0);
}
if (mResetBaseInstance)
{
mProgramObject->setBaseInstanceUniform(0);
}
}
}
private:
Program *mProgramObject;
bool mResetBaseVertex;
bool mResetBaseInstance;
};
} // anonymous namespace
void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode, void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode,
GLint first, GLint first,
GLsizei count, GLsizei count,
...@@ -5841,7 +5688,7 @@ void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode, ...@@ -5841,7 +5688,7 @@ void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode,
programObject->setBaseInstanceUniform(baseInstance); programObject->setBaseInstanceUniform(baseInstance);
} }
ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance); rx::ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
// The input gl_InstanceID does not follow the baseinstance. gl_InstanceID always falls on // The input gl_InstanceID does not follow the baseinstance. gl_InstanceID always falls on
// the half-open range [0, instancecount). No need to set other stuff. Except for Vulkan. // the half-open range [0, instancecount). No need to set other stuff. Except for Vulkan.
...@@ -5879,58 +5726,12 @@ void Context::drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode, ...@@ -5879,58 +5726,12 @@ void Context::drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
programObject->setBaseInstanceUniform(baseInstance); programObject->setBaseInstanceUniform(baseInstance);
} }
ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance); rx::ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance( ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance(
this, mode, count, type, indices, instanceCounts, baseVertex, baseInstance)); this, mode, count, type, indices, instanceCounts, baseVertex, baseInstance));
} }
#define SET_DRAW_ID_UNIFORM_0(drawID) \
{}
#define SET_DRAW_ID_UNIFORM_1(drawID) programObject->setDrawIDUniform(drawID);
#define SET_DRAW_ID_UNIFORM(cond) SET_DRAW_ID_UNIFORM_##cond
#define SET_BASE_VERTEX_UNIFORM_0(baseVertex) \
{}
#define SET_BASE_VERTEX_UNIFORM_1(baseVertex) programObject->setBaseVertexUniform(baseVertex);
#define SET_BASE_VERTEX_UNIFORM(cond) SET_BASE_VERTEX_UNIFORM_##cond
#define SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \
{}
#define SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \
programObject->setBaseInstanceUniform(baseInstance);
#define SET_BASE_INSTANCE_UNIFORM(cond) SET_BASE_INSTANCE_UNIFORM_##cond
#define MULTI_DRAW_ARRAYS_BLOCK(hasDrawID, hasBaseInstance) \
for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
{ \
if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])) \
{ \
continue; \
} \
SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstancedBaseInstance( \
this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID], \
baseInstances[drawID])); \
MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]); \
}
#define MULTI_DRAW_ELEMENTS_BLOCK(hasDrawID, hasBaseVertex, hasBaseInstance) \
for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
{ \
if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])) \
{ \
continue; \
} \
SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \
SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance( \
this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID], \
baseVertices[drawID], baseInstances[drawID])); \
}
void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode, void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode,
const GLint *firsts, const GLint *firsts,
const GLsizei *counts, const GLsizei *counts,
...@@ -5939,28 +5740,8 @@ void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode, ...@@ -5939,28 +5740,8 @@ void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode,
GLsizei drawcount) GLsizei drawcount)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw(mode)); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Program *programObject = mState.getLinkedProgram(this); ANGLE_CONTEXT_TRY(mImplementation->multiDrawArraysInstancedBaseInstance(
const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform(); this, mode, firsts, counts, instanceCounts, baseInstances, drawcount));
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
if (hasDrawID && hasBaseInstance)
{
MULTI_DRAW_ARRAYS_BLOCK(1, 1)
}
else if (hasDrawID)
{
MULTI_DRAW_ARRAYS_BLOCK(1, 0)
}
else if (hasBaseInstance)
{
MULTI_DRAW_ARRAYS_BLOCK(0, 1)
}
else
{
MULTI_DRAW_ARRAYS_BLOCK(0, 0)
}
} }
void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode, void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
...@@ -5973,63 +5754,8 @@ void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mod ...@@ -5973,63 +5754,8 @@ void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mod
GLsizei drawcount) GLsizei drawcount)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw(mode)); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Program *programObject = mState.getLinkedProgram(this); ANGLE_CONTEXT_TRY(mImplementation->multiDrawElementsInstancedBaseVertexBaseInstance(
const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform(); this, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances, drawcount));
const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
if (hasDrawID)
{
if (hasBaseVertex)
{
if (hasBaseInstance)
{
MULTI_DRAW_ELEMENTS_BLOCK(1, 1, 1)
}
else
{
MULTI_DRAW_ELEMENTS_BLOCK(1, 1, 0)
}
}
else
{
if (hasBaseInstance)
{
MULTI_DRAW_ELEMENTS_BLOCK(1, 0, 1)
}
else
{
MULTI_DRAW_ELEMENTS_BLOCK(1, 0, 0)
}
}
}
else
{
if (hasBaseVertex)
{
if (hasBaseInstance)
{
MULTI_DRAW_ELEMENTS_BLOCK(0, 1, 1)
}
else
{
MULTI_DRAW_ELEMENTS_BLOCK(0, 1, 0)
}
}
else
{
if (hasBaseInstance)
{
MULTI_DRAW_ELEMENTS_BLOCK(0, 0, 1)
}
else
{
MULTI_DRAW_ELEMENTS_BLOCK(0, 0, 0)
}
}
}
} }
void Context::provokingVertex(ProvokingVertexConvention provokeMode) void Context::provokingVertex(ProvokingVertexConvention provokeMode)
......
...@@ -613,12 +613,12 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -613,12 +613,12 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
egl::Error reacquireHighPowerGPU(); egl::Error reacquireHighPowerGPU();
void onGPUSwitch(); void onGPUSwitch();
bool noopDraw(PrimitiveMode mode, GLsizei count) const;
bool noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const;
private: private:
void initialize(); void initialize();
bool noopDraw(PrimitiveMode mode, GLsizei count);
bool noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount);
angle::Result prepareForDraw(PrimitiveMode mode); angle::Result prepareForDraw(PrimitiveMode mode);
angle::Result prepareForClear(GLbitfield mask); angle::Result prepareForClear(GLbitfield mask);
angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer); angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer);
......
...@@ -64,7 +64,7 @@ ANGLE_INLINE void MarkShaderStorageBufferUsage(const Context *context) ...@@ -64,7 +64,7 @@ ANGLE_INLINE void MarkShaderStorageBufferUsage(const Context *context)
// an error. ANGLE will treat this as a no-op. // an error. ANGLE will treat this as a no-op.
// A no-op draw occurs if the count of vertices is less than the minimum required to // A no-op draw occurs if the count of vertices is less than the minimum required to
// have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris). // have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count) ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count) const
{ {
if (!mStateCache.getCanDraw()) if (!mStateCache.getCanDraw())
{ {
......
...@@ -115,6 +115,49 @@ class ContextImpl : public GLImplFactory ...@@ -115,6 +115,49 @@ class ContextImpl : public GLImplFactory
gl::DrawElementsType type, gl::DrawElementsType type,
const void *indirect) = 0; const void *indirect) = 0;
// MultiDraw* impl added as we need workaround for promoting dynamic attributes in D3D backend
virtual angle::Result multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount) = 0;
virtual angle::Result multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount) = 0;
virtual angle::Result multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount) = 0;
virtual angle::Result multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount) = 0;
virtual angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount) = 0;
virtual angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount) = 0;
// Device loss // Device loss
virtual gl::GraphicsResetStatus getResetStatus() = 0; virtual gl::GraphicsResetStatus getResetStatus() = 0;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "common/string_utils.h" #include "common/string_utils.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/MemoryProgramCache.h" #include "libANGLE/MemoryProgramCache.h"
#include "libANGLE/renderer/OverlayImpl.h" #include "libANGLE/renderer/OverlayImpl.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h" #include "libANGLE/renderer/d3d/CompilerD3D.h"
...@@ -469,6 +470,76 @@ angle::Result Context11::drawElementsIndirect(const gl::Context *context, ...@@ -469,6 +470,76 @@ angle::Result Context11::drawElementsIndirect(const gl::Context *context,
} }
} }
angle::Result Context11::multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount)
{
return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount);
}
angle::Result Context11::multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts,
drawcount);
}
angle::Result Context11::multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount)
{
return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount);
}
angle::Result Context11::multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices,
instanceCounts, drawcount);
}
angle::Result Context11::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedBaseInstanceGeneral(
this, context, mode, firsts, counts, instanceCounts, baseInstances, drawcount);
}
angle::Result Context11::multiDrawElementsInstancedBaseVertexBaseInstance(
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(
this, context, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances,
drawcount);
}
gl::GraphicsResetStatus Context11::getResetStatus() gl::GraphicsResetStatus Context11::getResetStatus()
{ {
return mRenderer->getResetStatus(); return mRenderer->getResetStatus();
......
...@@ -147,6 +147,47 @@ class Context11 : public ContextD3D, public MultisampleTextureInitializer ...@@ -147,6 +147,47 @@ class Context11 : public ContextD3D, public MultisampleTextureInitializer
gl::DrawElementsType type, gl::DrawElementsType type,
const void *indirect) override; const void *indirect) override;
angle::Result multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount) override;
// Device loss // Device loss
gl::GraphicsResetStatus getResetStatus() override; gl::GraphicsResetStatus getResetStatus() override;
......
...@@ -283,6 +283,75 @@ angle::Result Context9::drawElementsIndirect(const gl::Context *context, ...@@ -283,6 +283,75 @@ angle::Result Context9::drawElementsIndirect(const gl::Context *context,
return angle::Result::Stop; return angle::Result::Stop;
} }
angle::Result Context9::multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount)
{
return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount);
}
angle::Result Context9::multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts,
drawcount);
}
angle::Result Context9::multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount)
{
return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount);
}
angle::Result Context9::multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices,
instanceCounts, drawcount);
}
angle::Result Context9::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount)
{
ANGLE_HR_UNREACHABLE(this);
return angle::Result::Stop;
}
angle::Result Context9::multiDrawElementsInstancedBaseVertexBaseInstance(
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount)
{
ANGLE_HR_UNREACHABLE(this);
return angle::Result::Stop;
}
gl::GraphicsResetStatus Context9::getResetStatus() gl::GraphicsResetStatus Context9::getResetStatus()
{ {
return mRenderer->getResetStatus(); return mRenderer->getResetStatus();
......
...@@ -146,6 +146,47 @@ class Context9 : public ContextD3D ...@@ -146,6 +146,47 @@ class Context9 : public ContextD3D
gl::DrawElementsType type, gl::DrawElementsType type,
const void *indirect) override; const void *indirect) override;
angle::Result multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount) override;
// Device loss // Device loss
gl::GraphicsResetStatus getResetStatus() override; gl::GraphicsResetStatus getResetStatus() override;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "libANGLE/renderer/gl/ContextGL.h" #include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/renderer/OverlayImpl.h" #include "libANGLE/renderer/OverlayImpl.h"
#include "libANGLE/renderer/gl/BufferGL.h" #include "libANGLE/renderer/gl/BufferGL.h"
#include "libANGLE/renderer/gl/CompilerGL.h" #include "libANGLE/renderer/gl/CompilerGL.h"
...@@ -650,6 +651,76 @@ angle::Result ContextGL::drawElementsIndirect(const gl::Context *context, ...@@ -650,6 +651,76 @@ angle::Result ContextGL::drawElementsIndirect(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ContextGL::multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount)
{
return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount);
}
angle::Result ContextGL::multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts,
drawcount);
}
angle::Result ContextGL::multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount)
{
return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount);
}
angle::Result ContextGL::multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices,
instanceCounts, drawcount);
}
angle::Result ContextGL::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedBaseInstanceGeneral(
this, context, mode, firsts, counts, instanceCounts, baseInstances, drawcount);
}
angle::Result ContextGL::multiDrawElementsInstancedBaseVertexBaseInstance(
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(
this, context, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances,
drawcount);
}
gl::GraphicsResetStatus ContextGL::getResetStatus() gl::GraphicsResetStatus ContextGL::getResetStatus()
{ {
return mRenderer->getResetStatus(); return mRenderer->getResetStatus();
......
...@@ -161,6 +161,47 @@ class ContextGL : public ContextImpl ...@@ -161,6 +161,47 @@ class ContextGL : public ContextImpl
gl::DrawElementsType type, gl::DrawElementsType type,
const void *indirect) override; const void *indirect) override;
angle::Result multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount) override;
// Device loss // Device loss
gl::GraphicsResetStatus getResetStatus() override; gl::GraphicsResetStatus getResetStatus() override;
......
...@@ -113,6 +113,46 @@ class ContextMtl : public ContextImpl, public mtl::Context ...@@ -113,6 +113,46 @@ class ContextMtl : public ContextImpl, public mtl::Context
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
gl::DrawElementsType type, gl::DrawElementsType type,
const void *indirect) override; const void *indirect) override;
angle::Result multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount) override;
// Device loss // Device loss
gl::GraphicsResetStatus getResetStatus() override; gl::GraphicsResetStatus getResetStatus() override;
......
...@@ -488,6 +488,76 @@ angle::Result ContextMtl::drawElementsIndirect(const gl::Context *context, ...@@ -488,6 +488,76 @@ angle::Result ContextMtl::drawElementsIndirect(const gl::Context *context,
return angle::Result::Stop; return angle::Result::Stop;
} }
angle::Result ContextMtl::multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount)
{
return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount);
}
angle::Result ContextMtl::multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts,
drawcount);
}
angle::Result ContextMtl::multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount)
{
return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount);
}
angle::Result ContextMtl::multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices,
instanceCounts, drawcount);
}
angle::Result ContextMtl::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedBaseInstanceGeneral(
this, context, mode, firsts, counts, instanceCounts, baseInstances, drawcount);
}
angle::Result ContextMtl::multiDrawElementsInstancedBaseVertexBaseInstance(
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(
this, context, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances,
drawcount);
}
// Device loss // Device loss
gl::GraphicsResetStatus ContextMtl::getResetStatus() gl::GraphicsResetStatus ContextMtl::getResetStatus()
{ {
......
...@@ -242,6 +242,71 @@ angle::Result ContextNULL::drawElementsIndirect(const gl::Context *context, ...@@ -242,6 +242,71 @@ angle::Result ContextNULL::drawElementsIndirect(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ContextNULL::multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount)
{
return angle::Result::Continue;
}
angle::Result ContextNULL::multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return angle::Result::Continue;
}
angle::Result ContextNULL::multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount)
{
return angle::Result::Continue;
}
angle::Result ContextNULL::multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return angle::Result::Continue;
}
angle::Result ContextNULL::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount)
{
return angle::Result::Continue;
}
angle::Result ContextNULL::multiDrawElementsInstancedBaseVertexBaseInstance(
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount)
{
return angle::Result::Continue;
}
gl::GraphicsResetStatus ContextNULL::getResetStatus() gl::GraphicsResetStatus ContextNULL::getResetStatus()
{ {
return gl::GraphicsResetStatus::NoError; return gl::GraphicsResetStatus::NoError;
......
...@@ -116,6 +116,47 @@ class ContextNULL : public ContextImpl ...@@ -116,6 +116,47 @@ class ContextNULL : public ContextImpl
gl::DrawElementsType type, gl::DrawElementsType type,
const void *indirect) override; const void *indirect) override;
angle::Result multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount) override;
// Device loss // Device loss
gl::GraphicsResetStatus getResetStatus() override; gl::GraphicsResetStatus getResetStatus() override;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "image_util/imageformats.h" #include "image_util/imageformats.h"
#include "libANGLE/AttributeMap.h" #include "libANGLE/AttributeMap.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/ContextImpl.h" #include "libANGLE/renderer/ContextImpl.h"
...@@ -935,4 +936,257 @@ void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy) ...@@ -935,4 +936,257 @@ void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy)
xy[1] = kSamplePositions[indexKey][2 * index + 1]; xy[1] = kSamplePositions[indexKey][2 * index + 1];
} }
} }
// These macros are to avoid code too much duplication for variations of multi draw types
#define DRAW_ARRAYS__ contextImpl->drawArrays(context, mode, firsts[drawID], counts[drawID])
#define DRAW_ARRAYS_INSTANCED_ \
contextImpl->drawArraysInstanced(context, mode, firsts[drawID], counts[drawID], \
instanceCounts[drawID])
#define DRAW_ELEMENTS__ \
contextImpl->drawElements(context, mode, counts[drawID], type, indices[drawID])
#define DRAW_ELEMENTS_INSTANCED_ \
contextImpl->drawElementsInstanced(context, mode, counts[drawID], type, indices[drawID], \
instanceCounts[drawID])
#define DRAW_ARRAYS_INSTANCED_BASE_INSTANCE \
contextImpl->drawArraysInstancedBaseInstance(context, mode, firsts[drawID], counts[drawID], \
instanceCounts[drawID], baseInstances[drawID])
#define DRAW_ELEMENTS_INSTANCED_BASE_VERTEX_BASE_INSTANCE \
contextImpl->drawElementsInstancedBaseVertexBaseInstance( \
context, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID], \
baseVertices[drawID], baseInstances[drawID])
#define DRAW_CALL(drawType, instanced, bvbi) DRAW_##drawType##instanced##bvbi
#define MULTI_DRAW_BLOCK(drawType, instanced, bvbi, hasDrawID, hasBaseVertex, hasBaseInstance) \
for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
{ \
if (ANGLE_NOOP_DRAW(instanced)) \
{ \
continue; \
} \
ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
ANGLE_SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \
ANGLE_SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
ANGLE_TRY(DRAW_CALL(drawType, instanced, bvbi)); \
ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced); \
gl::MarkShaderStorageBufferUsage(context); \
}
angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount)
{
gl::Program *programObject = context->getState().getLinkedProgram(context);
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
if (hasDrawID)
{
MULTI_DRAW_BLOCK(ARRAYS, _, _, 1, 0, 0)
}
else
{
MULTI_DRAW_BLOCK(ARRAYS, _, _, 0, 0, 0)
}
return angle::Result::Continue;
}
angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
gl::Program *programObject = context->getState().getLinkedProgram(context);
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
if (hasDrawID)
{
MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 1, 0, 0)
}
else
{
MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 0, 0, 0)
}
return angle::Result::Continue;
}
angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount)
{
gl::Program *programObject = context->getState().getLinkedProgram(context);
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
if (hasDrawID)
{
MULTI_DRAW_BLOCK(ELEMENTS, _, _, 1, 0, 0)
}
else
{
MULTI_DRAW_BLOCK(ELEMENTS, _, _, 0, 0, 0)
}
return angle::Result::Continue;
}
angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
gl::Program *programObject = context->getState().getLinkedProgram(context);
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
if (hasDrawID)
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 1, 0, 0)
}
else
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 0, 0, 0)
}
return angle::Result::Continue;
}
angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount)
{
gl::Program *programObject = context->getState().getLinkedProgram(context);
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
if (hasDrawID && hasBaseInstance)
{
MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 1)
}
else if (hasDrawID)
{
MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 0)
}
else if (hasBaseInstance)
{
MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 1)
}
else
{
MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 0)
}
return angle::Result::Continue;
}
angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount)
{
gl::Program *programObject = context->getState().getLinkedProgram(context);
const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
if (hasDrawID)
{
if (hasBaseVertex)
{
if (hasBaseInstance)
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 1)
}
else
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 0)
}
}
else
{
if (hasBaseInstance)
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 1)
}
else
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 0)
}
}
}
else
{
if (hasBaseVertex)
{
if (hasBaseInstance)
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 1)
}
else
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 0)
}
}
else
{
if (hasBaseInstance)
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 1)
}
else
{
MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 0)
}
}
}
return angle::Result::Continue;
}
ResetBaseVertexBaseInstance::ResetBaseVertexBaseInstance(gl::Program *programObject,
bool resetBaseVertex,
bool resetBaseInstance)
: mProgramObject(programObject),
mResetBaseVertex(resetBaseVertex),
mResetBaseInstance(resetBaseInstance)
{}
ResetBaseVertexBaseInstance::~ResetBaseVertexBaseInstance()
{
if (mProgramObject)
{
// Reset emulated uniforms to zero to avoid affecting other draw calls
if (mResetBaseVertex)
{
mProgramObject->setBaseVertexUniform(0);
}
if (mResetBaseInstance)
{
mProgramObject->setBaseInstanceUniform(0);
}
}
}
} // namespace rx } // namespace rx
...@@ -349,6 +349,102 @@ void CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, u ...@@ -349,6 +349,102 @@ void CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, u
} }
void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy); void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount);
angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount);
angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount);
angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount);
angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount);
angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl,
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount);
// RAII object making sure reset uniforms is called no matter whether there's an error in draw calls
class ResetBaseVertexBaseInstance : angle::NonCopyable
{
public:
ResetBaseVertexBaseInstance(gl::Program *programObject,
bool resetBaseVertex,
bool resetBaseInstance);
~ResetBaseVertexBaseInstance();
private:
gl::Program *mProgramObject;
bool mResetBaseVertex;
bool mResetBaseInstance;
};
} // namespace rx } // namespace rx
// MultiDraw macro patterns
// These macros are to avoid too much code duplication as we don't want to have if detect for
// hasDrawID/BaseVertex/BaseInstance inside for loop in a multiDraw call Part of these are put in
// the header as we want to share with specialized context impl on some platforms for multidraw
#define ANGLE_SET_DRAW_ID_UNIFORM_0(drawID) \
{}
#define ANGLE_SET_DRAW_ID_UNIFORM_1(drawID) programObject->setDrawIDUniform(drawID)
#define ANGLE_SET_DRAW_ID_UNIFORM(cond) ANGLE_SET_DRAW_ID_UNIFORM_##cond
#define ANGLE_SET_BASE_VERTEX_UNIFORM_0(baseVertex) \
{}
#define ANGLE_SET_BASE_VERTEX_UNIFORM_1(baseVertex) programObject->setBaseVertexUniform(baseVertex);
#define ANGLE_SET_BASE_VERTEX_UNIFORM(cond) ANGLE_SET_BASE_VERTEX_UNIFORM_##cond
#define ANGLE_SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \
{}
#define ANGLE_SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \
programObject->setBaseInstanceUniform(baseInstance)
#define ANGLE_SET_BASE_INSTANCE_UNIFORM(cond) ANGLE_SET_BASE_INSTANCE_UNIFORM_##cond
#define ANGLE_NOOP_DRAW_ context->noopDraw(mode, counts[drawID])
#define ANGLE_NOOP_DRAW_INSTANCED \
context->noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])
#define ANGLE_NOOP_DRAW(_instanced) ANGLE_NOOP_DRAW##_instanced
#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_ \
gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], 1)
#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_INSTANCED \
gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], instanceCounts[drawID])
#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced) \
ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE##instanced
#endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_ #endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_
...@@ -2269,6 +2269,76 @@ angle::Result ContextVk::drawElementsIndirect(const gl::Context *context, ...@@ -2269,6 +2269,76 @@ angle::Result ContextVk::drawElementsIndirect(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ContextVk::multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount)
{
return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount);
}
angle::Result ContextVk::multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts,
drawcount);
}
angle::Result ContextVk::multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount)
{
return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount);
}
angle::Result ContextVk::multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices,
instanceCounts, drawcount);
}
angle::Result ContextVk::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount)
{
return rx::MultiDrawArraysInstancedBaseInstanceGeneral(
this, context, mode, firsts, counts, instanceCounts, baseInstances, drawcount);
}
angle::Result ContextVk::multiDrawElementsInstancedBaseVertexBaseInstance(
const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount)
{
return rx::MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(
this, context, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances,
drawcount);
}
void ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferHandle) void ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferHandle)
{ {
if (!mRenderPassCommands->started()) if (!mRenderPassCommands->started())
......
...@@ -187,6 +187,47 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -187,6 +187,47 @@ class ContextVk : public ContextImpl, public vk::Context
gl::DrawElementsType type, gl::DrawElementsType type,
const void *indirect) override; const void *indirect) override;
angle::Result multiDrawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawElements(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstanced(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
GLsizei drawcount) override;
angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLint *firsts,
const GLsizei *counts,
const GLsizei *instanceCounts,
const GLuint *baseInstances,
GLsizei drawcount) override;
angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
const GLsizei *counts,
gl::DrawElementsType type,
const GLvoid *const *indices,
const GLsizei *instanceCounts,
const GLint *baseVertices,
const GLuint *baseInstances,
GLsizei drawcount) override;
// Device loss // Device loss
gl::GraphicsResetStatus getResetStatus() override; gl::GraphicsResetStatus getResetStatus() override;
......
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