mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-20 21:46:52 +00:00
Support VK_EXT_load_store_op_none & color_write_enable. Closes #2363
* These are added together because VK_EXT_load_store_op_none is easier to test in a realistic fashion using VK_EXT_color_write_enable
This commit is contained in:
@@ -26,6 +26,7 @@ Maintainers can update this file by updating vk.xml in this folder and running `
|
||||
* `VK_EXT_astc_decode_mode`
|
||||
* `VK_EXT_buffer_device_address`
|
||||
* `VK_EXT_calibrated_timestamps`
|
||||
* `VK_EXT_color_write_enable`
|
||||
* `VK_EXT_conditional_rendering`
|
||||
* `VK_EXT_conservative_rasterization`
|
||||
* `VK_EXT_custom_border_color`
|
||||
@@ -55,6 +56,7 @@ Maintainers can update this file by updating vk.xml in this folder and running `
|
||||
* `VK_EXT_index_type_uint8`
|
||||
* `VK_EXT_inline_uniform_block`
|
||||
* `VK_EXT_line_rasterization`
|
||||
* `VK_EXT_load_store_op_none`
|
||||
* `VK_EXT_memory_budget`
|
||||
* `VK_EXT_memory_priority`
|
||||
* `VK_EXT_metal_surface`
|
||||
@@ -220,12 +222,10 @@ Ray tracing extensions are now standard and will likely be supported at some poi
|
||||
* `VK_EXT_acquire_drm_display`
|
||||
* `VK_EXT_blend_operation_advanced`
|
||||
* `VK_EXT_border_color_swizzle`
|
||||
* `VK_EXT_color_write_enable`
|
||||
* `VK_EXT_device_memory_report`
|
||||
* `VK_EXT_extended_dynamic_state2`
|
||||
* `VK_EXT_external_memory_host`
|
||||
* `VK_EXT_image_drm_format_modifier`
|
||||
* `VK_EXT_load_store_op_none`
|
||||
* `VK_EXT_multi_draw`
|
||||
* `VK_EXT_pageable_device_local_memory`
|
||||
* `VK_EXT_physical_device_drm`
|
||||
|
||||
@@ -715,6 +715,7 @@ enum class VulkanChunk : uint32_t
|
||||
vkCmdWriteTimestamp2KHR,
|
||||
vkQueueSubmit2KHR,
|
||||
vkCmdWriteBufferMarker2AMD,
|
||||
vkCmdSetColorWriteEnableEXT,
|
||||
Max,
|
||||
};
|
||||
|
||||
@@ -917,6 +918,7 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceASTCDecodeFeaturesEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceBufferDeviceAddressFeatures);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceBufferDeviceAddressFeaturesEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceCoherentMemoryFeaturesAMD);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceColorWriteEnableFeaturesEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceComputeShaderDerivativesFeaturesNV);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceConditionalRenderingFeaturesEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceConservativeRasterizationPropertiesEXT);
|
||||
@@ -1026,6 +1028,7 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkPipelineCacheCreateInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkPipelineColorBlendStateCreateInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkPipelineColorWriteCreateInfoEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPipelineCreationFeedbackCreateInfoEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPipelineDepthStencilStateCreateInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkPipelineDiscardRectangleStateCreateInfoEXT);
|
||||
@@ -1262,6 +1265,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDevice16BitStorageFeatures);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDevice8BitStorageFeatures);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceASTCDecodeFeaturesEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceCoherentMemoryFeaturesAMD);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceColorWriteEnableFeaturesEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceComputeShaderDerivativesFeaturesNV);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceConditionalRenderingFeaturesEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceConservativeRasterizationPropertiesEXT);
|
||||
@@ -1371,6 +1375,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR);
|
||||
DECLARE_DESERIALISE_TYPE(VkPipelineCacheCreateInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkPipelineColorBlendStateCreateInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkPipelineColorWriteCreateInfoEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPipelineCreationFeedbackCreateInfoEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPipelineDepthStencilStateCreateInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkPipelineDiscardRectangleStateCreateInfoEXT);
|
||||
|
||||
@@ -878,6 +878,9 @@ static const VkExtensionProperties supportedExtensions[] = {
|
||||
{
|
||||
VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, VK_EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION,
|
||||
},
|
||||
{
|
||||
VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME, VK_EXT_COLOR_WRITE_ENABLE_SPEC_VERSION,
|
||||
},
|
||||
{
|
||||
VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION,
|
||||
},
|
||||
@@ -965,6 +968,9 @@ static const VkExtensionProperties supportedExtensions[] = {
|
||||
{
|
||||
VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION,
|
||||
},
|
||||
{
|
||||
VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME, VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION,
|
||||
},
|
||||
{
|
||||
VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, VK_EXT_LINE_RASTERIZATION_SPEC_VERSION,
|
||||
},
|
||||
@@ -3478,6 +3484,8 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
|
||||
case VulkanChunk::vkCmdWriteBufferMarker2AMD:
|
||||
return Serialise_vkCmdWriteBufferMarker2AMD(ser, VK_NULL_HANDLE, VK_PIPELINE_STAGE_2_NONE_KHR,
|
||||
VK_NULL_HANDLE, 0, 0);
|
||||
case VulkanChunk::vkCmdSetColorWriteEnableEXT:
|
||||
return Serialise_vkCmdSetColorWriteEnableEXT(ser, VK_NULL_HANDLE, 0, NULL);
|
||||
|
||||
// chunks that are reserved but not yet serialised
|
||||
case VulkanChunk::vkResetCommandPool:
|
||||
|
||||
@@ -407,6 +407,7 @@ private:
|
||||
bool m_SeparateDepthStencil = false;
|
||||
bool m_NULLDescriptorsAllowed = false;
|
||||
bool m_ExtendedDynState = false;
|
||||
bool m_DynColorWrite = false;
|
||||
|
||||
PFN_vkSetDeviceLoaderData m_SetDeviceLoaderData;
|
||||
|
||||
@@ -1122,6 +1123,7 @@ public:
|
||||
bool SeparateDepthStencil() const { return m_SeparateDepthStencil; }
|
||||
bool NULLDescriptorsAllowed() const { return m_NULLDescriptorsAllowed; }
|
||||
bool ExtendedDynamicState() const { return m_ExtendedDynState; }
|
||||
bool DynamicColorWrite() const { return m_DynColorWrite; }
|
||||
VulkanRenderState &GetRenderState() { return m_RenderState; }
|
||||
void SetActionCB(VulkanActionCallback *cb) { m_ActionCallback = cb; }
|
||||
void SetSubmitChain(void *submitChain) { m_SubmitChain = submitChain; }
|
||||
@@ -2473,4 +2475,9 @@ public:
|
||||
const VkDeviceImageMemoryRequirementsKHR *pInfo,
|
||||
uint32_t *pSparseMemoryRequirementCount,
|
||||
VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements);
|
||||
|
||||
// VK_EXT_color_write_enable
|
||||
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetColorWriteEnableEXT, VkCommandBuffer commandBuffer,
|
||||
uint32_t attachmentCount, const VkBool32 *pColorWriteEnables);
|
||||
};
|
||||
|
||||
@@ -529,7 +529,8 @@
|
||||
DeclExt(KHR_copy_commands2); \
|
||||
DeclExt(KHR_synchronization2); \
|
||||
DeclExt(KHR_present_wait); \
|
||||
DeclExt(KHR_maintenance4);
|
||||
DeclExt(KHR_maintenance4); \
|
||||
DeclExt(EXT_color_write_enable);
|
||||
|
||||
// for simplicity and since the check itself is platform agnostic,
|
||||
// these aren't protected in platform defines
|
||||
@@ -629,7 +630,10 @@
|
||||
CheckExt(EXT_private_data, VKXX); \
|
||||
CheckExt(EXT_extended_dynamic_state, VKXX); \
|
||||
CheckExt(KHR_copy_commands2, VKXX); \
|
||||
CheckExt(KHR_synchronization2, VKXX);
|
||||
CheckExt(KHR_synchronization2, VKXX); \
|
||||
CheckExt(KHR_present_wait, VKXX); \
|
||||
CheckExt(KHR_maintenance4, VKXX); \
|
||||
CheckExt(EXT_color_write_enable, VKXX);
|
||||
|
||||
#define HookInitVulkanInstanceExts_PhysDev() \
|
||||
HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \
|
||||
@@ -874,6 +878,7 @@
|
||||
HookInitExtension(KHR_maintenance4, GetDeviceBufferMemoryRequirementsKHR); \
|
||||
HookInitExtension(KHR_maintenance4, GetDeviceImageMemoryRequirementsKHR); \
|
||||
HookInitExtension(KHR_maintenance4, GetDeviceImageSparseMemoryRequirementsKHR); \
|
||||
HookInitExtension(EXT_color_write_enable, CmdSetColorWriteEnableEXT); \
|
||||
/* No GetQueueCheckpointData2NV without VK_NV_device_diagnostic_checkpoints */ \
|
||||
HookInitExtension_Device_Win32(); \
|
||||
HookInitExtension_Device_Linux(); \
|
||||
@@ -1570,6 +1575,8 @@
|
||||
const VkDeviceImageMemoryRequirementsKHR *, pInfo, uint32_t *, \
|
||||
pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 *, \
|
||||
pSparseMemoryRequirements); \
|
||||
HookDefine3(void, vkCmdSetColorWriteEnableEXT, VkCommandBuffer, commandBuffer, uint32_t, \
|
||||
attachmentCount, const VkBool32 *, pColorWriteEnables); \
|
||||
HookDefine_Win32(); \
|
||||
HookDefine_Linux(); \
|
||||
HookDefine_GGP(); \
|
||||
|
||||
@@ -699,6 +699,22 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
|
||||
attachments.clear();
|
||||
}
|
||||
|
||||
// this struct probably will never get used, since the user could just set the colorWriteMask
|
||||
// above to 0. It's really only useful for specifying how the dynamic state works. However just
|
||||
// for completeness...
|
||||
const VkPipelineColorWriteCreateInfoEXT *colorWriteEnable =
|
||||
(const VkPipelineColorWriteCreateInfoEXT *)FindNextStruct(
|
||||
pCreateInfo->pRasterizationState, VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT);
|
||||
if(colorWriteEnable)
|
||||
{
|
||||
RDCASSERTEQUAL(attachments.size(), colorWriteEnable->attachmentCount);
|
||||
for(size_t i = 0; i < attachments.size() && i < colorWriteEnable->attachmentCount; i++)
|
||||
{
|
||||
if(!colorWriteEnable->pColorWriteEnables[i])
|
||||
attachments[i].channelWriteMask = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
|
||||
@@ -374,7 +374,7 @@ struct VulkanCreationInfo
|
||||
VkLogicOp logicOp;
|
||||
float blendConst[4];
|
||||
|
||||
struct Attachment
|
||||
struct CBAttachment
|
||||
{
|
||||
bool blendEnable;
|
||||
|
||||
@@ -387,7 +387,7 @@ struct VulkanCreationInfo
|
||||
|
||||
uint8_t channelWriteMask;
|
||||
};
|
||||
rdcarray<Attachment> attachments;
|
||||
rdcarray<CBAttachment> attachments;
|
||||
|
||||
// VkPipelineDynamicStateCreateInfo
|
||||
bool dynamicStates[VkDynamicCount];
|
||||
|
||||
@@ -203,6 +203,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
|
||||
VkPhysicalDeviceBufferDeviceAddressFeatures); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, \
|
||||
VkPhysicalDeviceCoherentMemoryFeaturesAMD); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, \
|
||||
VkPhysicalDeviceColorWriteEnableFeaturesEXT); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV, \
|
||||
VkPhysicalDeviceComputeShaderDerivativesFeaturesNV); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, \
|
||||
@@ -416,6 +418,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
|
||||
VkPipelineCreationFeedbackCreateInfoEXT); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, \
|
||||
VkPipelineColorBlendStateCreateInfo); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT, \
|
||||
VkPipelineColorWriteCreateInfoEXT); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT, \
|
||||
VkPipelineRasterizationDepthClipStateCreateInfoEXT); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, \
|
||||
@@ -726,7 +730,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV: \
|
||||
@@ -775,7 +778,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD: \
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV: \
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV: \
|
||||
|
||||
@@ -2766,6 +2766,11 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
state.front.passOp, state.front.depthFailOp,
|
||||
state.front.compareOp);
|
||||
}
|
||||
else if(d == VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)
|
||||
{
|
||||
vt->CmdSetColorWriteEnableEXT(Unwrap(cmd), (uint32_t)state.colorWriteEnable.size(),
|
||||
state.colorWriteEnable.data());
|
||||
}
|
||||
}
|
||||
|
||||
if(fmt.indexByteStride)
|
||||
|
||||
@@ -687,6 +687,15 @@ protected:
|
||||
descs[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
descs[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
descs[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
if(rpInfo.attachments[i].loadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
descs[i].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
|
||||
if(rpInfo.attachments[i].storeOp == VK_ATTACHMENT_STORE_OP_NONE_EXT)
|
||||
descs[i].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
|
||||
if(rpInfo.attachments[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
descs[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
|
||||
if(rpInfo.attachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_NONE_EXT)
|
||||
descs[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
|
||||
|
||||
descs[i].initialLayout = rpInfo.attachments[i].initialLayout;
|
||||
descs[i].finalLayout = rpInfo.attachments[i].finalLayout;
|
||||
}
|
||||
|
||||
@@ -1452,6 +1452,9 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
|
||||
MakeBlendOp(p.attachments[i].alphaBlend.Operation);
|
||||
|
||||
ret.colorBlend.blends[i].writeMask = p.attachments[i].channelWriteMask;
|
||||
|
||||
if(i < state.colorWriteEnable.size() && !state.colorWriteEnable[i])
|
||||
ret.colorBlend.blends[i].writeMask = 0;
|
||||
}
|
||||
|
||||
ret.colorBlend.blendFactor = state.blendConst;
|
||||
|
||||
@@ -556,6 +556,12 @@ SERIALISE_VK_HANDLES();
|
||||
/* VK_EXT_calibrated_timestamps */ \
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, VkCalibratedTimestampInfoEXT) \
|
||||
\
|
||||
/* VK_EXT_color_write_enable */ \
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, \
|
||||
VkPhysicalDeviceColorWriteEnableFeaturesEXT) \
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT, \
|
||||
VkPipelineColorWriteCreateInfoEXT) \
|
||||
\
|
||||
/* VK_EXT_conditional_rendering */ \
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT, \
|
||||
VkCommandBufferInheritanceConditionalRenderingInfoEXT) \
|
||||
@@ -1256,10 +1262,6 @@ SERIALISE_VK_HANDLES();
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT) \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT) \
|
||||
\
|
||||
/* VK_EXT_color_write_enable */ \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT) \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) \
|
||||
\
|
||||
/* VK_EXT_device_memory_report */ \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT) \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT) \
|
||||
@@ -7695,6 +7697,38 @@ void Deserialise(const VkCalibratedTimestampInfoEXT &el)
|
||||
DeserialiseNext(el.pNext);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceColorWriteEnableFeaturesEXT &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() ||
|
||||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER(colorWriteEnable);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Deserialise(const VkPhysicalDeviceColorWriteEnableFeaturesEXT &el)
|
||||
{
|
||||
DeserialiseNext(el.pNext);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkPipelineColorWriteCreateInfoEXT &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER(attachmentCount);
|
||||
SERIALISE_MEMBER_ARRAY(pColorWriteEnables, attachmentCount);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Deserialise(const VkPipelineColorWriteCreateInfoEXT &el)
|
||||
{
|
||||
DeserialiseNext(el.pNext);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkSwapchainCounterCreateInfoEXT &el)
|
||||
{
|
||||
@@ -9731,6 +9765,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceASTCDecodeFeaturesEXT)
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceBufferDeviceAddressFeatures);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceBufferDeviceAddressFeaturesEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceCoherentMemoryFeaturesAMD);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceColorWriteEnableFeaturesEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceComputeShaderDerivativesFeaturesNV);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceConditionalRenderingFeaturesEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceConservativeRasterizationPropertiesEXT);
|
||||
@@ -9838,6 +9873,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPipelineCacheCreateInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPipelineColorBlendStateCreateInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPipelineColorWriteCreateInfoEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPipelineCreationFeedbackCreateInfoEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPipelineDepthStencilStateCreateInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPipelineDiscardRectangleStateCreateInfoEXT);
|
||||
|
||||
@@ -181,6 +181,13 @@ void VulkanRenderState::BindPipeline(WrappedVulkan *vk, VkCommandBuffer cmd,
|
||||
if(!scissors.empty() && dynamicStates[VkDynamicScissor])
|
||||
ObjDisp(cmd)->CmdSetScissor(Unwrap(cmd), 0, (uint32_t)scissors.size(), &scissors[0]);
|
||||
|
||||
if(vk->DynamicColorWrite())
|
||||
{
|
||||
if(!colorWriteEnable.empty() && dynamicStates[VkDynamicColorWriteEXT])
|
||||
ObjDisp(cmd)->CmdSetColorWriteEnableEXT(Unwrap(cmd), (uint32_t)colorWriteEnable.size(),
|
||||
colorWriteEnable.data());
|
||||
}
|
||||
|
||||
if(vk->ExtendedDynamicState())
|
||||
{
|
||||
if(!views.empty() && dynamicStates[VkDynamicViewportCountEXT])
|
||||
|
||||
@@ -191,6 +191,9 @@ struct VulkanRenderState
|
||||
|
||||
VkBool32 stencilTestEnable = VK_FALSE;
|
||||
|
||||
// color write enable
|
||||
rdcarray<VkBool32> colorWriteEnable;
|
||||
|
||||
private:
|
||||
ResourceId framebuffer;
|
||||
rdcarray<ResourceId> fbattachments;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
template <>
|
||||
rdcstr DoStringise(const VulkanChunk &el)
|
||||
{
|
||||
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1166, "Chunks changed without updating names");
|
||||
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1167, "Chunks changed without updating names");
|
||||
|
||||
BEGIN_ENUM_STRINGISE(VulkanChunk)
|
||||
{
|
||||
@@ -198,6 +198,7 @@ rdcstr DoStringise(const VulkanChunk &el)
|
||||
STRINGISE_ENUM_CLASS(vkCmdWriteTimestamp2KHR);
|
||||
STRINGISE_ENUM_CLASS(vkQueueSubmit2KHR);
|
||||
STRINGISE_ENUM_CLASS(vkCmdWriteBufferMarker2AMD);
|
||||
STRINGISE_ENUM_CLASS(vkCmdSetColorWriteEnableEXT);
|
||||
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
|
||||
}
|
||||
END_ENUM_STRINGISE()
|
||||
|
||||
@@ -36,7 +36,7 @@ static rdcstr ToHumanStr(const VkAttachmentLoadOp &el)
|
||||
{
|
||||
case VK_ATTACHMENT_LOAD_OP_LOAD: return "Load";
|
||||
case VK_ATTACHMENT_LOAD_OP_CLEAR: return "Clear";
|
||||
case VK_ATTACHMENT_LOAD_OP_DONT_CARE: return "Don't Care";
|
||||
case VK_ATTACHMENT_LOAD_OP_NONE_EXT: return "None";
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
}
|
||||
@@ -47,6 +47,7 @@ static rdcstr ToHumanStr(const VkAttachmentStoreOp &el)
|
||||
{
|
||||
case VK_ATTACHMENT_STORE_OP_STORE: return "Store";
|
||||
case VK_ATTACHMENT_STORE_OP_DONT_CARE: return "Don't Care";
|
||||
case VK_ATTACHMENT_STORE_OP_NONE_EXT: return "None";
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
}
|
||||
@@ -1485,8 +1486,17 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(SerialiserType &ser, VkComman
|
||||
if(att >= rpinfo.attachments.size())
|
||||
continue;
|
||||
|
||||
if(rpinfo.attachments[att].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR ||
|
||||
rpinfo.attachments[att].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
VkImageAspectFlags clearAspects = 0;
|
||||
|
||||
// loadOp governs color, and depth
|
||||
if(rpinfo.attachments[att].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
clearAspects |= VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
// stencilLoadOp governs the stencil
|
||||
if(rpinfo.attachments[att].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
clearAspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
// if any aspect is set to clear, go check it in more detail
|
||||
if(clearAspects != 0)
|
||||
{
|
||||
VulkanCreationInfo::ImageView viewinfo = m_CreationInfo.m_ImageView[fbattachments[att]];
|
||||
|
||||
@@ -1498,8 +1508,15 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(SerialiserType &ser, VkComman
|
||||
clear.clearValue = unwrappedInfo.pClearValues[att];
|
||||
else
|
||||
RDCWARN("Missing clear value for attachment %u", att);
|
||||
clearrects.push_back(rect);
|
||||
clearatts.push_back(clear);
|
||||
|
||||
// check that the actual aspects in the attachment overlap with those being cleared.
|
||||
// In particular this means we ignore stencil load op being CLEAR for a color
|
||||
// attachment - that doesn't mean we should clear the color
|
||||
if(clear.aspectMask & clearAspects)
|
||||
{
|
||||
clearrects.push_back(rect);
|
||||
clearatts.push_back(clear);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1662,7 +1679,8 @@ void WrappedVulkan::vkCmdBeginRenderPass(VkCommandBuffer commandBuffer,
|
||||
|
||||
if(renderArea_covers_entire_framebuffer && framebuffer_reference_entire_attachment)
|
||||
{
|
||||
if(rpInfo->loadOpTable[i] != VK_ATTACHMENT_LOAD_OP_LOAD)
|
||||
if(rpInfo->loadOpTable[i] != VK_ATTACHMENT_LOAD_OP_LOAD &&
|
||||
rpInfo->loadOpTable[i] != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
{
|
||||
refType = eFrameRef_CompleteWrite;
|
||||
}
|
||||
@@ -2291,7 +2309,8 @@ void WrappedVulkan::vkCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
|
||||
|
||||
if(renderArea_covers_entire_framebuffer && framebuffer_reference_entire_attachment)
|
||||
{
|
||||
if(rpInfo->loadOpTable[i] != VK_ATTACHMENT_LOAD_OP_LOAD)
|
||||
if(rpInfo->loadOpTable[i] != VK_ATTACHMENT_LOAD_OP_LOAD &&
|
||||
rpInfo->loadOpTable[i] != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
{
|
||||
refType = eFrameRef_CompleteWrite;
|
||||
}
|
||||
@@ -2758,6 +2777,12 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline(SerialiserType &ser, VkCommandBu
|
||||
renderstate.vbuffers[bind.vbufferBinding].stride = bind.bytestride;
|
||||
}
|
||||
}
|
||||
if(!pipeInfo.dynamicStates[VkDynamicColorWriteEXT])
|
||||
{
|
||||
renderstate.colorWriteEnable.resize(pipeInfo.attachments.size());
|
||||
for(size_t i = 0; i < renderstate.colorWriteEnable.size(); i++)
|
||||
renderstate.colorWriteEnable[i] = pipeInfo.attachments[i].channelWriteMask != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2799,6 +2799,15 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
CHECK_PHYS_EXT_FEATURE(globalPriorityQuery);
|
||||
}
|
||||
END_PHYS_EXT_CHECK();
|
||||
|
||||
BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceColorWriteEnableFeaturesEXT,
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT);
|
||||
{
|
||||
CHECK_PHYS_EXT_FEATURE(colorWriteEnable);
|
||||
|
||||
m_DynColorWrite = (ext->colorWriteEnable != VK_FALSE);
|
||||
}
|
||||
END_PHYS_EXT_CHECK();
|
||||
}
|
||||
|
||||
if(availFeatures.depthClamp)
|
||||
|
||||
@@ -1514,6 +1514,72 @@ void WrappedVulkan::vkCmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStenci
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedVulkan::Serialise_vkCmdSetColorWriteEnableEXT(SerialiserType &ser,
|
||||
VkCommandBuffer commandBuffer,
|
||||
uint32_t attachmentCount,
|
||||
const VkBool32 *pColorWriteEnables)
|
||||
{
|
||||
SERIALISE_ELEMENT(commandBuffer);
|
||||
SERIALISE_ELEMENT(attachmentCount);
|
||||
SERIALISE_ELEMENT_ARRAY(pColorWriteEnables, attachmentCount).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.colorWriteEnable.assign(pColorWriteEnables, attachmentCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
commandBuffer = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
if(commandBuffer != VK_NULL_HANDLE)
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdSetColorWriteEnableEXT(Unwrap(commandBuffer), attachmentCount, pColorWriteEnables);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WrappedVulkan::vkCmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,
|
||||
uint32_t attachmentCount,
|
||||
const VkBool32 *pColorWriteEnables)
|
||||
{
|
||||
SCOPED_DBG_SINK();
|
||||
|
||||
SERIALISE_TIME_CALL(
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdSetColorWriteEnableEXT(Unwrap(commandBuffer), attachmentCount, pColorWriteEnables));
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
VkResourceRecord *record = GetRecord(commandBuffer);
|
||||
|
||||
CACHE_THREAD_SERIALISER();
|
||||
|
||||
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetColorWriteEnableEXT);
|
||||
Serialise_vkCmdSetColorWriteEnableEXT(ser, commandBuffer, attachmentCount, pColorWriteEnables);
|
||||
|
||||
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetViewport, VkCommandBuffer commandBuffer,
|
||||
uint32_t firstViewport, uint32_t viewportCount,
|
||||
const VkViewport *pViewports);
|
||||
@@ -1587,3 +1653,6 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetStencilTestEnableEXT, VkCommandBuf
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetStencilOpEXT, VkCommandBuffer commandBuffer,
|
||||
VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp,
|
||||
VkStencilOp depthFailOp, VkCompareOp compareOp);
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetColorWriteEnableEXT, VkCommandBuffer commandBuffer,
|
||||
uint32_t attachmentCount, const VkBool32 *pColorWriteEnables);
|
||||
|
||||
@@ -957,8 +957,10 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass(SerialiserType &ser, VkDevice d
|
||||
{
|
||||
if(m_ReplayOptions.optimisation != ReplayOptimisationLevel::Fastest)
|
||||
{
|
||||
att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
if(att[i].storeOp != VK_ATTACHMENT_STORE_OP_NONE_EXT)
|
||||
att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
if(att[i].stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE_EXT)
|
||||
att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
||||
if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
|
||||
{
|
||||
@@ -1035,8 +1037,10 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass(SerialiserType &ser, VkDevice d
|
||||
// without doing a clear or a DONT_CARE load.
|
||||
for(uint32_t i = 0; i < CreateInfo.attachmentCount; i++)
|
||||
{
|
||||
att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(att[i].loadOp != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(att[i].stencilLoadOp != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
}
|
||||
|
||||
VkRenderPassCreateInfo loadInfo = CreateInfo;
|
||||
@@ -1139,8 +1143,10 @@ VkResult WrappedVulkan::vkCreateRenderPass(VkDevice device, const VkRenderPassCr
|
||||
for(uint32_t i = 0; i < info.attachmentCount; i++)
|
||||
{
|
||||
atts[i] = info.pAttachments[i];
|
||||
atts[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
atts[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(atts[i].loadOp != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
atts[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(atts[i].stencilLoadOp != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
atts[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
}
|
||||
|
||||
info.pAttachments = atts.data();
|
||||
@@ -1207,8 +1213,10 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass2(SerialiserType &ser, VkDevice
|
||||
VkAttachmentDescription2 *att = (VkAttachmentDescription2 *)CreateInfo.pAttachments;
|
||||
for(uint32_t i = 0; i < CreateInfo.attachmentCount; i++)
|
||||
{
|
||||
att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
if(att[i].storeOp != VK_ATTACHMENT_STORE_OP_NONE_EXT)
|
||||
att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
if(att[i].stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE_EXT)
|
||||
att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
||||
if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
|
||||
att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
@@ -1265,8 +1273,10 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass2(SerialiserType &ser, VkDevice
|
||||
// without doing a clear or a DONT_CARE load.
|
||||
for(uint32_t i = 0; i < CreateInfo.attachmentCount; i++)
|
||||
{
|
||||
att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(att[i].loadOp != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(att[i].stencilLoadOp != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
}
|
||||
|
||||
VkRenderPassCreateInfo2 loadInfo = CreateInfo;
|
||||
@@ -1371,8 +1381,10 @@ VkResult WrappedVulkan::vkCreateRenderPass2(VkDevice device,
|
||||
for(uint32_t i = 0; i < info.attachmentCount; i++)
|
||||
{
|
||||
atts[i] = info.pAttachments[i];
|
||||
atts[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
atts[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(atts[i].loadOp != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
atts[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(atts[i].stencilLoadOp != VK_ATTACHMENT_LOAD_OP_NONE_EXT)
|
||||
atts[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
}
|
||||
|
||||
info.pAttachments = atts.data();
|
||||
|
||||
@@ -29,6 +29,7 @@ set(VULKAN_SRC
|
||||
vk/vk_large_descriptor_sets.cpp
|
||||
vk/vk_leak_check.cpp
|
||||
vk/vk_line_raster.cpp
|
||||
vk/vk_load_store_none.cpp
|
||||
vk/vk_mesh_zoo.cpp
|
||||
vk/vk_misaligned_dirty.cpp
|
||||
vk/vk_multi_thread_windows.cpp
|
||||
|
||||
@@ -290,6 +290,7 @@
|
||||
<ClCompile Include="vk\vk_large_buffer.cpp" />
|
||||
<ClCompile Include="vk\vk_large_descriptor_sets.cpp" />
|
||||
<ClCompile Include="vk\vk_leak_check.cpp" />
|
||||
<ClCompile Include="vk\vk_load_store_none.cpp" />
|
||||
<ClCompile Include="vk\vk_mesh_zoo.cpp" />
|
||||
<ClCompile Include="vk\vk_parameter_zoo.cpp" />
|
||||
<ClCompile Include="vk\vk_imageless_framebuffer.cpp" />
|
||||
|
||||
@@ -607,6 +607,9 @@
|
||||
<ClCompile Include="d3d12\d3d12_descriptor_indexing.cpp">
|
||||
<Filter>D3D12\demos</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vk\vk_load_store_none.cpp">
|
||||
<Filter>Vulkan\demos</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="D3D11">
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019-2021 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"
|
||||
|
||||
RD_TEST(VK_Load_Store_None, VulkanGraphicsTest)
|
||||
{
|
||||
static constexpr const char *Description =
|
||||
"Tests the use of LOAD_OP_NONE and STORE_OP_NONE to preserve an attachment without "
|
||||
"modification.";
|
||||
|
||||
std::string pixel = R"EOSHADER(
|
||||
#version 460 core
|
||||
|
||||
layout(location = 0, index = 0) out vec4 Color1;
|
||||
layout(location = 1, index = 0) out vec4 Color2;
|
||||
|
||||
void main()
|
||||
{
|
||||
Color1 = Color2 = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
void Prepare(int argc, char **argv)
|
||||
{
|
||||
devExts.push_back(VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME);
|
||||
|
||||
// require dynamic color write enable for the easiest time testing both load and store op none.
|
||||
//
|
||||
// these ops are there because renderpasses with different ops but everything else is the same
|
||||
// are still compatible, so these can be switched last minute without needing to recompile a
|
||||
// pipeline. So the cases they are useful are those where a pipeline is declared to use an
|
||||
// attachment then at the last minute the application realises it doesn't need it.
|
||||
//
|
||||
// NONE store op can be useful on its own in a couple of scenarios when you're using read-only
|
||||
// depth, as there's no way to express "this was not written and no synchronisation is needed"
|
||||
// because don't care and store are both write operations.
|
||||
//
|
||||
// NONE load op is only useful when you want to preserve an attachment that's now unused but had
|
||||
// it declared as modified and e.g. load/store'd at creation time. For depth this could happen
|
||||
// with EXT_extended_dynamic_state if you disabled depth testing which was previously used,
|
||||
// and wanted to preserve the depth. That's more annoying to test though, so we require
|
||||
// color_write_enable for the same purpose (dynamically disabling).
|
||||
//
|
||||
// We could just create the pipeline as not writing to those attachments from the start, but
|
||||
// that would be a bit too artificial and not how this is used in practice.
|
||||
devExts.push_back(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
|
||||
|
||||
VulkanGraphicsTest::Prepare(argc, argv);
|
||||
|
||||
static VkPhysicalDeviceColorWriteEnableFeaturesEXT colorEnableFeats = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT,
|
||||
};
|
||||
|
||||
colorEnableFeats.colorWriteEnable = VK_TRUE;
|
||||
devInfoNext = &colorEnableFeats;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// initialise, create window, create context, etc
|
||||
if(!Init())
|
||||
return 3;
|
||||
|
||||
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({}));
|
||||
|
||||
AllocatedImage img(
|
||||
this,
|
||||
vkh::ImageCreateInfo(mainWindow->scissor.extent.width, mainWindow->scissor.extent.height, 0,
|
||||
VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
||||
|
||||
VkImageView imgview = createImageView(
|
||||
vkh::ImageViewCreateInfo(img.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R32G32B32A32_SFLOAT));
|
||||
|
||||
AllocatedImage preserveimg(
|
||||
this,
|
||||
vkh::ImageCreateInfo(mainWindow->scissor.extent.width, mainWindow->scissor.extent.height, 0,
|
||||
VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
||||
|
||||
setName(preserveimg.image, "PreserveImg");
|
||||
|
||||
VkImageView preserveimgview = createImageView(vkh::ImageViewCreateInfo(
|
||||
preserveimg.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R32G32B32A32_SFLOAT));
|
||||
|
||||
vkh::RenderPassCreator renderPassCreateInfo;
|
||||
|
||||
renderPassCreateInfo.attachments.push_back(
|
||||
vkh::AttachmentDescription(VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_GENERAL, VK_ATTACHMENT_LOAD_OP_CLEAR));
|
||||
// unused attachment
|
||||
renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
|
||||
VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE));
|
||||
|
||||
renderPassCreateInfo.addSubpass({VkAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL}),
|
||||
VkAttachmentReference({1, VK_IMAGE_LAYOUT_GENERAL})});
|
||||
|
||||
// this RP has clear/store
|
||||
VkRenderPass pipeRP = createRenderPass(renderPassCreateInfo);
|
||||
|
||||
renderPassCreateInfo.attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
|
||||
renderPassCreateInfo.attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
|
||||
|
||||
// this RP has none/none and will be used for rendering
|
||||
VkRenderPass renderPass = createRenderPass(renderPassCreateInfo);
|
||||
|
||||
VkFramebuffer framebuffer = createFramebuffer(vkh::FramebufferCreateInfo(
|
||||
renderPass, {imgview, preserveimgview}, mainWindow->scissor.extent));
|
||||
|
||||
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
|
||||
|
||||
pipeCreateInfo.layout = layout;
|
||||
pipeCreateInfo.renderPass = pipeRP;
|
||||
|
||||
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(VKDefaultVertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
};
|
||||
|
||||
pipeCreateInfo.dynamicState.dynamicStates.push_back(VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
|
||||
|
||||
pipeCreateInfo.colorBlendState.attachments.push_back({
|
||||
// blendEnable
|
||||
VK_FALSE,
|
||||
// color*
|
||||
VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_OP_ADD,
|
||||
// alpha*
|
||||
VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_OP_ADD,
|
||||
// colorWriteMask
|
||||
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
|
||||
VK_COLOR_COMPONENT_A_BIT,
|
||||
});
|
||||
|
||||
VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);
|
||||
|
||||
AllocatedBuffer vb(
|
||||
this, vkh::BufferCreateInfo(sizeof(DefaultTri), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
|
||||
vb.upload(DefaultTri);
|
||||
|
||||
{
|
||||
VkCommandBuffer cmd = GetCommandBuffer();
|
||||
|
||||
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
|
||||
|
||||
// put the attachment in GENERAL
|
||||
vkh::cmdPipelineBarrier(
|
||||
cmd, {
|
||||
vkh::ImageMemoryBarrier(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
|
||||
preserveimg.image),
|
||||
});
|
||||
|
||||
// use the original pipeline's RP to clear and store
|
||||
vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(pipeRP, framebuffer, mainWindow->scissor,
|
||||
{vkh::ClearValue(0.2f, 0.2f, 0.2f, 1.0f),
|
||||
vkh::ClearValue(0.2f, 0.2f, 0.2f, 1.0f)}),
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
// clear a rect in the middle of the preserve attachment to green
|
||||
VkClearAttachment att = {};
|
||||
att.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
att.clearValue.color.float32[1] = 1.0f;
|
||||
att.clearValue.color.float32[3] = 1.0f;
|
||||
att.colorAttachment = 1;
|
||||
VkClearRect rect = {};
|
||||
rect.baseArrayLayer = 0;
|
||||
rect.layerCount = 1;
|
||||
rect.rect.offset.x = 150;
|
||||
rect.rect.offset.y = 100;
|
||||
rect.rect.extent.width = 75;
|
||||
rect.rect.extent.height = 50;
|
||||
vkCmdClearAttachments(cmd, 1, &att, 1, &rect);
|
||||
|
||||
vkCmdEndRenderPass(cmd);
|
||||
|
||||
// we'll be reading later, synchronise here once
|
||||
vkh::cmdPipelineBarrier(
|
||||
cmd, {
|
||||
vkh::ImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_GENERAL, preserveimg.image),
|
||||
});
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(99, 99, {cmd});
|
||||
}
|
||||
|
||||
while(Running())
|
||||
{
|
||||
VkCommandBuffer cmd = GetCommandBuffer();
|
||||
|
||||
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
|
||||
|
||||
VkImage swapimg =
|
||||
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(renderPass, framebuffer, mainWindow->scissor,
|
||||
{vkh::ClearValue(0.2f, 0.2f, 0.2f, 1.0f),
|
||||
vkh::ClearValue(1.0f, 0.2f, 0.2f, 1.0f)}),
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
|
||||
|
||||
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
|
||||
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
|
||||
|
||||
VkBool32 enables[2] = {true, false};
|
||||
vkCmdSetColorWriteEnableEXT(cmd, 2, enables);
|
||||
|
||||
vkCmdDraw(cmd, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRenderPass(cmd);
|
||||
|
||||
// no need to synchronise here, nothing changed the preserved image
|
||||
|
||||
blitToSwap(cmd, preserveimg.image, VK_IMAGE_LAYOUT_GENERAL, swapimg, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(0, 1, {cmd});
|
||||
|
||||
Present();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST();
|
||||
@@ -0,0 +1,21 @@
|
||||
import renderdoc as rd
|
||||
import rdtest
|
||||
|
||||
|
||||
class VK_Load_Store_None(rdtest.TestCase):
|
||||
demos_test_name = 'VK_Load_Store_None'
|
||||
|
||||
def check_capture(self):
|
||||
res = self.get_resource_by_name('PreserveImg').resourceId
|
||||
|
||||
for action in [self.find_action("BeginRender"), self.find_action("Draw"), self.find_action("EndRender"),
|
||||
self.find_action("Blit")]:
|
||||
self.controller.SetFrameEvent(action.eventId, True)
|
||||
|
||||
self.check_pixel_value(res, 200, 125, [0.0, 1.0, 0.0, 1.0])
|
||||
self.check_pixel_value(res, 200, 90, [0.2, 0.2, 0.2, 1.0])
|
||||
self.check_pixel_value(res, 200, 160, [0.2, 0.2, 0.2, 1.0])
|
||||
self.check_pixel_value(res, 250, 125, [0.2, 0.2, 0.2, 1.0])
|
||||
self.check_pixel_value(res, 100, 125, [0.2, 0.2, 0.2, 1.0])
|
||||
|
||||
rdtest.log.success("Preserved image is as expected at {}".format(self.action_name(action)))
|
||||
Reference in New Issue
Block a user