From b2d55742b3edd74f0bc64e6ee8337689ac61e789 Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Fri, 21 Jan 2022 12:28:32 -0500 Subject: Program: Add generic uniform update methods. This will make it easier to make central changes to all the update methods. Otherwise we'd have to replicate changes in each separate member. Bug: angleproject:3570 Change-Id: Ia765720507642338d6e9777b7e38fb323800359b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3407734 Reviewed-by: Shahbaz Youssefi Reviewed-by: Tim Van Patten Commit-Queue: Jamie Madill --- src/libANGLE/Program.cpp | 212 ++++++++--------------------- src/libANGLE/Program.h | 15 ++ src/tests/gl_tests/ProgramPipelineTest.cpp | 92 +++++++++++++ 3 files changed, 160 insertions(+), 159 deletions(-) diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp index bfe3177e1b..ca65550cff 100644 --- a/src/libANGLE/Program.cpp +++ b/src/libANGLE/Program.cpp @@ -2308,7 +2308,10 @@ bool Program::shouldIgnoreUniform(UniformLocation location) const return false; } -void Program::setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v) +template +void Program::setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v) { ASSERT(!mLinkingState); if (shouldIgnoreUniform(location)) @@ -2317,47 +2320,28 @@ void Program::setUniform1fv(UniformLocation location, GLsizei count, const GLflo } const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v); - mProgram->setUniform1fv(location.value, clampedCount, v); + GLsizei clampedCount = clampUniformCount(locationInfo, count, UniformSize, v); + (mProgram->*SetUniformFunc)(location.value, clampedCount, v); } -void Program::setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v) +void Program::setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } + setUniformGeneric(location, count, v); +} - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v); - mProgram->setUniform2fv(location.value, clampedCount, v); +void Program::setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v) +{ + setUniformGeneric(location, count, v); } void Program::setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v); - mProgram->setUniform3fv(location.value, clampedCount, v); + setUniformGeneric(location, count, v); } void Program::setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v); - mProgram->setUniform4fv(location.value, clampedCount, v); + setUniformGeneric(location, count, v); } void Program::setUniform1iv(Context *context, @@ -2384,83 +2368,48 @@ void Program::setUniform1iv(Context *context, void Program::setUniform2iv(UniformLocation location, GLsizei count, const GLint *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v); - mProgram->setUniform2iv(location.value, clampedCount, v); + setUniformGeneric(location, count, v); } void Program::setUniform3iv(UniformLocation location, GLsizei count, const GLint *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v); - mProgram->setUniform3iv(location.value, clampedCount, v); + setUniformGeneric(location, count, v); } void Program::setUniform4iv(UniformLocation location, GLsizei count, const GLint *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v); - mProgram->setUniform4iv(location.value, clampedCount, v); + setUniformGeneric(location, count, v); } void Program::setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v); - mProgram->setUniform1uiv(location.value, clampedCount, v); + setUniformGeneric(location, count, v); } void Program::setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v); - mProgram->setUniform2uiv(location.value, clampedCount, v); + setUniformGeneric(location, count, v); } void Program::setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v); - mProgram->setUniform3uiv(location.value, clampedCount, v); + setUniformGeneric(location, count, v); } void Program::setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v) +{ + setUniformGeneric(location, count, v); +} + +template < + typename UniformT, + GLint MatrixC, + GLint MatrixR, + void (rx::ProgramImpl::*SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)> +void Program::setUniformMatrixGeneric(UniformLocation location, + GLsizei count, + GLboolean transpose, + const UniformT *v) { ASSERT(!mLinkingState); if (shouldIgnoreUniform(location)) @@ -2468,9 +2417,8 @@ void Program::setUniform4uiv(UniformLocation location, GLsizei count, const GLui return; } - const VariableLocation &locationInfo = mState.mUniformLocations[location.value]; - GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v); - mProgram->setUniform4uiv(location.value, clampedCount, v); + GLsizei clampedCount = clampMatrixUniformCount(location, count, transpose, v); + (mProgram->*SetUniformMatrixFunc)(location.value, clampedCount, transpose, v); } void Program::setUniformMatrix2fv(UniformLocation location, @@ -2478,14 +2426,8 @@ void Program::setUniformMatrix2fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<2, 2>(location, count, transpose, v); - mProgram->setUniformMatrix2fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } void Program::setUniformMatrix3fv(UniformLocation location, @@ -2493,14 +2435,8 @@ void Program::setUniformMatrix3fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<3, 3>(location, count, transpose, v); - mProgram->setUniformMatrix3fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } void Program::setUniformMatrix4fv(UniformLocation location, @@ -2508,14 +2444,8 @@ void Program::setUniformMatrix4fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<4, 4>(location, count, transpose, v); - mProgram->setUniformMatrix4fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } void Program::setUniformMatrix2x3fv(UniformLocation location, @@ -2523,14 +2453,8 @@ void Program::setUniformMatrix2x3fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<2, 3>(location, count, transpose, v); - mProgram->setUniformMatrix2x3fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } void Program::setUniformMatrix2x4fv(UniformLocation location, @@ -2538,14 +2462,8 @@ void Program::setUniformMatrix2x4fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<2, 4>(location, count, transpose, v); - mProgram->setUniformMatrix2x4fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } void Program::setUniformMatrix3x2fv(UniformLocation location, @@ -2553,14 +2471,8 @@ void Program::setUniformMatrix3x2fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<3, 2>(location, count, transpose, v); - mProgram->setUniformMatrix3x2fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } void Program::setUniformMatrix3x4fv(UniformLocation location, @@ -2568,14 +2480,8 @@ void Program::setUniformMatrix3x4fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<3, 4>(location, count, transpose, v); - mProgram->setUniformMatrix3x4fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } void Program::setUniformMatrix4x2fv(UniformLocation location, @@ -2583,14 +2489,8 @@ void Program::setUniformMatrix4x2fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<4, 2>(location, count, transpose, v); - mProgram->setUniformMatrix4x2fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } void Program::setUniformMatrix4x3fv(UniformLocation location, @@ -2598,14 +2498,8 @@ void Program::setUniformMatrix4x3fv(UniformLocation location, GLboolean transpose, const GLfloat *v) { - ASSERT(!mLinkingState); - if (shouldIgnoreUniform(location)) - { - return; - } - - GLsizei clampedCount = clampMatrixUniformCount<4, 3>(location, count, transpose, v); - mProgram->setUniformMatrix4x3fv(location.value, clampedCount, transpose, v); + setUniformMatrixGeneric(location, count, + transpose, v); } GLuint Program::getSamplerUniformBinding(const VariableLocation &uniformLocation) const diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h index 410b97f9f9..d35c0a86d4 100644 --- a/src/libANGLE/Program.h +++ b/src/libANGLE/Program.h @@ -853,6 +853,21 @@ class Program final : public LabeledObject, public angle::Subject void postResolveLink(const gl::Context *context); + template + void setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v); + + template < + typename UniformT, + GLint MatrixC, + GLint MatrixR, + void (rx::ProgramImpl::*SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)> + void setUniformMatrixGeneric(UniformLocation location, + GLsizei count, + GLboolean transpose, + const UniformT *v); + rx::Serial mSerial; ProgramState mState; rx::ProgramImpl *mProgram; diff --git a/src/tests/gl_tests/ProgramPipelineTest.cpp b/src/tests/gl_tests/ProgramPipelineTest.cpp index 5386301c6a..8e3c036daa 100644 --- a/src/tests/gl_tests/ProgramPipelineTest.cpp +++ b/src/tests/gl_tests/ProgramPipelineTest.cpp @@ -824,6 +824,98 @@ void main() EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2 + 1, 0, GLColor::green); } +// Test that uniform updates propagate to two pipelines. +TEST_P(ProgramPipelineTest31, UniformUpdateTwoPipelines) +{ + ANGLE_SKIP_TEST_IF(!IsVulkan()); + + // Create two separable program objects from a + // single source string respectively (vertSrc and fragSrc) + const GLchar *vertString = essl31_shaders::vs::Simple(); + const GLchar *fragString = R"(#version 310 es +precision highp float; +uniform float redColorIn; +uniform float greenColorIn; +out vec4 my_FragColor; +void main() +{ + my_FragColor = vec4(redColorIn, greenColorIn, 0.0, 1.0); +})"; + + mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString); + ASSERT_NE(mVertProg, 0u); + mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString); + ASSERT_NE(mFragProg, 0u); + + GLint redLoc = glGetUniformLocation(mFragProg, "redColorIn"); + ASSERT_NE(-1, redLoc); + GLint greenLoc = glGetUniformLocation(mFragProg, "greenColorIn"); + ASSERT_NE(-1, greenLoc); + + GLProgramPipeline ppo1; + glUseProgramStages(ppo1, GL_VERTEX_SHADER_BIT, mVertProg); + glUseProgramStages(ppo1, GL_FRAGMENT_SHADER_BIT, mFragProg); + glBindProgramPipeline(ppo1); + glActiveShaderProgram(ppo1, mFragProg); + ASSERT_GL_NO_ERROR(); + + GLProgramPipeline ppo2; + glUseProgramStages(ppo2, GL_VERTEX_SHADER_BIT, mVertProg); + glUseProgramStages(ppo2, GL_FRAGMENT_SHADER_BIT, mFragProg); + glBindProgramPipeline(ppo2); + glActiveShaderProgram(ppo2, mFragProg); + ASSERT_GL_NO_ERROR(); + + std::array verts = GetQuadVertices(); + + GLBuffer vbo; + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(verts[0]), verts.data(), GL_STATIC_DRAW); + + GLint posLoc = glGetAttribLocation(mVertProg, "a_position"); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + glEnableVertexAttribArray(posLoc); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + const GLsizei w = getWindowWidth() / 2; + const GLsizei h = getWindowHeight() / 2; + + // Set the output color to red, draw to UL quad of window with first PPO. + glUniform1f(redLoc, 1.0); + glUniform1f(greenLoc, 0.0); + glBindProgramPipeline(ppo1); + glViewport(0, 0, w, h); + glDrawArrays(GL_TRIANGLES, 0, 6); + ASSERT_GL_NO_ERROR(); + + // Draw red to UR half of window with second PPO. + glBindProgramPipeline(ppo2); + glViewport(w, 0, w, h); + glDrawArrays(GL_TRIANGLES, 0, 6); + ASSERT_GL_NO_ERROR(); + + // Draw green to LL corner of window with first PPO. + glUniform1f(redLoc, 0.0); + glUniform1f(greenLoc, 1.0); + glBindProgramPipeline(ppo1); + glViewport(0, h, w, h); + glDrawArrays(GL_TRIANGLES, 0, 6); + ASSERT_GL_NO_ERROR(); + + // Draw green to LR half of window with second PPO. + glBindProgramPipeline(ppo2); + glViewport(w, h, w, h); + glDrawArrays(GL_TRIANGLES, 0, 6); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(w + 1, 0, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(0, h + 1, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(w + 1, h + 1, GLColor::green); +} + // Tests that setting sampler bindings on a program before the pipeline works as expected. TEST_P(ProgramPipelineTest31, BindSamplerBeforeCreatingPipeline) { -- cgit v1.2.3