Commit 8e9d2340 by Jamie Madill Committed by Commit Bot

Vulkan: Fix FragCoord scaling when a viewport is applied.

We were using the pivot based on the viewport dimensions which is only valid if the viewport is the size of the framebuffer. The more correct pivot size is actually based on the Framebuffer height. Also updates the driver uniforms block to be a bit simpler. Bug: angleproject:2598 Change-Id: I1cb500cded7141d10e8db6862b6ed29758cc7fb4 Reviewed-on: https://chromium-review.googlesource.com/1214205 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent 480edb8c
......@@ -1091,6 +1091,8 @@ angle::Result ContextVk::handleDirtyDriverUniforms(const gl::Context *context,
mDriverUniformsBuffer.releaseRetainedBuffers(mRenderer);
const gl::Rectangle &glViewport = mState.getState().getViewport();
float halfRenderAreaHeight =
static_cast<float>(mDrawFramebuffer->getState().getDimensions().height) * 0.5f;
// Allocate a new region in the dynamic buffer.
uint8_t *ptr = nullptr;
......@@ -1110,7 +1112,10 @@ angle::Result ContextVk::handleDirtyDriverUniforms(const gl::Context *context,
*driverUniforms = {
{static_cast<float>(glViewport.x), static_cast<float>(glViewport.y),
static_cast<float>(glViewport.width), static_cast<float>(glViewport.height)},
{1.0f, -scaleY, 1.0f, scaleY},
halfRenderAreaHeight,
scaleY,
-scaleY,
0.0f,
{depthRangeNear, depthRangeFar, depthRangeDiff, 0.0f}};
ANGLE_TRY(mDriverUniformsBuffer.flush(this));
......
......@@ -284,11 +284,16 @@ class ContextVk : public ContextImpl, public vk::Context
struct DriverUniforms
{
std::array<float, 4> viewport;
std::array<float, 4> viewportScaleFactor;
float halfRenderAreaHeight;
float viewportYScale;
float invViewportYScale;
float padding;
// We'll use x, y, z for near / far / diff respectively.
std::array<float, 4> depthRange;
};
vk::DynamicBuffer mDriverUniformsBuffer;
VkDescriptorSet mDriverUniformsDescriptorSet;
vk::BindingPointer<vk::DescriptorSetLayout> mDriverUniformsSetLayout;
......
......@@ -4836,6 +4836,26 @@ void main()
EXPECT_EQ(userFBOData, backbufferData);
}
bool SubrectEquals(const std::vector<GLColor> &bigArray,
const std::vector<GLColor> &smallArray,
int bigSize,
int offset,
int smallSize)
{
int badPixels = 0;
for (int y = 0; y < smallSize; y++)
{
for (int x = 0; x < smallSize; x++)
{
int bigOffset = (y + offset) * bigSize + x + offset;
int smallOffset = y * smallSize + x;
if (bigArray[bigOffset] != smallArray[smallOffset])
badPixels++;
}
}
return badPixels == 0;
}
// Tests that FragCoord behaves the same betweeen a user FBO and the back buffer.
TEST_P(GLSLTest, FragCoordConsistency)
{
......@@ -4881,7 +4901,38 @@ void main()
ASSERT_GL_NO_ERROR();
ASSERT_EQ(userFBOData.size(), backbufferData.size());
EXPECT_EQ(userFBOData, backbufferData);
EXPECT_EQ(userFBOData, backbufferData)
<< "FragCoord should be the same to default and user FBO";
// Repeat the same test but with a smaller viewport.
ASSERT_EQ(getWindowHeight(), getWindowWidth());
const int kQuarterSize = getWindowWidth() >> 2;
glViewport(kQuarterSize, kQuarterSize, kQuarterSize * 2, kQuarterSize * 2);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
std::vector<GLColor> userFBOViewportData(kQuarterSize * kQuarterSize * 4);
glReadPixels(kQuarterSize, kQuarterSize, kQuarterSize * 2, kQuarterSize * 2, GL_RGBA,
GL_UNSIGNED_BYTE, userFBOViewportData.data());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
std::vector<GLColor> defaultFBOViewportData(kQuarterSize * kQuarterSize * 4);
glReadPixels(kQuarterSize, kQuarterSize, kQuarterSize * 2, kQuarterSize * 2, GL_RGBA,
GL_UNSIGNED_BYTE, defaultFBOViewportData.data());
ASSERT_GL_NO_ERROR();
EXPECT_EQ(userFBOViewportData, defaultFBOViewportData)
<< "FragCoord should be the same to default and user FBO even with a custom viewport";
// Check that the subrectangles are the same between the viewport and non-viewport modes.
EXPECT_TRUE(SubrectEquals(userFBOData, userFBOViewportData, getWindowWidth(), kQuarterSize,
kQuarterSize * 2));
EXPECT_TRUE(SubrectEquals(backbufferData, defaultFBOViewportData, getWindowWidth(),
kQuarterSize, kQuarterSize * 2));
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
......
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