Commit ec30d78d by Jiacheng Lu Committed by Commit Bot

Optimize uniform matrix update

1. Add a fast matrix update function to do a single memcpy for uniform matrix assignment with same layout. It benefits row-4 no-transpose GLSL matrix and col-4 transpose HLSL matrix. 2. Make boolean IsColumnMajor to be a template parameter in generate uniform matrix updating, which gets rid of the conditional branch in loop and has better performance. 3. Add e2e test of uploading multiple 3x4 GLSL matrices at the same time, which adds coverage to this CL. Bug: angleproject:3632 Change-Id: Id1701ef6fbf63ea4b9884254d93ea8eacfe4e16a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1688274 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 69194e5f
...@@ -2602,9 +2602,9 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location, ...@@ -2602,9 +2602,9 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location,
{ {
if (targetUniform->mShaderData[shaderType]) if (targetUniform->mShaderData[shaderType])
{ {
if (SetFloatUniformMatrixHLSL<cols, rows>(arrayElementOffset, elementCount, countIn, if (SetFloatUniformMatrixHLSL<cols, rows>::Run(arrayElementOffset, elementCount,
transpose, value, countIn, transpose, value,
targetUniform->mShaderData[shaderType])) targetUniform->mShaderData[shaderType]))
{ {
mShaderUniformsDirty.set(shaderType); mShaderUniformsDirty.set(shaderType);
} }
......
...@@ -267,19 +267,26 @@ class IncompleteTextureSet final : angle::NonCopyable ...@@ -267,19 +267,26 @@ class IncompleteTextureSet final : angle::NonCopyable
// Helpers to set a matrix uniform value based on GLSL or HLSL semantics. // Helpers to set a matrix uniform value based on GLSL or HLSL semantics.
// The return value indicate if the data was updated or not. // The return value indicate if the data was updated or not.
template <int cols, int rows> template <int cols, int rows>
bool SetFloatUniformMatrixGLSL(unsigned int arrayElementOffset, struct SetFloatUniformMatrixGLSL
unsigned int elementCount, {
GLsizei countIn, static bool Run(unsigned int arrayElementOffset,
GLboolean transpose, unsigned int elementCount,
const GLfloat *value, GLsizei countIn,
uint8_t *targetData); GLboolean transpose,
const GLfloat *value,
uint8_t *targetData);
};
template <int cols, int rows> template <int cols, int rows>
bool SetFloatUniformMatrixHLSL(unsigned int arrayElementOffset, struct SetFloatUniformMatrixHLSL
unsigned int elementCount, {
GLsizei countIn, static bool Run(unsigned int arrayElementOffset,
GLboolean transpose, unsigned int elementCount,
const GLfloat *value, GLsizei countIn,
uint8_t *targetData); GLboolean transpose,
const GLfloat *value,
uint8_t *targetData);
};
// Helper method to de-tranpose a matrix uniform for an API query. // Helper method to de-tranpose a matrix uniform for an API query.
void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose); void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose);
......
...@@ -783,7 +783,7 @@ void ProgramVk::setUniformMatrixfv(GLint location, ...@@ -783,7 +783,7 @@ void ProgramVk::setUniformMatrixfv(GLint location,
continue; continue;
} }
bool updated = SetFloatUniformMatrixGLSL<cols, rows>( bool updated = SetFloatUniformMatrixGLSL<cols, rows>::Run(
locationInfo.arrayIndex, linkedUniform.getArraySizeProduct(), count, transpose, value, locationInfo.arrayIndex, linkedUniform.getArraySizeProduct(), count, transpose, value,
uniformBlock.uniformData.data() + layoutInfo.offset); uniformBlock.uniformData.data() + layoutInfo.offset);
......
...@@ -684,6 +684,60 @@ class UniformTestES3 : public ANGLETest ...@@ -684,6 +684,60 @@ class UniformTestES3 : public ANGLETest
GLuint mProgram; GLuint mProgram;
}; };
// Test that we can get and set an array of matrices uniform.
TEST_P(UniformTestES3, MatrixArrayUniformStateQuery)
{
constexpr char kFragShader[] =
"#version 300 es\n"
"precision mediump float;\n"
"uniform mat3x4 uniMat3x4[5];\n"
"out vec4 fragColor;\n"
"void main() {\n"
" fragColor = vec4(uniMat3x4[0]);\n"
" fragColor += vec4(uniMat3x4[1]);\n"
" fragColor += vec4(uniMat3x4[2]);\n"
" fragColor += vec4(uniMat3x4[3]);\n"
" fragColor += vec4(uniMat3x4[4]);\n"
"}\n";
constexpr unsigned int kArrayCount = 5;
constexpr unsigned int kMatrixStride = 3 * 4;
mProgram = CompileProgram(essl3_shaders::vs::Zero(), kFragShader);
ASSERT_NE(mProgram, 0u);
glUseProgram(mProgram);
GLfloat expected[kArrayCount][kMatrixStride] = {
{0.6f, -0.4f, 0.6f, 0.9f, -0.6f, 0.3f, -0.3f, -0.1f, -0.4f, -0.3f, 0.7f, 0.1f},
{-0.4f, -0.4f, -0.5f, -0.7f, 0.1f, -0.5f, 0.0f, -0.9f, -0.4f, 0.8f, -0.6f, 0.9f},
{0.4f, 0.1f, -0.9f, 1.0f, -0.8f, 0.4f, -0.2f, 0.4f, -0.0f, 0.2f, 0.9f, -0.3f},
{0.5f, 0.7f, -0.0f, 1.0f, 0.7f, 0.7f, 0.7f, -0.7f, -0.8f, 0.6f, 0.5f, -0.2f},
{-1.0f, 0.8f, 1.0f, -0.4f, 0.7f, 0.5f, 0.5f, 0.8f, 0.6f, 0.1f, 0.4f, -0.9f}};
GLint baseLocation = glGetUniformLocation(mProgram, "uniMat3x4");
ASSERT_NE(-1, baseLocation);
glUniformMatrix3x4fv(baseLocation, kArrayCount, GL_FALSE, &expected[0][0]);
for (size_t i = 0; i < kArrayCount; i++)
{
std::stringstream nameStr;
nameStr << "uniMat3x4[" << i << "]";
std::string name = nameStr.str();
GLint location = glGetUniformLocation(mProgram, name.c_str());
ASSERT_GL_NO_ERROR();
ASSERT_NE(-1, location);
std::vector<GLfloat> results(12, 0);
glGetUniformfv(mProgram, location, results.data());
ASSERT_GL_NO_ERROR();
for (size_t compIdx = 0; compIdx < kMatrixStride; compIdx++)
{
EXPECT_EQ(results[compIdx], expected[i][compIdx]);
}
}
}
// Test queries for transposed arrays of non-square matrix uniforms. // Test queries for transposed arrays of non-square matrix uniforms.
TEST_P(UniformTestES3, TransposedMatrixArrayUniformStateQuery) TEST_P(UniformTestES3, TransposedMatrixArrayUniformStateQuery)
{ {
......
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