Commit d17bdfe5 by Luc Ferron Committed by Commit Bot

Vulkan: 3 Final bugfixes to enable all dEQP depth_stencil tests

- The scissor when clearing should not be clipped against the viewport. - The render pass was created with a render area == to the current viewport, but the viewport can be changed by the tests multiple times per render pass, so we should always keep the renderArea to the full framebuffer instead. - Enables an additional 163 dEQP tests. - We should clip the scissor to the framebuffer dimensions instead of the viewport. Its valid to do a cmdClearAttachments outside the viewport, but not outside the full framebuffer's dimension. Bug: angleproject:2443 Change-Id: I79168e9f0c782d6dec77470fef938b85ad7a8794 Reviewed-on: https://chromium-review.googlesource.com/998448 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 785b20b7
...@@ -340,6 +340,22 @@ void ContextVk::popDebugGroup() ...@@ -340,6 +340,22 @@ void ContextVk::popDebugGroup()
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
void ContextVk::updateScissor(const gl::State &glState)
{
if (glState.isScissorTestEnabled())
{
mPipelineDesc->updateScissor(glState.getScissor(),
glState.getDrawFramebuffer()->getDimensions());
}
else
{
// If the scissor test isn't enabled, we have to also update the scissor to
// be equal to the framebuffer dimensions to make sure we keep rendering everything.
mPipelineDesc->updateScissor(glState.getViewport(),
glState.getDrawFramebuffer()->getDimensions());
}
}
void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
{ {
if (dirtyBits.any()) if (dirtyBits.any())
...@@ -357,34 +373,20 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits ...@@ -357,34 +373,20 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits
switch (dirtyBit) switch (dirtyBit)
{ {
case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
if (glState.isScissorTestEnabled()) updateScissor(glState);
{
mPipelineDesc->updateScissor(glState.getScissor());
}
else
{
mPipelineDesc->updateScissor(glState.getViewport());
}
break; break;
case gl::State::DIRTY_BIT_SCISSOR: case gl::State::DIRTY_BIT_SCISSOR:
// Only modify the scissor region if the test is enabled, otherwise we want to keep // Only modify the scissor region if the test is enabled, otherwise we want to keep
// the viewport size as the scissor region. // the viewport size as the scissor region.
if (glState.isScissorTestEnabled()) if (glState.isScissorTestEnabled())
{ {
mPipelineDesc->updateScissor(glState.getScissor()); mPipelineDesc->updateScissor(glState.getScissor(),
glState.getDrawFramebuffer()->getDimensions());
} }
break; break;
case gl::State::DIRTY_BIT_VIEWPORT: case gl::State::DIRTY_BIT_VIEWPORT:
mPipelineDesc->updateViewport(glState.getViewport(), glState.getNearPlane(), mPipelineDesc->updateViewport(glState.getViewport(), glState.getNearPlane(),
glState.getFarPlane()); glState.getFarPlane());
// If the scissor test isn't enabled, we have to also update the scissor to
// be equal to the viewport to make sure we keep rendering everything in the
// viewport.
if (!glState.isScissorTestEnabled())
{
mPipelineDesc->updateScissor(glState.getViewport());
}
break; break;
case gl::State::DIRTY_BIT_DEPTH_RANGE: case gl::State::DIRTY_BIT_DEPTH_RANGE:
WARN() << "DIRTY_BIT_DEPTH_RANGE unimplemented"; WARN() << "DIRTY_BIT_DEPTH_RANGE unimplemented";
......
...@@ -167,6 +167,8 @@ class ContextVk : public ContextImpl ...@@ -167,6 +167,8 @@ class ContextVk : public ContextImpl
vk::CommandGraphNode **drawNodeOut, vk::CommandGraphNode **drawNodeOut,
bool *newCommandBufferOut); bool *newCommandBufferOut);
void updateScissor(const gl::State &glState);
RendererVk *mRenderer; RendererVk *mRenderer;
vk::PipelineAndSerial *mCurrentPipeline; vk::PipelineAndSerial *mCurrentPipeline;
GLenum mCurrentDrawMode; GLenum mCurrentDrawMode;
......
...@@ -579,10 +579,11 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context, ...@@ -579,10 +579,11 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue()); attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
} }
gl::Rectangle renderArea =
gl::Rectangle(0, 0, mState.getDimensions().width, mState.getDimensions().height);
// Hard-code RenderPass to clear the first render target to the current clear value. // Hard-code RenderPass to clear the first render target to the current clear value.
// TODO(jmadill): Proper clear value implementation. http://anglebug.com/2361 // TODO(jmadill): Proper clear value implementation. http://anglebug.com/2361
const gl::State &glState = context->getGLState(); (*nodeOut)->storeRenderPassInfo(*framebuffer, renderArea, attachmentClearValues);
(*nodeOut)->storeRenderPassInfo(*framebuffer, glState.getViewport(), attachmentClearValues);
return gl::NoError(); return gl::NoError();
} }
......
...@@ -808,21 +808,21 @@ void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &renderPassDesc) ...@@ -808,21 +808,21 @@ void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &renderPassDesc)
mRenderPassDesc = renderPassDesc; mRenderPassDesc = renderPassDesc;
} }
void PipelineDesc::updateScissor(const gl::Rectangle &rect) void PipelineDesc::updateScissor(const gl::Rectangle &rect, gl::Box framebufferDimensions)
{ {
gl::Rectangle intersection; gl::Rectangle intersection;
gl::Rectangle clipRect(static_cast<GLuint>(mViewport.x), static_cast<GLuint>(mViewport.y), gl::Rectangle clipRect(static_cast<GLuint>(0), static_cast<GLuint>(0),
static_cast<GLuint>(mViewport.width), static_cast<GLuint>(framebufferDimensions.width),
static_cast<GLuint>(mViewport.height)); static_cast<GLuint>(framebufferDimensions.height));
// Coordinates outside surface aren't valid in Vulkan but not error is returned, the scissor is // Coordinates outside the framebuffer aren't valid in Vulkan but not error is returned, the
// just ignored. // scissor is just ignored.
if (ClipRectangle(rect, clipRect, &intersection)) if (ClipRectangle(rect, clipRect, &intersection))
{ {
mScissor = ConvertGlRectToVkRect(intersection); mScissor = gl_vk::GetRect(intersection);
} }
else else
{ {
mScissor = ConvertGlRectToVkRect(rect); mScissor = gl_vk::GetRect(rect);
} }
} }
......
...@@ -292,7 +292,7 @@ class PipelineDesc final ...@@ -292,7 +292,7 @@ class PipelineDesc final
// Scissor support // Scissor support
const VkRect2D &getScissor() const { return mScissor; } const VkRect2D &getScissor() const { return mScissor; }
void updateScissor(const gl::Rectangle &rect); void updateScissor(const gl::Rectangle &rect, gl::Box surfaceDimensions);
// Blend states // Blend states
void updateBlendEnabled(bool isBlendEnabled); void updateBlendEnabled(bool isBlendEnabled);
......
...@@ -251,12 +251,6 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro ...@@ -251,12 +251,6 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro
namespace vk namespace vk
{ {
VkRect2D ConvertGlRectToVkRect(const gl::Rectangle &source)
{
return {{source.x, source.y},
{static_cast<uint32_t>(source.width), static_cast<uint32_t>(source.height)}};
}
Error::Error(VkResult result) : mResult(result), mFile(nullptr), mLine(0) Error::Error(VkResult result) : mResult(result), mFile(nullptr), mLine(0)
{ {
ASSERT(result == VK_SUCCESS); ASSERT(result == VK_SUCCESS);
...@@ -1145,6 +1139,12 @@ void GarbageObject::destroy(VkDevice device) ...@@ -1145,6 +1139,12 @@ void GarbageObject::destroy(VkDevice device)
namespace gl_vk namespace gl_vk
{ {
VkRect2D GetRect(const gl::Rectangle &source)
{
return {{source.x, source.y},
{static_cast<uint32_t>(source.width), static_cast<uint32_t>(source.height)}};
}
VkPrimitiveTopology GetPrimitiveTopology(GLenum mode) VkPrimitiveTopology GetPrimitiveTopology(GLenum mode)
{ {
switch (mode) switch (mode)
......
...@@ -87,8 +87,6 @@ struct Format; ...@@ -87,8 +87,6 @@ struct Format;
template <typename T> template <typename T>
struct ImplTypeHelper; struct ImplTypeHelper;
VkRect2D ConvertGlRectToVkRect(const gl::Rectangle &source);
// clang-format off // clang-format off
#define ANGLE_IMPL_TYPE_HELPER_GL(OBJ) \ #define ANGLE_IMPL_TYPE_HELPER_GL(OBJ) \
template<> \ template<> \
...@@ -651,6 +649,7 @@ Error AllocateImageMemory(VkDevice device, ...@@ -651,6 +649,7 @@ Error AllocateImageMemory(VkDevice device,
namespace gl_vk namespace gl_vk
{ {
VkRect2D GetRect(const gl::Rectangle &source);
VkPrimitiveTopology GetPrimitiveTopology(GLenum mode); VkPrimitiveTopology GetPrimitiveTopology(GLenum mode);
VkCullModeFlags GetCullMode(const gl::RasterizerState &rasterState); VkCullModeFlags GetCullMode(const gl::RasterizerState &rasterState);
VkFrontFace GetFrontFace(GLenum frontFace); VkFrontFace GetFrontFace(GLenum frontFace);
......
...@@ -229,7 +229,6 @@ ...@@ -229,7 +229,6 @@
2161 VULKAN : dEQP-GLES2.functional.texture.vertex.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.texture.vertex.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.fragment_ops.random.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.fragment_ops.random.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.fragment_ops.interaction.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.fragment_ops.interaction.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.fragment_ops.depth_stencil.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.fbo.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.fbo.* = SKIP
// Conflicts with Android expectation, specify the OSs // Conflicts with Android expectation, specify the OSs
2161 VULKAN WIN LINUX MAC : dEQP-GLES2.functional.vertex_arrays.* = SKIP 2161 VULKAN WIN LINUX MAC : dEQP-GLES2.functional.vertex_arrays.* = SKIP
......
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