Commit 713e4db7 by Jamie Madill

D3D11: Fix RGBA32_UNORM integer vertex attribs.

This formats were mistakenly listed as having no conversion necessary in the vertex formats table. Fix is to mark them as CPU-converted. This bug would only occur for 'direct' storage attributes, not those that were dynamically streamed. BUG=angleproject:1331 Change-Id: Ifa51b47d75e2f5bc762a718587470950cf195cb4 Reviewed-on: https://chromium-review.googlesource.com/329999 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent bdec2f4e
...@@ -998,12 +998,14 @@ const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D ...@@ -998,12 +998,14 @@ const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D
// GL_UNSIGNED_INT -- normalized // GL_UNSIGNED_INT -- normalized
case gl::VERTEX_FORMAT_UINT1_NORM: case gl::VERTEX_FORMAT_UINT1_NORM:
{ {
static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLuint, 1, 1, true>); static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT,
&CopyTo32FVertexData<GLuint, 1, 1, true>);
return info; return info;
} }
case gl::VERTEX_FORMAT_UINT2_NORM: case gl::VERTEX_FORMAT_UINT2_NORM:
{ {
static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLuint, 2, 2, true>); static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
&CopyTo32FVertexData<GLuint, 2, 2, true>);
return info; return info;
} }
case gl::VERTEX_FORMAT_UINT3_NORM: case gl::VERTEX_FORMAT_UINT3_NORM:
...@@ -1013,7 +1015,8 @@ const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D ...@@ -1013,7 +1015,8 @@ const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D
} }
case gl::VERTEX_FORMAT_UINT4_NORM: case gl::VERTEX_FORMAT_UINT4_NORM:
{ {
static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLuint, 4, 4, true>); static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
&CopyTo32FVertexData<GLuint, 4, 4, true>);
return info; return info;
} }
......
...@@ -11,10 +11,30 @@ using namespace angle; ...@@ -11,10 +11,30 @@ using namespace angle;
namespace namespace
{ {
GLsizei TypeStride(GLenum attribType)
{
switch (attribType)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
return 1;
case GL_UNSIGNED_SHORT:
case GL_SHORT:
return 2;
case GL_UNSIGNED_INT:
case GL_INT:
case GL_FLOAT:
return 4;
default:
UNREACHABLE();
return 0;
}
}
class VertexAttributeTest : public ANGLETest class VertexAttributeTest : public ANGLETest
{ {
protected: protected:
VertexAttributeTest() VertexAttributeTest() : mProgram(0), mTestAttrib(-1), mExpectedAttrib(-1), mBuffer(0)
{ {
setWindowWidth(128); setWindowWidth(128);
setWindowHeight(128); setWindowHeight(128);
...@@ -23,22 +43,25 @@ class VertexAttributeTest : public ANGLETest ...@@ -23,22 +43,25 @@ class VertexAttributeTest : public ANGLETest
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
setConfigDepthBits(24); setConfigDepthBits(24);
mProgram = 0;
mTestAttrib = -1;
mExpectedAttrib = -1;
} }
enum class Source
{
BUFFER,
IMMEDIATE,
};
struct TestData struct TestData
{ {
GLenum type; GLenum type;
GLboolean normalized; GLboolean normalized;
Source source;
const void *inputData; const void *inputData;
const GLfloat *expectedData; const GLfloat *expectedData;
}; };
void runTest(const TestData& test) void runTest(const TestData &test)
{ {
// TODO(geofflang): Figure out why this is broken on AMD OpenGL // TODO(geofflang): Figure out why this is broken on AMD OpenGL
if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
...@@ -55,9 +78,27 @@ class VertexAttributeTest : public ANGLETest ...@@ -55,9 +78,27 @@ class VertexAttributeTest : public ANGLETest
for (GLint i = 0; i < 4; i++) for (GLint i = 0; i < 4; i++)
{ {
glBindBuffer(GL_ARRAY_BUFFER, 0); GLint typeSize = i + 1;
glVertexAttribPointer(mTestAttrib, i + 1, test.type, test.normalized, 0, test.inputData);
glVertexAttribPointer(mExpectedAttrib, i + 1, GL_FLOAT, GL_FALSE, 0, test.expectedData); if (test.source == Source::BUFFER)
{
GLsizei dataSize = mVertexCount * TypeStride(test.type) * typeSize;
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
glBufferData(GL_ARRAY_BUFFER, dataSize, test.inputData, GL_STATIC_DRAW);
glVertexAttribPointer(mTestAttrib, typeSize, test.type, test.normalized, 0,
nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
else
{
ASSERT_EQ(Source::IMMEDIATE, test.source);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribPointer(mTestAttrib, typeSize, test.type, test.normalized, 0,
test.inputData);
}
glVertexAttribPointer(mExpectedAttrib, typeSize, GL_FLOAT, GL_FALSE, 0,
test.expectedData);
glEnableVertexAttribArray(mTestAttrib); glEnableVertexAttribArray(mTestAttrib);
glEnableVertexAttribArray(mExpectedAttrib); glEnableVertexAttribArray(mExpectedAttrib);
...@@ -91,7 +132,8 @@ class VertexAttributeTest : public ANGLETest ...@@ -91,7 +132,8 @@ class VertexAttributeTest : public ANGLETest
void main(void) void main(void)
{ {
gl_Position = position; gl_Position = position;
color = vec4(lessThan(abs(test - expected), vec4(1.0 / 64.0))); vec4 threshold = max(abs(expected) * 0.01, 1.0 / 64.0);
color = vec4(lessThanEqual(abs(test - expected), threshold));
} }
); );
...@@ -120,11 +162,14 @@ class VertexAttributeTest : public ANGLETest ...@@ -120,11 +162,14 @@ class VertexAttributeTest : public ANGLETest
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glGenBuffers(1, &mBuffer);
} }
void TearDown() override void TearDown() override
{ {
glDeleteProgram(mProgram); glDeleteProgram(mProgram);
glDeleteBuffers(1, &mBuffer);
ANGLETest::TearDown(); ANGLETest::TearDown();
} }
...@@ -179,6 +224,7 @@ class VertexAttributeTest : public ANGLETest ...@@ -179,6 +224,7 @@ class VertexAttributeTest : public ANGLETest
GLuint mProgram; GLuint mProgram;
GLint mTestAttrib; GLint mTestAttrib;
GLint mExpectedAttrib; GLint mExpectedAttrib;
GLuint mBuffer;
}; };
TEST_P(VertexAttributeTest, UnsignedByteUnnormalized) TEST_P(VertexAttributeTest, UnsignedByteUnnormalized)
...@@ -190,7 +236,7 @@ TEST_P(VertexAttributeTest, UnsignedByteUnnormalized) ...@@ -190,7 +236,7 @@ TEST_P(VertexAttributeTest, UnsignedByteUnnormalized)
expectedData[i] = inputData[i]; expectedData[i] = inputData[i];
} }
TestData data = { GL_UNSIGNED_BYTE, GL_FALSE, inputData, expectedData }; TestData data = {GL_UNSIGNED_BYTE, GL_FALSE, Source::IMMEDIATE, inputData, expectedData};
runTest(data); runTest(data);
} }
...@@ -203,7 +249,7 @@ TEST_P(VertexAttributeTest, UnsignedByteNormalized) ...@@ -203,7 +249,7 @@ TEST_P(VertexAttributeTest, UnsignedByteNormalized)
expectedData[i] = inputData[i] / 255.0f; expectedData[i] = inputData[i] / 255.0f;
} }
TestData data = { GL_UNSIGNED_BYTE, GL_TRUE, inputData, expectedData }; TestData data = {GL_UNSIGNED_BYTE, GL_TRUE, Source::IMMEDIATE, inputData, expectedData};
runTest(data); runTest(data);
} }
...@@ -216,7 +262,7 @@ TEST_P(VertexAttributeTest, ByteUnnormalized) ...@@ -216,7 +262,7 @@ TEST_P(VertexAttributeTest, ByteUnnormalized)
expectedData[i] = inputData[i]; expectedData[i] = inputData[i];
} }
TestData data = { GL_BYTE, GL_FALSE, inputData, expectedData }; TestData data = {GL_BYTE, GL_FALSE, Source::IMMEDIATE, inputData, expectedData};
runTest(data); runTest(data);
} }
...@@ -229,7 +275,7 @@ TEST_P(VertexAttributeTest, ByteNormalized) ...@@ -229,7 +275,7 @@ TEST_P(VertexAttributeTest, ByteNormalized)
expectedData[i] = ((2.0f * inputData[i]) + 1.0f) / 255.0f; expectedData[i] = ((2.0f * inputData[i]) + 1.0f) / 255.0f;
} }
TestData data = { GL_BYTE, GL_TRUE, inputData, expectedData }; TestData data = {GL_BYTE, GL_TRUE, Source::IMMEDIATE, inputData, expectedData};
runTest(data); runTest(data);
} }
...@@ -242,7 +288,7 @@ TEST_P(VertexAttributeTest, UnsignedShortUnnormalized) ...@@ -242,7 +288,7 @@ TEST_P(VertexAttributeTest, UnsignedShortUnnormalized)
expectedData[i] = inputData[i]; expectedData[i] = inputData[i];
} }
TestData data = { GL_UNSIGNED_SHORT, GL_FALSE, inputData, expectedData }; TestData data = {GL_UNSIGNED_SHORT, GL_FALSE, Source::IMMEDIATE, inputData, expectedData};
runTest(data); runTest(data);
} }
...@@ -255,7 +301,7 @@ TEST_P(VertexAttributeTest, UnsignedShortNormalized) ...@@ -255,7 +301,7 @@ TEST_P(VertexAttributeTest, UnsignedShortNormalized)
expectedData[i] = inputData[i] / 65535.0f; expectedData[i] = inputData[i] / 65535.0f;
} }
TestData data = { GL_UNSIGNED_SHORT, GL_TRUE, inputData, expectedData }; TestData data = {GL_UNSIGNED_SHORT, GL_TRUE, Source::IMMEDIATE, inputData, expectedData};
runTest(data); runTest(data);
} }
...@@ -268,7 +314,7 @@ TEST_P(VertexAttributeTest, ShortUnnormalized) ...@@ -268,7 +314,7 @@ TEST_P(VertexAttributeTest, ShortUnnormalized)
expectedData[i] = inputData[i]; expectedData[i] = inputData[i];
} }
TestData data = { GL_SHORT, GL_FALSE, inputData, expectedData }; TestData data = {GL_SHORT, GL_FALSE, Source::IMMEDIATE, inputData, expectedData};
runTest(data); runTest(data);
} }
...@@ -281,7 +327,75 @@ TEST_P(VertexAttributeTest, ShortNormalized) ...@@ -281,7 +327,75 @@ TEST_P(VertexAttributeTest, ShortNormalized)
expectedData[i] = ((2.0f * inputData[i]) + 1.0f) / 65535.0f; expectedData[i] = ((2.0f * inputData[i]) + 1.0f) / 65535.0f;
} }
TestData data = { GL_SHORT, GL_TRUE, inputData, expectedData }; TestData data = {GL_SHORT, GL_TRUE, Source::IMMEDIATE, inputData, expectedData};
runTest(data);
}
class VertexAttributeTestES3 : public VertexAttributeTest
{
protected:
VertexAttributeTestES3() {}
};
TEST_P(VertexAttributeTestES3, IntUnnormalized)
{
GLint lo = std::numeric_limits<GLint>::min();
GLint hi = std::numeric_limits<GLint>::max();
GLint inputData[mVertexCount] = {0, 1, 2, 3, -1, -2, -3, -4, -1, hi, hi - 1, lo, lo + 1};
GLfloat expectedData[mVertexCount];
for (size_t i = 0; i < mVertexCount; i++)
{
expectedData[i] = static_cast<GLfloat>(inputData[i]);
}
TestData data = {GL_INT, GL_FALSE, Source::BUFFER, inputData, expectedData};
runTest(data);
}
TEST_P(VertexAttributeTestES3, IntNormalized)
{
GLint lo = std::numeric_limits<GLint>::min();
GLint hi = std::numeric_limits<GLint>::max();
GLint inputData[mVertexCount] = {0, 1, 2, 3, -1, -2, -3, -4, -1, hi, hi - 1, lo, lo + 1};
GLfloat expectedData[mVertexCount];
for (size_t i = 0; i < mVertexCount; i++)
{
expectedData[i] = ((2.0f * inputData[i]) + 1.0f) / static_cast<GLfloat>(0xFFFFFFFFu);
}
TestData data = {GL_INT, GL_TRUE, Source::BUFFER, inputData, expectedData};
runTest(data);
}
TEST_P(VertexAttributeTestES3, UnsignedIntUnnormalized)
{
GLuint mid = std::numeric_limits<GLuint>::max() >> 1;
GLuint hi = std::numeric_limits<GLuint>::max();
GLuint inputData[mVertexCount] = {0, 1, 2, 3, 254, 255, 256,
mid - 1, mid, mid + 1, hi - 2, hi - 1, hi};
GLfloat expectedData[mVertexCount];
for (size_t i = 0; i < mVertexCount; i++)
{
expectedData[i] = static_cast<GLfloat>(inputData[i]);
}
TestData data = {GL_UNSIGNED_INT, GL_FALSE, Source::BUFFER, inputData, expectedData};
runTest(data);
}
TEST_P(VertexAttributeTestES3, UnsignedIntNormalized)
{
GLuint mid = std::numeric_limits<GLuint>::max() >> 1;
GLuint hi = std::numeric_limits<GLuint>::max();
GLuint inputData[mVertexCount] = {0, 1, 2, 3, 254, 255, 256,
mid - 1, mid, mid + 1, hi - 2, hi - 1, hi};
GLfloat expectedData[mVertexCount];
for (size_t i = 0; i < mVertexCount; i++)
{
expectedData[i] = static_cast<GLfloat>(inputData[i]) / static_cast<GLfloat>(hi);
}
TestData data = {GL_UNSIGNED_INT, GL_TRUE, Source::BUFFER, inputData, expectedData};
runTest(data); runTest(data);
} }
...@@ -367,4 +481,6 @@ ANGLE_INSTANTIATE_TEST(VertexAttributeTest, ...@@ -367,4 +481,6 @@ ANGLE_INSTANTIATE_TEST(VertexAttributeTest,
ES2_OPENGLES(), ES2_OPENGLES(),
ES3_OPENGLES()); ES3_OPENGLES());
} // namespace ANGLE_INSTANTIATE_TEST(VertexAttributeTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
} // anonymous namespace
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