vulkan: reduced descriptor set bindings by aliasing; fixes with barriers; fixed memory overwrite that seems to happen with RWTexture2D out of bounds writes;

This commit is contained in:
Turánszki János
2023-06-06 11:10:10 +02:00
parent 169e394e53
commit be2da70bcd
5 changed files with 81 additions and 30 deletions
+11 -5
View File
@@ -46,6 +46,17 @@ RWTexture2D<uint4> output : register(u0);
[numthreads(8, 8, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
uint2 dim;
input.GetDimensions(dim.x, dim.y);
uint2 block_dim = dim / 4;
[branch]
if (any(DTid.xy >= block_dim))
return;
const float2 dim_rcp = rcp(dim);
const float2 uv = float2(DTid.xy * 4 + 1) * dim_rcp;
#ifdef BC1
float3 block[16];
#endif // BC1
@@ -64,11 +75,6 @@ void main(uint3 DTid : SV_DispatchThreadID)
float block_v[16];
#endif // BC5
uint2 dim;
input.GetDimensions(dim.x, dim.y);
const float2 dim_rcp = rcp(dim);
const float2 uv = float2(DTid.xy * 4 + 1) * dim_rcp;
//SUB-BLOCK///////////////////////////////////////////////////////////////////////
float4 red = input.GatherRed(sampler_linear_clamp, uv, int2(0, 0));
@@ -710,9 +710,14 @@ void main(uint3 groupID : SV_GroupID,
uint2 dim;
SrcTexture.GetDimensions(dim.x, dim.y);
float2 TextureSizeRcp = rcp(dim);
uint2 TextureSizeInBlocks = dim / 4;
[branch]
if (any(blockCoord >= TextureSizeInBlocks))
return;
float2 TextureSizeRcp = rcp(dim);
if (all(blockCoord < TextureSizeInBlocks))
{
// Gather texels for current 4x4 block
+36
View File
@@ -70,6 +70,41 @@ SamplerState sampler_aniso_wrap : register(s107);
SamplerState sampler_aniso_mirror : register(s108);
SamplerComparisonState sampler_cmp_depth : register(s109);
#ifdef SPIRV
// In Vulkan, we can manually overlap descriptor sets to reduce bindings:
// Note that HLSL register space declaration was not working correctly with overlapped spaces,
// But vk::binding works correctly in this case.
// HLSL register space declaration is working well with Vulkan when spaces are not overlapping.
static const uint DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER = 1;
static const uint DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER = 2;
static const uint DESCRIPTOR_SET_BINDLESS_SAMPLER = 3;
static const uint DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE = 4;
static const uint DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE = 5;
static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 6;
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] ByteAddressBuffer bindless_buffers[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint> bindless_ib[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLER)]] SamplerState bindless_samplers[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D bindless_textures[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2DArray bindless_textures2DArray[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] TextureCube bindless_cubemaps[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] TextureCubeArray bindless_cubearrays[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture3D bindless_textures3D[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D<float> bindless_textures_float[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D<float2> bindless_textures_float2[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D<uint> bindless_textures_uint[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D<uint4> bindless_textures_uint4[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] RWByteAddressBuffer bindless_rwbuffers[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2D<float4> bindless_rwtextures[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2DArray<float4> bindless_rwtextures2DArray[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture3D<float4> bindless_rwtextures3D[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2D<uint> bindless_rwtextures_uint[];
#ifdef RTAPI
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE)]] RaytracingAccelerationStructure bindless_accelerationstructures[];
#endif // RTAPI
#else
SamplerState bindless_samplers[] : register(space1);
Texture2D bindless_textures[] : register(space2);
ByteAddressBuffer bindless_buffers[] : register(space3);
@@ -91,6 +126,7 @@ RWByteAddressBuffer bindless_rwbuffers[] : register(space15);
RWTexture2DArray<float4> bindless_rwtextures2DArray[] : register(space16);
RWTexture3D<float4> bindless_rwtextures3D[] : register(space17);
RWTexture2D<uint> bindless_rwtextures_uint[] : register(space18);
#endif // SPIRV
#include "ShaderInterop_Renderer.h"
+27 -23
View File
@@ -1482,6 +1482,7 @@ using namespace vulkan_internal;
{
cbSubmitInfo.commandBuffer = cmd.transferCommandBuffer;
signalSemaphoreInfos[0].semaphore = cmd.semaphores[0]; // signal for graphics queue
signalSemaphoreInfos[0].stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
submitInfo.commandBufferInfoCount = 1;
submitInfo.pCommandBufferInfos = &cbSubmitInfo;
@@ -1495,7 +1496,7 @@ using namespace vulkan_internal;
{
waitSemaphoreInfo.semaphore = cmd.semaphores[0]; // wait for copy queue
waitSemaphoreInfo.stageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
waitSemaphoreInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
cbSubmitInfo.commandBuffer = cmd.transitionCommandBuffer;
signalSemaphoreInfos[0].semaphore = cmd.semaphores[1]; // signal for compute queue
@@ -1525,7 +1526,7 @@ using namespace vulkan_internal;
if (device->queues[QUEUE_VIDEO_DECODE].queue != VK_NULL_HANDLE)
{
waitSemaphoreInfo.semaphore = cmd.semaphores[2]; // wait for graphics queue
waitSemaphoreInfo.stageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR;
waitSemaphoreInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
submitInfo.waitSemaphoreInfoCount = 1;
submitInfo.pWaitSemaphoreInfos = &waitSemaphoreInfo;
@@ -3879,24 +3880,6 @@ using namespace vulkan_internal;
if(cmd.IsValid())
{
VkBufferMemoryBarrier2 barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2;
barrier.buffer = internal_state->resource;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
barrier.srcAccessMask = 0;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
barrier.size = VK_WHOLE_SIZE;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
VkDependencyInfo dependencyInfo = {};
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
dependencyInfo.bufferMemoryBarrierCount = 1;
dependencyInfo.pBufferMemoryBarriers = &barrier;
vkCmdPipelineBarrier2(cmd.transferCommandBuffer, &dependencyInfo);
VkBufferCopy copyRegion = {};
copyRegion.size = buffer->desc.size;
copyRegion.srcOffset = 0;
@@ -3910,8 +3893,17 @@ using namespace vulkan_internal;
&copyRegion
);
std::swap(barrier.srcStageMask, barrier.dstStageMask);
std::swap(barrier.srcAccessMask, barrier.dstAccessMask);
VkBufferMemoryBarrier2 barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2;
barrier.buffer = internal_state->resource;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
barrier.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT;
barrier.size = VK_WHOLE_SIZE;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
if (has_flag(buffer->desc.bind_flags, BindFlag::CONSTANT_BUFFER))
{
@@ -3919,10 +3911,12 @@ using namespace vulkan_internal;
}
if (has_flag(buffer->desc.bind_flags, BindFlag::VERTEX_BUFFER))
{
barrier.dstStageMask |= VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT;
barrier.dstAccessMask |= VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT;
}
if (has_flag(buffer->desc.bind_flags, BindFlag::INDEX_BUFFER))
{
barrier.dstStageMask |= VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT;
barrier.dstAccessMask |= VK_ACCESS_2_INDEX_READ_BIT;
}
if (has_flag(buffer->desc.bind_flags, BindFlag::SHADER_RESOURCE))
@@ -3942,7 +3936,17 @@ using namespace vulkan_internal;
{
barrier.dstAccessMask |= VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR;
}
vkCmdPipelineBarrier2(cmd.transferCommandBuffer, &dependencyInfo);
if (has_flag(buffer->desc.misc_flags, ResourceMiscFlag::VIDEO_DECODE))
{
barrier.dstAccessMask |= VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR;
}
VkDependencyInfo dependencyInfo = {};
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
dependencyInfo.bufferMemoryBarrierCount = 1;
dependencyInfo.pBufferMemoryBarriers = &barrier;
vkCmdPipelineBarrier2(cmd.transitionCommandBuffer, &dependencyInfo);
copyAllocator.submit(cmd);
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 219;
const int revision = 220;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);