Commit 95bfb3e5 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Fix resolve draw path

If the draw path is taken for resolve, the internal shader previously calculated (1+sum(sample.a))/sampleCount instead of sum(sample.a)/sampleCount. Additionally, due to a typo, the result was rounded. This change also fixes a number of off-by-one errors when calculating src/dst offsets in blit/resolve path. Tests are added to resolve from default to FBO and vice versa to exercise the draw path which was otherwise never invoked for color buffers. Bug: angleproject:4746 BUg: angleproject:4092 Change-Id: I4b9c181339b89af44b27d61d27a6b3d88cde2eea Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2288224 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com>
parent d98afb78
...@@ -6,25 +6,25 @@ ...@@ -6,25 +6,25 @@
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000001.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000001.inc":
"306459ff1f9226448f267aae177e38c0", "306459ff1f9226448f267aae177e38c0",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000002.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000002.inc":
"2d57b7813e495527dcb528d479ff315d", "698ed869e1dd9413769621ededb07126",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000003.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000003.inc":
"792521860c9ba04aa770bfc8b5697151", "46ff8d5be28b964024157928d36565cc",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000004.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000004.inc":
"ac50f9c433a003ad1ccbd03b8ea01a47", "ac50f9c433a003ad1ccbd03b8ea01a47",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000005.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000005.inc":
"12dd587152aa9b5bc7ebc4b6200c276c", "12dd587152aa9b5bc7ebc4b6200c276c",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000006.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000006.inc":
"2fa8d1a18f17067248d5c189b98eb080", "483e4ffd5174d36169c62b8c6bd1a9e6",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000007.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000007.inc":
"809d73acd3a6085d7fb413d48ae5556a", "b03bc8a94eb7ccf07583a4627c8754ea",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000008.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000008.inc":
"d9cac7374f77e92cc5eb46a0474702ea", "d9cac7374f77e92cc5eb46a0474702ea",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000009.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.00000009.inc":
"4cba3f62439146a3ade21d6b2d530c60", "4cba3f62439146a3ade21d6b2d530c60",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.0000000A.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.0000000A.inc":
"fdecc4f8a847effc81aa21a158868227", "f0f6058f8bb8a80766a0e685c4b7c1b2",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.0000000B.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.0000000B.inc":
"52af293e2f2e4bfbd773f5ad1dff468b", "da4a6c7a303eb3d38a4c1af01a6bdf27",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.0000000C.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.0000000C.inc":
"216bf108564f9760f8830d4489e7c603", "216bf108564f9760f8830d4489e7c603",
"src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.0000000D.inc": "src/libANGLE/renderer/vulkan/shaders/gen/BlitResolve.frag.0000000D.inc":
...@@ -210,7 +210,7 @@ ...@@ -210,7 +210,7 @@
"src/libANGLE/renderer/vulkan/shaders/gen/OverlayDraw.comp.00000001.inc": "src/libANGLE/renderer/vulkan/shaders/gen/OverlayDraw.comp.00000001.inc":
"0e2519fa1e1c57c85df370d2178fb155", "0e2519fa1e1c57c85df370d2178fb155",
"src/libANGLE/renderer/vulkan/shaders/src/BlitResolve.frag": "src/libANGLE/renderer/vulkan/shaders/src/BlitResolve.frag":
"e47ecdcabdecde4b71eb3f27af50e3ea", "0b16d3ad95d7dbc2ce7175462152e4f9",
"src/libANGLE/renderer/vulkan/shaders/src/BlitResolve.frag.json": "src/libANGLE/renderer/vulkan/shaders/src/BlitResolve.frag.json":
"353929c45304fe9c327b50a53c5f1918", "353929c45304fe9c327b50a53c5f1918",
"src/libANGLE/renderer/vulkan/shaders/src/BlitResolveStencilNoExport.comp": "src/libANGLE/renderer/vulkan/shaders/src/BlitResolveStencilNoExport.comp":
......
...@@ -898,6 +898,37 @@ angle::Result FramebufferVk::blit(const gl::Context *context, ...@@ -898,6 +898,37 @@ angle::Result FramebufferVk::blit(const gl::Context *context,
bool disableFlippingBlitWithCommand = bool disableFlippingBlitWithCommand =
contextVk->getRenderer()->getFeatures().disableFlippingBlitWithCommand.enabled; contextVk->getRenderer()->getFeatures().disableFlippingBlitWithCommand.enabled;
// When blitting, the source and destination areas are viewed like UVs. For example, a 64x64
// texture if flipped should have an offset of 64 in either X or Y which corresponds to U or V
// of 1. On the other hand, when resolving, the source and destination areas are used as
// fragment coordinates to fetch from. In that case, when flipped, the texture in the above
// example must have an offset of 63.
//
// Now that all flipping is done, adjust the offsets for resolve.
if (isResolve)
{
if (sourceArea.isReversedX())
{
ASSERT(sourceArea.x > 0);
--sourceArea.x;
}
if (sourceArea.isReversedY())
{
ASSERT(sourceArea.y > 0);
--sourceArea.y;
}
if (destArea.isReversedX())
{
ASSERT(destArea.x > 0);
--destArea.x;
}
if (destArea.isReversedY())
{
ASSERT(destArea.y > 0);
--destArea.y;
}
}
UtilsVk::BlitResolveParameters params; UtilsVk::BlitResolveParameters params;
params.srcOffset[0] = sourceArea.x; params.srcOffset[0] = sourceArea.x;
params.srcOffset[1] = sourceArea.y; params.srcOffset[1] = sourceArea.y;
......
...@@ -187,12 +187,12 @@ void main() ...@@ -187,12 +187,12 @@ void main()
#if IsBlitColor #if IsBlitColor
#if IsResolve #if IsResolve
ColorType colorValue = ColorType(0, 0, 0, 1); ColorType colorValue = ColorType(0, 0, 0, 0);
for (int i = 0; i < params.samples; ++i) for (int i = 0; i < params.samples; ++i)
{ {
colorValue += COLOR_TEXEL_FETCH(color, srcImageCoords, i); colorValue += COLOR_TEXEL_FETCH(color, srcImageCoords, i);
} }
#if IsFloat #if BlitColorFloat
colorValue *= params.invSamples; colorValue *= params.invSamples;
#else #else
colorValue = ColorType(round(colorValue * params.invSamples)); colorValue = ColorType(round(colorValue * params.invSamples));
......
...@@ -928,9 +928,6 @@ class FramebufferTest_ES31 : public ANGLETest ...@@ -928,9 +928,6 @@ class FramebufferTest_ES31 : public ANGLETest
// FRAMEBUFFER_DEFAULT_HEIGHT parameters is zero, the framebuffer is incomplete. // FRAMEBUFFER_DEFAULT_HEIGHT parameters is zero, the framebuffer is incomplete.
TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam) TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam)
{ {
// anglebug.com/3565
ANGLE_SKIP_TEST_IF(IsVulkan());
GLFramebuffer mFramebuffer; GLFramebuffer mFramebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get()); glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
...@@ -959,9 +956,6 @@ TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam) ...@@ -959,9 +956,6 @@ TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam)
// Test that the sample count of a mix of texture and renderbuffer should be same. // Test that the sample count of a mix of texture and renderbuffer should be same.
TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix) TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix)
{ {
// anglebug.com/3565
ANGLE_SKIP_TEST_IF(IsVulkan());
GLFramebuffer mFramebuffer; GLFramebuffer mFramebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get()); glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
...@@ -998,9 +992,6 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix) ...@@ -998,9 +992,6 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix)
// Test that the sample count of texture attachments should be same. // Test that the sample count of texture attachments should be same.
TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex) TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex)
{ {
// anglebug.com/3565
ANGLE_SKIP_TEST_IF(IsVulkan());
GLFramebuffer mFramebuffer; GLFramebuffer mFramebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get()); glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
...@@ -1035,9 +1026,6 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex) ...@@ -1035,9 +1026,6 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex)
// TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures. // TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix) TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix)
{ {
// anglebug.com/3565
ANGLE_SKIP_TEST_IF(IsVulkan());
GLFramebuffer mFramebuffer; GLFramebuffer mFramebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get()); glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
...@@ -1061,9 +1049,6 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix) ...@@ -1061,9 +1049,6 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix)
// Test that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures. // Test that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures.
TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex) TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
{ {
// anglebug.com/3565
ANGLE_SKIP_TEST_IF(IsVulkan());
GLFramebuffer mFramebuffer; GLFramebuffer mFramebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get()); glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
......
...@@ -125,6 +125,9 @@ class MultisampleTest : public ANGLETest ...@@ -125,6 +125,9 @@ class MultisampleTest : public ANGLETest
bool mMultisampledConfigExists = false; bool mMultisampledConfigExists = false;
}; };
class MultisampleTestES3 : public MultisampleTest
{};
// Test point rendering on a multisampled surface. GLES2 section 3.3.1. // Test point rendering on a multisampled surface. GLES2 section 3.3.1.
TEST_P(MultisampleTest, Point) TEST_P(MultisampleTest, Point)
{ {
...@@ -264,6 +267,44 @@ TEST_P(MultisampleTest, Triangle) ...@@ -264,6 +267,44 @@ TEST_P(MultisampleTest, Triangle)
} }
} }
// Test that resolve from multisample default framebuffer works.
TEST_P(MultisampleTestES3, ResolveToFBO)
{
ANGLE_SKIP_TEST_IF(!mMultisampledConfigExists);
GLTexture resolveTexture;
glBindTexture(GL_TEXTURE_2D, resolveTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWindowSize, kWindowSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLFramebuffer resolveFBO;
glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
// Clear the default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.25, 0.5, 0.75, 0.25);
glClear(GL_COLOR_BUFFER_BIT);
// Resolve into FBO
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glBlitFramebuffer(0, 0, kWindowSize, kWindowSize, 0, 0, kWindowSize, kWindowSize,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
ASSERT_GL_NO_ERROR();
const GLColor kResult = GLColor(63, 127, 191, 63);
glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
EXPECT_PIXEL_COLOR_NEAR(0, 0, kResult, 1);
EXPECT_PIXEL_COLOR_NEAR(kWindowSize - 1, 0, kResult, 1);
EXPECT_PIXEL_COLOR_NEAR(0, kWindowSize - 1, kResult, 1);
EXPECT_PIXEL_COLOR_NEAR(kWindowSize - 1, kWindowSize - 1, kResult, 1);
EXPECT_PIXEL_COLOR_NEAR(kWindowSize / 2, kWindowSize / 2, kResult, 1);
}
ANGLE_INSTANTIATE_TEST(MultisampleTest, ANGLE_INSTANTIATE_TEST(MultisampleTest,
WithNoFixture(ES2_D3D11()), WithNoFixture(ES2_D3D11()),
WithNoFixture(ES3_D3D11()), WithNoFixture(ES3_D3D11()),
...@@ -275,5 +316,15 @@ ANGLE_INSTANTIATE_TEST(MultisampleTest, ...@@ -275,5 +316,15 @@ ANGLE_INSTANTIATE_TEST(MultisampleTest,
WithNoFixture(ES3_OPENGLES()), WithNoFixture(ES3_OPENGLES()),
WithNoFixture(ES31_OPENGLES()), WithNoFixture(ES31_OPENGLES()),
WithNoFixture(ES2_VULKAN()), WithNoFixture(ES2_VULKAN()),
WithNoFixture(ES3_VULKAN())); WithNoFixture(ES3_VULKAN()),
WithNoFixture(ES31_VULKAN()));
ANGLE_INSTANTIATE_TEST(MultisampleTestES3,
WithNoFixture(ES3_D3D11()),
WithNoFixture(ES31_D3D11()),
WithNoFixture(ES3_OPENGL()),
WithNoFixture(ES31_OPENGL()),
WithNoFixture(ES3_OPENGLES()),
WithNoFixture(ES31_OPENGLES()),
WithNoFixture(ES3_VULKAN()),
WithNoFixture(ES31_VULKAN()));
} // anonymous namespace } // anonymous namespace
...@@ -298,8 +298,6 @@ TEST_P(TextureMultisampleTest, MultisampleTargetGetInternalFormativBase) ...@@ -298,8 +298,6 @@ TEST_P(TextureMultisampleTest, MultisampleTargetGetInternalFormativBase)
TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D) TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D)
{ {
ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported()); ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
// http://anglebug.com/4092
ANGLE_SKIP_TEST_IF(IsVulkan());
GLint samples = 1; GLint samples = 1;
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 64, 64, GL_FALSE); texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 64, 64, GL_FALSE);
...@@ -314,8 +312,6 @@ TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D) ...@@ -314,8 +312,6 @@ TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D)
// Tests basic functionality of glTexStorage2DMultisample. // Tests basic functionality of glTexStorage2DMultisample.
TEST_P(TextureMultisampleTest, ValidateTextureStorageMultisampleParameters) TEST_P(TextureMultisampleTest, ValidateTextureStorageMultisampleParameters)
{ {
// http://anglebug.com/4092
ANGLE_SKIP_TEST_IF(IsVulkan());
ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported()); ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
...@@ -394,8 +390,6 @@ TEST_P(TextureMultisampleTest, MaxDepthTextureSamples) ...@@ -394,8 +390,6 @@ TEST_P(TextureMultisampleTest, MaxDepthTextureSamples)
TEST_P(TextureMultisampleTest, GetTexLevelParameter) TEST_P(TextureMultisampleTest, GetTexLevelParameter)
{ {
ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported()); ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
// http://anglebug.com/4092
ANGLE_SKIP_TEST_IF(IsVulkan());
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 1, 1, GL_TRUE); texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 1, 1, GL_TRUE);
...@@ -511,6 +505,44 @@ TEST_P(TextureMultisampleTest, SampleMaski) ...@@ -511,6 +505,44 @@ TEST_P(TextureMultisampleTest, SampleMaski)
ASSERT_GL_ERROR(GL_INVALID_VALUE); ASSERT_GL_ERROR(GL_INVALID_VALUE);
} }
TEST_P(TextureMultisampleTest, ResolveToDefaultFramebuffer)
{
ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, getWindowWidth(),
getWindowHeight(), GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
mTexture, 0);
ASSERT_GL_NO_ERROR();
// Clear the framebuffer
glClearColor(0.25, 0.5, 0.75, 0.25);
glClear(GL_COLOR_BUFFER_BIT);
// Resolve into default framebuffer
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
ASSERT_GL_NO_ERROR();
const GLColor kResult = GLColor(63, 127, 191, 63);
const int w = getWindowWidth() - 1;
const int h = getWindowHeight() - 1;
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
EXPECT_PIXEL_COLOR_NEAR(0, 0, kResult, 1);
EXPECT_PIXEL_COLOR_NEAR(w, 0, kResult, 1);
EXPECT_PIXEL_COLOR_NEAR(0, h, kResult, 1);
EXPECT_PIXEL_COLOR_NEAR(w, h, kResult, 1);
EXPECT_PIXEL_COLOR_NEAR(w / 2, h / 2, kResult, 1);
}
// Negative tests of multisample texture. When context less than ES 3.1 and ANGLE_texture_multsample // Negative tests of multisample texture. When context less than ES 3.1 and ANGLE_texture_multsample
// not enabled, the feature isn't supported. // not enabled, the feature isn't supported.
TEST_P(NegativeTextureMultisampleTest, Negtive) TEST_P(NegativeTextureMultisampleTest, Negtive)
......
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