diff --git a/qrenderdoc/Code/pyrenderdoc/renderdoc.i b/qrenderdoc/Code/pyrenderdoc/renderdoc.i
index 594a7f763..636479034 100644
--- a/qrenderdoc/Code/pyrenderdoc/renderdoc.i
+++ b/qrenderdoc/Code/pyrenderdoc/renderdoc.i
@@ -291,6 +291,7 @@ TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, DescriptorBinding)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, DescriptorSet)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, ImageData)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, ImageLayout)
+TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, RenderArea)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, SpecializationConstant)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, XFBBuffer)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, VertexBuffer)
diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp
index e2ca8da1d..dfe3429a2 100644
--- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp
+++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp
@@ -284,6 +284,18 @@ VulkanPipelineStateViewer::VulkanPipelineStateViewer(ICaptureContext &ctx,
ui->scissors->setInstantTooltips(true);
}
+ {
+ RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this);
+ ui->discards->setHeader(header);
+
+ ui->discards->setColumns({tr("Slot"), tr("X"), tr("Y"), tr("Width"), tr("Height")});
+ header->setColumnStretchHints({-1, -1, -1, -1, 1});
+ header->setMinimumSectionSize(40);
+
+ ui->discards->setClearSelectionOnFocusLoss(true);
+ ui->discards->setInstantTooltips(true);
+ }
+
for(RDLabel *rp : {ui->renderpass, ui->framebuffer, ui->predicateBuffer, ui->csPredicateBuffer})
{
rp->setAutoFillBackground(true);
@@ -663,6 +675,9 @@ void VulkanPipelineStateViewer::clearState()
ui->viewports->clear();
ui->scissors->clear();
+ ui->discards->clear();
+ ui->discardMode->setText(tr("Inclusive"));
+ ui->discardGroup->setVisible(false);
ui->renderpass->setText(QFormatStr("Render Pass: %1").arg(ToQStr(ResourceId())));
ui->framebuffer->setText(QFormatStr("Framebuffer: %1").arg(ToQStr(ResourceId())));
@@ -1981,6 +1996,34 @@ void VulkanPipelineStateViewer::setState()
////////////////////////////////////////////////
// Rasterizer
+ vs = ui->discards->verticalScrollBar()->value();
+ ui->discards->beginUpdate();
+ ui->discards->clear();
+
+ {
+ int i = 0;
+ for(const VKPipe::RenderArea &v : state.viewportScissor.discardRectangles)
+ {
+ RDTreeWidgetItem *node = new RDTreeWidgetItem({i, v.x, v.y, v.width, v.height});
+ ui->discards->addTopLevelItem(node);
+
+ if(v.width == 0 || v.height == 0)
+ setEmptyRow(node);
+
+ i++;
+ }
+ }
+
+ ui->discards->verticalScrollBar()->setValue(vs);
+ ui->discards->clearSelection();
+ ui->discards->endUpdate();
+
+ ui->discardMode->setText(state.viewportScissor.discardRectanglesExclusive ? tr("Exclusive")
+ : tr("Inclusive"));
+
+ ui->discardGroup->setVisible(!state.viewportScissor.discardRectanglesExclusive ||
+ !state.viewportScissor.discardRectangles.isEmpty());
+
vs = ui->viewports->verticalScrollBar()->value();
ui->viewports->beginUpdate();
ui->viewports->clear();
diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui
index d0b626622..8e4f9fc0a 100644
--- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui
+++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui
@@ -1696,116 +1696,6 @@
0
- -
-
-
-
- 0
- 0
-
-
-
- Scissor Regions
-
-
-
- 2
-
-
- 2
-
-
- 2
-
-
- 2
-
-
-
-
-
- QFrame::Box
-
-
- QFrame::Plain
-
-
- QAbstractItemView::NoEditTriggers
-
-
- false
-
-
- 0
-
-
- false
-
-
- true
-
-
- 50
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Viewports
-
-
-
- 2
-
-
- 2
-
-
- 2
-
-
- 2
-
-
-
-
-
- QFrame::Box
-
-
- QFrame::Plain
-
-
- QAbstractItemView::NoEditTriggers
-
-
- false
-
-
- 0
-
-
- false
-
-
- true
-
-
- 50
-
-
-
-
-
-
-
@@ -2512,6 +2402,193 @@
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 1
+
+
+
+ Scissor Regions
+
+
+
+ 2
+
+
+ 2
+
+
+ 2
+
+
+ 2
+
+
-
+
+
+ QFrame::Box
+
+
+ QFrame::Plain
+
+
+ QAbstractScrollArea::AdjustToContents
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ 0
+
+
+ false
+
+
+ true
+
+
+ 50
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 1
+
+
+
+ Discard Rectangles
+
+
+
+ 2
+
+
+ 2
+
+
+ 2
+
+
+ 2
+
+
-
+
+
+
+ 12
+
+
+
+ Exclusive
+
+
+
+ -
+
+
+ QFrame::Box
+
+
+ QFrame::Plain
+
+
+ QAbstractScrollArea::AdjustToContents
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ 0
+
+
+ false
+
+
+ 50
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Viewports
+
+
+
+ 2
+
+
+ 2
+
+
+ 2
+
+
+ 2
+
+
-
+
+
+ QFrame::Box
+
+
+ QFrame::Plain
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ 0
+
+
+ false
+
+
+ true
+
+
+ 50
+
+
+
+
+
+
@@ -3552,7 +3629,7 @@
0
0
911
- 458
+ 394
diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h
index d36d73dbe..e289de5cc 100644
--- a/renderdoc/api/replay/vk_pipestate.h
+++ b/renderdoc/api/replay/vk_pipestate.h
@@ -566,6 +566,39 @@ struct TransformFeedback
rdcarray buffers;
};
+DOCUMENT("Describes a render area in the current framebuffer.");
+struct RenderArea
+{
+ DOCUMENT("");
+ RenderArea() = default;
+ RenderArea(const RenderArea &) = default;
+ bool operator==(const RenderArea &o) const
+ {
+ return x == o.x && y == o.y && width == o.width && height == o.height;
+ }
+ bool operator<(const RenderArea &o) const
+ {
+ if(!(x == o.x))
+ return x < o.x;
+ if(!(y == o.y))
+ return y < o.y;
+ if(!(width == o.width))
+ return width < o.width;
+ if(!(height == o.height))
+ return height < o.height;
+ return false;
+ }
+
+ DOCUMENT("The X co-ordinate of the render area.");
+ int32_t x = 0;
+ DOCUMENT("The Y co-ordinate of the render area.");
+ int32_t y = 0;
+ DOCUMENT("The width of the render area.");
+ int32_t width = 0;
+ DOCUMENT("The height of the render area.");
+ int32_t height = 0;
+};
+
DOCUMENT("Describes a combined viewport and scissor region.");
struct ViewportScissor
{
@@ -574,7 +607,14 @@ struct ViewportScissor
ViewportScissor(const ViewportScissor &) = default;
bool operator==(const ViewportScissor &o) const { return vp == o.vp && scissor == o.scissor; }
- bool operator<(const ViewportScissor &o) const { return vp == o.vp && scissor == o.scissor; }
+ bool operator<(const ViewportScissor &o) const
+ {
+ if(!(vp == o.vp))
+ return vp < o.vp;
+ if(!(scissor == o.scissor))
+ return scissor < o.scissor;
+ return false;
+ }
DOCUMENT("The :class:`Viewport`.");
Viewport vp;
DOCUMENT("The :class:`Scissor`.");
@@ -590,6 +630,21 @@ struct ViewState
DOCUMENT("A list of :class:`VKViewportScissor`.");
rdcarray viewportScissors;
+
+ DOCUMENT("A list of :class:`VKRenderArea` defining discard rectangles.");
+ rdcarray discardRectangles;
+
+ DOCUMENT(R"( ``True`` if a fragment in any one of the discard rectangles fails the discard test,
+and a fragment in none of them passes.
+
+``False`` if a fragment in any one of the discard rectangles passes the discard test,
+and a fragment in none of them is discarded.
+
+.. note:
+ A ``True`` value and an empty list of :data:`discardRectangles` means the test is effectively
+ disabled, since with no rectangles no fragment can be inside one.
+)");
+ bool discardRectanglesExclusive = true;
};
DOCUMENT("Describes the rasterizer state in the pipeline.");
@@ -839,23 +894,6 @@ struct Framebuffer
uint32_t layers = 0;
};
-DOCUMENT("Describes the render area for a render pass instance.");
-struct RenderArea
-{
- DOCUMENT("");
- RenderArea() = default;
- RenderArea(const RenderArea &) = default;
-
- DOCUMENT("The X co-ordinate of the render area.");
- int32_t x = 0;
- DOCUMENT("The Y co-ordinate of the render area.");
- int32_t y = 0;
- DOCUMENT("The width of the render area.");
- int32_t width = 0;
- DOCUMENT("The height of the render area.");
- int32_t height = 0;
-};
-
DOCUMENT("Describes the current pass instance at the current time.");
struct CurrentPass
{
diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h
index c283478fc..5d68018b9 100644
--- a/renderdoc/driver/vulkan/vk_common.h
+++ b/renderdoc/driver/vulkan/vk_common.h
@@ -520,6 +520,7 @@ enum class VulkanChunk : uint32_t
vkCmdBeginConditionalRenderingEXT,
vkCmdEndConditionalRenderingEXT,
vkCmdSetSampleLocationsEXT,
+ vkCmdSetDiscardRectangleEXT,
Max,
};
@@ -680,12 +681,15 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceASTCDecodeFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceConditionalRenderingFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceConservativeRasterizationPropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDepthStencilResolvePropertiesKHR);
+DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDiscardRectanglePropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDriverPropertiesKHR);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExternalBufferInfo);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExternalFenceInfo);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExternalImageFormatInfo);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExternalSemaphoreInfo);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFeatures2);
+DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFloat16Int8FeaturesKHR);
+DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFloatControlsPropertiesKHR);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGroupProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceIDProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceImageFormatInfo2);
@@ -707,8 +711,6 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderAtomicInt64FeaturesKHR);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderCorePropertiesAMD);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderDrawParameterFeatures);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderImageFootprintFeaturesNV);
-DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFloat16Int8FeaturesKHR);
-DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFloatControlsPropertiesKHR);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceSampleLocationsPropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceSparseImageFormatInfo2);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceSubgroupProperties);
@@ -722,6 +724,7 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceVulkanMemoryModelFeaturesKHR);
DECLARE_REFLECTION_STRUCT(VkPipelineCacheCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineColorBlendStateCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineDepthStencilStateCreateInfo);
+DECLARE_REFLECTION_STRUCT(VkPipelineDiscardRectangleStateCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineDynamicStateCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineInputAssemblyStateCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineLayoutCreateInfo);
@@ -890,6 +893,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceASTCDecodeFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceConditionalRenderingFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceConservativeRasterizationPropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDepthStencilResolvePropertiesKHR);
+DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDiscardRectanglePropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDriverPropertiesKHR);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExternalBufferInfo);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExternalFenceInfo);
@@ -932,6 +936,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceVulkanMemoryModelFeaturesKHR);
DECLARE_DESERIALISE_TYPE(VkPipelineCacheCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineColorBlendStateCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineDepthStencilStateCreateInfo);
+DECLARE_DESERIALISE_TYPE(VkPipelineDiscardRectangleStateCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkPipelineDynamicStateCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineInputAssemblyStateCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineLayoutCreateInfo);
@@ -1139,6 +1144,7 @@ DECLARE_REFLECTION_ENUM(VkDescriptorUpdateTemplateType);
DECLARE_REFLECTION_ENUM(VkDeviceEventTypeEXT);
DECLARE_REFLECTION_ENUM(VkDeviceGroupPresentModeFlagBitsKHR);
DECLARE_REFLECTION_ENUM(VkDeviceQueueCreateFlagBits);
+DECLARE_REFLECTION_ENUM(VkDiscardRectangleModeEXT);
DECLARE_REFLECTION_ENUM(VkDisplayEventTypeEXT);
DECLARE_REFLECTION_ENUM(VkDisplayPlaneAlphaFlagBitsKHR);
DECLARE_REFLECTION_ENUM(VkDisplayPowerStateEXT);
diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp
index 28e2faccf..3964417d4 100644
--- a/renderdoc/driver/vulkan/vk_core.cpp
+++ b/renderdoc/driver/vulkan/vk_core.cpp
@@ -657,6 +657,9 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION,
},
+ {
+ VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION,
+ },
{
VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME, VK_EXT_DISPLAY_CONTROL_SPEC_VERSION,
},
@@ -2772,6 +2775,8 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
return Serialise_vkCmdEndConditionalRenderingEXT(ser, VK_NULL_HANDLE);
case VulkanChunk::vkCmdSetSampleLocationsEXT:
return Serialise_vkCmdSetSampleLocationsEXT(ser, VK_NULL_HANDLE, NULL);
+ case VulkanChunk::vkCmdSetDiscardRectangleEXT:
+ return Serialise_vkCmdSetDiscardRectangleEXT(ser, VK_NULL_HANDLE, 0, 0, NULL);
default:
{
SystemChunk system = (SystemChunk)chunk;
diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h
index 84a1a8a46..5a8269317 100644
--- a/renderdoc/driver/vulkan/vk_core.h
+++ b/renderdoc/driver/vulkan/vk_core.h
@@ -2007,4 +2007,10 @@ public:
void vkGetPhysicalDeviceMultisamplePropertiesEXT(VkPhysicalDevice physicalDevice,
VkSampleCountFlagBits samples,
VkMultisamplePropertiesEXT *pMultisampleProperties);
+
+ // VK_EXT_discard_rectangles
+
+ IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetDiscardRectangleEXT, VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle, uint32_t discardRectangleCount,
+ const VkRect2D *pDiscardRectangles);
};
diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h
index 2714c01cd..2b9ddafb5 100644
--- a/renderdoc/driver/vulkan/vk_hookset_defs.h
+++ b/renderdoc/driver/vulkan/vk_hookset_defs.h
@@ -354,7 +354,8 @@
DeclExt(KHR_create_renderpass2); \
DeclExt(EXT_transform_feedback); \
DeclExt(EXT_conditional_rendering); \
- DeclExt(EXT_sample_locations);
+ DeclExt(EXT_sample_locations); \
+ DeclExt(EXT_discard_rectangles);
// for simplicity and since the check itself is platform agnostic,
// these aren't protected in platform defines
@@ -421,7 +422,8 @@
CheckExt(KHR_create_renderpass2, VKXX); \
CheckExt(EXT_transform_feedback, VKXX); \
CheckExt(EXT_conditional_rendering, VKXX); \
- CheckExt(EXT_sample_locations, VKXX);
+ CheckExt(EXT_sample_locations, VKXX); \
+ CheckExt(EXT_discard_rectangles, VKXX);
#define HookInitVulkanInstanceExts() \
HookInitExtension(KHR_surface, DestroySurfaceKHR); \
@@ -552,6 +554,7 @@
HookInitExtension(EXT_conditional_rendering, CmdBeginConditionalRenderingEXT); \
HookInitExtension(EXT_conditional_rendering, CmdEndConditionalRenderingEXT); \
HookInitExtension(EXT_sample_locations, CmdSetSampleLocationsEXT); \
+ HookInitExtension(EXT_discard_rectangles, CmdSetDiscardRectangleEXT); \
HookInitDevice_PlatformSpecific()
#define DefineHooks() \
@@ -1112,6 +1115,9 @@
const VkSampleLocationsInfoEXT *, pSampleLocationsInfo); \
HookDefine3(void, vkGetPhysicalDeviceMultisamplePropertiesEXT, VkPhysicalDevice, physicalDevice, \
VkSampleCountFlagBits, samples, VkMultisamplePropertiesEXT *, pMultisampleProperties); \
+ HookDefine4(void, vkCmdSetDiscardRectangleEXT, VkCommandBuffer, commandBuffer, uint32_t, \
+ firstDiscardRectangle, uint32_t, discardRectangleCount, const VkRect2D *, \
+ pDiscardRectangles); \
HookDefine_PlatformSpecific()
struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable
diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp
index 1794d0b52..1cf0bc306 100644
--- a/renderdoc/driver/vulkan/vk_info.cpp
+++ b/renderdoc/driver/vulkan/vk_info.cpp
@@ -334,6 +334,25 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
scissors[i] = pCreateInfo->pViewportState->pScissors[i];
}
+ // VkPipelineDiscardRectangleStateCreateInfoEXT
+ discardMode = VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT;
+
+ const VkPipelineDiscardRectangleStateCreateInfoEXT *discardRects =
+ (const VkPipelineDiscardRectangleStateCreateInfoEXT *)FindNextStruct(
+ pCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT);
+ if(discardRects)
+ {
+ discardRectangles.resize(discardRects->discardRectangleCount);
+
+ if(discardRects->pDiscardRectangles)
+ {
+ for(uint32_t i = 0; i < discardRects->discardRectangleCount; i++)
+ discardRectangles[i] = discardRects->pDiscardRectangles[i];
+ }
+
+ discardMode = discardRects->discardRectangleMode;
+ }
+
// VkPipelineRasterStateCreateInfo
depthClampEnable = pCreateInfo->pRasterizationState->depthClampEnable ? true : false;
rasterizerDiscardEnable = pCreateInfo->pRasterizationState->rasterizerDiscardEnable ? true : false;
diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h
index 40b2e6891..53ab7c6fe 100644
--- a/renderdoc/driver/vulkan/vk_info.h
+++ b/renderdoc/driver/vulkan/vk_info.h
@@ -270,6 +270,10 @@ struct VulkanCreationInfo
// VkPipelineDynamicStateCreateInfo
bool dynamicStates[VkDynamicCount];
+
+ // VkPipelineDiscardRectangleStateCreateInfoEXT
+ std::vector discardRectangles;
+ VkDiscardRectangleModeEXT discardMode;
};
map m_Pipeline;
diff --git a/renderdoc/driver/vulkan/vk_next_chains.cpp b/renderdoc/driver/vulkan/vk_next_chains.cpp
index e3bb3e83b..b9cca8c53 100644
--- a/renderdoc/driver/vulkan/vk_next_chains.cpp
+++ b/renderdoc/driver/vulkan/vk_next_chains.cpp
@@ -151,12 +151,16 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPhysicalDeviceASTCDecodeFeaturesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT, \
VkPhysicalDeviceBufferAddressFeaturesEXT); \
+ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, \
+ VkPhysicalDeviceConditionalRenderingFeaturesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT, \
VkPhysicalDeviceConservativeRasterizationPropertiesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, \
VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR, \
VkPhysicalDeviceDepthStencilResolvePropertiesKHR); \
+ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT, \
+ VkPhysicalDeviceDiscardRectanglePropertiesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR, \
VkPhysicalDeviceDriverPropertiesKHR); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, \
@@ -232,13 +236,13 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR, \
VkPhysicalDeviceVulkanMemoryModelFeaturesKHR); \
- COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, \
- VkPhysicalDeviceConditionalRenderingFeaturesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, VkPipelineCacheCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, \
VkPipelineColorBlendStateCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, \
VkPipelineDepthStencilStateCreateInfo); \
+ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT, \
+ VkPipelineDiscardRectangleStateCreateInfoEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, \
VkPipelineDynamicStateCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, \
@@ -459,7 +463,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT: \
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV: \
@@ -478,7 +481,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT: \
case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV: \
- case VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT: \
case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD: \
case VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV: \
diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp
index ef5c2b830..fd643e0d4 100644
--- a/renderdoc/driver/vulkan/vk_replay.cpp
+++ b/renderdoc/driver/vulkan/vk_replay.cpp
@@ -1049,6 +1049,24 @@ void VulkanReplay::SavePipelineState()
}
}
+ {
+ m_VulkanPipelineState.viewportScissor.discardRectangles.resize(p.discardRectangles.size());
+ for(size_t i = 0; i < p.discardRectangles.size() && i < state.discardRectangles.size(); i++)
+ {
+ m_VulkanPipelineState.viewportScissor.discardRectangles[i].x =
+ state.discardRectangles[i].offset.x;
+ m_VulkanPipelineState.viewportScissor.discardRectangles[i].y =
+ state.discardRectangles[i].offset.y;
+ m_VulkanPipelineState.viewportScissor.discardRectangles[i].width =
+ state.discardRectangles[i].extent.width;
+ m_VulkanPipelineState.viewportScissor.discardRectangles[i].height =
+ state.discardRectangles[i].extent.height;
+ }
+
+ m_VulkanPipelineState.viewportScissor.discardRectanglesExclusive =
+ (p.discardMode == VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT);
+ }
+
// Rasterizer
m_VulkanPipelineState.rasterizer.depthClampEnable = p.depthClampEnable;
m_VulkanPipelineState.rasterizer.rasterizerDiscardEnable = p.rasterizerDiscardEnable;
@@ -1211,6 +1229,9 @@ void VulkanReplay::SavePipelineState()
*stages[i] = VKPipe::Shader();
m_VulkanPipelineState.viewportScissor.viewportScissors.clear();
+ m_VulkanPipelineState.viewportScissor.discardRectangles.clear();
+ m_VulkanPipelineState.viewportScissor.discardRectanglesExclusive = true;
+
m_VulkanPipelineState.colorBlend.blends.clear();
}
diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp
index 04c1cbf6e..196d06f76 100644
--- a/renderdoc/driver/vulkan/vk_serialise.cpp
+++ b/renderdoc/driver/vulkan/vk_serialise.cpp
@@ -445,6 +445,12 @@ SERIALISE_VK_HANDLES();
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, \
VkDebugUtilsMessengerCreateInfoEXT) \
\
+ /* VK_EXT_discard_rectangles */ \
+ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT, \
+ VkPhysicalDeviceDiscardRectanglePropertiesEXT) \
+ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT, \
+ VkPipelineDiscardRectangleStateCreateInfoEXT) \
+ \
/* VK_EXT_display_control */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT, VkDisplayPowerInfoEXT) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT, VkDeviceEventInfoEXT) \
@@ -788,10 +794,6 @@ SERIALISE_VK_HANDLES();
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT) \
\
- /* VK_EXT_discard_rectangles */ \
- PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT) \
- PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT) \
- \
/* VK_EXT_external_memory_host */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT) \
@@ -4951,6 +4953,43 @@ void Deserialise(const VkFenceGetFdInfoKHR &el)
DeserialiseNext(el.pNext);
}
+template
+void DoSerialise(SerialiserType &ser, VkPhysicalDeviceDiscardRectanglePropertiesEXT &el)
+{
+ RDCASSERT(ser.IsReading() ||
+ el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT);
+ SerialiseNext(ser, el.sType, el.pNext);
+
+ SERIALISE_MEMBER(maxDiscardRectangles);
+}
+
+template <>
+void Deserialise(const VkPhysicalDeviceDiscardRectanglePropertiesEXT &el)
+{
+ DeserialiseNext(el.pNext);
+}
+
+template
+void DoSerialise(SerialiserType &ser, VkPipelineDiscardRectangleStateCreateInfoEXT &el)
+{
+ RDCASSERT(ser.IsReading() ||
+ el.sType == VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT);
+ SerialiseNext(ser, el.sType, el.pNext);
+
+ SERIALISE_MEMBER_VKFLAGS(VkPipelineDiscardRectangleStateCreateFlagsEXT, flags);
+
+ SERIALISE_MEMBER(discardRectangleMode);
+ SERIALISE_MEMBER(discardRectangleCount);
+ SERIALISE_MEMBER_ARRAY(pDiscardRectangles, discardRectangleCount);
+}
+
+template <>
+void Deserialise(const VkPipelineDiscardRectangleStateCreateInfoEXT &el)
+{
+ DeserialiseNext(el.pNext);
+ delete[] el.pDiscardRectangles;
+}
+
template
void DoSerialise(SerialiserType &ser, VkDisplayPowerInfoEXT &el)
{
@@ -6173,6 +6212,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevice8BitStorageFeaturesKHR);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceASTCDecodeFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceConservativeRasterizationPropertiesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceDepthStencilResolvePropertiesKHR);
+INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceDiscardRectanglePropertiesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceDriverPropertiesKHR);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceExternalBufferInfo);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceExternalFenceInfo);
@@ -6213,6 +6253,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceConditionalRenderingFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineCacheCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineColorBlendStateCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineDepthStencilStateCreateInfo);
+INSTANTIATE_SERIALISE_TYPE(VkPipelineDiscardRectangleStateCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineDynamicStateCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineInputAssemblyStateCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineLayoutCreateInfo);
diff --git a/renderdoc/driver/vulkan/vk_state.cpp b/renderdoc/driver/vulkan/vk_state.cpp
index 54449caf5..6967dc9e0 100644
--- a/renderdoc/driver/vulkan/vk_state.cpp
+++ b/renderdoc/driver/vulkan/vk_state.cpp
@@ -275,6 +275,10 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd, PipelineBinding bindin
ObjDisp(cmd)->CmdSetSampleLocationsEXT(Unwrap(cmd), &info);
}
+ if(!discardRectangles.empty() && dynamicStates[VkDynamicDiscardRectangleEXT])
+ ObjDisp(cmd)->CmdSetDiscardRectangleEXT(Unwrap(cmd), 0, (uint32_t)discardRectangles.size(),
+ &discardRectangles[0]);
+
// only set push constant ranges that the layout uses
for(size_t i = 0; i < pushRanges.size(); i++)
ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags,
diff --git a/renderdoc/driver/vulkan/vk_state.h b/renderdoc/driver/vulkan/vk_state.h
index bd6d01355..20c1ea7dd 100644
--- a/renderdoc/driver/vulkan/vk_state.h
+++ b/renderdoc/driver/vulkan/vk_state.h
@@ -82,6 +82,8 @@ struct VulkanRenderState
std::vector locations;
} sampleLocations;
+ std::vector discardRectangles;
+
// this should be big enough for any implementation
byte pushconsts[1024];
// the actual number of bytes that have been uploaded
diff --git a/renderdoc/driver/vulkan/vk_stringise.cpp b/renderdoc/driver/vulkan/vk_stringise.cpp
index 7345a2e56..f1a9b5948 100644
--- a/renderdoc/driver/vulkan/vk_stringise.cpp
+++ b/renderdoc/driver/vulkan/vk_stringise.cpp
@@ -28,7 +28,7 @@
template <>
std::string DoStringise(const VulkanChunk &el)
{
- RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1131, "Chunks changed without updating names");
+ RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1132, "Chunks changed without updating names");
BEGIN_ENUM_STRINGISE(VulkanChunk)
{
@@ -163,6 +163,7 @@ std::string DoStringise(const VulkanChunk &el)
STRINGISE_ENUM_CLASS(vkCmdBeginConditionalRenderingEXT)
STRINGISE_ENUM_CLASS(vkCmdEndConditionalRenderingEXT)
STRINGISE_ENUM_CLASS(vkCmdSetSampleLocationsEXT)
+ STRINGISE_ENUM_CLASS(vkCmdSetDiscardRectangleEXT)
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
}
END_ENUM_STRINGISE()
@@ -2216,6 +2217,17 @@ std::string DoStringise(const VkDisplayEventTypeEXT &el)
END_ENUM_STRINGISE();
}
+template <>
+std::string DoStringise(const VkDiscardRectangleModeEXT &el)
+{
+ BEGIN_ENUM_STRINGISE(VkDiscardRectangleModeEXT);
+ {
+ STRINGISE_ENUM(VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT)
+ STRINGISE_ENUM(VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT)
+ }
+ END_ENUM_STRINGISE();
+}
+
template <>
std::string DoStringise(const VkPointClippingBehavior &el)
{
diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp
index 9c7a4b867..0501ee5b5 100644
--- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp
+++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp
@@ -1879,6 +1879,10 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline(SerialiserType &ser, VkCommandBu
m_RenderState.sampleLocations.sampleCount =
m_CreationInfo.m_Pipeline[liveid].rasterizationSamples;
}
+ if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VkDynamicDiscardRectangleEXT])
+ {
+ m_RenderState.discardRectangles = m_CreationInfo.m_Pipeline[liveid].discardRectangles;
+ }
}
}
}
diff --git a/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp
index 2471b736e..df0a73d44 100644
--- a/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp
+++ b/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp
@@ -667,6 +667,81 @@ void WrappedVulkan::vkCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
}
}
+template
+bool WrappedVulkan::Serialise_vkCmdSetDiscardRectangleEXT(SerialiserType &ser,
+ VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle,
+ uint32_t discardRectangleCount,
+ const VkRect2D *pDiscardRectangles)
+{
+ SERIALISE_ELEMENT(commandBuffer);
+ SERIALISE_ELEMENT(firstDiscardRectangle);
+ SERIALISE_ELEMENT(discardRectangleCount);
+ SERIALISE_ELEMENT_ARRAY(pDiscardRectangles, discardRectangleCount);
+
+ Serialise_DebugMessages(ser);
+
+ SERIALISE_CHECK_READ_ERRORS();
+
+ if(IsReplayingAndReading())
+ {
+ m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
+
+ if(IsActiveReplaying(m_State))
+ {
+ if(InRerecordRange(m_LastCmdBufferID))
+ {
+ commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
+
+ if(ShouldUpdateRenderState(m_LastCmdBufferID))
+ {
+ if(m_RenderState.discardRectangles.size() < firstDiscardRectangle + discardRectangleCount)
+ m_RenderState.discardRectangles.resize(firstDiscardRectangle + discardRectangleCount);
+
+ for(uint32_t i = 0; i < discardRectangleCount; i++)
+ m_RenderState.discardRectangles[firstDiscardRectangle + i] = pDiscardRectangles[i];
+ }
+ }
+ else
+ {
+ commandBuffer = VK_NULL_HANDLE;
+ }
+ }
+
+ if(commandBuffer != VK_NULL_HANDLE)
+ ObjDisp(commandBuffer)
+ ->CmdSetDiscardRectangleEXT(Unwrap(commandBuffer), firstDiscardRectangle,
+ discardRectangleCount, pDiscardRectangles);
+ }
+
+ return true;
+}
+
+void WrappedVulkan::vkCmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle,
+ uint32_t discardRectangleCount,
+ const VkRect2D *pDiscardRectangles)
+{
+ SCOPED_DBG_SINK();
+
+ SERIALISE_TIME_CALL(ObjDisp(commandBuffer)
+ ->CmdSetDiscardRectangleEXT(Unwrap(commandBuffer), firstDiscardRectangle,
+ discardRectangleCount, pDiscardRectangles));
+
+ if(IsCaptureMode(m_State))
+ {
+ VkResourceRecord *record = GetRecord(commandBuffer);
+
+ CACHE_THREAD_SERIALISER();
+
+ SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetDiscardRectangleEXT);
+ Serialise_vkCmdSetDiscardRectangleEXT(ser, commandBuffer, firstDiscardRectangle,
+ discardRectangleCount, pDiscardRectangles);
+
+ record->AddChunk(scope.Get());
+ }
+}
+
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetViewport, VkCommandBuffer commandBuffer,
uint32_t firstViewport, uint32_t viewportCount,
const VkViewport *pViewports);
@@ -698,4 +773,8 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetStencilReference, VkCommandBuffer
VkStencilFaceFlags faceMask, uint32_t reference);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetSampleLocationsEXT, VkCommandBuffer commandBuffer,
- const VkSampleLocationsInfoEXT *pSampleLocationsInfo);
\ No newline at end of file
+ const VkSampleLocationsInfoEXT *pSampleLocationsInfo);
+
+INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetDiscardRectangleEXT, VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle, uint32_t discardRectangleCount,
+ const VkRect2D *pDiscardRectangles);
\ No newline at end of file
diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl
index 40a908164..ebb2f1fd5 100644
--- a/renderdoc/replay/renderdoc_serialise.inl
+++ b/renderdoc/replay/renderdoc_serialise.inl
@@ -1976,8 +1976,10 @@ template
void DoSerialise(SerialiserType &ser, VKPipe::ViewState &el)
{
SERIALISE_MEMBER(viewportScissors);
+ SERIALISE_MEMBER(discardRectangles);
+ SERIALISE_MEMBER(discardRectanglesExclusive);
- SIZE_CHECK(16);
+ SIZE_CHECK(40);
}
template
@@ -2181,7 +2183,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::State &el)
SERIALISE_MEMBER(conditionalRendering);
- SIZE_CHECK(1408);
+ SIZE_CHECK(1432);
}
#pragma endregion Vulkan pipeline state
diff --git a/util/test/demos/demos.vcxproj b/util/test/demos/demos.vcxproj
index 4add3184f..3ff7a167e 100644
--- a/util/test/demos/demos.vcxproj
+++ b/util/test/demos/demos.vcxproj
@@ -192,6 +192,7 @@
+
diff --git a/util/test/demos/demos.vcxproj.filters b/util/test/demos/demos.vcxproj.filters
index 84cfcd6c6..632f0c4b2 100644
--- a/util/test/demos/demos.vcxproj.filters
+++ b/util/test/demos/demos.vcxproj.filters
@@ -249,6 +249,9 @@
Vulkan\demos
+
+ Vulkan\demos
+
diff --git a/util/test/demos/vk/vk_discard_rects.cpp b/util/test/demos/vk/vk_discard_rects.cpp
new file mode 100644
index 000000000..b8f8495bf
--- /dev/null
+++ b/util/test/demos/vk/vk_discard_rects.cpp
@@ -0,0 +1,209 @@
+/******************************************************************************
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018-2019 Baldur Karlsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ ******************************************************************************/
+
+#include "vk_test.h"
+
+struct VK_Discard_Rectangles : VulkanGraphicsTest
+{
+ static constexpr const char *Description =
+ "Draws a large number of triangles using VK_EXT_discard_rectangles discard rectangles to "
+ "either cut-out or filter for a series of rects";
+
+ std::string common = R"EOSHADER(
+
+#version 420 core
+
+struct v2f
+{
+ vec4 pos;
+ vec4 col;
+ vec4 uv;
+};
+
+)EOSHADER";
+
+ const std::string vertex = R"EOSHADER(
+
+layout(location = 0) in vec3 Position;
+layout(location = 1) in vec4 Color;
+layout(location = 2) in vec2 UV;
+
+layout(location = 0) out v2f vertOut;
+
+void main()
+{
+ vertOut.pos = vec4(Position.xyz*vec3(1,-1,1), 1);
+ gl_Position = vertOut.pos;
+ vertOut.col = Color;
+ vertOut.uv = vec4(UV.xy, 0, 1);
+}
+
+)EOSHADER";
+
+ const std::string pixel = R"EOSHADER(
+
+layout(location = 0) in v2f vertIn;
+
+layout(location = 0, index = 0) out vec4 Color;
+
+void main()
+{
+ Color = vertIn.col;
+}
+
+)EOSHADER";
+
+ int main(int argc, char **argv)
+ {
+ instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ devExts.push_back(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
+
+ // initialise, create window, create context, etc
+ if(!Init(argc, argv))
+ return 3;
+
+ VkPhysicalDeviceDiscardRectanglePropertiesEXT discardProps = {
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT};
+
+ vkGetPhysicalDeviceProperties2KHR(phys, vkh::PhysicalDeviceProperties2KHR().next(&discardProps));
+
+ const int32_t w = (int32_t)scissor.extent.width;
+ const int32_t h = (int32_t)scissor.extent.height;
+
+ VkRect2D discardRects[] = {
+ // TL eye
+ {{64, 64}, {64, 64}},
+ // TR eye
+ {{w - 64 * 2, 64}, {64, 64}},
+ // nose
+ {{w / 2 - 16, 128}, {32, 32}},
+ // long mouth
+ {{96, h - 48}, {(uint32_t)w - 96 * 2, 32}},
+ // left mouth edge
+ {{64, h - 48 - 32}, {32, 32}},
+ // right mouth edge
+ {{w - 96, h - 48 - 32}, {32, 32}},
+ };
+
+ TEST_ASSERT(discardProps.maxDiscardRectangles >= ARRAY_COUNT(discardRects),
+ "not enough discard rectangles supported");
+
+ VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo());
+
+ vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
+
+ pipeCreateInfo.layout = layout;
+ pipeCreateInfo.renderPass = swapRenderPass;
+
+ pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
+ pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
+ vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
+ vkh::vertexAttr(2, 0, DefaultA2V, uv),
+ };
+
+ pipeCreateInfo.stages = {
+ CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
+ CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
+ };
+
+ pipeCreateInfo.dynamicState.dynamicStates.push_back(VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
+
+ VkPipelineDiscardRectangleStateCreateInfoEXT discardInfo = {
+ VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT,
+ };
+ discardInfo.discardRectangleMode = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT;
+ discardInfo.discardRectangleCount = ARRAY_COUNT(discardRects);
+
+ pipeCreateInfo.pNext = &discardInfo;
+
+ VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);
+
+ discardInfo.discardRectangleMode = VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT;
+
+ VkPipeline pipe2 = createGraphicsPipeline(pipeCreateInfo);
+
+ DefaultA2V trispam[3000];
+ for(int i = 0; i < 3000; i++)
+ {
+ trispam[i].pos = Vec3f(RANDF(-1.0f, 1.0f), RANDF(-1.0f, 1.0f), RANDF(0.0f, 1.0f));
+ trispam[i].col = Vec4f(RANDF(0.0f, 1.0f), RANDF(0.0f, 1.0f), RANDF(0.0f, 1.0f), 1.0f);
+ trispam[i].uv = Vec2f(0.0f, 0.0f);
+ }
+
+ AllocatedBuffer vb(allocator,
+ vkh::BufferCreateInfo(sizeof(trispam), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT),
+ VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
+
+ vb.upload(trispam);
+
+ while(Running())
+ {
+ VkCommandBuffer cmd = GetCommandBuffer();
+
+ vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
+
+ VkImage swapimg =
+ StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+
+ vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
+ vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
+ vkh::ImageSubresourceRange());
+
+ vkCmdBeginRenderPass(
+ cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
+ VK_SUBPASS_CONTENTS_INLINE);
+
+ VkViewport view = viewport;
+ view.width /= 2.0f;
+
+ vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
+ vkCmdSetDiscardRectangleEXT(cmd, 0, ARRAY_COUNT(discardRects), discardRects);
+ vkCmdSetViewport(cmd, 0, 1, &view);
+ vkCmdSetScissor(cmd, 0, 1, &scissor);
+ vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
+ vkCmdDraw(cmd, 3000, 1, 0, 0);
+
+ view.x += view.width;
+
+ vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2);
+ vkCmdSetViewport(cmd, 0, 1, &view);
+ vkCmdDraw(cmd, 3000, 1, 0, 0);
+
+ vkCmdEndRenderPass(cmd);
+
+ FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+
+ vkEndCommandBuffer(cmd);
+
+ Submit(0, 1, {cmd});
+
+ Present();
+ }
+
+ return 0;
+ }
+};
+
+REGISTER_TEST(VK_Discard_Rectangles);
\ No newline at end of file