зеркало из https://github.com/AvaloniaUI/angle.git
Vulkan: Support fetching from default FBO
If GL_EXT_shader_framebuffer_fetch is enabled, specify framebuffer attachments as having VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT. Add new test FramebufferFetchES31.DefaultFramebufferTest which exercises the behavior. Also limit exposure of either framebuffer fetch extension to be Android only due to swapchain images requiring INPUT_ATTACHMENT. Test: FramebufferFetchES31.DefaultFramebufferTest Bug: angleproject:6893 Change-Id: I227e36a9844e2301f0fe0602f4e4d905874b32e3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3389791 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Ian Elliott <ianelliott@google.com> Commit-Queue: Cody Northrop <cnorthrop@google.com>
This commit is contained in:
Родитель
ff5368cd21
Коммит
b536079817
|
@ -3020,14 +3020,14 @@ void RendererVk::initFeatures(DisplayVk *displayVk,
|
|||
// http://anglebug.com/6872
|
||||
// On ARM hardware, framebuffer-fetch-like behavior on Vulkan is already coherent, so we can
|
||||
// expose the coherent version of the GL extension despite unofficial Vulkan support.
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFramebufferFetch, isARM);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFramebufferFetch, IsAndroid() && isARM);
|
||||
|
||||
// Important games are not checking supported extensions properly, and are confusing the
|
||||
// GL_EXT_shader_framebuffer_fetch_non_coherent as the GL_EXT_shader_framebuffer_fetch
|
||||
// extension. Therefore, don't enable the extension on Arm and Qualcomm by default.
|
||||
// https://issuetracker.google.com/issues/186643966
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFramebufferFetchNonCoherent,
|
||||
!(isARM || isQualcomm));
|
||||
IsAndroid() && !(isARM || isQualcomm));
|
||||
|
||||
angle::PlatformMethods *platform = ANGLEPlatformCurrent();
|
||||
platform->overrideFeaturesVk(platform, &mFeatures);
|
||||
|
|
|
@ -126,14 +126,21 @@ angle::Result InitImageHelper(DisplayVk *displayVk,
|
|||
{
|
||||
const angle::Format &textureFormat = vkFormat.getActualRenderableImageFormat();
|
||||
bool isDepthOrStencilFormat = textureFormat.depthBits > 0 || textureFormat.stencilBits > 0;
|
||||
const VkImageUsageFlags usage = isDepthOrStencilFormat ? kSurfaceVkDepthStencilImageUsageFlags
|
||||
VkImageUsageFlags usage = isDepthOrStencilFormat ? kSurfaceVkDepthStencilImageUsageFlags
|
||||
: kSurfaceVkColorImageUsageFlags;
|
||||
|
||||
RendererVk *rendererVk = displayVk->getRenderer();
|
||||
// If shaders may be fetching from this, we need this image to be an input
|
||||
if (rendererVk->getFeatures().supportsShaderFramebufferFetch.enabled ||
|
||||
rendererVk->getFeatures().supportsShaderFramebufferFetchNonCoherent.enabled)
|
||||
{
|
||||
usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
|
||||
}
|
||||
|
||||
VkExtent3D extents = {std::max(static_cast<uint32_t>(width), 1u),
|
||||
std::max(static_cast<uint32_t>(height), 1u), 1u};
|
||||
|
||||
angle::FormatID renderableFormatId = vkFormat.getActualRenderableImageFormatID();
|
||||
RendererVk *rendererVk = displayVk->getRenderer();
|
||||
// For devices that don't support creating swapchain images with RGB8, emulate with RGBA8.
|
||||
if (rendererVk->getFeatures().overrideSurfaceFormatRGB8toRGBA8.enabled &&
|
||||
renderableFormatId == angle::FormatID::R8G8B8_UNORM)
|
||||
|
@ -1105,6 +1112,13 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
|
|||
// We need transfer src for reading back from the backbuffer.
|
||||
VkImageUsageFlags imageUsageFlags = kSurfaceVkColorImageUsageFlags;
|
||||
|
||||
// If shaders may be fetching from this, we need this image to be an input
|
||||
if (renderer->getFeatures().supportsShaderFramebufferFetch.enabled ||
|
||||
renderer->getFeatures().supportsShaderFramebufferFetchNonCoherent.enabled)
|
||||
{
|
||||
imageUsageFlags |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
|
||||
}
|
||||
|
||||
// We need storage image for compute writes (debug overlay output).
|
||||
if (kEnableOverlay)
|
||||
{
|
||||
|
|
|
@ -1612,6 +1612,59 @@ void main (void)
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
// Verify we can use inout with the default framebuffer
|
||||
// http://anglebug.com/6893
|
||||
TEST_P(FramebufferFetchES31, DefaultFramebufferTest)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
|
||||
|
||||
constexpr char kVS[] = R"(#version 300 es
|
||||
in highp vec4 a_position;
|
||||
|
||||
void main (void)
|
||||
{
|
||||
gl_Position = a_position;
|
||||
})";
|
||||
|
||||
constexpr char kFS[] = R"(#version 300 es
|
||||
#extension GL_EXT_shader_framebuffer_fetch : require
|
||||
layout(location = 0) inout highp vec4 o_color;
|
||||
|
||||
uniform highp vec4 u_color;
|
||||
void main (void)
|
||||
{
|
||||
o_color += u_color;
|
||||
})";
|
||||
|
||||
GLProgram program;
|
||||
program.makeRaster(kVS, kFS);
|
||||
glUseProgram(program);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Ensure that we're rendering to the default framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// Start with a clear buffer
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
GLint positionLocation = glGetAttribLocation(program, "a_position");
|
||||
GLint colorLocation = glGetUniformLocation(program, "u_color");
|
||||
|
||||
// Draw once with red
|
||||
glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
|
||||
render(positionLocation, GL_FALSE);
|
||||
EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Draw again with blue, adding it to the existing red, ending up with magenta
|
||||
glUniform4fv(colorLocation, 1, GLColor::blue.toNormalizedVector().data());
|
||||
render(positionLocation, GL_FALSE);
|
||||
EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferFetchES31);
|
||||
ANGLE_INSTANTIATE_TEST_ES31(FramebufferFetchES31);
|
||||
} // namespace angle
|
||||
|
|
Загрузка…
Ссылка в новой задаче