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/+/1553973
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Ian Elliott <ianelliott@google.com>
This commit is contained in:
Ian Elliott 2019-04-26 01:48:31 -06:00 коммит произвёл Commit Bot
Родитель e9421b2cae
Коммит 19905aea14
4 изменённых файлов: 42 добавлений и 15 удалений

Просмотреть файл

@ -89,6 +89,11 @@ struct FeaturesVk
// 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
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;

Просмотреть файл

@ -15,6 +15,8 @@
#include "libANGLE/Context.h"
#include "libANGLE/Program.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/CommandGraph.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
@ -704,10 +706,34 @@ void ContextVk::updateDepthRange(float nearPlane, float farPlane)
void ContextVk::updateScissor(const gl::State &glState)
{
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
gl::Rectangle scissoredRenderArea = framebufferVk->getScissoredRenderArea(this);
VkRect2D scissor = gl_vk::GetRect(scissoredRenderArea);
mGraphicsPipelineDesc->updateScissor(&mGraphicsPipelineTransition, scissor);
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
gl::Rectangle renderArea = framebufferVk->getCompleteRenderArea();
// 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);
}
@ -736,6 +762,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
updateViewport(framebufferVk, glState.getViewport(), glState.getNearPlane(),
glState.getFarPlane(), isViewportFlipEnabledForDrawFBO());
// Update the scissor, which will be constrained to the viewport
updateScissor(glState);
break;
}
case gl::State::DIRTY_BIT_DEPTH_RANGE:

Просмотреть файл

@ -1314,6 +1314,11 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames)
mFeatures.bindEmptyForUnusedDescriptorSets = true;
}
if (IsWindows() && IsIntel(mPhysicalDeviceProperties.vendorID))
{
mFeatures.forceNonZeroScissor = true;
}
}
void RendererVk::initPipelineCacheVkKey()

Просмотреть файл

@ -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_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
3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL
3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_linear = FAIL
@ -334,9 +326,6 @@
// 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
// 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.
2727 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.pointcoord = FAIL
2808 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.fragcoord_w = FAIL