Commit f6f20601 by Jamie Madill Committed by Commit Bot

Vulkan: Optimize Attribute Change Perf (4/5)

This patch series optimizes programs that use the pattern: for (;;) { glVertexAttribPointer(...) glDraw(...) } Change 4: Inline ValidateProgramDrawStates. A hotspot in most draw calls that change state. In total the patch series reduces test iteration time by 25%. This change reduces the listed "null" benchmark time from 295 -> 286 ns. Test: DrawCallPerfBenchmark.Run/vulkan_null_attrib_change Bug: angleproject:5045 Bug: b/168493024 Change-Id: I80959c9d06030709d7f4eba696e43614c33d5a8f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2409176 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent a42a7f06
......@@ -537,6 +537,64 @@ unsigned int GetSamplerParameterCount(GLenum pname)
return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
}
ANGLE_INLINE const char *ValidateProgramDrawStates(const State &state,
const Extensions &extensions,
Program *program)
{
if (extensions.multiview || extensions.multiview2)
{
const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
Framebuffer *framebuffer = state.getDrawFramebuffer();
const int framebufferNumViews = framebuffer->getNumViews();
if (framebufferNumViews != programNumViews)
{
return gl::err::kMultiviewMismatch;
}
if (state.isTransformFeedbackActiveUnpaused() && framebufferNumViews > 1)
{
return gl::err::kMultiviewTransformFeedback;
}
if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
state.isQueryActive(QueryType::TimeElapsed))
{
return gl::err::kMultiviewTimerQuery;
}
}
// Uniform buffer validation
for (unsigned int uniformBlockIndex = 0;
uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
{
const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
const OffsetBindingPointer<Buffer> &uniformBuffer =
state.getIndexedUniformBuffer(blockBinding);
if (uniformBuffer.get() == nullptr)
{
// undefined behaviour
return gl::err::kUniformBufferUnbound;
}
size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
if (uniformBufferSize < uniformBlock.dataSize)
{
// undefined behaviour
return gl::err::kUniformBufferTooSmall;
}
if (extensions.webglCompatibility &&
uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
{
return gl::err::kUniformBufferBoundForTransformFeedback;
}
}
return nullptr;
}
} // anonymous namespace
void SetRobustLengthParam(const GLsizei *length, GLsizei value)
......@@ -2734,65 +2792,6 @@ bool ValidateCopyTexImageParametersBase(const Context *context,
return true;
}
const char *ValidateProgramDrawStates(const State &state,
const Extensions &extensions,
Program *program)
{
if (extensions.multiview || extensions.multiview2)
{
const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
Framebuffer *framebuffer = state.getDrawFramebuffer();
const int framebufferNumViews = framebuffer->getNumViews();
if (framebufferNumViews != programNumViews)
{
return gl::err::kMultiviewMismatch;
}
if (state.isTransformFeedbackActiveUnpaused() && framebufferNumViews > 1)
{
return gl::err::kMultiviewTransformFeedback;
}
if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
state.isQueryActive(QueryType::TimeElapsed))
{
return gl::err::kMultiviewTimerQuery;
}
}
// Uniform buffer validation
for (unsigned int uniformBlockIndex = 0;
uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
{
const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
const OffsetBindingPointer<Buffer> &uniformBuffer =
state.getIndexedUniformBuffer(blockBinding);
if (uniformBuffer.get() == nullptr)
{
// undefined behaviour
return gl::err::kUniformBufferUnbound;
}
size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
if (uniformBufferSize < uniformBlock.dataSize)
{
// undefined behaviour
return gl::err::kUniformBufferTooSmall;
}
if (extensions.webglCompatibility &&
uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
{
return gl::err::kUniformBufferBoundForTransformFeedback;
}
}
return nullptr;
}
const char *ValidateProgramPipelineDrawStates(const State &state,
const Extensions &extensions,
ProgramPipeline *programPipeline)
......
......@@ -755,9 +755,6 @@ ANGLE_INLINE bool ValidateFramebufferComplete(const Context *context,
return true;
}
const char *ValidateProgramDrawStates(const State &state,
const Extensions &extensions,
Program *program);
const char *ValidateProgramPipelineDrawStates(const State &state,
const Extensions &extensions,
ProgramPipeline *programPipeline);
......
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