Commit d03b15b2 by Jamie Madill Committed by Commit Bot

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: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent 68083e89
...@@ -13,11 +13,11 @@ ...@@ -13,11 +13,11 @@
#include <string> #include <string>
#include <vector> #include <vector>
#define ANGLE_FEATURE_CONDITION(set, feature, cond) \ #define ANGLE_FEATURE_CONDITION(set, feature, cond) \
do \ do \
{ \ { \
set->feature.enabled = cond; \ (set)->feature.enabled = cond; \
set->feature.condition = ANGLE_STRINGIFY(cond); \ (set)->feature.condition = ANGLE_STRINGIFY(cond); \
} while (0) } while (0)
namespace angle namespace angle
......
...@@ -268,6 +268,12 @@ struct FeaturesVk : FeatureSetBase ...@@ -268,6 +268,12 @@ struct FeaturesVk : FeatureSetBase
Feature enablePrecisionQualifiers = { Feature enablePrecisionQualifiers = {
"enable_precision_qualifiers", FeatureCategory::VulkanFeatures, "enable_precision_qualifiers", FeatureCategory::VulkanFeatures,
"Enable precision qualifiers in shaders", &members, "http://anglebug.com/3078"}; "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; inline FeaturesVk::FeaturesVk() = default;
......
...@@ -61,14 +61,9 @@ ANGLE_INLINE void MarkShaderStorageBufferUsage(const Context *context) ...@@ -61,14 +61,9 @@ ANGLE_INLINE void MarkShaderStorageBufferUsage(const Context *context)
// Return true if the draw is a no-op, else return false. // 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 // 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). // 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) ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count)
{ {
return count < kMinimumPrimitiveCounts[mode] || return count < kMinimumPrimitiveCounts[mode];
mState.mDrawFramebuffer->hasRenderingFeedbackLoop();
} }
ANGLE_INLINE angle::Result Context::syncDirtyBits() ANGLE_INLINE angle::Result Context::syncDirtyBits()
......
...@@ -699,11 +699,13 @@ bool FramebufferState::updateAttachmentFeedbackLoopAndReturnIfChanged(size_t dir ...@@ -699,11 +699,13 @@ bool FramebufferState::updateAttachmentFeedbackLoopAndReturnIfChanged(size_t dir
break; break;
default: default:
{
ASSERT(dirtyBit <= Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX); ASSERT(dirtyBit <= Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
previous = mDrawBufferFeedbackLoops.test(dirtyBit); previous = mDrawBufferFeedbackLoops.test(dirtyBit);
loop = mColorAttachments[dirtyBit].isBoundAsSamplerOrImage(); loop = mColorAttachments[dirtyBit].isBoundAsSamplerOrImage();
mDrawBufferFeedbackLoops[dirtyBit] = loop; mDrawBufferFeedbackLoops[dirtyBit] = loop;
break; break;
}
} }
updateHasRenderingFeedbackLoop(); updateHasRenderingFeedbackLoop();
......
...@@ -114,7 +114,9 @@ FramebufferVk::FramebufferVk(RendererVk *renderer, ...@@ -114,7 +114,9 @@ FramebufferVk::FramebufferVk(RendererVk *renderer,
: FramebufferImpl(state), : FramebufferImpl(state),
mBackbuffer(backbuffer), mBackbuffer(backbuffer),
mFramebuffer(nullptr), mFramebuffer(nullptr),
mActiveColorComponents(0) mActiveColorComponents(0),
mSupportDepthStencilFeedbackLoops(
renderer->getFeatures().supportDepthStencilRenderingFeedbackLoops.enabled)
{ {
mReadPixelBuffer.init(renderer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, kReadPixelsBufferAlignment, mReadPixelBuffer.init(renderer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, kReadPixelsBufferAlignment,
kMinReadPixelsBufferSize, true); kMinReadPixelsBufferSize, true);
...@@ -229,6 +231,36 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context, ...@@ -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. // The front-end should ensure we don't attempt to clear stencil if all bits are masked.
ASSERT(!clearStencil || stencilMask != 0); 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 // If there is nothing to clear, return right away (for example, if asked to clear depth, but
// there is no depth attachment). // there is no depth attachment).
if (!clearColor && !clearDepth && !clearStencil) if (!clearColor && !clearDepth && !clearStencil)
...@@ -447,7 +479,9 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context, ...@@ -447,7 +479,9 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context,
RenderTargetVk *FramebufferVk::getDepthStencilRenderTarget() const 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 RenderTargetVk *FramebufferVk::getColorDrawRenderTarget(size_t colorIndex) const
...@@ -983,7 +1017,7 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk, ...@@ -983,7 +1017,7 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk) void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk)
{ {
RenderTargetVk *depthStencilRT = mRenderTargetCache.getDepthStencil(true); RenderTargetVk *depthStencilRT = getDepthStencilRenderTarget();
if (depthStencilRT != nullptr) if (depthStencilRT != nullptr)
{ {
...@@ -1021,7 +1055,7 @@ angle::Result FramebufferVk::syncState(const gl::Context *context, ...@@ -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_DEPTH_BUFFER_CONTENTS:
case gl::Framebuffer::DIRTY_BIT_STENCIL_BUFFER_CONTENTS: case gl::Framebuffer::DIRTY_BIT_STENCIL_BUFFER_CONTENTS:
{ {
RenderTargetVk *depthStencilRT = mRenderTargetCache.getDepthStencil(true); RenderTargetVk *depthStencilRT = getDepthStencilRenderTarget();
ASSERT(depthStencilRT != nullptr); ASSERT(depthStencilRT != nullptr);
ANGLE_TRY(depthStencilRT->flushStagedUpdates(contextVk)); ANGLE_TRY(depthStencilRT->flushStagedUpdates(contextVk));
mCurrentFramebufferDesc.update(vk::kFramebufferDescDepthStencilIndex, mCurrentFramebufferDesc.update(vk::kFramebufferDescDepthStencilIndex,
...@@ -1141,7 +1175,7 @@ void FramebufferVk::updateRenderPassDesc() ...@@ -1141,7 +1175,7 @@ void FramebufferVk::updateRenderPassDesc()
} }
} }
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(true); RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
if (depthStencilRenderTarget) if (depthStencilRenderTarget)
{ {
mRenderPassDesc.packDepthStencilAttachment( mRenderPassDesc.packDepthStencilAttachment(
...@@ -1200,7 +1234,7 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe ...@@ -1200,7 +1234,7 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
attachmentsSize = colorRenderTarget->getExtents(); attachmentsSize = colorRenderTarget->getExtents();
} }
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(true); RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
if (depthStencilRenderTarget) if (depthStencilRenderTarget)
{ {
const vk::ImageView *imageView = nullptr; const vk::ImageView *imageView = nullptr;
...@@ -1324,7 +1358,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -1324,7 +1358,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
attachmentClearValues.emplace_back(kUninitializedClearValue); attachmentClearValues.emplace_back(kUninitializedClearValue);
} }
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(true); RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
if (depthStencilRenderTarget) if (depthStencilRenderTarget)
{ {
ANGLE_TRY(depthStencilRenderTarget->onDepthStencilDraw(contextVk)); ANGLE_TRY(depthStencilRenderTarget->onDepthStencilDraw(contextVk));
...@@ -1402,7 +1436,7 @@ RenderTargetVk *FramebufferVk::getFirstRenderTarget() const ...@@ -1402,7 +1436,7 @@ RenderTargetVk *FramebufferVk::getFirstRenderTarget() const
} }
} }
return mRenderTargetCache.getDepthStencil(true); return getDepthStencilRenderTarget();
} }
GLint FramebufferVk::getSamples() const GLint FramebufferVk::getSamples() const
......
...@@ -186,6 +186,7 @@ class FramebufferVk : public FramebufferImpl ...@@ -186,6 +186,7 @@ class FramebufferVk : public FramebufferImpl
vk::FramebufferDesc mCurrentFramebufferDesc; vk::FramebufferDesc mCurrentFramebufferDesc;
std::unordered_map<vk::FramebufferDesc, vk::FramebufferHelper> mFramebufferCache; std::unordered_map<vk::FramebufferDesc, vk::FramebufferHelper> mFramebufferCache;
bool mSupportDepthStencilFeedbackLoops;
}; };
} // namespace rx } // namespace rx
......
...@@ -767,7 +767,7 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk, ...@@ -767,7 +767,7 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk,
if (ExtensionFound(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, instanceExtensionNames)) if (ExtensionFound(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, instanceExtensionNames))
{ {
enabledInstanceExtensions.push_back(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME); 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. // 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 ...@@ -1543,35 +1543,35 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
{ {
ASSERT(mLineRasterizationFeatures.sType == ASSERT(mLineRasterizationFeatures.sType ==
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT); VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT);
ANGLE_FEATURE_CONDITION((&mFeatures), bresenhamLineRasterization, true); ANGLE_FEATURE_CONDITION(&mFeatures, bresenhamLineRasterization, true);
} }
else else
{ {
// Use OpenGL line rasterization rules if extension not available by default. // Use OpenGL line rasterization rules if extension not available by default.
// TODO(jmadill): Fix Android support. http://anglebug.com/2830 // 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) if (mProvokingVertexFeatures.provokingVertexLast == VK_TRUE)
{ {
ASSERT(mProvokingVertexFeatures.sType == ASSERT(mProvokingVertexFeatures.sType ==
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT); 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 // TODO(lucferron): Currently disabled on Intel only since many tests are failing and need
// investigation. http://anglebug.com/2728 // investigation. http://anglebug.com/2728
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), flipViewportY, &mFeatures, flipViewportY,
!IsIntel(mPhysicalDeviceProperties.vendorID) && !IsIntel(mPhysicalDeviceProperties.vendorID) &&
(mPhysicalDeviceProperties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) || (mPhysicalDeviceProperties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) ||
ExtensionFound(VK_KHR_MAINTENANCE1_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_KHR_MAINTENANCE1_EXTENSION_NAME, deviceExtensionNames));
// http://anglebug.com/2838 // http://anglebug.com/2838
ANGLE_FEATURE_CONDITION((&mFeatures), extraCopyBufferRegion, IsWindows() && isIntel); ANGLE_FEATURE_CONDITION(&mFeatures, extraCopyBufferRegion, IsWindows() && isIntel);
// http://anglebug.com/3055 // 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. // Work around incorrect NVIDIA point size range clamping.
// http://anglebug.com/2970#c10 // http://anglebug.com/2970#c10
...@@ -1584,23 +1584,23 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev ...@@ -1584,23 +1584,23 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
nvidiaVersion = nvidiaVersion =
angle::ParseNvidiaDriverVersion(this->mPhysicalDeviceProperties.driverVersion); angle::ParseNvidiaDriverVersion(this->mPhysicalDeviceProperties.driverVersion);
} }
ANGLE_FEATURE_CONDITION((&mFeatures), clampPointSize, ANGLE_FEATURE_CONDITION(&mFeatures, clampPointSize,
isNvidia && nvidiaVersion.major < uint32_t(IsWindows() ? 430 : 421)); isNvidia && nvidiaVersion.major < uint32_t(IsWindows() ? 430 : 421));
// Work around ineffective compute-graphics barriers on Nexus 5X. // Work around ineffective compute-graphics barriers on Nexus 5X.
// TODO(syoussefi): Figure out which other vendors and driver versions are affected. // TODO(syoussefi): Figure out which other vendors and driver versions are affected.
// http://anglebug.com/3019 // http://anglebug.com/3019
ANGLE_FEATURE_CONDITION((&mFeatures), flushAfterVertexConversion, ANGLE_FEATURE_CONDITION(&mFeatures, flushAfterVertexConversion,
IsAndroid() && IsNexus5X(mPhysicalDeviceProperties.vendorID, IsAndroid() && IsNexus5X(mPhysicalDeviceProperties.vendorID,
mPhysicalDeviceProperties.deviceID)); mPhysicalDeviceProperties.deviceID));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsIncrementalPresent, &mFeatures, supportsIncrementalPresent,
ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionNames));
#if defined(ANGLE_PLATFORM_ANDROID) #if defined(ANGLE_PLATFORM_ANDROID)
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsAndroidHardwareBuffer, &mFeatures, supportsAndroidHardwareBuffer,
IsAndroid() && IsAndroid() &&
ExtensionFound(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, ExtensionFound(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
deviceExtensionNames) && deviceExtensionNames) &&
...@@ -1608,73 +1608,74 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev ...@@ -1608,73 +1608,74 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
#endif #endif
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalMemoryFd, &mFeatures, supportsExternalMemoryFd,
ExtensionFound(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalMemoryFuchsia, &mFeatures, supportsExternalMemoryFuchsia,
ExtensionFound(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalSemaphoreFd, &mFeatures, supportsExternalSemaphoreFd,
ExtensionFound(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalSemaphoreFuchsia, &mFeatures, supportsExternalSemaphoreFuchsia,
ExtensionFound(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsShaderStencilExport, &mFeatures, supportsShaderStencilExport,
ExtensionFound(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION((&mFeatures), supportsTransformFeedbackExtension, ANGLE_FEATURE_CONDITION(&mFeatures, supportsTransformFeedbackExtension,
mTransformFeedbackFeatures.transformFeedback == VK_TRUE); mTransformFeedbackFeatures.transformFeedback == VK_TRUE);
ANGLE_FEATURE_CONDITION((&mFeatures), supportsIndexTypeUint8, ANGLE_FEATURE_CONDITION(&mFeatures, supportsIndexTypeUint8,
mIndexTypeUint8Features.indexTypeUint8 == VK_TRUE); mIndexTypeUint8Features.indexTypeUint8 == VK_TRUE);
ANGLE_FEATURE_CONDITION((&mFeatures), emulateTransformFeedback, ANGLE_FEATURE_CONDITION(&mFeatures, emulateTransformFeedback,
(mFeatures.supportsTransformFeedbackExtension.enabled == VK_FALSE && (mFeatures.supportsTransformFeedbackExtension.enabled == VK_FALSE &&
mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics == VK_TRUE)); 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); 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()); isIntel || (IsWindows() && isAMD) || IsFuchsia());
// Disabled on AMD/windows due to buggy behavior. // 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), mMaxVertexAttribStride = std::min(static_cast<uint32_t>(gl::limits::kMaxVertexAttribStride),
mPhysicalDeviceProperties.limits.maxVertexInputBindingStride); mPhysicalDeviceProperties.limits.maxVertexInputBindingStride);
ANGLE_FEATURE_CONDITION((&mFeatures), forceD16TexFilter, IsAndroid() && isQualcomm); ANGLE_FEATURE_CONDITION(&mFeatures, forceD16TexFilter, IsAndroid() && isQualcomm);
ANGLE_FEATURE_CONDITION((&mFeatures), disableFlippingBlitWithCommand, ANGLE_FEATURE_CONDITION(&mFeatures, disableFlippingBlitWithCommand, IsAndroid() && isQualcomm);
IsAndroid() && isQualcomm);
// Allocation sanitization disabled by default because of a heaveyweight implementation // Allocation sanitization disabled by default because of a heaveyweight implementation
// that can cause OOM and timeouts. // that can cause OOM and timeouts.
ANGLE_FEATURE_CONDITION((&mFeatures), allocateNonZeroMemory, false); ANGLE_FEATURE_CONDITION(&mFeatures, allocateNonZeroMemory, false);
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalMemoryHost, &mFeatures, supportsExternalMemoryHost,
ExtensionFound(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionNames));
// Pre-rotation support is not fully ready to be enabled. // 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 // 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 // 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(); angle::PlatformMethods *platform = ANGLEPlatformCurrent();
platform->overrideFeaturesVk(platform, &mFeatures); platform->overrideFeaturesVk(platform, &mFeatures);
......
...@@ -1252,6 +1252,74 @@ TEST_P(FramebufferTest_ES3, AttachmentStateChange) ...@@ -1252,6 +1252,74 @@ TEST_P(FramebufferTest_ES3, AttachmentStateChange)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); 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(AddDummyTextureNoRenderTargetTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferFormatsTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferFormatsTest);
ANGLE_INSTANTIATE_TEST_ES3(FramebufferTest_ES3); ANGLE_INSTANTIATE_TEST_ES3(FramebufferTest_ES3);
......
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