diff --git a/renderdoc/CMakeLists.txt b/renderdoc/CMakeLists.txt index cee6b3b02..97be3601b 100644 --- a/renderdoc/CMakeLists.txt +++ b/renderdoc/CMakeLists.txt @@ -386,6 +386,7 @@ set(data data/glsl/quadresolve.frag data/glsl/quadwrite.frag data/glsl/pixelhistory_mscopy.comp + data/glsl/pixelhistory_mscopy_depth.comp data/glsl/pixelhistory_primid.frag data/glsl/shaderdebug_sample.vert data/glsl/texdisplay.frag diff --git a/renderdoc/data/embedded_files.h b/renderdoc/data/embedded_files.h index b3f2a3252..560b29026 100644 --- a/renderdoc/data/embedded_files.h +++ b/renderdoc/data/embedded_files.h @@ -64,6 +64,7 @@ DECLARE_EMBED(glsl_deptharr2ms_frag); DECLARE_EMBED(glsl_depthms2arr_frag); DECLARE_EMBED(glsl_gles_texsample_h); DECLARE_EMBED(glsl_pixelhistory_mscopy_comp); +DECLARE_EMBED(glsl_pixelhistory_mscopy_depth_comp); DECLARE_EMBED(glsl_pixelhistory_primid_frag); DECLARE_EMBED(glsl_shaderdebug_sample_vert); DECLARE_EMBED(glsl_texremap_frag); diff --git a/renderdoc/data/glsl/pixelhistory_mscopy.comp b/renderdoc/data/glsl/pixelhistory_mscopy.comp index 2e6927349..bb8aaf3a9 100644 --- a/renderdoc/data/glsl/pixelhistory_mscopy.comp +++ b/renderdoc/data/glsl/pixelhistory_mscopy.comp @@ -26,9 +26,7 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; -layout(binding = 0) uniform PRECISION usampler2DMSArray srcMS0; -layout(binding = 1) uniform PRECISION usampler2DMSArray srcMS1; - +layout(binding = 0) uniform PRECISION usampler2DMSArray srcMS; layout(binding = 2, std140) writeonly buffer pixelhistorydest { uvec4 result[]; @@ -37,7 +35,6 @@ dest; layout(push_constant) uniform multisamplePush { - int depthCopy; int currentSample; int x; int y; @@ -45,7 +42,6 @@ layout(push_constant) uniform multisamplePush } mscopy; -#define depthCopy (mscopy.depthCopy) #define currentSample (mscopy.currentSample) #define x (mscopy.x) #define y (mscopy.y) @@ -53,15 +49,6 @@ mscopy; void main() { - if(depthCopy == 0) - { - uvec4 data = texelFetch(srcMS0, ivec3(x, y, 0), currentSample); - dest.result[dstOffset] = data; - } - else if(depthCopy == 1) - { - uint depth = texelFetch(srcMS0, ivec3(x, y, 0), currentSample).r; - uint stencil = texelFetch(srcMS1, ivec3(x, y, 0), currentSample).r; - dest.result[dstOffset] = uvec4(depth, stencil, 0, 0); - } + uvec4 data = texelFetch(srcMS, ivec3(x, y, 0), currentSample); + dest.result[dstOffset] = data; } diff --git a/renderdoc/data/glsl/pixelhistory_mscopy_depth.comp b/renderdoc/data/glsl/pixelhistory_mscopy_depth.comp new file mode 100644 index 000000000..af35e02e5 --- /dev/null +++ b/renderdoc/data/glsl/pixelhistory_mscopy_depth.comp @@ -0,0 +1,65 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2020 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 "glsl_globals.h" + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +layout(binding = 0) uniform PRECISION sampler2DMSArray depthMS; +layout(binding = 1) uniform PRECISION usampler2DMSArray stencilMS; + +layout(binding = 2, std140) writeonly buffer pixelhistorydest +{ + uvec4 result[]; +} +dest; + +layout(push_constant) uniform multisamplePush +{ + int currentSample; + int x; + int y; + int dstOffset; + int hasDepth; + int hasStencil; +} +mscopy; + +#define currentSample (mscopy.currentSample) +#define x (mscopy.x) +#define y (mscopy.y) +#define dstOffset (mscopy.dstOffset) +#define hasDepth (mscopy.hasDepth) +#define hasStencil (mscopy.hasStencil) + +void main() +{ + float depth = 0.0; + if(hasDepth == 1) + depth = texelFetch(depthMS, ivec3(x, y, 0), currentSample).r; + uint stencil = 0; + if(hasStencil == 1) + stencil = texelFetch(stencilMS, ivec3(x, y, 0), currentSample).r; + dest.result[dstOffset] = uvec4(floatBitsToUint(depth), stencil, 0, 0); +} diff --git a/renderdoc/data/renderdoc.rc b/renderdoc/data/renderdoc.rc index 264df0ac3..04abb3803 100644 --- a/renderdoc/data/renderdoc.rc +++ b/renderdoc/data/renderdoc.rc @@ -129,6 +129,7 @@ RESOURCE_glsl_minmaxtile_comp TYPE_EMBED "glsl/minmaxtile.comp" RESOURCE_glsl_minmaxresult_comp TYPE_EMBED "glsl/minmaxresult.comp" RESOURCE_glsl_histogram_comp TYPE_EMBED "glsl/histogram.comp" RESOURCE_glsl_pixelhistory_mscopy_comp TYPE_EMBED "glsl/pixelhistory_mscopy.comp" +RESOURCE_glsl_pixelhistory_mscopy_depth_comp TYPE_EMBED "glsl/pixelhistory_mscopy_depth.comp" RESOURCE_glsl_pixelhistory_primid_frag TYPE_EMBED "glsl/pixelhistory_primid.frag" RESOURCE_glsl_glsl_ubos_h TYPE_EMBED "glsl/glsl_ubos.h" RESOURCE_glsl_gl_texsample_h TYPE_EMBED "glsl/gl_texsample.h" diff --git a/renderdoc/data/resource.h b/renderdoc/data/resource.h index 45eb5b9be..69f072d39 100644 --- a/renderdoc/data/resource.h +++ b/renderdoc/data/resource.h @@ -19,38 +19,39 @@ #define RESOURCE_sourcecodepro_ttf 301 -#define RESOURCE_glsl_blit_vert 401 -#define RESOURCE_glsl_checkerboard_frag 402 -#define RESOURCE_glsl_texdisplay_frag 403 -#define RESOURCE_glsl_vktext_vert 404 -#define RESOURCE_glsl_vktext_frag 405 -#define RESOURCE_glsl_fixedcol_frag 408 -#define RESOURCE_glsl_mesh_vert 409 -#define RESOURCE_glsl_mesh_geom 410 -#define RESOURCE_glsl_mesh_frag 411 -#define RESOURCE_glsl_minmaxtile_comp 412 -#define RESOURCE_glsl_minmaxresult_comp 413 -#define RESOURCE_glsl_histogram_comp 414 -#define RESOURCE_glsl_glsl_ubos_h 416 -#define RESOURCE_glsl_gl_texsample_h 417 -#define RESOURCE_glsl_vk_texsample_h 418 -#define RESOURCE_glsl_quadresolve_frag 419 -#define RESOURCE_glsl_quadwrite_frag 420 -#define RESOURCE_glsl_mesh_comp 421 -#define RESOURCE_glsl_array2ms_comp 422 -#define RESOURCE_glsl_ms2array_comp 423 -#define RESOURCE_glsl_trisize_geom 424 -#define RESOURCE_glsl_trisize_frag 425 -#define RESOURCE_glsl_deptharr2ms_frag 426 -#define RESOURCE_glsl_depthms2arr_frag 427 -#define RESOURCE_glsl_gles_texsample_h 428 -#define RESOURCE_glsl_gltext_vert 429 -#define RESOURCE_glsl_gltext_frag 430 -#define RESOURCE_glsl_glsl_globals_h 440 -#define RESOURCE_glsl_texremap_frag 441 -#define RESOURCE_glsl_pixelhistory_mscopy_comp 442 -#define RESOURCE_glsl_pixelhistory_primid_frag 443 -#define RESOURCE_glsl_shaderdebug_sample_vert 444 +#define RESOURCE_glsl_blit_vert 401 +#define RESOURCE_glsl_checkerboard_frag 402 +#define RESOURCE_glsl_texdisplay_frag 403 +#define RESOURCE_glsl_vktext_vert 404 +#define RESOURCE_glsl_vktext_frag 405 +#define RESOURCE_glsl_fixedcol_frag 408 +#define RESOURCE_glsl_mesh_vert 409 +#define RESOURCE_glsl_mesh_geom 410 +#define RESOURCE_glsl_mesh_frag 411 +#define RESOURCE_glsl_minmaxtile_comp 412 +#define RESOURCE_glsl_minmaxresult_comp 413 +#define RESOURCE_glsl_histogram_comp 414 +#define RESOURCE_glsl_glsl_ubos_h 416 +#define RESOURCE_glsl_gl_texsample_h 417 +#define RESOURCE_glsl_vk_texsample_h 418 +#define RESOURCE_glsl_quadresolve_frag 419 +#define RESOURCE_glsl_quadwrite_frag 420 +#define RESOURCE_glsl_mesh_comp 421 +#define RESOURCE_glsl_array2ms_comp 422 +#define RESOURCE_glsl_ms2array_comp 423 +#define RESOURCE_glsl_trisize_geom 424 +#define RESOURCE_glsl_trisize_frag 425 +#define RESOURCE_glsl_deptharr2ms_frag 426 +#define RESOURCE_glsl_depthms2arr_frag 427 +#define RESOURCE_glsl_gles_texsample_h 428 +#define RESOURCE_glsl_gltext_vert 429 +#define RESOURCE_glsl_gltext_frag 430 +#define RESOURCE_glsl_glsl_globals_h 440 +#define RESOURCE_glsl_texremap_frag 441 +#define RESOURCE_glsl_pixelhistory_mscopy_comp 442 +#define RESOURCE_glsl_pixelhistory_mscopy_depth_comp 443 +#define RESOURCE_glsl_pixelhistory_primid_frag 444 +#define RESOURCE_glsl_shaderdebug_sample_vert 445 // Next default values for new objects // diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 92d248a35..e97414448 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -3224,12 +3224,30 @@ void VulkanReplay::PixelHistory::Init(WrappedVulkan *driver, VkDescriptorPool de {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL}, {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL}, }); - CREATE_OBJECT(MSCopyDescSet, descriptorPool, MSCopyDescSetLayout); - CREATE_OBJECT(MSDepthCopyDescSet, descriptorPool, MSCopyDescSetLayout); + + VkResult vkr = VK_SUCCESS; + VkDescriptorPoolSize descPoolTypes[] = { + {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 64}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 32}, + }; + + VkDescriptorPoolCreateInfo descPoolInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + NULL, + 0, + 32, + ARRAY_COUNT(descPoolTypes), + &descPoolTypes[0], + }; + + // create descriptor pool + vkr = driver->vkCreateDescriptorPool(driver->GetDev(), &descPoolInfo, NULL, &MSCopyDescPool); + RDCASSERTEQUAL(vkr, VK_SUCCESS); CREATE_OBJECT(MSCopyPipeLayout, MSCopyDescSetLayout, 32); CREATE_OBJECT(MSCopyPipe, MSCopyPipeLayout, driver->GetShaderCache()->GetBuiltinModule(BuiltinShader::PixelHistoryMSCopyCS)); + CREATE_OBJECT(MSCopyDepthPipe, MSCopyPipeLayout, + driver->GetShaderCache()->GetBuiltinModule(BuiltinShader::PixelHistoryMSCopyDepthCS)); } void VulkanReplay::PixelHistory::Destroy(WrappedVulkan *driver) @@ -3240,6 +3258,8 @@ void VulkanReplay::PixelHistory::Destroy(WrappedVulkan *driver) driver->vkDestroyPipelineLayout(driver->GetDev(), MSCopyPipeLayout, NULL); if(MSCopyDescSetLayout != VK_NULL_HANDLE) driver->vkDestroyDescriptorSetLayout(driver->GetDev(), MSCopyDescSetLayout, NULL); + if(MSCopyDescPool != VK_NULL_HANDLE) + driver->vkDestroyDescriptorPool(driver->GetDev(), MSCopyDescPool, NULL); } void VulkanReplay::HistogramMinMax::Init(WrappedVulkan *driver, VkDescriptorPool descriptorPool) diff --git a/renderdoc/driver/vulkan/vk_pixelhistory.cpp b/renderdoc/driver/vulkan/vk_pixelhistory.cpp index 2fd1fce59..38f365f1d 100644 --- a/renderdoc/driver/vulkan/vk_pixelhistory.cpp +++ b/renderdoc/driver/vulkan/vk_pixelhistory.cpp @@ -77,18 +77,6 @@ struct PixelHistoryResources VkImage dsImage; VkImageView dsImageView; VkDeviceMemory gpuMem; - - // Following are only used and created for multi sampled images. - // This is an image view for colorImage which uses a UINT format. - VkImageView colorImageAliasView; - // Image view for target image which uses a UINT format. - VkImageView targetImageView; - // Image view for dsImage depth stencil image that includes depth - // aspect only. - VkImageView depthOnlyImageView; - // Image view for dsImage depth stencil image that includes stencil - // aspect only. - VkImageView stencilOnlyImageView; }; struct PixelHistoryCallbackInfo @@ -387,6 +375,9 @@ struct VulkanPixelHistoryCallback : public VulkanDrawcallCallback m_pDriver->vkDestroyRenderPass(m_pDriver->GetDev(), rp, NULL); for(const VkFramebuffer &fb : m_FbsToDestroy) m_pDriver->vkDestroyFramebuffer(m_pDriver->GetDev(), fb, NULL); + for(const VkImageView &imageView : m_ImageViewsToDestroy) + m_pDriver->vkDestroyImageView(m_pDriver->GetDev(), imageView, NULL); + m_pDriver->GetReplay()->ResetPixelHistoryDescriptorPool(); } // Update the given scissor to just the pixel for which pixel history was requested. void ScissorToPixel(const VkViewport &view, VkRect2D &scissor) @@ -747,6 +738,61 @@ protected: return framebuffer; } + VkDescriptorSet GetCopyDescriptor(VkImage image, VkFormat format, uint32_t baseMip, + uint32_t baseSlice) + { + auto it = m_CopyDescriptors.find(image); + if(it != m_CopyDescriptors.end()) + return it->second; + + VkImageViewCreateInfo viewInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + viewInfo.image = image; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + viewInfo.format = format; + viewInfo.subresourceRange = {0, baseMip, 1, baseSlice, 1}; + + if(IsDepthOrStencilFormat(format)) + { + viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + } + else + { + viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + uint32_t bs = GetByteSize(1, 1, 1, format, 0); + + if(bs == 1) + viewInfo.format = VK_FORMAT_R8_UINT; + else if(bs == 2) + viewInfo.format = VK_FORMAT_R16_UINT; + else if(bs == 4) + viewInfo.format = VK_FORMAT_R32_UINT; + else if(bs == 8) + viewInfo.format = VK_FORMAT_R32G32_UINT; + else if(bs == 16) + viewInfo.format = VK_FORMAT_R32G32B32A32_UINT; + } + + VkImageView imageView; + VkResult vkr = m_pDriver->vkCreateImageView(m_pDriver->GetDev(), &viewInfo, NULL, &imageView); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + m_ImageViewsToDestroy.push_back(imageView); + + VkImageView imageView2 = VK_NULL_HANDLE; + if(IsStencilFormat(format)) + { + viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + vkr = m_pDriver->vkCreateImageView(m_pDriver->GetDev(), &viewInfo, NULL, &imageView2); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + m_ImageViewsToDestroy.push_back(imageView2); + } + + VkDescriptorSet descSet = m_pDriver->GetReplay()->GetPixelHistoryDescriptor(); + m_pDriver->GetReplay()->UpdatePixelHistoryDescriptor(descSet, m_CallbackInfo.dstBuffer, + imageView, imageView2); + m_CopyDescriptors.insert(std::make_pair(image, descSet)); + return descSet; + } + void CopyImagePixel(VkCommandBuffer cmd, CopyPixelParams &p, size_t offset) { VkImageAspectFlags aspectFlags = 0; @@ -786,55 +832,14 @@ protected: VK_ACCESS_MEMORY_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, p.srcImageLayout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(p.srcImage), subresource}; - - if(depthCopy && p.srcImage != m_CallbackInfo.dsImage) - { - // This is an original depth image that is used in a draw. - // The descriptor for MSAA copy has the dsImage created for pixel history. - // So copy the pixel value there first. - VkImageCopy region = {}; - region.srcSubresource = {aspectFlags, baseMip, baseSlice, 1}; - region.srcOffset = {(int32_t)m_CallbackInfo.x, (int32_t)m_CallbackInfo.y, 0}; - region.dstSubresource = {aspectFlags, 0, 0, 1}; - region.dstOffset = {(int32_t)m_CallbackInfo.x, (int32_t)m_CallbackInfo.y, 0}; - region.extent = {1, 1, 1}; - - VkImageMemoryBarrier barriers[2]; - barriers[0] = barrier; - barriers[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - barriers[0].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - barriers[1] = barriers[0]; - barriers[1].image = Unwrap(m_CallbackInfo.dsImage); - barriers[1].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - barriers[1].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - - DoPipelineBarrier(cmd, 2, barriers); - - ObjDisp(cmd)->CmdCopyImage( - Unwrap(cmd), Unwrap(p.srcImage), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - Unwrap(m_CallbackInfo.dsImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - - // Return src image to its layout. - barrier.image = Unwrap(p.srcImage); - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - barrier.newLayout = p.srcImageLayout; - barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.dstAccessMask = VK_ACCESS_ALL_WRITE_BITS; - DoPipelineBarrier(cmd, 1, &barrier); - - barrier.image = Unwrap(m_CallbackInfo.dsImage); - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - } + VkDescriptorSet descSet = GetCopyDescriptor(p.srcImage, p.srcImageFormat, baseMip, baseSlice); // Transition src image to SHADER_READ_ONLY_OPTIMAL. DoPipelineBarrier(cmd, 1, &barrier); m_pDriver->GetReplay()->CopyPixelForPixelHistory( cmd, {(int32_t)m_CallbackInfo.x, (int32_t)m_CallbackInfo.y}, - m_CallbackInfo.targetSubresource.sample, (uint32_t)offset / 16, depthCopy); + m_CallbackInfo.targetSubresource.sample, (uint32_t)offset / 16, p.srcImageFormat, descSet); // Transition src image back to its layout. barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; @@ -947,6 +952,8 @@ protected: rdcarray m_RpsToDestroy; rdcarray m_FbsToDestroy; rdcarray m_DynamicStates; + std::map m_CopyDescriptors; + rdcarray m_ImageViewsToDestroy; }; // VulkanOcclusionCallback callback is used to determine which draw events might have @@ -1400,11 +1407,15 @@ private: CopyPixelParams targetCopyParams = {}; targetCopyParams.srcImage = m_CallbackInfo.targetImage; targetCopyParams.srcImageFormat = m_CallbackInfo.targetImageFormat; - targetCopyParams.srcImageLayout = m_pDriver->GetDebugManager()->GetImageLayout( - GetResID(m_CallbackInfo.targetImage), VK_IMAGE_ASPECT_COLOR_BIT, - m_CallbackInfo.targetSubresource.mip, m_CallbackInfo.targetSubresource.slice); + VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT; if(IsDepthOrStencilFormat(m_CallbackInfo.targetImageFormat)) + { offset += offsetof(struct PixelHistoryValue, depth); + aspect = VK_IMAGE_ASPECT_DEPTH_BIT; + } + targetCopyParams.srcImageLayout = m_pDriver->GetDebugManager()->GetImageLayout( + GetResID(m_CallbackInfo.targetImage), aspect, m_CallbackInfo.targetSubresource.mip, + m_CallbackInfo.targetSubresource.slice); CopyImagePixel(cmd, targetCopyParams, offset); // If the target image is a depth/stencil attachment, we already @@ -2242,7 +2253,7 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback CopyPixelParams depthCopyParams = colourCopyParams; depthCopyParams.srcImage = m_CallbackInfo.dsImage; depthCopyParams.srcImageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - depthCopyParams.srcImageFormat = depthFormat; + depthCopyParams.srcImageFormat = m_CallbackInfo.dsFormat; CopyImagePixel(cmd, depthCopyParams, (fragsProcessed + f) * sizeof(PerFragmentInfo) + offsetof(struct PerFragmentInfo, postMod) + offsetof(struct PixelHistoryValue, depth)); @@ -2593,11 +2604,6 @@ bool VulkanDebugManager::PixelHistorySetupResources(PixelHistoryResources &resou VkImage dsImage; VkImageView dsImageView; - VkImageView colorImageAliasView = VK_NULL_HANDLE; - VkImageView targetImageView = VK_NULL_HANDLE; - VkImageView depthOnlyImageView = VK_NULL_HANDLE; - VkImageView stencilOnlyImageView = VK_NULL_HANDLE; - VkDeviceMemory gpuMem; VkBuffer dstBuffer; @@ -2691,46 +2697,6 @@ bool VulkanDebugManager::PixelHistorySetupResources(PixelHistoryResources &resou vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &dsImageView); RDCASSERTEQUAL(vkr, VK_SUCCESS); - if(samples != VK_SAMPLE_COUNT_1_BIT) - { - uint32_t bs = GetByteSize(1, 1, 1, format, 0); - - if(bs == 1) - viewInfo.format = VK_FORMAT_R8_UINT; - else if(bs == 2) - viewInfo.format = VK_FORMAT_R16_UINT; - else if(bs == 4) - viewInfo.format = VK_FORMAT_R32_UINT; - else if(bs == 8) - viewInfo.format = VK_FORMAT_R32G32_UINT; - else if(bs == 16) - viewInfo.format = VK_FORMAT_R32G32B32A32_UINT; - - if(viewInfo.format == VK_FORMAT_UNDEFINED) - { - RDCERR("Can't copy 2D to Array with format %s", ToStr(format).c_str()); - } - - viewInfo.image = targetImage; - viewInfo.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, sub.mip, 1, sub.slice, 1}; - vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &targetImageView); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - viewInfo.format = VK_FORMAT_R32G32B32A32_UINT; - viewInfo.image = colorImage; - viewInfo.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; - vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &colorImageAliasView); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - viewInfo.image = dsImage; - viewInfo.format = dsFormat; - viewInfo.subresourceRange = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1}; - vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &depthOnlyImageView); - - viewInfo.subresourceRange = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1}; - vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &stencilOnlyImageView); - } - VkBufferCreateInfo bufferInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; // TODO: the size for memory is calculated to fit pre and post modification values and // stencil values. But we might run out of space when getting per fragment data. @@ -2777,59 +2743,65 @@ bool VulkanDebugManager::PixelHistorySetupResources(PixelHistoryResources &resou resources.dsImageView = dsImageView; resources.gpuMem = gpuMem; - resources.colorImageAliasView = colorImageAliasView; - resources.targetImageView = targetImageView; - resources.depthOnlyImageView = depthOnlyImageView; - resources.stencilOnlyImageView = stencilOnlyImageView; - resources.bufferMemory = bufferMemory; resources.dstBuffer = dstBuffer; return true; } -void VulkanReplay::UpdatePixelHistoryDescriptor(VkImageView sourceView, VkImageView depthImageView, - VkImageView stencilImageView, VkBuffer destBuffer) +VkDescriptorSet VulkanReplay::GetPixelHistoryDescriptor() +{ + VkDescriptorSet descSet; + + VkDescriptorSetAllocateInfo descSetAllocInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + NULL, + m_PixelHistory.MSCopyDescPool, + 1, + &m_PixelHistory.MSCopyDescSetLayout, + }; + + // don't expect this to fail (or if it does then it should be immediately obvious, not transient). + VkResult vkr = + m_pDriver->vkAllocateDescriptorSets(m_pDriver->GetDev(), &descSetAllocInfo, &descSet); + if(vkr != VK_SUCCESS) + RDCERR("Failed creating object"); + return descSet; +} + +void VulkanReplay::ResetPixelHistoryDescriptorPool() +{ + m_pDriver->vkResetDescriptorPool(m_pDriver->GetDev(), m_PixelHistory.MSCopyDescPool, 0); +} + +void VulkanReplay::UpdatePixelHistoryDescriptor(VkDescriptorSet descSet, VkBuffer buffer, + VkImageView imgView1, VkImageView imgView2) { VkDescriptorBufferInfo destdesc = {0}; - destdesc.buffer = Unwrap(destBuffer); + destdesc.buffer = Unwrap(buffer); destdesc.range = VK_WHOLE_SIZE; { VkDescriptorImageInfo srcdesc = {}; srcdesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - srcdesc.imageView = Unwrap(sourceView); + srcdesc.imageView = Unwrap(imgView1); srcdesc.sampler = Unwrap(m_General.PointSampler); // not used - we use texelFetch - VkWriteDescriptorSet writeSet[] = { - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_PixelHistory.MSCopyDescSet), 0, 0, - 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc, NULL, NULL}, - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_PixelHistory.MSCopyDescSet), 1, 0, - 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc, NULL, NULL}, - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_PixelHistory.MSCopyDescSet), 2, 0, - 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL}, - }; - - ObjDisp(m_pDriver->GetDev()) - ->UpdateDescriptorSets(Unwrap(m_pDriver->GetDev()), ARRAY_COUNT(writeSet), writeSet, 0, NULL); - } - - { - VkDescriptorImageInfo srcdesc[2] = {}; - srcdesc[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - srcdesc[0].imageView = Unwrap(depthImageView); - srcdesc[0].sampler = Unwrap(m_General.PointSampler); // not used - we use texelFetch - - srcdesc[1] = srcdesc[0]; - srcdesc[1].imageView = Unwrap(stencilImageView); + VkDescriptorImageInfo srcdesc2 = {}; + srcdesc2.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + if(imgView2 != VK_NULL_HANDLE) + srcdesc2.imageView = Unwrap(imgView2); + else + srcdesc2.imageView = Unwrap(imgView1); + srcdesc2.sampler = Unwrap(m_General.PointSampler); VkWriteDescriptorSet writeSet[] = { - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_PixelHistory.MSDepthCopyDescSet), 0, - 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc[0], NULL, NULL}, - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_PixelHistory.MSDepthCopyDescSet), 1, - 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc[1], NULL, NULL}, - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_PixelHistory.MSDepthCopyDescSet), 2, - 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 0, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc, NULL, NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 1, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc2, NULL, NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 2, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL}, }; ObjDisp(m_pDriver->GetDev()) @@ -2850,14 +2822,6 @@ bool VulkanDebugManager::PixelHistoryDestroyResources(const PixelHistoryResource m_pDriver->vkDestroyImage(dev, r.dsImage, NULL); if(r.dsImageView != VK_NULL_HANDLE) m_pDriver->vkDestroyImageView(dev, r.dsImageView, NULL); - if(r.colorImageAliasView != VK_NULL_HANDLE) - m_pDriver->vkDestroyImageView(dev, r.colorImageAliasView, NULL); - if(r.targetImageView != VK_NULL_HANDLE) - m_pDriver->vkDestroyImageView(dev, r.targetImageView, NULL); - if(r.depthOnlyImageView != VK_NULL_HANDLE) - m_pDriver->vkDestroyImageView(dev, r.depthOnlyImageView, NULL); - if(r.stencilOnlyImageView != VK_NULL_HANDLE) - m_pDriver->vkDestroyImageView(dev, r.stencilOnlyImageView, NULL); if(r.dstBuffer != VK_NULL_HANDLE) m_pDriver->vkDestroyBuffer(dev, r.dstBuffer, NULL); if(r.bufferMemory != VK_NULL_HANDLE) @@ -3054,9 +3018,6 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even GetDebugManager()->PixelHistorySetupResources(resources, targetImage, imginfo.extent, imginfo.format, imginfo.samples, sub, (uint32_t)events.size()); - if(multisampled) - UpdatePixelHistoryDescriptor(resources.targetImageView, resources.depthOnlyImageView, - resources.stencilOnlyImageView, resources.dstBuffer); PixelHistoryShaderCache *shaderCache = new PixelHistoryShaderCache(m_pDriver); @@ -3218,10 +3179,18 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even VkFormat depthFormat = cb.GetDepthFormat(mod.eventId); if(depthFormat != VK_FORMAT_UNDEFINED) { - mod.preMod.depth = GetDepthValue(depthFormat, ei.premod); mod.preMod.stencil = ei.premod.stencil; - mod.postMod.depth = GetDepthValue(depthFormat, ei.postmod); mod.postMod.stencil = ei.postmod.stencil; + if(multisampled) + { + mod.preMod.depth = ei.premod.depth.fdepth; + mod.postMod.depth = ei.postmod.depth.fdepth; + } + else + { + mod.preMod.depth = GetDepthValue(depthFormat, ei.premod); + mod.postMod.depth = GetDepthValue(depthFormat, ei.postmod); + } } int32_t frags = int32_t(ei.dsWithoutShaderDiscard[4]); @@ -3256,9 +3225,6 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even { // Replay to get shader output value, post modification value and primitive ID for every // fragment. - if(multisampled) - UpdatePixelHistoryDescriptor(resources.colorImageAliasView, resources.depthOnlyImageView, - resources.stencilOnlyImageView, resources.dstBuffer); VulkanPixelHistoryPerFragmentCallback perFragmentCB(m_pDriver, shaderCache, callbackInfo, eventsWithFrags, eventPremods); { diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 3602a3fef..b991c4e58 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -2837,24 +2837,29 @@ rdcarray VulkanReplay::GetUsage(ResourceId id) } void VulkanReplay::CopyPixelForPixelHistory(VkCommandBuffer cmd, VkOffset2D offset, uint32_t sample, - uint32_t bufferOffset, bool depthCopy) + uint32_t bufferOffset, VkFormat format, + VkDescriptorSet descSet) { - if(m_PixelHistory.MSCopyPipe == VK_NULL_HANDLE) - return; - - VkDescriptorSet descSet; - if(depthCopy) - descSet = m_PixelHistory.MSDepthCopyDescSet; + VkPipeline pipe; + if(IsDepthOrStencilFormat(format)) + pipe = m_PixelHistory.MSCopyDepthPipe; else - descSet = m_PixelHistory.MSCopyDescSet; + pipe = m_PixelHistory.MSCopyPipe; + if(pipe == VK_NULL_HANDLE) + return; if(!m_pDriver->GetDeviceEnabledFeatures().shaderStorageImageWriteWithoutFormat) return; - ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, - Unwrap(m_PixelHistory.MSCopyPipe)); + ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(pipe)); - uint32_t params[8] = {depthCopy, sample, (uint32_t)offset.x, (uint32_t)offset.y, bufferOffset, 0, - 0, 0}; + int32_t params[8] = {(int32_t)sample, + offset.x, + offset.y, + (int32_t)bufferOffset, + !IsStencilOnlyFormat(format), + IsStencilFormat(format), + 0, + 0}; ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(m_PixelHistory.MSCopyPipeLayout), 0, 1, UnwrapPtr(descSet), 0, NULL); diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index d55222fd4..c66492589 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -322,8 +322,11 @@ public: float *maxval); bool GetHistogram(ResourceId texid, const Subresource &sub, CompType typeCast, float minval, float maxval, bool channels[4], rdcarray &histogram); - void UpdatePixelHistoryDescriptor(VkImageView sourceView, VkImageView depthImageView, - VkImageView stencilImageView, VkBuffer destBuffer); + + VkDescriptorSet GetPixelHistoryDescriptor(); + void ResetPixelHistoryDescriptorPool(); + void UpdatePixelHistoryDescriptor(VkDescriptorSet descSet, VkBuffer buffer, VkImageView imgView1, + VkImageView imgView2); void InitPostVSBuffers(uint32_t eventId); void InitPostVSBuffers(uint32_t eventId, VulkanRenderState &state); @@ -417,7 +420,7 @@ public: AMDCounters *GetAMDCounters() { return m_pAMDCounters; } void CopyPixelForPixelHistory(VkCommandBuffer cmd, VkOffset2D offset, uint32_t sample, - uint32_t bufferOffset, bool depthCopy); + uint32_t bufferOffset, VkFormat format, VkDescriptorSet descSet); private: void FetchShaderFeedback(uint32_t eventId); @@ -675,9 +678,9 @@ private: void Destroy(WrappedVulkan *driver); VkDescriptorSetLayout MSCopyDescSetLayout = VK_NULL_HANDLE; - VkDescriptorSet MSCopyDescSet = VK_NULL_HANDLE; - VkDescriptorSet MSDepthCopyDescSet = VK_NULL_HANDLE; + VkDescriptorPool MSCopyDescPool = VK_NULL_HANDLE; VkPipeline MSCopyPipe = VK_NULL_HANDLE; + VkPipeline MSCopyDepthPipe = VK_NULL_HANDLE; VkPipelineLayout MSCopyPipeLayout = VK_NULL_HANDLE; } m_PixelHistory; diff --git a/renderdoc/driver/vulkan/vk_shader_cache.cpp b/renderdoc/driver/vulkan/vk_shader_cache.cpp index 2e11b83a3..d332351b3 100644 --- a/renderdoc/driver/vulkan/vk_shader_cache.cpp +++ b/renderdoc/driver/vulkan/vk_shader_cache.cpp @@ -94,6 +94,8 @@ static const BuiltinShaderConfig builtinShaders[] = { rdcspv::ShaderStage::Fragment, FeatureCheck::NoCheck, true}, {BuiltinShader::PixelHistoryMSCopyCS, EmbeddedResource(glsl_pixelhistory_mscopy_comp), rdcspv::ShaderStage::Compute, FeatureCheck::NoCheck, true}, + {BuiltinShader::PixelHistoryMSCopyDepthCS, EmbeddedResource(glsl_pixelhistory_mscopy_depth_comp), + rdcspv::ShaderStage::Compute, FeatureCheck::NoCheck, true}, {BuiltinShader::PixelHistoryPrimIDFS, EmbeddedResource(glsl_pixelhistory_primid_frag), rdcspv::ShaderStage::Fragment, FeatureCheck::NoCheck, true}, {BuiltinShader::ShaderDebugSampleVS, EmbeddedResource(glsl_shaderdebug_sample_vert), diff --git a/renderdoc/driver/vulkan/vk_shader_cache.h b/renderdoc/driver/vulkan/vk_shader_cache.h index aebb22c90..be78d0bce 100644 --- a/renderdoc/driver/vulkan/vk_shader_cache.h +++ b/renderdoc/driver/vulkan/vk_shader_cache.h @@ -55,6 +55,7 @@ enum class BuiltinShader TexRemapUInt, TexRemapSInt, PixelHistoryMSCopyCS, + PixelHistoryMSCopyDepthCS, PixelHistoryPrimIDFS, ShaderDebugSampleVS, Count, diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index affef3b01..22e18ed11 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -561,16 +561,19 @@ VkResult WrappedVulkan::vkResetDescriptorPool(VkDevice device, VkDescriptorPool // need to free all child descriptor pools. Application is responsible for // ensuring no concurrent use with alloc/free from this pool, the same as // for DestroyDescriptorPool. - VkResourceRecord *record = GetRecord(descriptorPool); - - // delete all of the children - for(auto it = record->pooledChildren.begin(); it != record->pooledChildren.end(); ++it) + if(IsCaptureMode(m_State)) { - // unset record->pool so we don't recurse - (*it)->pool = NULL; - GetResourceManager()->ReleaseWrappedResource((VkDescriptorSet)(uint64_t)(*it)->Resource, true); + VkResourceRecord *record = GetRecord(descriptorPool); + + // delete all of the children + for(auto it = record->pooledChildren.begin(); it != record->pooledChildren.end(); ++it) + { + // unset record->pool so we don't recurse + (*it)->pool = NULL; + GetResourceManager()->ReleaseWrappedResource((VkDescriptorSet)(uint64_t)(*it)->Resource, true); + } + record->pooledChildren.clear(); } - record->pooledChildren.clear(); return ObjDisp(device)->ResetDescriptorPool(Unwrap(device), Unwrap(descriptorPool), flags); } diff --git a/renderdoc/renderdoc.vcxproj b/renderdoc/renderdoc.vcxproj index 215862812..f2b7f4592 100644 --- a/renderdoc/renderdoc.vcxproj +++ b/renderdoc/renderdoc.vcxproj @@ -600,6 +600,7 @@ + diff --git a/renderdoc/renderdoc.vcxproj.filters b/renderdoc/renderdoc.vcxproj.filters index 4b8f24fb4..e224831d7 100644 --- a/renderdoc/renderdoc.vcxproj.filters +++ b/renderdoc/renderdoc.vcxproj.filters @@ -1075,6 +1075,9 @@ Resources\glsl + + Resources\glsl + diff --git a/util/test/demos/vk/vk_pixel_history_test.cpp b/util/test/demos/vk/vk_pixel_history_test.cpp index f72aab8a7..650ea2336 100644 --- a/util/test/demos/vk/vk_pixel_history_test.cpp +++ b/util/test/demos/vk/vk_pixel_history_test.cpp @@ -240,15 +240,33 @@ void main() vb.upload(VBData); + VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED; + { + std::vector formats; + for(VkFormat fmt : + {VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT}) + { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(phys, fmt, &props); + if(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) + { + depthStencilFormat = fmt; + break; + } + } + TEST_ASSERT(depthStencilFormat != VK_FORMAT_UNDEFINED, + "Couldn't find depth/stencil attachment image format"); + } + // create depth-stencil image - AllocatedImage depthimg(this, vkh::ImageCreateInfo(mainWindow->scissor.extent.width, - mainWindow->scissor.extent.height, 0, - VK_FORMAT_D32_SFLOAT_S8_UINT, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), - VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY})); + AllocatedImage depthimg( + this, + vkh::ImageCreateInfo(mainWindow->scissor.extent.width, mainWindow->scissor.extent.height, 0, + depthStencilFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), + VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY})); VkImageView dsvview = createImageView(vkh::ImageViewCreateInfo( - depthimg.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D32_SFLOAT_S8_UINT, {}, + depthimg.image, VK_IMAGE_VIEW_TYPE_2D, depthStencilFormat, {}, vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))); // create renderpass using the DS image @@ -258,7 +276,7 @@ void main() mainWindow->format, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE)); renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription( - VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, + depthStencilFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE)); @@ -397,7 +415,34 @@ void main() subrp, {subview}, {mainWindow->scissor.extent.width / 4, mainWindow->scissor.extent.height / 4})); + // Multi sampled + + { + std::vector formats; + for(VkFormat fmt : + {VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT}) + { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(phys, fmt, &props); + if(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) + { + depthStencilFormat = fmt; + break; + } + } + TEST_ASSERT(depthStencilFormat != VK_FORMAT_UNDEFINED, + "Couldn't find depth/stencil attachment image format"); + } + renderPassCreateInfo.attachments[0].samples = VK_SAMPLE_COUNT_4_BIT; + renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription( + depthStencilFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, + VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_SAMPLE_COUNT_4_BIT, + VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE)); + renderPassCreateInfo.subpasses.clear(); + renderPassCreateInfo.addSubpass({VkAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL})}, 1, + VK_IMAGE_LAYOUT_GENERAL); VkRenderPass submsrp = createRenderPass(renderPassCreateInfo); @@ -406,6 +451,7 @@ void main() pipeCreateInfo.renderPass = submsrp; pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; + pipeCreateInfo.depthStencilState.depthWriteEnable = VK_TRUE; VkPipeline mspipe = createGraphicsPipeline(pipeCreateInfo); AllocatedImage submsimg( @@ -418,8 +464,20 @@ void main() submsimg.image, VK_IMAGE_VIEW_TYPE_2D, mainWindow->format, {}, vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 2, 1))); + AllocatedImage msimgdepth( + this, + vkh::ImageCreateInfo(mainWindow->scissor.extent.width, mainWindow->scissor.extent.height, 0, + depthStencilFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1, 4, + VK_SAMPLE_COUNT_4_BIT), + VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY})); + + VkImageView msdepthview = createImageView(vkh::ImageViewCreateInfo( + msimgdepth.image, VK_IMAGE_VIEW_TYPE_2D, depthStencilFormat, {}, + vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 2, 1))); + VkFramebuffer submsfb = createFramebuffer(vkh::FramebufferCreateInfo( - submsrp, {submsview}, {mainWindow->scissor.extent.width, mainWindow->scissor.extent.height})); + submsrp, {submsview, msdepthview}, + {mainWindow->scissor.extent.width, mainWindow->scissor.extent.height})); while(Running()) { @@ -518,7 +576,8 @@ void main() { setMarker(cmd, "Multisampled: begin renderpass"); vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(submsrp, submsfb, mainWindow->scissor, - {vkh::ClearValue(0.f, 1.0f, 0.f, 1.0f)}), + {vkh::ClearValue(0.f, 1.0f, 0.f, 1.0f), + vkh::ClearValue(0.f, 0)}), VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, mspipe); diff --git a/util/test/tests/Vulkan/VK_Pixel_History.py b/util/test/tests/Vulkan/VK_Pixel_History.py index e201a38e4..3bf74f3a7 100644 --- a/util/test/tests/Vulkan/VK_Pixel_History.py +++ b/util/test/tests/Vulkan/VK_Pixel_History.py @@ -174,9 +174,13 @@ class VK_Pixel_History(rdtest.TestCase): rdtest.log.print("Testing pixel {}, {} at sample {}".format(x, y, sub.sample)) modifs: List[rd.PixelModification] = self.controller.PixelHistory(tex, x, y, sub, rt.typeCast) events = [ - [[event_id, beg_renderpass_eid], [passed, True], [post_mod_col, (0.0, 1.0, 0.0, 1.0)]], - [[event_id, draw_eid], [passed, True], [primitive_id, 0], [shader_out_col, (1.0, 0.0, 1.0, 1.0)], [post_mod_col, (1.0, 0.0, 1.0, 1.0)]], - [[event_id, draw_eid], [passed, True], [primitive_id, 1], [shader_out_col, (0.0, 0.0, 1.0, 1.0)], [post_mod_col, (0.0, 0.0, 1.0, 1.0)]], + [[event_id, beg_renderpass_eid], [passed, True], [post_mod_col, (0.0, 1.0, 0.0, 1.0)], [post_mod_depth, 0.0]], + [[event_id, draw_eid], [passed, True], [primitive_id, 0], + [shader_out_col, (1.0, 0.0, 1.0, 1.0)], [post_mod_col, (1.0, 0.0, 1.0, 1.0)], + [pre_mod_depth, 0.0], [shader_out_depth, 0.9], [post_mod_depth, 0.9]], + [[event_id, draw_eid], [passed, True], [primitive_id, 1], + [shader_out_col, (0.0, 0.0, 1.0, 1.0)], [post_mod_col, (0.0, 0.0, 1.0, 1.0)], + [shader_out_depth, 0.95], [post_mod_depth, 0.95]], ] self.check_events(events, modifs, True) self.check_pixel_value(tex, x, y, value_selector(modifs[-1].postMod.col), sub=sub, cast=rt.typeCast) @@ -186,8 +190,10 @@ class VK_Pixel_History(rdtest.TestCase): modifs: List[rd.PixelModification] = self.controller.PixelHistory(tex, x, y, sub, rt.typeCast) events = [ [[event_id, beg_renderpass_eid], [passed, True], [post_mod_col, (0.0, 1.0, 0.0, 1.0)]], - [[event_id, draw_eid], [passed, True], [primitive_id, 0], [shader_out_col, (1.0, 0.0, 1.0, 1.0)], [post_mod_col, (1.0, 0.0, 1.0, 1.0)]], - [[event_id, draw_eid], [passed, True], [primitive_id, 1], [shader_out_col, (0.0, 1.0, 1.0, 1.0)], [post_mod_col, (0.0, 1.0, 1.0, 1.0)]], + [[event_id, draw_eid], [passed, True], [primitive_id, 0], + [shader_out_col, (1.0, 0.0, 1.0, 1.0)], [post_mod_col, (1.0, 0.0, 1.0, 1.0)]], + [[event_id, draw_eid], [passed, True], [primitive_id, 1], + [shader_out_col, (0.0, 1.0, 1.0, 1.0)], [post_mod_col, (0.0, 1.0, 1.0, 1.0)]], ] self.check_events(events, modifs, True) self.check_pixel_value(tex, x, y, value_selector(modifs[-1].postMod.col), sub=sub, cast=rt.typeCast)