Add support for VK_EXT_discard_rectangles

This commit is contained in:
baldurk
2019-02-05 18:40:31 +00:00
parent 354b37be56
commit 6d07e1c42e
22 changed files with 730 additions and 145 deletions
+1
View File
@@ -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)
@@ -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();
@@ -1696,116 +1696,6 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="3" column="1">
<widget class="QGroupBox" name="scissorGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Scissor Regions</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_22">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="scissors">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerMinimumSectionSize">
<number>50</number>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QGroupBox" name="viewportsGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Viewports</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_21">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="viewports">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerMinimumSectionSize">
<number>50</number>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="conditionalRenderingGroup">
<property name="title">
@@ -2512,6 +2402,193 @@
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QVBoxLayout" name="verticalLayout_18">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="scissorGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Scissor Regions</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_22">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="scissors">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerMinimumSectionSize">
<number>50</number>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="discardGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Discard Rectangles</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_19">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="discardMode">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Exclusive</string>
</property>
</widget>
</item>
<item>
<widget class="RDTreeWidget" name="discards">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<attribute name="headerMinimumSectionSize">
<number>50</number>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QGroupBox" name="viewportsGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Viewports</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_21">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="viewports">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerMinimumSectionSize">
<number>50</number>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="FS">
@@ -3552,7 +3629,7 @@
<x>0</x>
<y>0</y>
<width>911</width>
<height>458</height>
<height>394</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
+56 -18
View File
@@ -566,6 +566,39 @@ struct TransformFeedback
rdcarray<XFBBuffer> 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<ViewportScissor> viewportScissors;
DOCUMENT("A list of :class:`VKRenderArea` defining discard rectangles.");
rdcarray<RenderArea> 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
{
+8 -2
View File
@@ -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);
+5
View File
@@ -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;
+6
View File
@@ -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);
};
+8 -2
View File
@@ -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
+19
View File
@@ -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;
+4
View File
@@ -270,6 +270,10 @@ struct VulkanCreationInfo
// VkPipelineDynamicStateCreateInfo
bool dynamicStates[VkDynamicCount];
// VkPipelineDiscardRectangleStateCreateInfoEXT
std::vector<VkRect2D> discardRectangles;
VkDiscardRectangleModeEXT discardMode;
};
map<ResourceId, Pipeline> m_Pipeline;
+6 -4
View File
@@ -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: \
+21
View File
@@ -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();
}
+45 -4
View File
@@ -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 <typename SerialiserType>
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 <typename SerialiserType>
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 <typename SerialiserType>
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);
+4
View File
@@ -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,
+2
View File
@@ -82,6 +82,8 @@ struct VulkanRenderState
std::vector<VkSampleLocationEXT> locations;
} sampleLocations;
std::vector<VkRect2D> discardRectangles;
// this should be big enough for any implementation
byte pushconsts[1024];
// the actual number of bytes that have been uploaded
+13 -1
View File
@@ -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)
{
@@ -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;
}
}
}
}
@@ -667,6 +667,81 @@ void WrappedVulkan::vkCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
}
}
template <typename SerialiserType>
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);
const VkSampleLocationsInfoEXT *pSampleLocationsInfo);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetDiscardRectangleEXT, VkCommandBuffer commandBuffer,
uint32_t firstDiscardRectangle, uint32_t discardRectangleCount,
const VkRect2D *pDiscardRectangles);
+4 -2
View File
@@ -1976,8 +1976,10 @@ template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VKPipe::ViewState &el)
{
SERIALISE_MEMBER(viewportScissors);
SERIALISE_MEMBER(discardRectangles);
SERIALISE_MEMBER(discardRectanglesExclusive);
SIZE_CHECK(16);
SIZE_CHECK(40);
}
template <typename SerialiserType>
@@ -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
+1
View File
@@ -192,6 +192,7 @@
<ClCompile Include="test_common.cpp" />
<ClCompile Include="vk\vk_awkward_triangle.cpp" />
<ClCompile Include="vk\vk_cbuffer_zoo.cpp" />
<ClCompile Include="vk\vk_discard_rects.cpp" />
<ClCompile Include="vk\vk_draw_zoo.cpp" />
<ClCompile Include="vk\vk_helpers.cpp" />
<ClCompile Include="vk\vk_indirect.cpp" />
+3
View File
@@ -249,6 +249,9 @@
<ClCompile Include="vk\vk_sample_locations.cpp">
<Filter>Vulkan\demos</Filter>
</ClCompile>
<ClCompile Include="vk\vk_discard_rects.cpp">
<Filter>Vulkan\demos</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="D3D11">
+209
View File
@@ -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);