Commit 172e5d37 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Implement universal stencil resolve

This is done by resolving stencil into a temporary buffer and copying that into the stencil aspect of the resolved image. Bug: angleproject:3200 Change-Id: I29111b44db2cb093acc4544034fbe61178f055a1 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1635709 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent ab6a59b2
......@@ -359,6 +359,10 @@
"69e0611ce405ee7525af2a59fe3dce02",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ResolveDepthStencil.frag.00000005.inc":
"ba039e31d7c2259337f80ed6038aafd5",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ResolveStencilNoExport.comp.00000000.inc":
"46e731194edd3eca95a8aeade5fea543",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ResolveStencilNoExport.comp.00000001.inc":
"5f9bbc046387b04be58dbd71988abfc2",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/BufferUtils.comp":
"0c8c050841543da0d7faca2559212aa8",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ConvertVertex.comp":
......@@ -373,10 +377,12 @@
"8279b03e2a8b9a495167bf7fe2567716",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ResolveDepthStencil.frag":
"59a1e12ffdb34a4aacf92f96a4fe9c5a",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ResolveStencilNoExport.comp":
"645d157257fd8b5315ed56cc12bc94b9",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp":
"50608a69c5126b000ab57d3ea4f1ee18",
"0826fbfe8c7282b0c99739f75f32f3ed",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h":
"719c05d2beed281df2227626a44de35f",
"c2fe4b6694f433e53177ab9377e4f487",
"Vulkan internal shader programs:tools/glslang/glslang_validator.exe.sha1":
"9f1f0fc61116a657e065c40f9296e5ab",
"Vulkan internal shader programs:tools/glslang/glslang_validator.sha1":
......
......@@ -956,8 +956,26 @@ angle::Result FramebufferVk::resolve(ContextVk *contextVk,
&stencilView.get(), levelIndex, 1, layerIndex, 1));
}
ANGLE_TRY(utilsVk.depthStencilResolve(contextVk, this, depthStencilImage, &depthView.get(),
&stencilView.get(), params));
// If shader stencil export is not possible, defer stencil resolve to another pass.
bool hasShaderStencilExport =
contextVk->getRenderer()->getFeatures().supportsShaderStencilExport.enabled;
vk::ImageView noStencilView;
// Resolve depth. If shader stencil export is present, resolve stencil as well.
if (resolveDepthBuffer || (resolveStencilBuffer && hasShaderStencilExport))
{
ANGLE_TRY(utilsVk.depthStencilResolve(
contextVk, this, depthStencilImage, &depthView.get(),
hasShaderStencilExport ? &stencilView.get() : &noStencilView, params));
}
// If shader stencil export is not present, resolve stencil through a different path.
if (resolveStencilBuffer && !hasShaderStencilExport)
{
ANGLE_TRY(utilsVk.stencilResolveNoShaderExport(contextVk, this, depthStencilImage,
&stencilView.get(), params));
}
vk::ImageView depthViewObject = depthView.release();
vk::ImageView stencilViewObject = stencilView.release();
......
......@@ -138,6 +138,11 @@ class UtilsVk : angle::NonCopyable
const vk::ImageView *srcDepthView,
const vk::ImageView *srcStencilView,
const ResolveParameters &params);
angle::Result stencilResolveNoShaderExport(ContextVk *contextVk,
FramebufferVk *framebuffer,
vk::ImageHelper *src,
const vk::ImageView *srcStencilView,
const ResolveParameters &params);
angle::Result copyImage(ContextVk *contextVk,
vk::ImageHelper *dest,
......@@ -215,7 +220,7 @@ class UtilsVk : angle::NonCopyable
struct ResolveDepthStencilShaderParams
{
// Structure matching PushConstants in ResolvedDepthStencil.frag
// Structure matching PushConstants in ResolveDepthStencil.frag
int32_t srcExtent[2] = {};
int32_t srcOffset[2] = {};
int32_t destOffset[2] = {};
......@@ -224,6 +229,18 @@ class UtilsVk : angle::NonCopyable
uint32_t flipY = 0;
};
struct ResolveStencilNoExportShaderParams
{
// Structure matching PushConstants in ResolveStencilNoExport.comp
int32_t srcExtent[2] = {};
int32_t srcOffset[2] = {};
int32_t srcLayer = 0;
int32_t destPitch = 0;
int32_t destExtent[2] = {};
uint32_t flipX = 0;
uint32_t flipY = 0;
};
// Functions implemented by the class:
enum class Function
{
......@@ -234,13 +251,14 @@ class UtilsVk : angle::NonCopyable
ResolveDepthStencil = 3,
// Functions implemented in compute
ComputeStartIndex = 4, // Special value to separate draw and dispatch functions.
BufferClear = 4,
BufferCopy = 5,
ConvertVertexBuffer = 6,
InvalidEnum = 7,
EnumCount = 7,
ComputeStartIndex = 4, // Special value to separate draw and dispatch functions.
BufferClear = 4,
BufferCopy = 5,
ConvertVertexBuffer = 6,
ResolveStencilNoExport = 7,
InvalidEnum = 8,
EnumCount = 8,
};
// Common function that creates the pipeline for the specified function, binds it and prepares
......@@ -279,6 +297,7 @@ class UtilsVk : angle::NonCopyable
angle::Result ensureImageCopyResourcesInitialized(ContextVk *context);
angle::Result ensureResolveColorResourcesInitialized(ContextVk *context);
angle::Result ensureResolveDepthStencilResourcesInitialized(ContextVk *context);
angle::Result ensureResolveStencilNoExportResourcesInitialized(ContextVk *context);
angle::Result startRenderPass(ContextVk *contextVk,
vk::ImageHelper *image,
......@@ -311,6 +330,8 @@ class UtilsVk : angle::NonCopyable
vk::ShaderProgramHelper
mResolveDepthStencilPrograms[vk::InternalShader::ResolveDepthStencil_frag::kFlagsMask |
vk::InternalShader::ResolveDepthStencil_frag::kResolveMask];
vk::ShaderProgramHelper mResolveStencilNoExportPrograms
[vk::InternalShader::ResolveStencilNoExport_comp::kFlagsMask];
};
} // namespace rx
......
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ResolveStencilNoExport.comp: Resolve multisampled stencil images into a buffer. This is used
// where VK_EXT_shader_stencil_export is not available, to output the resolved stencil into a
// temporary buffer, which is then copied into the stencil aspect of the final image.
#version 450 core
#extension GL_EXT_samplerless_texture_functions : require
#define MAKE_SRC_RESOURCE(prefix, type) prefix ## type
#define STENCIL_SRC_RESOURCE(type) MAKE_SRC_RESOURCE(u, type)
#if SrcIsArray
#define SRC_RESOURCE_NAME texture2DMSArray
#else
#define SRC_RESOURCE_NAME texture2DMS
#endif
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout (set = 0, binding = 0) buffer dest
{
// Note: every invocation handles 4 stencil value and output one value here.
uint destData[];
};
layout(push_constant) uniform PushConstants {
// Robust access.
ivec2 srcExtent;
// Translation from source to destination coordinates.
ivec2 srcOffset;
int srcLayer;
// Output.
int destPitch;
ivec2 destExtent;
// Flip control.
bool flipX;
bool flipY;
} params;
layout(set = 0, binding = 1) uniform STENCIL_SRC_RESOURCE(SRC_RESOURCE_NAME) stencil;
void main()
{
ivec2 destSubImageCoords = ivec2(gl_GlobalInvocationID.x * 4, gl_GlobalInvocationID.y);
if (any(lessThanEqual(params.destExtent, destSubImageCoords)))
{
return;
}
ivec2 srcSubImageCoords = destSubImageCoords;
// If flipping, srcOffset would contain the opposite coordinates, so we can
// simply reverse the direction in which x/y grows.
if (params.flipX)
srcSubImageCoords.x = -srcSubImageCoords.x;
if (params.flipY)
srcSubImageCoords.y = -srcSubImageCoords.y;
ivec2 srcImageCoords = params.srcOffset + srcSubImageCoords;
int xDir = params.flipX ? -1 : 1;
uint outStencils = 0;
// Bounds check on Y:
if (srcImageCoords.y >= 0 && srcImageCoords.y < params.srcExtent.y)
{
for (int i = 0; i < 4; ++i)
{
// Bounds check on X:
uint stencilValue = 0;
if (srcImageCoords.x >= 0 && srcImageCoords.x < params.srcExtent.x)
{
// Note: always resolve using sample 0. GLES3 gives us freedom in choosing how to resolve
// depth/stencil images.
#if SrcIsArray
stencilValue = texelFetch(stencil, ivec3(srcImageCoords, params.srcLayer), 0).x;
#else
stencilValue = texelFetch(stencil, srcImageCoords, 0).x;
#endif
#if IsBigEndian
outStencils |= (stencilValue & 0xFF) << ((3 - i) * 8);
#else
outStencils |= (stencilValue & 0xFF) << (i * 8);
#endif
}
srcImageCoords.x += xDir;
}
}
destData[gl_GlobalInvocationID.y * params.destPitch + gl_GlobalInvocationID.x] = outStencils;
}
{
"Description": [
"Copyright 2019 The ANGLE Project Authors. All rights reserved.",
"Use of this source code is governed by a BSD-style license that can be",
"found in the LICENSE file.",
"",
"ResolveStencilNoExport.frag.comp: Build parameters for ResolveStencilNoExport.comp."
],
"Flags": [
"SrcIsArray"
]
}
......@@ -99,6 +99,8 @@ namespace
#include "libANGLE/renderer/vulkan/shaders/gen/ResolveDepthStencil.frag.00000003.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ResolveDepthStencil.frag.00000004.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ResolveDepthStencil.frag.00000005.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ResolveStencilNoExport.comp.00000000.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ResolveStencilNoExport.comp.00000001.inc"
// This is SPIR-V binary blob and the size.
struct ShaderBlob
......@@ -208,6 +210,10 @@ constexpr ShaderBlob kResolveDepthStencil_frag_shaders[] = {
{kResolveDepthStencil_frag_00000004, sizeof(kResolveDepthStencil_frag_00000004)},
{kResolveDepthStencil_frag_00000005, sizeof(kResolveDepthStencil_frag_00000005)},
};
constexpr ShaderBlob kResolveStencilNoExport_comp_shaders[] = {
{kResolveStencilNoExport_comp_00000000, sizeof(kResolveStencilNoExport_comp_00000000)},
{kResolveStencilNoExport_comp_00000001, sizeof(kResolveStencilNoExport_comp_00000001)},
};
angle::Result GetShader(Context *context,
RefCounted<ShaderAndSerial> *shaders,
......@@ -267,6 +273,10 @@ void ShaderLibrary::destroy(VkDevice device)
{
shader.get().destroy(device);
}
for (RefCounted<ShaderAndSerial> &shader : mResolveStencilNoExport_comp_shaders)
{
shader.get().destroy(device);
}
}
angle::Result ShaderLibrary::getBufferUtils_comp(Context *context,
......@@ -325,5 +335,14 @@ angle::Result ShaderLibrary::getResolveDepthStencil_frag(Context *context,
ArraySize(kResolveDepthStencil_frag_shaders), shaderFlags, shaderOut);
}
angle::Result ShaderLibrary::getResolveStencilNoExport_comp(Context *context,
uint32_t shaderFlags,
RefCounted<ShaderAndSerial> **shaderOut)
{
return GetShader(context, mResolveStencilNoExport_comp_shaders,
kResolveStencilNoExport_comp_shaders,
ArraySize(kResolveStencilNoExport_comp_shaders), shaderFlags, shaderOut);
}
} // namespace vk
} // namespace rx
......@@ -92,4 +92,6 @@ angle_vulkan_internal_shaders = [
"shaders/gen/ResolveDepthStencil.frag.00000003.inc",
"shaders/gen/ResolveDepthStencil.frag.00000004.inc",
"shaders/gen/ResolveDepthStencil.frag.00000005.inc",
"shaders/gen/ResolveStencilNoExport.comp.00000000.inc",
"shaders/gen/ResolveStencilNoExport.comp.00000001.inc",
]
......@@ -143,6 +143,15 @@ enum Resolve
};
} // namespace ResolveDepthStencil_frag
namespace ResolveStencilNoExport_comp
{
enum flags
{
kSrcIsArray = 0x00000001,
kFlagsMask = 0x00000001,
};
} // namespace ResolveStencilNoExport_comp
} // namespace InternalShader
class ShaderLibrary final : angle::NonCopyable
......@@ -174,6 +183,9 @@ class ShaderLibrary final : angle::NonCopyable
angle::Result getResolveDepthStencil_frag(Context *context,
uint32_t shaderFlags,
RefCounted<ShaderAndSerial> **shaderOut);
angle::Result getResolveStencilNoExport_comp(Context *context,
uint32_t shaderFlags,
RefCounted<ShaderAndSerial> **shaderOut);
private:
RefCounted<ShaderAndSerial>
......@@ -197,6 +209,8 @@ class ShaderLibrary final : angle::NonCopyable
RefCounted<ShaderAndSerial>
mResolveDepthStencil_frag_shaders[InternalShader::ResolveDepthStencil_frag::kFlagsMask |
InternalShader::ResolveDepthStencil_frag::kResolveMask];
RefCounted<ShaderAndSerial> mResolveStencilNoExport_comp_shaders
[InternalShader::ResolveStencilNoExport_comp::kFlagsMask];
};
} // namespace vk
} // namespace rx
......
......@@ -545,15 +545,6 @@
3189 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.* = SKIP
// Multisampling:
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.2_samples.depth32f_stencil8 = FAIL
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.2_samples.depth24_stencil8 = FAIL
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.2_samples.stencil_index8 = FAIL
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.4_samples.depth32f_stencil8 = FAIL
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.4_samples.depth24_stencil8 = FAIL
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.4_samples.stencil_index8 = FAIL
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.8_samples.depth32f_stencil8 = FAIL
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.8_samples.depth24_stencil8 = FAIL
3200 VULKAN : dEQP-GLES3.functional.fbo.msaa.8_samples.stencil_index8 = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.default_framebuffer.sample_coverage_invert = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.default_framebuffer.proportionality_sample_coverage = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.default_framebuffer.proportionality_sample_coverage_inverted = FAIL
......
......@@ -1287,10 +1287,6 @@ TEST_P(BlitFramebufferTest, MultisampleStencil)
// Incorrect rendering results seen on AMD Windows OpenGL. http://anglebug.com/2486
ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL() && IsWindows());
// TODO(syoussefi): Multisampled stencil resolve requires workaround where
// VK_EXT_shader_stencil_export is not supported. http://anglebug.com/3200
ANGLE_SKIP_TEST_IF(IsVulkan() && !IsAMD());
GLRenderbuffer renderbuf;
glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, 256, 256);
......
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