mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-28 17:36:36 +00:00
Add support for multiview with quad overdraw overlay. Closes #3424
* We multiply the internal array image up by the number of views and read from viewindex to write and resolve from different sets of slices
This commit is contained in:
@@ -26,6 +26,10 @@
|
||||
#extension GL_ARB_shader_image_load_store : require
|
||||
#endif
|
||||
|
||||
#if defined(VULKAN) && defined(USE_MULTIVIEW)
|
||||
#extension GL_EXT_multiview : require
|
||||
#endif
|
||||
|
||||
#include "glsl_globals.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -47,9 +51,14 @@ void main()
|
||||
{
|
||||
ivec2 quad = ivec2(gl_FragCoord.xy * 0.5f);
|
||||
|
||||
uint view_offset = 0u;
|
||||
#if defined(VULKAN) && defined(USE_MULTIVIEW)
|
||||
view_offset += 4 * gl_ViewIndex;
|
||||
#endif
|
||||
|
||||
uint overdraw = 0u;
|
||||
for(uint i = 0u; i < 4u; i++)
|
||||
overdraw += imageLoad(overdrawImage, ivec3(quad, i)).x / (i + 1u);
|
||||
overdraw += imageLoad(overdrawImage, ivec3(quad, i + view_offset)).x / (i + 1u);
|
||||
|
||||
color_out = vec4(overdraw);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#extension GL_ARB_gpu_shader5 : require
|
||||
#endif
|
||||
|
||||
#if defined(VULKAN) && defined(USE_MULTIVIEW)
|
||||
#extension GL_EXT_multiview : require
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Below shaders courtesy of Stephen Hill (@self_shadow), converted to glsl trivially
|
||||
//
|
||||
@@ -71,7 +75,12 @@ void main()
|
||||
// Count the live pixels, minus 1 (zero indexing)
|
||||
uint pixelCount = c0 + c1 + c2 + c3 - 1u;
|
||||
|
||||
ivec3 quad = ivec3(gl_FragCoord.xy * 0.5, pixelCount);
|
||||
uint arrayIndex = pixelCount;
|
||||
#if defined(VULKAN) && defined(USE_MULTIVIEW)
|
||||
arrayIndex += 4 * gl_ViewIndex;
|
||||
#endif
|
||||
|
||||
ivec3 quad = ivec3(gl_FragCoord.xy * 0.5, arrayIndex);
|
||||
imageAtomicAdd(overdrawImage, quad, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -4330,6 +4330,34 @@ void VulkanReplay::OverlayRendering::Init(WrappedVulkan *driver, VkDescriptorPoo
|
||||
driver->vkDestroyRenderPass(driver->GetDev(), SRGBA8MSRP, NULL);
|
||||
}
|
||||
|
||||
VkPipeline VulkanReplay::OverlayRendering::CreateTempMultiviewQuadResolvePipe(WrappedVulkan *driver)
|
||||
{
|
||||
VulkanShaderCache *shaderCache = driver->GetShaderCache();
|
||||
|
||||
ConciseGraphicsPipeline pipeInfo = {
|
||||
NoDepthRP,
|
||||
m_QuadResolvePipeLayout,
|
||||
shaderCache->GetBuiltinModule(BuiltinShader::BlitVS),
|
||||
shaderCache->GetBuiltinModule(BuiltinShader::QuadResolveMultiviewFS),
|
||||
{VK_DYNAMIC_STATE_VIEWPORT},
|
||||
Samples,
|
||||
false, // sampleRateShading
|
||||
false, // depthEnable
|
||||
false, // stencilEnable
|
||||
StencilMode::KEEP,
|
||||
true, // colourOutput
|
||||
false, // blendEnable
|
||||
VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
0xf, // writeMask
|
||||
};
|
||||
|
||||
VkPipeline ret;
|
||||
CREATE_OBJECT(ret, pipeInfo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VulkanReplay::OverlayRendering::Destroy(WrappedVulkan *driver)
|
||||
{
|
||||
if(ImageMem == VK_NULL_HANDLE)
|
||||
|
||||
@@ -45,8 +45,13 @@ RDOC_EXTERN_CONFIG(bool, Vulkan_Debug_SingleSubmitFlushing);
|
||||
struct VulkanQuadOverdrawCallback : public VulkanActionCallback
|
||||
{
|
||||
VulkanQuadOverdrawCallback(WrappedVulkan *vk, VkDescriptorSetLayout descSetLayout,
|
||||
VkDescriptorSet descSet, const rdcarray<uint32_t> &events)
|
||||
: m_pDriver(vk), m_DescSetLayout(descSetLayout), m_DescSet(descSet), m_Events(events)
|
||||
VkDescriptorSet descSet, const rdcarray<uint32_t> &events,
|
||||
bool multiview)
|
||||
: m_pDriver(vk),
|
||||
m_DescSetLayout(descSetLayout),
|
||||
m_DescSet(descSet),
|
||||
m_Events(events),
|
||||
m_Multiview(multiview)
|
||||
{
|
||||
m_pDriver->SetActionCB(this);
|
||||
}
|
||||
@@ -173,8 +178,8 @@ struct VulkanQuadOverdrawCallback : public VulkanActionCallback
|
||||
rs->rasterizerDiscardEnable = false;
|
||||
}
|
||||
|
||||
rdcarray<uint32_t> spirv =
|
||||
*m_pDriver->GetShaderCache()->GetBuiltinBlob(BuiltinShader::QuadWriteFS);
|
||||
rdcarray<uint32_t> spirv = *m_pDriver->GetShaderCache()->GetBuiltinBlob(
|
||||
m_Multiview ? BuiltinShader::QuadWriteMultiviewFS : BuiltinShader::QuadWriteFS);
|
||||
|
||||
// patch spirv, change descriptor set to descSet value
|
||||
size_t it = 5;
|
||||
@@ -375,6 +380,7 @@ struct VulkanQuadOverdrawCallback : public VulkanActionCallback
|
||||
VkDescriptorSetLayout m_DescSetLayout;
|
||||
VkDescriptorSet m_DescSet;
|
||||
const rdcarray<uint32_t> &m_Events;
|
||||
bool m_Multiview;
|
||||
|
||||
// cache modified pipelines
|
||||
struct CachedPipeline
|
||||
@@ -823,6 +829,9 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
subRange,
|
||||
};
|
||||
|
||||
if(subRange.layerCount > 1)
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
|
||||
vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &m_Overlay.ImageView);
|
||||
CHECK_VKR(m_pDriver, vkr);
|
||||
|
||||
@@ -839,6 +848,9 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
sub.numSlices,
|
||||
};
|
||||
|
||||
if(multiviewMask > 0)
|
||||
fbinfo.layers = 1;
|
||||
|
||||
vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &m_Overlay.NoDepthFB);
|
||||
CHECK_VKR(m_pDriver, vkr);
|
||||
|
||||
@@ -2822,10 +2834,19 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
events.erase(0);
|
||||
}
|
||||
|
||||
VkPipeline quadResolveMultiviewPipe = VK_NULL_HANDLE;
|
||||
VkImage quadImg;
|
||||
VkDeviceMemory quadImgMem;
|
||||
VkImageView quadImgView;
|
||||
|
||||
uint32_t quadImgArraySlices = 4;
|
||||
if(multiviewMask > 0)
|
||||
{
|
||||
quadImgArraySlices *= Bits::CountOnes(multiviewMask);
|
||||
|
||||
quadResolveMultiviewPipe = m_Overlay.CreateTempMultiviewQuadResolvePipe(m_pDriver);
|
||||
}
|
||||
|
||||
VkImageCreateInfo imInfo = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
NULL,
|
||||
@@ -2834,7 +2855,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
VK_FORMAT_R32_UINT,
|
||||
{RDCMAX(1U, m_Overlay.ImageDim.width >> 1), RDCMAX(1U, m_Overlay.ImageDim.height >> 1), 1},
|
||||
1,
|
||||
4,
|
||||
quadImgArraySlices,
|
||||
VK_SAMPLE_COUNT_1_BIT,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
@@ -2878,7 +2899,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
VK_FORMAT_R32_UINT,
|
||||
{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 4},
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, quadImgArraySlices},
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkCreateImageView(m_Device, &viewinfo, NULL, &quadImgView);
|
||||
@@ -2912,7 +2933,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(quadImg),
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 4},
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, quadImgArraySlices},
|
||||
};
|
||||
|
||||
// clear all to black
|
||||
@@ -2949,7 +2970,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
{
|
||||
// declare callback struct here
|
||||
VulkanQuadOverdrawCallback cb(m_pDriver, m_Overlay.m_QuadDescSetLayout,
|
||||
m_Overlay.m_QuadDescSet, events);
|
||||
m_Overlay.m_QuadDescSet, events, multiviewMask > 0);
|
||||
|
||||
m_pDriver->ReplayLog(events.front(), events.back(), eReplay_Full);
|
||||
|
||||
@@ -2983,8 +3004,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
};
|
||||
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_Overlay.m_QuadResolvePipeline[SampleIndex(iminfo.samples)]));
|
||||
if(multiviewMask > 0)
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(quadResolveMultiviewPipe));
|
||||
else
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_Overlay.m_QuadResolvePipeline[SampleIndex(iminfo.samples)]));
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_Overlay.m_QuadResolvePipeLayout), 0, 1,
|
||||
UnwrapPtr(m_Overlay.m_QuadDescSet), 0, NULL);
|
||||
@@ -3007,6 +3032,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
m_pDriver->vkDestroyImageView(m_Device, quadImgView, NULL);
|
||||
m_pDriver->vkDestroyImage(m_Device, quadImg, NULL);
|
||||
m_pDriver->vkFreeMemory(m_Device, quadImgMem, NULL);
|
||||
m_pDriver->vkDestroyPipeline(m_Device, quadResolveMultiviewPipe, NULL);
|
||||
}
|
||||
|
||||
// restore back to normal
|
||||
|
||||
@@ -667,6 +667,8 @@ private:
|
||||
void Init(WrappedVulkan *driver, VkDescriptorPool descriptorPool);
|
||||
void Destroy(WrappedVulkan *driver);
|
||||
|
||||
VkPipeline CreateTempMultiviewQuadResolvePipe(WrappedVulkan *driver);
|
||||
|
||||
VkDeviceMemory ImageMem = VK_NULL_HANDLE;
|
||||
VkDeviceSize ImageMemSize = 0;
|
||||
VkImage Image = VK_NULL_HANDLE;
|
||||
|
||||
@@ -44,6 +44,7 @@ enum class BuiltinShaderFlags
|
||||
None = 0x0,
|
||||
BaseTypeParameterised = 0x1,
|
||||
TextureTypeParameterised = 0x2,
|
||||
Multiview = 0x4,
|
||||
};
|
||||
|
||||
BITMASK_OPERATORS(BuiltinShaderFlags);
|
||||
@@ -86,9 +87,15 @@ static const BuiltinShaderConfig builtinShaders[] = {
|
||||
rdcspv::ShaderStage::Compute),
|
||||
BuiltinShaderConfig(BuiltinShader::QuadResolveFS, EmbeddedResource(glsl_quadresolve_frag),
|
||||
rdcspv::ShaderStage::Fragment, FeatureCheck::FragmentStores),
|
||||
BuiltinShaderConfig(BuiltinShader::QuadResolveMultiviewFS,
|
||||
EmbeddedResource(glsl_quadresolve_frag), rdcspv::ShaderStage::Fragment,
|
||||
FeatureCheck::FragmentStores, BuiltinShaderFlags::Multiview),
|
||||
BuiltinShaderConfig(BuiltinShader::QuadWriteFS, EmbeddedResource(glsl_quadwrite_frag),
|
||||
rdcspv::ShaderStage::Fragment),
|
||||
BuiltinShaderConfig(BuiltinShader::QuadWriteMultiviewFS, EmbeddedResource(glsl_quadwrite_frag),
|
||||
rdcspv::ShaderStage::Fragment,
|
||||
FeatureCheck::FragmentStores | FeatureCheck::NonMetalBackend),
|
||||
FeatureCheck::FragmentStores | FeatureCheck::NonMetalBackend,
|
||||
BuiltinShaderFlags::Multiview),
|
||||
BuiltinShaderConfig(BuiltinShader::TrisizeGS, EmbeddedResource(glsl_trisize_geom),
|
||||
rdcspv::ShaderStage::Geometry),
|
||||
BuiltinShaderConfig(BuiltinShader::TrisizeFS, EmbeddedResource(glsl_trisize_frag),
|
||||
@@ -282,6 +289,9 @@ VulkanShaderCache::VulkanShaderCache(WrappedVulkan *driver)
|
||||
defines += rdcstr("#define SHADER_RESTYPE ") + ToStr(textureType) + "\n";
|
||||
defines += rdcstr("#define SHADER_BASETYPE ") + ToStr(baseType) + "\n";
|
||||
|
||||
if(config.flags & BuiltinShaderFlags::Multiview)
|
||||
defines += rdcstr("#define USE_MULTIVIEW 1\n");
|
||||
|
||||
SPIRVBlob &blob = m_BuiltinShaderBlobs[i][baseType][textureType];
|
||||
rdcstr source = GetDynamicEmbeddedResource(config.resource);
|
||||
|
||||
|
||||
@@ -44,7 +44,9 @@ enum class BuiltinShader
|
||||
MeshFS,
|
||||
MeshCS,
|
||||
QuadResolveFS,
|
||||
QuadResolveMultiviewFS,
|
||||
QuadWriteFS,
|
||||
QuadWriteMultiviewFS,
|
||||
TrisizeGS,
|
||||
TrisizeFS,
|
||||
TexRemap,
|
||||
|
||||
Reference in New Issue
Block a user