Commit 2371acad by Luc Ferron Committed by Commit Bot

Vulkan: Support for uniform arrays

- Enable dEQP tests for uniform arrays - Fix the shader translator to support arrays - Fix for finding the uniforms location - Support get/set of uniform array values Bug: angleproject:2416 Change-Id: I7d0e9c602840ffb915f8ea3ba5d832d03bd74985 Reviewed-on: https://chromium-review.googlesource.com/984599 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 4733585d
......@@ -85,7 +85,7 @@ class DeclareDefaultUniformsTraverser : public TIntermTraverser
{
const ImmutableString &name = symbol->variable().name();
ASSERT(!name.beginsWith("gl_"));
(*mSink) << HashName(name, mHashFunction, mNameMap);
(*mSink) << HashName(name, mHashFunction, mNameMap) << ArrayString(symbol->getType());
}
}
......
......@@ -58,40 +58,59 @@ gl::Error InitDefaultUniformBlock(const gl::Context *context,
template <typename T>
void UpdateDefaultUniformBlock(GLsizei count,
uint32_t arrayIndex,
int componentCount,
const T *v,
const sh::BlockMemberInfo &layoutInfo,
angle::MemoryBuffer *uniformData)
{
int elementSize = sizeof(T) * componentCount;
const int elementSize = sizeof(T) * componentCount;
uint8_t *dst = uniformData->data() + layoutInfo.offset;
if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
{
uint8_t *writePtr = uniformData->data() + layoutInfo.offset;
uint32_t arrayOffset = arrayIndex * layoutInfo.arrayStride;
uint8_t *writePtr = dst + arrayOffset;
memcpy(writePtr, v, elementSize * count);
}
else
{
UNIMPLEMENTED();
// Have to respect the arrayStride between each element of the array.
int maxIndex = arrayIndex + count;
for (int writeIndex = arrayIndex, readIndex = 0; writeIndex < maxIndex;
writeIndex++, readIndex++)
{
const int arrayOffset = writeIndex * layoutInfo.arrayStride;
uint8_t *writePtr = dst + arrayOffset;
const T *readPtr = v + readIndex;
memcpy(writePtr, readPtr, elementSize);
}
}
}
template <typename T>
void ReadFromDefaultUniformBlock(int componentCount,
uint32_t arrayIndex,
T *dst,
const sh::BlockMemberInfo &layoutInfo,
const angle::MemoryBuffer *uniformData)
{
ASSERT(layoutInfo.offset != -1);
int elementSize = sizeof(T) * componentCount;
const int elementSize = sizeof(T) * componentCount;
const uint8_t *source = uniformData->data() + layoutInfo.offset;
if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
{
const uint8_t *readPtr = uniformData->data() + layoutInfo.offset;
const uint8_t *readPtr = source + arrayIndex * layoutInfo.arrayStride;
memcpy(dst, readPtr, elementSize);
}
else
{
UNIMPLEMENTED();
// Have to respect the arrayStride between each element of the array.
const int arrayOffset = arrayIndex * layoutInfo.arrayStride;
const uint8_t *readPtr = source + arrayOffset;
memcpy(dst, readPtr, elementSize);
}
}
......@@ -314,7 +333,8 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
std::string uniformName = uniform.name;
if (uniform.isArray())
{
uniformName += ArrayString(location.arrayIndex);
// Gets the uniform name without the [0] at the end.
uniformName = gl::ParseResourceName(uniformName, nullptr);
}
bool found = false;
......@@ -429,7 +449,8 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum
continue;
}
UpdateDefaultUniformBlock(count, linkedUniform.typeInfo->componentCount, v, layoutInfo,
UpdateDefaultUniformBlock(count, locationInfo.arrayIndex,
linkedUniform.typeInfo->componentCount, v, layoutInfo,
&uniformBlock.uniformData);
uniformBlock.uniformsDirty = true;
......@@ -461,8 +482,8 @@ void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) cons
const DefaultUniformBlock &uniformBlock =
mDefaultUniformBlocks[static_cast<GLuint>(shaderType)];
const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, v, layoutInfo,
&uniformBlock.uniformData);
ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, locationInfo.arrayIndex, v,
layoutInfo, &uniformBlock.uniformData);
}
void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
......
......@@ -224,6 +224,64 @@ void main() {
ASSERT_EQ(floats, expected);
}
// Test that we can get and set a float array of uniforms.
TEST_P(SimpleUniformTest, FloatArrayUniformStateQuery)
{
constexpr char kFragShader[] = R"(
precision mediump float;
uniform float ufloats[4];
void main() {
gl_FragColor = vec4(ufloats[0], ufloats[1], ufloats[2], ufloats[3]);
})";
ANGLE_GL_PROGRAM(program, kBasicVertexShader, kFragShader);
glUseProgram(program);
std::vector<GLfloat> expected = {{0.1f, 0.2f, 0.3f, 0.4f}};
for (size_t i = 0; i < expected.size(); i++)
{
std::string locationName = "ufloats[" + std::to_string(i) + "]";
GLint uniformLocation = glGetUniformLocation(program, locationName.c_str());
glUniform1f(uniformLocation, expected[i]);
ASSERT_GL_NO_ERROR();
ASSERT_NE(uniformLocation, -1);
GLfloat result = 0;
glGetUniformfv(program, uniformLocation, &result);
ASSERT_GL_NO_ERROR();
ASSERT_EQ(result, expected[i]);
}
}
// Test that we can get and set an int array of uniforms.
TEST_P(SimpleUniformTest, FloatIntUniformStateQuery)
{
constexpr char kFragShader[] = R"(
precision mediump float;
uniform int uints[4];
void main() {
gl_FragColor = vec4(uints[0], uints[1], uints[2], uints[3]);
})";
ANGLE_GL_PROGRAM(program, kBasicVertexShader, kFragShader);
glUseProgram(program);
std::vector<GLint> expected = {{1, 2, 3, 4}};
for (size_t i = 0; i < expected.size(); i++)
{
std::string locationName = "uints[" + std::to_string(i) + "]";
GLint uniformLocation = glGetUniformLocation(program, locationName.c_str());
glUniform1i(uniformLocation, expected[i]);
ASSERT_GL_NO_ERROR();
ASSERT_NE(uniformLocation, -1);
GLint result = 0;
glGetUniformiv(program, uniformLocation, &result);
ASSERT_GL_NO_ERROR();
ASSERT_EQ(result, expected[i]);
}
}
class UniformTest : public ANGLETest
{
protected:
......
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