From e45ba51ea451c5ce580dc248e932e5b6324c0bbc Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 9 Jul 2018 11:37:15 +0200 Subject: [PATCH] radv: add support for VK_EXT_conditional_rendering Inherited commands buffers are not supported. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_cmd_buffer.c | 37 +++++++++++++++++++++++++++ src/amd/vulkan/radv_device.c | 7 +++++ src/amd/vulkan/radv_extensions.py | 1 + src/amd/vulkan/radv_meta_blit.c | 10 ++++++++ src/amd/vulkan/radv_meta_buffer.c | 10 ++++++++ src/amd/vulkan/radv_meta_copy.c | 30 ++++++++++++++++++++++ src/amd/vulkan/radv_meta_fast_clear.c | 13 +++++++++- src/amd/vulkan/radv_private.h | 4 +++ 8 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index f1379d0de4b..cbcd3bc141f 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -4414,3 +4414,40 @@ void radv_CmdSetDeviceMask(VkCommandBuffer commandBuffer, { /* No-op */ } + +/* VK_EXT_conditional_rendering */ +void vkCmdBeginConditionalRenderingEXT( + VkCommandBuffer commandBuffer, + const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin) +{ + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + RADV_FROM_HANDLE(radv_buffer, buffer, pConditionalRenderingBegin->buffer); + bool inverted; + uint64_t va; + + va = radv_buffer_get_va(buffer->bo) + pConditionalRenderingBegin->offset; + + inverted = pConditionalRenderingBegin->flags & VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT; + + /* Enable predication for this command buffer. */ + si_emit_set_predication_state(cmd_buffer, inverted, va); + cmd_buffer->state.predicating = true; + + /* Store conditional rendering user info. */ + cmd_buffer->state.predication_type = inverted; + cmd_buffer->state.predication_va = va; +} + +void vkCmdEndConditionalRenderingEXT( + VkCommandBuffer commandBuffer) +{ + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + + /* Disable predication for this command buffer. */ + si_emit_set_predication_state(cmd_buffer, false, 0); + cmd_buffer->state.predicating = false; + + /* Reset conditional rendering user info. */ + cmd_buffer->state.predication_type = -1; + cmd_buffer->state.predication_va = 0; +} diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 8274b6ea096..edc0dd90d26 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -807,6 +807,13 @@ void radv_GetPhysicalDeviceFeatures2( features->runtimeDescriptorArray = true; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: { + VkPhysicalDeviceConditionalRenderingFeaturesEXT *features = + (VkPhysicalDeviceConditionalRenderingFeaturesEXT*)ext; + features->conditionalRendering = true; + features->inheritedConditionalRendering = false; + break; + } default: break; } diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py index 094ed3bce3e..a5fbffac33b 100644 --- a/src/amd/vulkan/radv_extensions.py +++ b/src/amd/vulkan/radv_extensions.py @@ -91,6 +91,7 @@ EXTENSIONS = [ Extension('VK_KHR_display', 23, 'VK_USE_PLATFORM_DISPLAY_KHR'), Extension('VK_EXT_direct_mode_display', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'), + Extension('VK_EXT_conditional_rendering', 1, True), Extension('VK_EXT_display_surface_counter', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), Extension('VK_EXT_display_control', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), Extension('VK_EXT_debug_report', 9, True), diff --git a/src/amd/vulkan/radv_meta_blit.c b/src/amd/vulkan/radv_meta_blit.c index a6ee0cb7e93..67c26aabdb3 100644 --- a/src/amd/vulkan/radv_meta_blit.c +++ b/src/amd/vulkan/radv_meta_blit.c @@ -520,6 +520,7 @@ void radv_CmdBlitImage( RADV_FROM_HANDLE(radv_image, src_image, srcImage); RADV_FROM_HANDLE(radv_image, dest_image, destImage); struct radv_meta_saved_state saved_state; + bool old_predicating; /* From the Vulkan 1.0 spec: * @@ -534,6 +535,12 @@ void radv_CmdBlitImage( RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS); + /* VK_EXT_conditional_rendering says that blit commands should not be + * affected by conditional rendering. + */ + old_predicating = cmd_buffer->state.predicating; + cmd_buffer->state.predicating = false; + for (unsigned r = 0; r < regionCount; r++) { const VkImageSubresourceLayers *src_res = &pRegions[r].srcSubresource; const VkImageSubresourceLayers *dst_res = &pRegions[r].dstSubresource; @@ -648,6 +655,9 @@ void radv_CmdBlitImage( } } + /* Restore conditional rendering. */ + cmd_buffer->state.predicating = old_predicating; + radv_meta_restore(&saved_state, cmd_buffer); } diff --git a/src/amd/vulkan/radv_meta_buffer.c b/src/amd/vulkan/radv_meta_buffer.c index 6c6d1cc41d7..f1887e33183 100644 --- a/src/amd/vulkan/radv_meta_buffer.c +++ b/src/amd/vulkan/radv_meta_buffer.c @@ -472,6 +472,13 @@ void radv_CmdCopyBuffer( RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); RADV_FROM_HANDLE(radv_buffer, src_buffer, srcBuffer); RADV_FROM_HANDLE(radv_buffer, dest_buffer, destBuffer); + bool old_predicating; + + /* VK_EXT_conditional_rendering says that copy commands should not be + * affected by conditional rendering. + */ + old_predicating = cmd_buffer->state.predicating; + cmd_buffer->state.predicating = false; for (unsigned r = 0; r < regionCount; r++) { uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset; @@ -481,6 +488,9 @@ void radv_CmdCopyBuffer( radv_copy_buffer(cmd_buffer, src_buffer->bo, dest_buffer->bo, src_offset, dest_offset, copy_size); } + + /* Restore conditional rendering. */ + cmd_buffer->state.predicating = old_predicating; } void radv_CmdUpdateBuffer( diff --git a/src/amd/vulkan/radv_meta_copy.c b/src/amd/vulkan/radv_meta_copy.c index 3442b49fb9c..f4de5528edf 100644 --- a/src/amd/vulkan/radv_meta_copy.c +++ b/src/amd/vulkan/radv_meta_copy.c @@ -117,6 +117,7 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, { bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; struct radv_meta_saved_state saved_state; + bool old_predicating; /* The Vulkan 1.0 spec says "dstImage must have a sample count equal to * VK_SAMPLE_COUNT_1_BIT." @@ -129,6 +130,12 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS); + /* VK_EXT_conditional_rendering says that copy commands should not be + * affected by conditional rendering. + */ + old_predicating = cmd_buffer->state.predicating; + cmd_buffer->state.predicating = false; + for (unsigned r = 0; r < regionCount; r++) { /** @@ -208,6 +215,9 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, } } + /* Restore conditional rendering. */ + cmd_buffer->state.predicating = old_predicating; + radv_meta_restore(&saved_state, cmd_buffer); } @@ -236,12 +246,19 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, const VkBufferImageCopy* pRegions) { struct radv_meta_saved_state saved_state; + bool old_predicating; radv_meta_save(&saved_state, cmd_buffer, RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS); + /* VK_EXT_conditional_rendering says that copy commands should not be + * affected by conditional rendering. + */ + old_predicating = cmd_buffer->state.predicating; + cmd_buffer->state.predicating = false; + for (unsigned r = 0; r < regionCount; r++) { /** @@ -313,6 +330,9 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, } } + /* Restore conditional rendering. */ + cmd_buffer->state.predicating = old_predicating; + radv_meta_restore(&saved_state, cmd_buffer); } @@ -344,6 +364,7 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, { bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; struct radv_meta_saved_state saved_state; + bool old_predicating; /* From the Vulkan 1.0 spec: * @@ -358,6 +379,12 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS); + /* VK_EXT_conditional_rendering says that copy commands should not be + * affected by conditional rendering. + */ + old_predicating = cmd_buffer->state.predicating; + cmd_buffer->state.predicating = false; + for (unsigned r = 0; r < regionCount; r++) { assert(pRegions[r].srcSubresource.aspectMask == pRegions[r].dstSubresource.aspectMask); @@ -465,6 +492,9 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, } } + /* Restore conditional rendering. */ + cmd_buffer->state.predicating = old_predicating; + radv_meta_restore(&saved_state, cmd_buffer); } diff --git a/src/amd/vulkan/radv_meta_fast_clear.c b/src/amd/vulkan/radv_meta_fast_clear.c index d3cd445d97f..932a6c93aa2 100644 --- a/src/amd/vulkan/radv_meta_fast_clear.c +++ b/src/amd/vulkan/radv_meta_fast_clear.c @@ -586,6 +586,7 @@ radv_emit_color_decompress(struct radv_cmd_buffer *cmd_buffer, VkDevice device_h = radv_device_to_handle(cmd_buffer->device); VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); uint32_t layer_count = radv_get_layerCount(image, subresourceRange); + bool old_predicating; VkPipeline pipeline; assert(cmd_buffer->queue_family_index == RADV_QUEUE_GENERAL); @@ -603,6 +604,8 @@ radv_emit_color_decompress(struct radv_cmd_buffer *cmd_buffer, } if (radv_image_has_dcc(image)) { + old_predicating = cmd_buffer->state.predicating; + radv_emit_set_predication_state_from_image(cmd_buffer, image, true); cmd_buffer->state.predicating = true; } @@ -669,13 +672,21 @@ radv_emit_color_decompress(struct radv_cmd_buffer *cmd_buffer, } if (radv_image_has_dcc(image)) { - cmd_buffer->state.predicating = false; + cmd_buffer->state.predicating = old_predicating; + radv_emit_set_predication_state_from_image(cmd_buffer, image, false); /* Clear the image's fast-clear eliminate predicate because * FMASK and DCC also imply a fast-clear eliminate. */ radv_set_dcc_need_cmask_elim_pred(cmd_buffer, image, false); + + if (cmd_buffer->state.predication_type != -1) { + /* Restore previous conditional rendering user state. */ + si_emit_set_predication_state(cmd_buffer, + cmd_buffer->state.predication_type, + cmd_buffer->state.predication_va); + } } radv_meta_restore(&saved_state, cmd_buffer); } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index c697964273d..d8443cb7bb0 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -982,6 +982,10 @@ struct radv_cmd_state { /* Whether CP DMA is busy/idle. */ bool dma_is_busy; + + /* Conditional rendering info. */ + int predication_type; /* -1: disabled, 0: normal, 1: inverted */ + uint64_t predication_va; }; struct radv_cmd_pool {