Add support for VK_EXT_attachment_feedback_loop_dynamic_state

This commit is contained in:
baldurk
2023-06-21 11:40:42 +01:00
parent 4b87803071
commit a6c1ba1fc5
16 changed files with 197 additions and 10 deletions
@@ -2866,6 +2866,41 @@ void VulkanPipelineStateViewer::setState()
resName +=
tr(" (%1x%2 texels)").arg(shadingRateTexelSize.first).arg(shadingRateTexelSize.second);
// append if colour or depth/stencil feedback is allowed
if(a.type == AttType::Color && state.currentPass.colorFeedbackAllowed)
{
resName += tr(" (Feedback)");
}
else if(a.type == AttType::Depth && state.currentPass.depthFeedbackAllowed &&
state.currentPass.stencilFeedbackAllowed)
{
resName += tr(" (Feedback)");
}
else if(a.type == AttType::Depth && (state.currentPass.depthFeedbackAllowed ||
state.currentPass.stencilFeedbackAllowed))
{
// if only one of depth or stencil is allowed, display that specifically
if(tex->format.type == ResourceFormatType::D16S8 ||
tex->format.type == ResourceFormatType::D24S8 ||
tex->format.type == ResourceFormatType::D32S8)
{
if(state.currentPass.depthFeedbackAllowed)
resName += tr(" (Depth Feedback)");
else if(state.currentPass.stencilFeedbackAllowed)
resName += tr(" (Depth Feedback)");
}
else if(tex->format.type == ResourceFormatType::S8 &&
state.currentPass.stencilFeedbackAllowed)
{
resName += tr(" (Feedback)");
}
// this case must be depth-only, since depth/stencil and stencil-only are covered above.
else if(state.currentPass.depthFeedbackAllowed)
{
resName += tr(" (Feedback)");
}
}
node = new RDTreeWidgetItem(
{slotname, resName, typeName, dimensions, format, samples, QString()});
+9
View File
@@ -1229,6 +1229,15 @@ struct CurrentPass
:type: VKRenderArea
)");
RenderArea renderArea;
DOCUMENT("If feedback loops are allowed on color attachments");
bool colorFeedbackAllowed = false;
DOCUMENT("If feedback loops are allowed on depth attachments");
bool depthFeedbackAllowed = false;
DOCUMENT("If feedback loops are allowed on stencil attachments");
bool stencilFeedbackAllowed = false;
};
DOCUMENT("Contains the layout of a range of subresources in an image.");
+3
View File
@@ -925,6 +925,7 @@ enum class VulkanChunk : uint32_t
vkCmdEndRendering,
vkCmdSetFragmentShadingRateKHR,
vkSetDeviceMemoryPriorityEXT,
vkCmdSetAttachmentFeedbackLoopEnableEXT,
Max,
};
@@ -1132,6 +1133,7 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDevice16BitStorageFeatures);
DECLARE_REFLECTION_STRUCT(VkPhysicalDevice4444FormatsFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDevice8BitStorageFeatures);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceASTCDecodeFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceBorderColorSwizzleFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceBufferDeviceAddressFeatures);
@@ -1540,6 +1542,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDevice16BitStorageFeatures);
DECLARE_DESERIALISE_TYPE(VkPhysicalDevice4444FormatsFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDevice8BitStorageFeatures);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceASTCDecodeFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceBorderColorSwizzleFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceCoherentMemoryFeaturesAMD);
+8
View File
@@ -895,6 +895,10 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION,
},
{
VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME,
VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_SPEC_VERSION,
},
{
VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME,
VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_SPEC_VERSION,
@@ -3718,6 +3722,10 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
case VulkanChunk::vkSetDeviceMemoryPriorityEXT:
return Serialise_vkSetDeviceMemoryPriorityEXT(ser, VK_NULL_HANDLE, VK_NULL_HANDLE, 0.0f);
case VulkanChunk::vkCmdSetAttachmentFeedbackLoopEnableEXT:
return Serialise_vkCmdSetAttachmentFeedbackLoopEnableEXT(ser, VK_NULL_HANDLE,
VK_IMAGE_ASPECT_NONE);
// chunks that are reserved but not yet serialised
case VulkanChunk::vkResetCommandPool:
case VulkanChunk::vkCreateDepthTargetView:
+6
View File
@@ -447,6 +447,7 @@ private:
bool m_FragmentShadingRate = false;
bool m_DynColorWrite = false;
bool m_DynVertexInput = false;
bool m_DynAttachmentLoop = false;
PFN_vkSetDeviceLoaderData m_SetDeviceLoaderData;
@@ -1220,6 +1221,7 @@ public:
bool FragmentShadingRate() const { return m_FragmentShadingRate; }
bool DynamicColorWrite() const { return m_DynColorWrite; }
bool DynamicVertexInput() const { return m_DynVertexInput; }
bool DynamicAttachmentLoop() const { return m_DynAttachmentLoop; }
VulkanRenderState &GetRenderState() { return m_RenderState; }
void SetActionCB(VulkanActionCallback *cb) { m_ActionCallback = cb; }
void SetSubmitChain(void *submitChain) { m_SubmitChain = submitChain; }
@@ -2633,4 +2635,8 @@ public:
// VK_EXT_swapchain_maintenance1
VkResult vkReleaseSwapchainImagesEXT(VkDevice device,
const VkReleaseSwapchainImagesInfoEXT *pReleaseInfo);
// VK_EXT_attachment_feedback_loop_dynamic_state
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetAttachmentFeedbackLoopEnableEXT,
VkCommandBuffer commandBuffer, VkImageAspectFlags aspectMask);
};
+8 -2
View File
@@ -547,7 +547,8 @@
DeclExt(EXT_attachment_feedback_loop_layout); \
DeclExt(EXT_pageable_device_local_memory); \
DeclExt(EXT_swapchain_maintenance1); \
DeclExt(EXT_provoking_vertex);
DeclExt(EXT_provoking_vertex); \
DeclExt(EXT_attachment_feedback_loop_dynamic_state);
// for simplicity and since the check itself is platform agnostic,
// these aren't protected in platform defines
@@ -665,7 +666,8 @@
CheckExt(EXT_attachment_feedback_loop_layout, VKXX); \
CheckExt(EXT_pageable_device_local_memory, VKXX); \
CheckExt(EXT_swapchain_maintenance1, VKXX); \
CheckExt(EXT_provoking_vertex, VKXX);
CheckExt(EXT_provoking_vertex, VKXX); \
CheckExt(EXT_attachment_feedback_loop_dynamic_state, VKXX);
#define HookInitVulkanInstanceExts_PhysDev() \
HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \
@@ -927,6 +929,8 @@
HookInitExtension(KHR_fragment_shading_rate, CmdSetFragmentShadingRateKHR); \
HookInitExtension(EXT_pageable_device_local_memory, SetDeviceMemoryPriorityEXT); \
HookInitExtension(EXT_swapchain_maintenance1, ReleaseSwapchainImagesEXT); \
HookInitExtension(EXT_attachment_feedback_loop_dynamic_state, \
CmdSetAttachmentFeedbackLoopEnableEXT); \
HookInitExtension_Device_Win32(); \
HookInitExtension_Device_Linux(); \
HookInitExtension_Device_GGP(); \
@@ -1653,6 +1657,8 @@
uint32_t, connectorId, VkDisplayKHR *, display); \
HookDefine2(VkResult, vkReleaseSwapchainImagesEXT, VkDevice, device, \
const VkReleaseSwapchainImagesInfoEXT *, pReleaseInfo); \
HookDefine2(void, vkCmdSetAttachmentFeedbackLoopEnableEXT, VkCommandBuffer, commandBuffer, \
VkImageAspectFlags, aspectMask); \
HookDefine_Win32(); \
HookDefine_Linux(); \
HookDefine_GGP(); \
+4
View File
@@ -2830,6 +2830,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
{
RDCERR("Vertex input dynamic state found, should have been stripped");
}
else if(d == VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT)
{
vt->CmdSetAttachmentFeedbackLoopEnableEXT(Unwrap(cmd), state.feedbackAspects);
}
}
if(fmt.indexByteStride)
+4
View File
@@ -1849,6 +1849,10 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
ret.currentPass.framebuffer.attachments.clear();
}
ret.currentPass.colorFeedbackAllowed = (state.feedbackAspects & VK_IMAGE_ASPECT_COLOR_BIT) != 0;
ret.currentPass.depthFeedbackAllowed = (state.feedbackAspects & VK_IMAGE_ASPECT_DEPTH_BIT) != 0;
ret.currentPass.stencilFeedbackAllowed = (state.feedbackAspects & VK_IMAGE_ASPECT_STENCIL_BIT) != 0;
// Descriptor sets
ret.graphics.descriptorSets.resize(state.graphics.descSets.size());
ret.compute.descriptorSets.resize(state.compute.descSets.size());
+23 -4
View File
@@ -565,6 +565,10 @@ SERIALISE_VK_HANDLES();
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, \
VkPhysicalDeviceASTCDecodeFeaturesEXT) \
\
/* VK_EXT_attachment_feedback_loop_dynamic_state */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT, \
VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT) \
\
/* VK_EXT_attachment_feedback_loop_layout */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT, \
VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT) \
@@ -1419,10 +1423,6 @@ SERIALISE_VK_HANDLES();
PNEXT_UNSUPPORTED( \
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD) \
\
/* VK_EXT_attachment_feedback_loop_dynamic_state */ \
PNEXT_UNSUPPORTED( \
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT) \
\
/* VK_EXT_external_memory_acquire_unmodified */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_EXT) \
\
@@ -8270,6 +8270,24 @@ void Deserialise(const VkExternalMemoryImageCreateInfoNV &el)
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser,
VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType ==
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(attachmentFeedbackLoopDynamicState);
}
template <>
void Deserialise(const VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT &el)
{
@@ -11397,6 +11415,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevice16BitStorageFeatures);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevice4444FormatsFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevice8BitStorageFeatures);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceASTCDecodeFeaturesEXT)
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceBorderColorSwizzleFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceBufferDeviceAddressFeatures);
+6
View File
@@ -475,6 +475,12 @@ void VulkanRenderState::BindPipeline(WrappedVulkan *vk, VkCommandBuffer cmd,
shadingRateCombiners);
}
if(vk->DynamicAttachmentLoop())
{
if(dynamicStates[VkDynamicAttachmentFeedbackLoopEnableEXT])
ObjDisp(cmd)->CmdSetAttachmentFeedbackLoopEnableEXT(Unwrap(cmd), feedbackAspects);
}
if(graphics.pipeline != ResourceId())
BindDescriptorSetsForPipeline(vk, cmd, graphics, VK_PIPELINE_BIND_POINT_GRAPHICS);
else
+3
View File
@@ -248,6 +248,9 @@ struct VulkanRenderState
VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
};
// attachment feedback loop
VkImageAspectFlags feedbackAspects = VK_IMAGE_ASPECT_NONE;
private:
ResourceId renderPass;
ResourceId framebuffer;
+2 -1
View File
@@ -28,7 +28,7 @@
template <>
rdcstr DoStringise(const VulkanChunk &el)
{
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1177, "Chunks changed without updating names");
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1178, "Chunks changed without updating names");
BEGIN_ENUM_STRINGISE(VulkanChunk)
{
@@ -209,6 +209,7 @@ rdcstr DoStringise(const VulkanChunk &el)
STRINGISE_ENUM_CLASS(vkCmdEndRendering)
STRINGISE_ENUM_CLASS(vkCmdSetFragmentShadingRateKHR)
STRINGISE_ENUM_CLASS(vkSetDeviceMemoryPriorityEXT)
STRINGISE_ENUM_CLASS(vkCmdSetAttachmentFeedbackLoopEnableEXT)
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
}
END_ENUM_STRINGISE()
@@ -3294,6 +3294,15 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline(SerialiserType &ser, VkCommandBu
renderstate.vertexBindings[i].divisor = pipeInfo.vertexBindings[i].instanceDivisor;
}
}
if(!pipeInfo.dynamicStates[VkDynamicAttachmentFeedbackLoopEnableEXT])
{
renderstate.feedbackAspects = VK_IMAGE_ASPECT_NONE;
if(pipeInfo.flags & VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
renderstate.feedbackAspects |= VK_IMAGE_ASPECT_COLOR_BIT;
if(pipeInfo.flags & VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
renderstate.feedbackAspects |=
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
}
}
}
}
@@ -3095,6 +3095,15 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
CHECK_PHYS_EXT_FEATURE(transformFeedbackPreservesProvokingVertex);
}
END_PHYS_EXT_CHECK();
BEGIN_PHYS_EXT_CHECK(
VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT);
{
CHECK_PHYS_EXT_FEATURE(attachmentFeedbackLoopDynamicState);
m_DynAttachmentLoop = ext->attachmentFeedbackLoopDynamicState != VK_FALSE;
}
END_PHYS_EXT_CHECK();
}
if(availFeatures.depthClamp)
@@ -1945,6 +1945,67 @@ void WrappedVulkan::vkCmdSetFragmentShadingRateKHR(
}
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkCmdSetAttachmentFeedbackLoopEnableEXT(SerialiserType &ser,
VkCommandBuffer commandBuffer,
VkImageAspectFlags aspectMask)
{
SERIALISE_ELEMENT(commandBuffer);
SERIALISE_ELEMENT(aspectMask).Important();
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);
{
VulkanRenderState &renderstate = GetCmdRenderState();
renderstate.feedbackAspects = aspectMask;
}
}
else
{
commandBuffer = VK_NULL_HANDLE;
}
}
if(commandBuffer != VK_NULL_HANDLE)
ObjDisp(commandBuffer)->CmdSetAttachmentFeedbackLoopEnableEXT(Unwrap(commandBuffer), aspectMask);
}
return true;
}
void WrappedVulkan::vkCmdSetAttachmentFeedbackLoopEnableEXT(VkCommandBuffer commandBuffer,
VkImageAspectFlags aspectMask)
{
SCOPED_DBG_SINK();
SERIALISE_TIME_CALL(
ObjDisp(commandBuffer)->CmdSetAttachmentFeedbackLoopEnableEXT(Unwrap(commandBuffer), aspectMask));
if(IsCaptureMode(m_State))
{
VkResourceRecord *record = GetRecord(commandBuffer);
CACHE_THREAD_SERIALISER();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetAttachmentFeedbackLoopEnableEXT);
Serialise_vkCmdSetAttachmentFeedbackLoopEnableEXT(ser, commandBuffer, aspectMask);
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetViewport, VkCommandBuffer commandBuffer,
uint32_t firstViewport, uint32_t viewportCount,
const VkViewport *pViewports);
@@ -2032,7 +2093,8 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetPrimitiveRestartEnable, VkCommandB
VkBool32 primitiveRestartEnable);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetRasterizerDiscardEnable,
VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetFragmentShadingRateKHR, VkCommandBuffer commandBuffer,
const VkExtent2D *pFragmentSize,
const VkFragmentShadingRateCombinerOpKHR combinerOps[2]);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetAttachmentFeedbackLoopEnableEXT,
VkCommandBuffer commandBuffer, VkImageAspectFlags aspectMask);
+5 -2
View File
@@ -2293,8 +2293,11 @@ void DoSerialise(SerialiserType &ser, VKPipe::CurrentPass &el)
SERIALISE_MEMBER(renderpass);
SERIALISE_MEMBER(framebuffer);
SERIALISE_MEMBER(renderArea);
SERIALISE_MEMBER(colorFeedbackAllowed);
SERIALISE_MEMBER(depthFeedbackAllowed);
SERIALISE_MEMBER(stencilFeedbackAllowed);
SIZE_CHECK(232);
SIZE_CHECK(240);
}
template <typename SerialiserType>
@@ -2362,7 +2365,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::State &el)
SERIALISE_MEMBER(conditionalRendering);
SIZE_CHECK(2256);
SIZE_CHECK(2264);
}
#pragma endregion Vulkan pipeline state