Commit 19905aea by Ian Elliott Committed by Commit Bot

Vulkan: Set the Vulkan scissor to the GLES viewport

Some Vulkan drivers are not clipping rendering that is outside of the viewport, and the Vulkan spec has some language that indicates that ANGLE should set the scissor: The application must ensure (using scissor if necessary) that all rendering is contained within the render area. In this case, ANGLE is "the application". Bug: angleproject:3253 Bug: angleproject:3254 Change-Id: I6885a3aa6daed57f6ae1c3d974663d763cad10c9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1553973Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Ian Elliott <ianelliott@google.com>
parent e9421b2c
...@@ -89,6 +89,11 @@ struct FeaturesVk ...@@ -89,6 +89,11 @@ struct FeaturesVk
// object within that set. This flag results in empty descriptor sets being bound for any // object within that set. This flag results in empty descriptor sets being bound for any
// unused descriptor set to work around this issue. http://anglebug.com/2727 // unused descriptor set to work around this issue. http://anglebug.com/2727
bool bindEmptyForUnusedDescriptorSets = false; bool bindEmptyForUnusedDescriptorSets = false;
// When the scissor is (0,0,0,0) on Windows Intel, the driver acts as if the scissor was
// disabled. Work-around this by setting the scissor to just outside of the render area
// (e.g. (renderArea.x, renderArea.y, 1, 1)). http://anglebug.com/3153
bool forceNonZeroScissor = false;
}; };
inline FeaturesVk::FeaturesVk() = default; inline FeaturesVk::FeaturesVk() = default;
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/vulkan/BufferVk.h" #include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h" #include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h" #include "libANGLE/renderer/vulkan/CompilerVk.h"
...@@ -704,10 +706,34 @@ void ContextVk::updateDepthRange(float nearPlane, float farPlane) ...@@ -704,10 +706,34 @@ void ContextVk::updateDepthRange(float nearPlane, float farPlane)
void ContextVk::updateScissor(const gl::State &glState) void ContextVk::updateScissor(const gl::State &glState)
{ {
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer()); FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
gl::Rectangle scissoredRenderArea = framebufferVk->getScissoredRenderArea(this); gl::Rectangle renderArea = framebufferVk->getCompleteRenderArea();
VkRect2D scissor = gl_vk::GetRect(scissoredRenderArea);
mGraphicsPipelineDesc->updateScissor(&mGraphicsPipelineTransition, scissor); // Clip the render area to the viewport.
gl::Rectangle viewportClippedRenderArea;
gl::ClipRectangle(renderArea, glState.getViewport(), &viewportClippedRenderArea);
gl::Rectangle scissoredArea = ClipRectToScissor(getState(), viewportClippedRenderArea, false);
if (isViewportFlipEnabledForDrawFBO())
{
scissoredArea.y = renderArea.height - scissoredArea.y - scissoredArea.height;
}
if (getRenderer()->getFeatures().forceNonZeroScissor && scissoredArea.width == 0 &&
scissoredArea.height == 0)
{
// There is no overlap between the app-set viewport and clippedRect. This code works
// around an Intel driver bug that causes the driver to treat a (0,0,0,0) scissor as if
// scissoring is disabled. In this case, set the scissor to be just outside of the
// renderArea. Remove this work-around when driver version 25.20.100.6519 has been
// deployed. http://anglebug.com/3407
scissoredArea.x = renderArea.x;
scissoredArea.y = renderArea.y;
scissoredArea.width = 1;
scissoredArea.height = 1;
}
mGraphicsPipelineDesc->updateScissor(&mGraphicsPipelineTransition,
gl_vk::GetRect(scissoredArea));
framebufferVk->onScissorChange(this); framebufferVk->onScissorChange(this);
} }
...@@ -736,6 +762,8 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -736,6 +762,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer()); FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
updateViewport(framebufferVk, glState.getViewport(), glState.getNearPlane(), updateViewport(framebufferVk, glState.getViewport(), glState.getNearPlane(),
glState.getFarPlane(), isViewportFlipEnabledForDrawFBO()); glState.getFarPlane(), isViewportFlipEnabledForDrawFBO());
// Update the scissor, which will be constrained to the viewport
updateScissor(glState);
break; break;
} }
case gl::State::DIRTY_BIT_DEPTH_RANGE: case gl::State::DIRTY_BIT_DEPTH_RANGE:
......
...@@ -1314,6 +1314,11 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames) ...@@ -1314,6 +1314,11 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames)
mFeatures.bindEmptyForUnusedDescriptorSets = true; mFeatures.bindEmptyForUnusedDescriptorSets = true;
} }
if (IsWindows() && IsIntel(mPhysicalDeviceProperties.vendorID))
{
mFeatures.forceNonZeroScissor = true;
}
} }
void RendererVk::initPipelineCacheVkKey() void RendererVk::initPipelineCacheVkKey()
......
...@@ -274,14 +274,6 @@ ...@@ -274,14 +274,6 @@
3253 VULKAN : dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_center = FAIL 3253 VULKAN : dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_center = FAIL
3253 VULKAN : dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_corner = FAIL 3253 VULKAN : dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_corner = FAIL
// Other clipping
3254 VULKAN : dEQP-GLES2.functional.clipping.line.line_clip_viewport_center = FAIL
3254 VULKAN : dEQP-GLES2.functional.clipping.line.line_clip_viewport_corner = FAIL
// Only seems to be an issue on NVIDIA
3254 VULKAN NVIDIA : dEQP-GLES2.functional.clipping.point.point_clip_viewport_center = FAIL
3254 VULKAN NVIDIA : dEQP-GLES2.functional.clipping.point.point_clip_viewport_corner = FAIL
// These seem to fail on both D3D11 and Vulkan // These seem to fail on both D3D11 and Vulkan
3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL 3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL
3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_linear = FAIL 3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_linear = FAIL
...@@ -334,9 +326,6 @@ ...@@ -334,9 +326,6 @@
// Passes on Pixel XL. Fails on 5x and Pixel 2. Might be fixed in latest driver. // Passes on Pixel XL. Fails on 5x and Pixel 2. Might be fixed in latest driver.
2609 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.generate.* = SKIP 2609 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.generate.* = SKIP
// Fails on Nexus 5x only. TODO(jmadill): Remove suppression when possible. http://anglebug.com/2791
2791 VULKAN ANDROID : dEQP-GLES2.functional.clipping.* = SKIP
// Failing on the Pixel 2. // Failing on the Pixel 2.
2727 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.pointcoord = FAIL 2727 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.pointcoord = FAIL
2808 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.fragcoord_w = FAIL 2808 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.fragcoord_w = FAIL
......
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