зеркало из https://github.com/AvaloniaUI/angle.git
Vulkan: Mask out Depth/Stencil RTs in feedback loops.
This should enable some cases of limited support for feedback loops with depth/stencil buffers. For example with Manhattan and the Vulkan back-end. Increases the number of RenderPasses in Manhattan slightly. This will regress performance slightly until we can work out a better solution that is also conformant with the spec. Bug: angleproject:4517 Change-Id: I2758e6b4c2a930474c09cdc0950f3b6c34541089 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2106670 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com>
This commit is contained in:
Родитель
68083e8996
Коммит
d03b15b2f9
|
@ -13,11 +13,11 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define ANGLE_FEATURE_CONDITION(set, feature, cond) \
|
||||
do \
|
||||
{ \
|
||||
set->feature.enabled = cond; \
|
||||
set->feature.condition = ANGLE_STRINGIFY(cond); \
|
||||
#define ANGLE_FEATURE_CONDITION(set, feature, cond) \
|
||||
do \
|
||||
{ \
|
||||
(set)->feature.enabled = cond; \
|
||||
(set)->feature.condition = ANGLE_STRINGIFY(cond); \
|
||||
} while (0)
|
||||
|
||||
namespace angle
|
||||
|
|
|
@ -268,6 +268,12 @@ struct FeaturesVk : FeatureSetBase
|
|||
Feature enablePrecisionQualifiers = {
|
||||
"enable_precision_qualifiers", FeatureCategory::VulkanFeatures,
|
||||
"Enable precision qualifiers in shaders", &members, "http://anglebug.com/3078"};
|
||||
|
||||
// Support Depth/Stencil rendering feedback loops by masking out the depth/stencil buffer.
|
||||
// Manhattan uses this feature in a few draw calls.
|
||||
Feature supportDepthStencilRenderingFeedbackLoops = {
|
||||
"support_depth_stencil_rendering_feedback_loops", FeatureCategory::VulkanFeatures,
|
||||
"Suport depth/stencil rendering feedback loops", &members, "http://anglebug.com/4490"};
|
||||
};
|
||||
|
||||
inline FeaturesVk::FeaturesVk() = default;
|
||||
|
|
|
@ -61,14 +61,9 @@ ANGLE_INLINE void MarkShaderStorageBufferUsage(const Context *context)
|
|||
// Return true if the draw is a no-op, else return false.
|
||||
// A no-op draw occurs if the count of vertices is less than the minimum required to
|
||||
// have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
|
||||
// We also no-op draws that have rendering feedback loops. This is spec:
|
||||
// "In this scenario, the framebuffer will be considered framebuffer complete
|
||||
// but the values of fragments rendered while in this state will be undefined."
|
||||
// From 3.2 spec: 9.3.1 Rendering Feedback Loops
|
||||
ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count)
|
||||
{
|
||||
return count < kMinimumPrimitiveCounts[mode] ||
|
||||
mState.mDrawFramebuffer->hasRenderingFeedbackLoop();
|
||||
return count < kMinimumPrimitiveCounts[mode];
|
||||
}
|
||||
|
||||
ANGLE_INLINE angle::Result Context::syncDirtyBits()
|
||||
|
|
|
@ -699,11 +699,13 @@ bool FramebufferState::updateAttachmentFeedbackLoopAndReturnIfChanged(size_t dir
|
|||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
ASSERT(dirtyBit <= Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
|
||||
previous = mDrawBufferFeedbackLoops.test(dirtyBit);
|
||||
loop = mColorAttachments[dirtyBit].isBoundAsSamplerOrImage();
|
||||
mDrawBufferFeedbackLoops[dirtyBit] = loop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updateHasRenderingFeedbackLoop();
|
||||
|
|
|
@ -114,7 +114,9 @@ FramebufferVk::FramebufferVk(RendererVk *renderer,
|
|||
: FramebufferImpl(state),
|
||||
mBackbuffer(backbuffer),
|
||||
mFramebuffer(nullptr),
|
||||
mActiveColorComponents(0)
|
||||
mActiveColorComponents(0),
|
||||
mSupportDepthStencilFeedbackLoops(
|
||||
renderer->getFeatures().supportDepthStencilRenderingFeedbackLoops.enabled)
|
||||
{
|
||||
mReadPixelBuffer.init(renderer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, kReadPixelsBufferAlignment,
|
||||
kMinReadPixelsBufferSize, true);
|
||||
|
@ -229,6 +231,36 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
|
|||
// The front-end should ensure we don't attempt to clear stencil if all bits are masked.
|
||||
ASSERT(!clearStencil || stencilMask != 0);
|
||||
|
||||
// Special case for rendering feedback loops: clears are always valid in GL since they don't
|
||||
// sample from any textures.
|
||||
if ((clearDepth || clearStencil) && mState.hasDepthStencilFeedbackLoop())
|
||||
{
|
||||
// We currently don't handle scissored clears with rendering feedback loops.
|
||||
ANGLE_VK_CHECK(contextVk, scissoredRenderArea == getCompleteRenderArea(),
|
||||
VK_ERROR_INCOMPATIBLE_DRIVER);
|
||||
|
||||
RenderTargetVk *depthStencilRT = mRenderTargetCache.getDepthStencil(true);
|
||||
vk::ImageHelper &image = depthStencilRT->getImage();
|
||||
|
||||
vk::CommandBuffer *commandBuffer;
|
||||
ANGLE_TRY(
|
||||
contextVk->onImageWrite(image.getAspectFlags(), vk::ImageLayout::TransferDst, &image));
|
||||
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
|
||||
|
||||
VkImageSubresourceRange range;
|
||||
range.aspectMask = image.getAspectFlags();
|
||||
range.baseMipLevel = depthStencilRT->getLevelIndex();
|
||||
range.levelCount = 1;
|
||||
range.baseArrayLayer = depthStencilRT->getLayerIndex();
|
||||
range.layerCount = 1;
|
||||
|
||||
commandBuffer->clearDepthStencilImage(image.getImage(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
clearDepthStencilValue, 1, &range);
|
||||
clearDepth = false;
|
||||
clearStencil = false;
|
||||
}
|
||||
|
||||
// If there is nothing to clear, return right away (for example, if asked to clear depth, but
|
||||
// there is no depth attachment).
|
||||
if (!clearColor && !clearDepth && !clearStencil)
|
||||
|
@ -447,7 +479,9 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context,
|
|||
|
||||
RenderTargetVk *FramebufferVk::getDepthStencilRenderTarget() const
|
||||
{
|
||||
return mRenderTargetCache.getDepthStencil(true);
|
||||
// If we mask out depth/stencil feedback loops, do not allow the user to access the looped DS
|
||||
// render target. Passing "false" to getDepthStencil forces a return of "nullptr" for loops.
|
||||
return mRenderTargetCache.getDepthStencil(!mSupportDepthStencilFeedbackLoops);
|
||||
}
|
||||
|
||||
RenderTargetVk *FramebufferVk::getColorDrawRenderTarget(size_t colorIndex) const
|
||||
|
@ -983,7 +1017,7 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
|
|||
|
||||
void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk)
|
||||
{
|
||||
RenderTargetVk *depthStencilRT = mRenderTargetCache.getDepthStencil(true);
|
||||
RenderTargetVk *depthStencilRT = getDepthStencilRenderTarget();
|
||||
|
||||
if (depthStencilRT != nullptr)
|
||||
{
|
||||
|
@ -1021,7 +1055,7 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
|
|||
case gl::Framebuffer::DIRTY_BIT_DEPTH_BUFFER_CONTENTS:
|
||||
case gl::Framebuffer::DIRTY_BIT_STENCIL_BUFFER_CONTENTS:
|
||||
{
|
||||
RenderTargetVk *depthStencilRT = mRenderTargetCache.getDepthStencil(true);
|
||||
RenderTargetVk *depthStencilRT = getDepthStencilRenderTarget();
|
||||
ASSERT(depthStencilRT != nullptr);
|
||||
ANGLE_TRY(depthStencilRT->flushStagedUpdates(contextVk));
|
||||
mCurrentFramebufferDesc.update(vk::kFramebufferDescDepthStencilIndex,
|
||||
|
@ -1141,7 +1175,7 @@ void FramebufferVk::updateRenderPassDesc()
|
|||
}
|
||||
}
|
||||
|
||||
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(true);
|
||||
RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
|
||||
if (depthStencilRenderTarget)
|
||||
{
|
||||
mRenderPassDesc.packDepthStencilAttachment(
|
||||
|
@ -1200,7 +1234,7 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
|
|||
attachmentsSize = colorRenderTarget->getExtents();
|
||||
}
|
||||
|
||||
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(true);
|
||||
RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
|
||||
if (depthStencilRenderTarget)
|
||||
{
|
||||
const vk::ImageView *imageView = nullptr;
|
||||
|
@ -1324,7 +1358,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
|
|||
attachmentClearValues.emplace_back(kUninitializedClearValue);
|
||||
}
|
||||
|
||||
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(true);
|
||||
RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
|
||||
if (depthStencilRenderTarget)
|
||||
{
|
||||
ANGLE_TRY(depthStencilRenderTarget->onDepthStencilDraw(contextVk));
|
||||
|
@ -1402,7 +1436,7 @@ RenderTargetVk *FramebufferVk::getFirstRenderTarget() const
|
|||
}
|
||||
}
|
||||
|
||||
return mRenderTargetCache.getDepthStencil(true);
|
||||
return getDepthStencilRenderTarget();
|
||||
}
|
||||
|
||||
GLint FramebufferVk::getSamples() const
|
||||
|
|
|
@ -186,6 +186,7 @@ class FramebufferVk : public FramebufferImpl
|
|||
|
||||
vk::FramebufferDesc mCurrentFramebufferDesc;
|
||||
std::unordered_map<vk::FramebufferDesc, vk::FramebufferHelper> mFramebufferCache;
|
||||
bool mSupportDepthStencilFeedbackLoops;
|
||||
};
|
||||
} // namespace rx
|
||||
|
||||
|
|
|
@ -767,7 +767,7 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk,
|
|||
if (ExtensionFound(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, instanceExtensionNames))
|
||||
{
|
||||
enabledInstanceExtensions.push_back(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), supportsSwapchainColorspace, true);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, supportsSwapchainColorspace, true);
|
||||
}
|
||||
|
||||
// Verify the required extensions are in the extension names set. Fail if not.
|
||||
|
@ -1543,35 +1543,35 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
|
|||
{
|
||||
ASSERT(mLineRasterizationFeatures.sType ==
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT);
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), bresenhamLineRasterization, true);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, bresenhamLineRasterization, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use OpenGL line rasterization rules if extension not available by default.
|
||||
// TODO(jmadill): Fix Android support. http://anglebug.com/2830
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), basicGLLineRasterization, !IsAndroid());
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, basicGLLineRasterization, !IsAndroid());
|
||||
}
|
||||
|
||||
if (mProvokingVertexFeatures.provokingVertexLast == VK_TRUE)
|
||||
{
|
||||
ASSERT(mProvokingVertexFeatures.sType ==
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT);
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), provokingVertex, true);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, provokingVertex, true);
|
||||
}
|
||||
|
||||
// TODO(lucferron): Currently disabled on Intel only since many tests are failing and need
|
||||
// investigation. http://anglebug.com/2728
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), flipViewportY,
|
||||
&mFeatures, flipViewportY,
|
||||
!IsIntel(mPhysicalDeviceProperties.vendorID) &&
|
||||
(mPhysicalDeviceProperties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) ||
|
||||
ExtensionFound(VK_KHR_MAINTENANCE1_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
// http://anglebug.com/2838
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), extraCopyBufferRegion, IsWindows() && isIntel);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, extraCopyBufferRegion, IsWindows() && isIntel);
|
||||
|
||||
// http://anglebug.com/3055
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), forceCPUPathForCubeMapCopy, IsWindows() && isIntel);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, forceCPUPathForCubeMapCopy, IsWindows() && isIntel);
|
||||
|
||||
// Work around incorrect NVIDIA point size range clamping.
|
||||
// http://anglebug.com/2970#c10
|
||||
|
@ -1584,23 +1584,23 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
|
|||
nvidiaVersion =
|
||||
angle::ParseNvidiaDriverVersion(this->mPhysicalDeviceProperties.driverVersion);
|
||||
}
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), clampPointSize,
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, clampPointSize,
|
||||
isNvidia && nvidiaVersion.major < uint32_t(IsWindows() ? 430 : 421));
|
||||
|
||||
// Work around ineffective compute-graphics barriers on Nexus 5X.
|
||||
// TODO(syoussefi): Figure out which other vendors and driver versions are affected.
|
||||
// http://anglebug.com/3019
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), flushAfterVertexConversion,
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, flushAfterVertexConversion,
|
||||
IsAndroid() && IsNexus5X(mPhysicalDeviceProperties.vendorID,
|
||||
mPhysicalDeviceProperties.deviceID));
|
||||
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), supportsIncrementalPresent,
|
||||
&mFeatures, supportsIncrementalPresent,
|
||||
ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
#if defined(ANGLE_PLATFORM_ANDROID)
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), supportsAndroidHardwareBuffer,
|
||||
&mFeatures, supportsAndroidHardwareBuffer,
|
||||
IsAndroid() &&
|
||||
ExtensionFound(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
|
||||
deviceExtensionNames) &&
|
||||
|
@ -1608,73 +1608,74 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
|
|||
#endif
|
||||
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), supportsExternalMemoryFd,
|
||||
&mFeatures, supportsExternalMemoryFd,
|
||||
ExtensionFound(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), supportsExternalMemoryFuchsia,
|
||||
&mFeatures, supportsExternalMemoryFuchsia,
|
||||
ExtensionFound(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), supportsExternalSemaphoreFd,
|
||||
&mFeatures, supportsExternalSemaphoreFd,
|
||||
ExtensionFound(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), supportsExternalSemaphoreFuchsia,
|
||||
&mFeatures, supportsExternalSemaphoreFuchsia,
|
||||
ExtensionFound(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), supportsShaderStencilExport,
|
||||
&mFeatures, supportsShaderStencilExport,
|
||||
ExtensionFound(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), supportsTransformFeedbackExtension,
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, supportsTransformFeedbackExtension,
|
||||
mTransformFeedbackFeatures.transformFeedback == VK_TRUE);
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), supportsIndexTypeUint8,
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, supportsIndexTypeUint8,
|
||||
mIndexTypeUint8Features.indexTypeUint8 == VK_TRUE);
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), emulateTransformFeedback,
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, emulateTransformFeedback,
|
||||
(mFeatures.supportsTransformFeedbackExtension.enabled == VK_FALSE &&
|
||||
mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics == VK_TRUE));
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), disableFifoPresentMode, IsLinux() && isIntel);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, disableFifoPresentMode, IsLinux() && isIntel);
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), bindEmptyForUnusedDescriptorSets,
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, bindEmptyForUnusedDescriptorSets,
|
||||
IsAndroid() && isQualcomm);
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), forceOldRewriteStructSamplers, IsAndroid() && !isSwS);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, forceOldRewriteStructSamplers, IsAndroid() && !isSwS);
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), perFrameWindowSizeQuery,
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, perFrameWindowSizeQuery,
|
||||
isIntel || (IsWindows() && isAMD) || IsFuchsia());
|
||||
|
||||
// Disabled on AMD/windows due to buggy behavior.
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), disallowSeamfulCubeMapEmulation, IsWindows() && isAMD);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, disallowSeamfulCubeMapEmulation, IsWindows() && isAMD);
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), padBuffersToMaxVertexAttribStride, isAMD);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, padBuffersToMaxVertexAttribStride, isAMD);
|
||||
mMaxVertexAttribStride = std::min(static_cast<uint32_t>(gl::limits::kMaxVertexAttribStride),
|
||||
mPhysicalDeviceProperties.limits.maxVertexInputBindingStride);
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), forceD16TexFilter, IsAndroid() && isQualcomm);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, forceD16TexFilter, IsAndroid() && isQualcomm);
|
||||
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), disableFlippingBlitWithCommand,
|
||||
IsAndroid() && isQualcomm);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, disableFlippingBlitWithCommand, IsAndroid() && isQualcomm);
|
||||
|
||||
// Allocation sanitization disabled by default because of a heaveyweight implementation
|
||||
// that can cause OOM and timeouts.
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), allocateNonZeroMemory, false);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, allocateNonZeroMemory, false);
|
||||
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
(&mFeatures), supportsExternalMemoryHost,
|
||||
&mFeatures, supportsExternalMemoryHost,
|
||||
ExtensionFound(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
// Pre-rotation support is not fully ready to be enabled.
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), enablePreRotateSurfaces, false);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, enablePreRotateSurfaces, false);
|
||||
|
||||
// Currently disable FramebufferVk cache on Apple: http://anglebug.com/4442
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), enableFramebufferVkCache, !IsApple());
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, enableFramebufferVkCache, !IsApple());
|
||||
|
||||
// Currently disabled by default: http://anglebug.com/3078
|
||||
ANGLE_FEATURE_CONDITION((&mFeatures), enablePrecisionQualifiers, false);
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, enablePrecisionQualifiers, false);
|
||||
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, supportDepthStencilRenderingFeedbackLoops, true);
|
||||
|
||||
angle::PlatformMethods *platform = ANGLEPlatformCurrent();
|
||||
platform->overrideFeaturesVk(platform, &mFeatures);
|
||||
|
|
|
@ -1252,6 +1252,74 @@ TEST_P(FramebufferTest_ES3, AttachmentStateChange)
|
|||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
|
||||
// Tests that we can support a feedback loop between a depth textures and the depth buffer.
|
||||
// Does not totally mirror the case used in Manhattan. The Manhattan case seems to handle
|
||||
// "clear" specially instead of rendering to depth in the same RP.
|
||||
TEST_P(FramebufferTest_ES3, DepthFeedbackLoopSupported)
|
||||
{
|
||||
// Feedback loops not supported on D3D11 and may not ever be.
|
||||
ANGLE_SKIP_TEST_IF(IsD3D11());
|
||||
|
||||
// Also this particular test doesn't work on Android despite similar support in Manhattan.
|
||||
ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
|
||||
|
||||
constexpr GLuint kSize = 2;
|
||||
glViewport(0, 0, kSize, kSize);
|
||||
|
||||
constexpr char kFS[] = R"(precision mediump float;
|
||||
varying vec2 v_texCoord;
|
||||
uniform sampler2D depth;
|
||||
void main()
|
||||
{
|
||||
if (abs(texture2D(depth, v_texCoord).x - 0.5) < 0.1)
|
||||
{
|
||||
gl_FragColor = vec4(0, 1, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = vec4(1, 0, 0, 1);
|
||||
}
|
||||
})";
|
||||
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
|
||||
|
||||
GLFramebuffer framebuffer;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
|
||||
GLTexture colorTexture;
|
||||
glBindTexture(GL_TEXTURE_2D, colorTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
|
||||
|
||||
GLTexture depthTexture;
|
||||
glBindTexture(GL_TEXTURE_2D, depthTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
|
||||
GL_UNSIGNED_INT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
|
||||
// Clear depth to 0.5.
|
||||
glClearDepthf(0.5f);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Disable the depth mask. Although this does not remove the feedback loop as defined by the
|
||||
// spec it mimics what gfxbench does in its rendering tests.
|
||||
glDepthMask(false);
|
||||
|
||||
// Verify we can sample the depth texture and get 0.5.
|
||||
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
|
||||
ANGLE_INSTANTIATE_TEST_ES2(AddDummyTextureNoRenderTargetTest);
|
||||
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferFormatsTest);
|
||||
ANGLE_INSTANTIATE_TEST_ES3(FramebufferTest_ES3);
|
||||
|
|
Загрузка…
Ссылка в новой задаче