mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-13 02:01:08 +00:00
Vk Pixel History: support other depth formats MSAA
- Separate the pixel history copy pixel shader into two separate shaders, one for colour copy and one for depth - Allocate and update descriptor sets on demand - Add another compute shader for pixel history depth copy
This commit is contained in:
committed by
Baldur Karlsson
parent
b2d85982a5
commit
0fd3d65a6f
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
+33
-32
@@ -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
|
||||
//
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<VkRenderPass> m_RpsToDestroy;
|
||||
rdcarray<VkFramebuffer> m_FbsToDestroy;
|
||||
rdcarray<VkDynamicState> m_DynamicStates;
|
||||
std::map<VkImage, VkDescriptorSet> m_CopyDescriptors;
|
||||
rdcarray<VkImageView> 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<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> 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<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> 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<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> 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);
|
||||
{
|
||||
|
||||
@@ -2837,24 +2837,29 @@ rdcarray<EventUsage> 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);
|
||||
|
||||
@@ -322,8 +322,11 @@ public:
|
||||
float *maxval);
|
||||
bool GetHistogram(ResourceId texid, const Subresource &sub, CompType typeCast, float minval,
|
||||
float maxval, bool channels[4], rdcarray<uint32_t> &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;
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -55,6 +55,7 @@ enum class BuiltinShader
|
||||
TexRemapUInt,
|
||||
TexRemapSInt,
|
||||
PixelHistoryMSCopyCS,
|
||||
PixelHistoryMSCopyDepthCS,
|
||||
PixelHistoryPrimIDFS,
|
||||
ShaderDebugSampleVS,
|
||||
Count,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -600,6 +600,7 @@
|
||||
<None Include="data\glsl\minmaxtile.comp" />
|
||||
<None Include="data\glsl\ms2array.comp" />
|
||||
<None Include="data\glsl\pixelhistory_mscopy.comp" />
|
||||
<None Include="data\glsl\pixelhistory_mscopy_depth.comp" />
|
||||
<None Include="data\glsl\pixelhistory_primid.frag" />
|
||||
<None Include="data\glsl\quadresolve.frag" />
|
||||
<None Include="data\glsl\quadwrite.frag" />
|
||||
|
||||
@@ -1075,6 +1075,9 @@
|
||||
<None Include="data\glsl\pixelhistory_mscopy.comp">
|
||||
<Filter>Resources\glsl</Filter>
|
||||
</None>
|
||||
<None Include="data\glsl\pixelhistory_mscopy_depth.comp">
|
||||
<Filter>Resources\glsl</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="data\renderdoc.rc">
|
||||
|
||||
@@ -240,15 +240,33 @@ void main()
|
||||
|
||||
vb.upload(VBData);
|
||||
|
||||
VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED;
|
||||
{
|
||||
std::vector<VkFormat> 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<VkFormat> 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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user