Commit 7cec3353 by Luc Ferron Committed by Commit Bot

Vulkan: Get/SetUniform for float / int and vec*

Bug:angleproject:2392 Change-Id: I2110ecde653a85a28b515dc9d8473a1b37a73eb6 Reviewed-on: https://chromium-review.googlesource.com/962718Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Luc Ferron <lucferron@chromium.org>
parent de51bf0a
......@@ -61,6 +61,21 @@ void StaticallyUsed::unionReferencesWith(const StaticallyUsed &other)
geometryStaticUse |= other.geometryStaticUse;
}
ShaderType StaticallyUsed::getFirstStaticUseShaderType() const
{
if (vertexStaticUse)
return SHADER_VERTEX;
if (fragmentStaticUse)
return SHADER_FRAGMENT;
if (computeStaticUse)
return SHADER_COMPUTE;
if (geometryStaticUse)
return SHADER_GEOMETRY;
UNREACHABLE();
return SHADER_TYPE_INVALID;
}
LinkedUniform::LinkedUniform()
: typeInfo(nullptr), bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
{
......
......@@ -28,6 +28,7 @@ struct StaticallyUsed
StaticallyUsed &operator=(const StaticallyUsed &rhs);
ShaderType getFirstStaticUseShaderType() const;
void setStaticUse(GLenum shaderType, bool used);
void unionReferencesWith(const StaticallyUsed &other);
......
......@@ -48,7 +48,8 @@ enum ShaderType
SHADER_FRAGMENT,
SHADER_GEOMETRY,
SHADER_COMPUTE,
SHADER_TYPE_MAX
SHADER_TYPE_MAX,
SHADER_TYPE_INVALID = SHADER_TYPE_MAX
};
struct Rectangle
......
......@@ -99,6 +99,26 @@ void UpdateDefaultUniformBlock(GLsizei count,
}
}
template <typename T>
void ReadFromDefaultUniformBlock(int componentCount,
T *dst,
const sh::BlockMemberInfo &layoutInfo,
const angle::MemoryBuffer *uniformData)
{
ASSERT(layoutInfo.offset != -1);
int elementSize = sizeof(T) * componentCount;
if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
{
const uint8_t *readPtr = uniformData->data() + layoutInfo.offset;
memcpy(dst, readPtr, elementSize);
}
else
{
UNIMPLEMENTED();
}
}
vk::Error SyncDefaultUniformBlock(VkDevice device,
vk::DeviceMemory *bufferMemory,
const angle::MemoryBuffer &bufferData)
......@@ -405,6 +425,12 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum
const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
if (linkedUniform.isSampler())
{
UNIMPLEMENTED();
return;
}
if (linkedUniform.type == entryPointType)
{
for (auto &uniformBlock : mDefaultUniformBlocks)
......@@ -421,6 +447,28 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum
}
}
template <typename T>
void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) const
{
const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
if (linkedUniform.isSampler())
{
UNIMPLEMENTED();
return;
}
ASSERT(linkedUniform.typeInfo->componentType == entryPointType);
const gl::ShaderType shaderType = linkedUniform.getFirstStaticUseShaderType();
ASSERT(shaderType != gl::ShaderType::SHADER_TYPE_INVALID);
const DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, v, layoutInfo,
&uniformBlock.uniformData);
}
void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
{
setUniformImpl(location, count, v, GL_FLOAT);
......@@ -443,7 +491,7 @@ void ProgramVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
void ProgramVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{
UNIMPLEMENTED();
setUniformImpl(location, count, v, GL_INT);
}
void ProgramVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
......@@ -617,12 +665,12 @@ vk::Error ProgramVk::initDescriptorSets(ContextVk *contextVk)
void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
{
UNIMPLEMENTED();
getUniformImpl(location, params, GL_FLOAT);
}
void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
{
UNIMPLEMENTED();
getUniformImpl(location, params, GL_INT);
}
void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
......
......@@ -125,6 +125,9 @@ class ProgramVk : public ProgramImpl
gl::Error initDefaultUniformBlocks(const gl::Context *glContext);
vk::Error updateDefaultUniformsDescriptorSet(ContextVk *contextVk);
template <class T>
void getUniformImpl(GLint location, T *v, GLenum entryPointType) const;
template <typename T>
void setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType);
......
......@@ -14,6 +14,142 @@ using namespace angle;
namespace
{
constexpr char kBasicVertexShader[] = R"(void main()
{
gl_Position = vec4(1);
})";
class SimpleUniformTest : public ANGLETest
{
protected:
SimpleUniformTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
};
// Test that we can get and set a float uniform successfully.
TEST_P(SimpleUniformTest, FloatUniformStateQuery)
{
constexpr char kFragShader[] = R"(precision mediump float;
uniform float uniF;
void main() {
gl_FragColor = vec4(uniF, 0.0, 0.0, 0.0);
})";
ANGLE_GL_PROGRAM(program, kBasicVertexShader, kFragShader);
glUseProgram(program);
GLint uniformLocation = glGetUniformLocation(program, "uniF");
ASSERT_NE(uniformLocation, -1);
GLfloat expected = 1.02f;
glUniform1f(uniformLocation, expected);
GLfloat f = 0.0f;
glGetUniformfv(program, uniformLocation, &f);
ASSERT_GL_NO_ERROR();
ASSERT_EQ(f, expected);
}
// Test that we can get and set an int uniform successfully.
TEST_P(SimpleUniformTest, IntUniformStateQuery)
{
constexpr char kFragShader[] = R"(uniform int uniI;
void main() {
gl_FragColor = vec4(uniI, 0.0, 0.0, 0.0);
})";
ANGLE_GL_PROGRAM(program, kBasicVertexShader, kFragShader);
glUseProgram(program);
GLint uniformLocation = glGetUniformLocation(program, "uniI");
ASSERT_NE(uniformLocation, -1);
GLint expected = 4;
glUniform1i(uniformLocation, expected);
GLint i = 0;
glGetUniformiv(program, uniformLocation, &i);
ASSERT_GL_NO_ERROR();
ASSERT_EQ(i, expected);
}
// Test that we can get and set a vec2 uniform successfully.
TEST_P(SimpleUniformTest, FloatVec2UniformStateQuery)
{
constexpr char kFragShader[] = R"(precision mediump float;
uniform vec2 uniVec2;
void main() {
gl_FragColor = vec4(uniVec2, 0.0, 0.0);
})";
ANGLE_GL_PROGRAM(program, kBasicVertexShader, kFragShader);
glUseProgram(program);
GLint uniformLocation = glGetUniformLocation(program, "uniVec2");
ASSERT_NE(uniformLocation, -1);
std::vector<GLfloat> expected = {{1.0f, 0.5f}};
glUniform2fv(uniformLocation, 1, expected.data());
std::vector<GLfloat> floats(2, 0);
glGetUniformfv(program, uniformLocation, floats.data());
ASSERT_GL_NO_ERROR();
ASSERT_EQ(floats, expected);
}
// Test that we can get and set a vec3 uniform successfully.
TEST_P(SimpleUniformTest, FloatVec3UniformStateQuery)
{
constexpr char kFragShader[] = R"(precision mediump float;
uniform vec3 uniVec3;
void main() {
gl_FragColor = vec4(uniVec3, 0.0);
})";
ANGLE_GL_PROGRAM(program, kBasicVertexShader, kFragShader);
glUseProgram(program);
GLint uniformLocation = glGetUniformLocation(program, "uniVec3");
ASSERT_NE(uniformLocation, -1);
std::vector<GLfloat> expected = {{1.0f, 0.5f, 0.2f}};
glUniform3fv(uniformLocation, 1, expected.data());
std::vector<GLfloat> floats(3, 0);
glGetUniformfv(program, uniformLocation, floats.data());
ASSERT_GL_NO_ERROR();
ASSERT_EQ(floats, expected);
}
// Test that we can get and set a vec4 uniform successfully.
TEST_P(SimpleUniformTest, FloatVec4UniformStateQuery)
{
constexpr char kFragShader[] = R"(precision mediump float;
uniform vec4 uniVec4;
void main() {
gl_FragColor = uniVec4;
})";
ANGLE_GL_PROGRAM(program, kBasicVertexShader, kFragShader);
glUseProgram(program);
GLint uniformLocation = glGetUniformLocation(program, "uniVec4");
ASSERT_NE(uniformLocation, -1);
std::vector<GLfloat> expected = {{1.0f, 0.5f, 0.2f, -0.8f}};
glUniform4fv(uniformLocation, 1, expected.data());
std::vector<GLfloat> floats(4, 0);
glGetUniformfv(program, uniformLocation, floats.data());
ASSERT_GL_NO_ERROR();
ASSERT_EQ(floats, expected);
}
class UniformTest : public ANGLETest
{
......@@ -964,6 +1100,16 @@ TEST_P(UniformTest, UniformWithReservedOpenGLName)
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(SimpleUniformTest,
ES2_D3D9(),
ES2_D3D11(),
ES2_D3D11_FL9_3(),
ES2_OPENGL(),
ES3_D3D11(),
ES3_OPENGL(),
ES3_OPENGLES(),
ES2_OPENGLES(),
ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(UniformTest,
ES2_D3D9(),
ES2_D3D11(),
......
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