Commit ed23dc84 by Le Hoang Quyen Committed by Commit Bot

Metal: default integer attribs & offset mod for idx conv.

- Support default integer attributes. - When converting index buffer, use offset modulo instead of offset to reduce number of conversions if application uses many different offsets to the index buffer. Bug: angleproject:2634 Change-Id: I97aa9ea1826ffc9dbe5784fe5b5af2f99df63e2c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2494524 Commit-Queue: Le Hoang Quyen <le.hoang.q@gmail.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 83539557
...@@ -503,8 +503,7 @@ class ContextMtl : public ContextImpl, public mtl::Context ...@@ -503,8 +503,7 @@ class ContextMtl : public ContextImpl, public mtl::Context
struct DefaultAttribute struct DefaultAttribute
{ {
// NOTE(hqle): Support integer default attributes in ES 3.0 uint8_t values[sizeof(float) * 4];
float values[4];
}; };
mtl::OcclusionQueryPool mOcclusionQueryPool; mtl::OcclusionQueryPool mOcclusionQueryPool;
......
...@@ -61,6 +61,10 @@ class VertexArrayMtl : public VertexArrayImpl ...@@ -61,6 +61,10 @@ class VertexArrayMtl : public VertexArrayImpl
private: private:
void reset(ContextMtl *context); void reset(ContextMtl *context);
void getVertexAttribFormatAndArraySize(const sh::ShaderVariable &var,
MTLVertexFormat *formatOut,
uint32_t *arraySizeOut);
angle::Result syncDirtyAttrib(const gl::Context *glContext, angle::Result syncDirtyAttrib(const gl::Context *glContext,
const gl::VertexAttribute &attrib, const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
...@@ -105,6 +109,10 @@ class VertexArrayMtl : public VertexArrayImpl ...@@ -105,6 +109,10 @@ class VertexArrayMtl : public VertexArrayImpl
gl::AttribArray<GLuint> mCurrentArrayBufferStrides; gl::AttribArray<GLuint> mCurrentArrayBufferStrides;
gl::AttribArray<const mtl::VertexFormat *> mCurrentArrayBufferFormats; gl::AttribArray<const mtl::VertexFormat *> mCurrentArrayBufferFormats;
const mtl::VertexFormat &mDefaultFloatVertexFormat;
const mtl::VertexFormat &mDefaultIntVertexFormat;
const mtl::VertexFormat &mDefaultUIntVertexFormat;
mtl::BufferPool mDynamicVertexData; mtl::BufferPool mDynamicVertexData;
mtl::BufferPool mDynamicIndexData; mtl::BufferPool mDynamicIndexData;
......
...@@ -861,7 +861,13 @@ void Buffer::flush(ContextMtl *context, size_t offsetWritten, size_t sizeWritten ...@@ -861,7 +861,13 @@ void Buffer::flush(ContextMtl *context, size_t offsetWritten, size_t sizeWritten
{ {
if (get().storageMode == MTLStorageModeManaged) if (get().storageMode == MTLStorageModeManaged)
{ {
[get() didModifyRange:NSMakeRange(offsetWritten, sizeWritten)]; size_t startOffset = std::min(offsetWritten, size());
size_t endOffset = std::min(offsetWritten + sizeWritten, size());
size_t clampedSize = endOffset - startOffset;
if (clampedSize > 0)
{
[get() didModifyRange:NSMakeRange(startOffset, clampedSize)];
}
} }
} }
#endif #endif
......
...@@ -2856,6 +2856,108 @@ void main() ...@@ -2856,6 +2856,108 @@ void main()
checkPixels(); checkPixels();
} }
// Test that default integer attribute works correctly even if there is a gap in
// attribute locations.
TEST_P(VertexAttributeTestES3, DefaultIntAttribWithGap)
{
constexpr char kVertexShader[] = R"(#version 300 es
layout(location = 0) in vec2 position;
layout(location = 3) in int actualValue;
uniform int expectedValue;
out float result;
void main()
{
result = (actualValue == expectedValue) ? 1.0 : 0.0;
gl_Position = vec4(position, 0, 1);
})";
constexpr char kFragmentShader[] = R"(#version 300 es
in mediump float result;
layout(location = 0) out lowp vec4 out_color;
void main()
{
out_color = result > 0.0 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
})";
ANGLE_GL_PROGRAM(program, kVertexShader, kFragmentShader);
// Re-link the program to update the attribute locations
glLinkProgram(program);
ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
glUseProgram(program);
GLint uniLoc = glGetUniformLocation(program, "expectedValue");
ASSERT_NE(-1, uniLoc);
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
setupQuadVertexBuffer(0.5f, 1.0f);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
std::array<GLint, 4> testValues = {{1, 2, 3, 4}};
for (GLfloat testValue : testValues)
{
glUniform1i(uniLoc, testValue);
glVertexAttribI4i(3, testValue, 0, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
}
// Test that default unsigned integer attribute works correctly even if there is a gap in
// attribute locations.
TEST_P(VertexAttributeTestES3, DefaultUIntAttribWithGap)
{
constexpr char kVertexShader[] = R"(#version 300 es
layout(location = 0) in vec2 position;
layout(location = 3) in uint actualValue;
uniform uint expectedValue;
out float result;
void main()
{
result = (actualValue == expectedValue) ? 1.0 : 0.0;
gl_Position = vec4(position, 0, 1);
})";
constexpr char kFragmentShader[] = R"(#version 300 es
in mediump float result;
layout(location = 0) out lowp vec4 out_color;
void main()
{
out_color = result > 0.0 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
})";
ANGLE_GL_PROGRAM(program, kVertexShader, kFragmentShader);
// Re-link the program to update the attribute locations
glLinkProgram(program);
ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
glUseProgram(program);
GLint uniLoc = glGetUniformLocation(program, "expectedValue");
ASSERT_NE(-1, uniLoc);
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
setupQuadVertexBuffer(0.5f, 1.0f);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
std::array<GLuint, 4> testValues = {{1, 2, 3, 4}};
for (GLfloat testValue : testValues)
{
glUniform1ui(uniLoc, testValue);
glVertexAttribI4ui(3, testValue, 0, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
}
// Tests that large strides that read past the end of the buffer work correctly. // Tests that large strides that read past the end of the buffer work correctly.
// Requires ES 3.1 to query MAX_VERTEX_ATTRIB_STRIDE. // Requires ES 3.1 to query MAX_VERTEX_ATTRIB_STRIDE.
TEST_P(VertexAttributeTestES31, LargeStride) TEST_P(VertexAttributeTestES31, LargeStride)
...@@ -3455,7 +3557,7 @@ ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(VertexAttributeTest); ...@@ -3455,7 +3557,7 @@ ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(VertexAttributeTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(VertexAttributeOORTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(VertexAttributeOORTest);
ANGLE_INSTANTIATE_TEST_ES3(VertexAttributeTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(VertexAttributeTestES3, ES3_METAL());
ANGLE_INSTANTIATE_TEST_ES31(VertexAttributeTestES31); ANGLE_INSTANTIATE_TEST_ES31(VertexAttributeTestES31);
......
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