Commit cb5c0b01 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Drop RelaxedPrecision from aliased attributes

Take the following example: attribute mediump vec4 a; // location 0 attribute highp vec2 b; // location 0 f(b) This was previously translated to: attribute mediump vec4 a; // location 0 f(a.xy) That difference here is that b was previously highp, but a.xy is mediump. This change drops RelaxedPrecision from attributes so that they are all highp. Note that the temporary SPIR-V ids these attributes are loaded into still retain their RelaxedPrecision decoration (if any), and the precision of calculations in the shader is not increased by this change. Bug: angleproject:4249 Change-Id: Idca0fc667ad6e36ddf428b65ea03706272a9ed9c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2488131 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent de3a7180
...@@ -2678,7 +2678,22 @@ bool SpirvVertexAttributeAliasingTransformer::transformDecorate(const uint32_t * ...@@ -2678,7 +2678,22 @@ bool SpirvVertexAttributeAliasingTransformer::transformDecorate(const uint32_t *
} }
else else
{ {
// If id is not that of an aliasing attribute, there's nothing to do. // If id is not that of an active attribute, there's nothing to do.
const ShaderInterfaceVariableInfo *info = mVariableInfoById[id];
if (info == nullptr || info->attributeComponentCount == 0 ||
!info->activeStages[gl::ShaderType::Vertex])
{
return false;
}
// Always drop RelaxedPrecision from input attributes. The temporary variable the attribute
// is loaded into has RelaxedPrecision and will implicitly convert.
if (decoration == spv::DecorationRelaxedPrecision)
{
return true;
}
// If id is not that of an aliasing attribute, there's nothing else to do.
ASSERT(id < mIsAliasingAttributeById.size()); ASSERT(id < mIsAliasingAttributeById.size());
if (!mIsAliasingAttributeById[id]) if (!mIsAliasingAttributeById[id])
{ {
......
...@@ -3430,6 +3430,110 @@ void main() ...@@ -3430,6 +3430,110 @@ void main()
} }
} }
// Test that aliasing attribute locations work with differing precisions.
TEST_P(VertexAttributeTest, AliasingVectorAttribLocationsDifferingPrecisions)
{
swapBuffers();
// http://anglebug.com/5180
ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGL());
// http://anglebug.com/3466
ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
// http://anglebug.com/3467
ANGLE_SKIP_TEST_IF(IsD3D());
constexpr char kVS[] = R"(attribute vec4 position;
// aliasing attributes.
attribute mediump vec2 attr0v2;
attribute highp vec3 attr0v3;
const vec3 attr0Expected = vec3(0.125, 0.25, 0.375);
// aliasing attributes.
attribute highp vec2 attr1v2;
attribute mediump vec3 attr1v3;
const vec3 attr1Expected = vec3(0.5, 0.625, 0.75);
uniform float attr0Select;
uniform float attr1Select;
// Each channel controlled by success from each set of aliasing attributes (R and G used only). If
// a channel is 0, the attribute test has failed. Otherwise it will be 0.5 or 1.0.
varying mediump vec4 color;
void main()
{
gl_Position = position;
vec4 result = vec4(0, 0, 0, 1);
if (attr0Select < 0.5)
result.r = all(lessThan(abs(attr0v2 - attr0Expected.xy), vec2(0.01))) ? 0.5 : 0.0;
else
result.r = all(lessThan(abs(attr0v3 - attr0Expected), vec3(0.01))) ? 1.0 : 0.0;
if (attr1Select < 0.5)
result.g = all(lessThan(abs(attr1v2 - attr1Expected.xy), vec2(0.01))) ? 0.5 : 0.0;
else
result.g = all(lessThan(abs(attr1v3 - attr1Expected), vec3(0.01))) ? 1.0 : 0.0;
color = result;
})";
constexpr char kFS[] = R"(varying mediump vec4 color;
void main(void)
{
gl_FragColor = color;
})";
// Compile shaders.
GLuint program = CompileProgram(kVS, kFS);
ASSERT_NE(program, 0u);
// Setup bindings.
glBindAttribLocation(program, 0, "attr0v2");
glBindAttribLocation(program, 0, "attr0v3");
glBindAttribLocation(program, 1, "attr1v2");
glBindAttribLocation(program, 1, "attr1v3");
EXPECT_GL_NO_ERROR();
// Link program and get uniform locations.
glLinkProgram(program);
glUseProgram(program);
GLint attr0SelectLoc = glGetUniformLocation(program, "attr0Select");
GLint attr1SelectLoc = glGetUniformLocation(program, "attr1Select");
ASSERT_NE(-1, attr0SelectLoc);
ASSERT_NE(-1, attr1SelectLoc);
EXPECT_GL_NO_ERROR();
// Set values for attributes.
glVertexAttrib3f(0, 0.125f, 0.25f, 0.375f);
glVertexAttrib3f(1, 0.5f, 0.625f, 0.75f);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
EXPECT_GL_NO_ERROR();
// Go through different combination of attributes and make sure reading through every alias is
// correctly handled.
GLColor expected;
expected.B = 0;
expected.A = 255;
for (uint32_t attr0Select = 0; attr0Select < 2; ++attr0Select)
{
glUniform1f(attr0SelectLoc, attr0Select);
expected.R = attr0Select * 128 + 127;
for (uint32_t attr1Select = 0; attr1Select < 2; ++attr1Select)
{
glUniform1f(attr1SelectLoc, attr1Select);
expected.G = attr1Select * 128 + 127;
drawQuad(program, "position", 0.5f);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_NEAR(0, 0, expected, 1);
}
}
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
// D3D11 Feature Level 9_3 uses different D3D formats for vertex attribs compared to Feature Levels // D3D11 Feature Level 9_3 uses different D3D formats for vertex attribs compared to Feature Levels
......
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