mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 15:06:32 +00:00
Implement custom display shaders for vulkan
This commit is contained in:
@@ -44,6 +44,24 @@ This input is defined as two parameters to the shader entry point. The first def
|
||||
|
||||
You must bind these parameters like this in this order to ensure the linkage with the vertex shader matches.
|
||||
|
||||
Constant Parameters
|
||||
```````````````````
|
||||
|
||||
There are several constant parameters available, each detailed below with the values they contain. Where possible these are bound by name as globals for convenience, but in Vulkan all variables must be contained within a single uniform buffer. The parameters correspond with the GLSL documentation but are contained within a uniform buffer at binding 0, with a structure given as so:
|
||||
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
layout(binding = 0, std140) uniform RENDERDOC_Uniforms
|
||||
{
|
||||
uvec4 TexDim;
|
||||
uint SelectedMip;
|
||||
uint TextureType;
|
||||
} RENDERDOC;
|
||||
|
||||
In this way you can access the properties as ``RENDERDOC.TexDim`` insetad of ``RENDERDOC_TexDim``.
|
||||
|
||||
Texture dimensions
|
||||
``````````````````
|
||||
|
||||
@@ -84,7 +102,7 @@ This variable will be set to a given integer value, depending on the type of the
|
||||
|
||||
.. note::
|
||||
|
||||
The value varies depending on whether this is an HLSL shader or GLSL, as they have different resource types.
|
||||
The value varies depending on the API this shader will be used for, as each has different resource bindings.
|
||||
|
||||
D3D11 / HLSL
|
||||
^^^^^^^^^^^^
|
||||
@@ -113,6 +131,14 @@ OpenGL / GLSL
|
||||
#. Buffer texture
|
||||
#. 2D texture (Multisampled)
|
||||
|
||||
Vulkan / GLSL
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
#. 1D texture
|
||||
#. 2D texture
|
||||
#. 3D texture
|
||||
#. 2D texture (Multisampled)
|
||||
|
||||
Samplers (D3D11 only)
|
||||
`````````````````````
|
||||
|
||||
@@ -195,6 +221,36 @@ OpenGL / GLSL
|
||||
layout (binding = 9) uniform samplerBuffer texBuffer;
|
||||
layout (binding = 10) uniform sampler2DMS tex2DMS;
|
||||
|
||||
Vulkan / GLSL
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
// Floating point samplers
|
||||
|
||||
// binding = 5 + RENDERDOC_TextureType
|
||||
layout(binding = 6) uniform sampler1DArray tex1DArray;
|
||||
layout(binding = 7) uniform sampler2DArray tex2DArray;
|
||||
layout(binding = 8) uniform sampler3D tex3D;
|
||||
layout(binding = 9) uniform sampler2DMS tex2DMS;
|
||||
|
||||
// Unsigned int samplers
|
||||
|
||||
// binding = 10 + RENDERDOC_TextureType
|
||||
layout(binding = 11) uniform usampler1DArray texUInt1DArray;
|
||||
layout(binding = 12) uniform usampler2DArray texUInt2DArray;
|
||||
layout(binding = 13) uniform usampler3D texUInt3D;
|
||||
layout(binding = 14) uniform usampler2DMS texUInt2DMS;
|
||||
|
||||
// Int samplers
|
||||
|
||||
// binding = 15 + RENDERDOC_TextureType
|
||||
layout(binding = 16) uniform isampler1DArray texSInt1DArray;
|
||||
layout(binding = 17) uniform isampler2DArray texSInt2DArray;
|
||||
layout(binding = 18) uniform isampler3D texSInt3D;
|
||||
layout(binding = 19) uniform isampler2DMS texSInt2DMS;
|
||||
|
||||
|
||||
These resources are bound sparsely with the appropriate type for the current texture. With a couple of exceptions there will only be one texture bound at any one time.
|
||||
|
||||
|
||||
@@ -253,6 +253,15 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
RDCEraseEl(m_TexDisplayDummyInfos);
|
||||
m_TexDisplayDummyMemory = VK_NULL_HANDLE;
|
||||
|
||||
m_CustomTexWidth = m_CustomTexHeight = 0;
|
||||
m_CustomTexImg = VK_NULL_HANDLE;
|
||||
m_CustomTexImgView = VK_NULL_HANDLE;
|
||||
m_CustomTexMemSize = 0;
|
||||
m_CustomTexMem = VK_NULL_HANDLE;
|
||||
m_CustomTexFB = VK_NULL_HANDLE;
|
||||
m_CustomTexRP = VK_NULL_HANDLE;
|
||||
m_CustomTexPipeline = VK_NULL_HANDLE;
|
||||
|
||||
m_PickPixelImageMem = VK_NULL_HANDLE;
|
||||
m_PickPixelImage = VK_NULL_HANDLE;
|
||||
m_PickPixelImageView = VK_NULL_HANDLE;
|
||||
@@ -1653,8 +1662,7 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
|
||||
for(size_t i = 0; i < ARRAY_COUNT(module); i++)
|
||||
{
|
||||
// hold onto the mesh shaders/modules as we create these
|
||||
// pipelines later
|
||||
// hold onto the shaders/modules we use later
|
||||
if(i == MESHVS)
|
||||
{
|
||||
m_MeshModules[0] = module[i];
|
||||
@@ -1667,6 +1675,10 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
{
|
||||
m_MeshModules[2] = module[i];
|
||||
}
|
||||
else if(i == BLITVS)
|
||||
{
|
||||
m_BlitVSModule = module[i];
|
||||
}
|
||||
else if(i == HISTOGRAMCS || i == MINMAXTILECS || i == MINMAXRESULTCS)
|
||||
{
|
||||
// not compiled normally
|
||||
@@ -2133,6 +2145,13 @@ VulkanDebugManager::~VulkanDebugManager()
|
||||
|
||||
m_pDriver->vkFreeMemory(dev, m_TexDisplayDummyMemory, NULL);
|
||||
|
||||
m_pDriver->vkDestroyRenderPass(dev, m_CustomTexRP, NULL);
|
||||
m_pDriver->vkDestroyFramebuffer(dev, m_CustomTexFB, NULL);
|
||||
m_pDriver->vkDestroyImage(dev, m_CustomTexImg, NULL);
|
||||
m_pDriver->vkDestroyImageView(dev, m_CustomTexImgView, NULL);
|
||||
m_pDriver->vkFreeMemory(dev, m_CustomTexMem, NULL);
|
||||
m_pDriver->vkDestroyPipeline(dev, m_CustomTexPipeline, NULL);
|
||||
|
||||
m_CheckerboardUBO.Destroy();
|
||||
m_TexDisplayUBO.Destroy();
|
||||
|
||||
@@ -2300,6 +2319,325 @@ void VulkanDebugManager::RenderTextInternal(const TextPrintState &textstate, flo
|
||||
ObjDisp(textstate.cmd)->CmdDraw(Unwrap(textstate.cmd), 4, (uint32_t)strlen(text), 0, 0);
|
||||
}
|
||||
|
||||
void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height)
|
||||
{
|
||||
VkDevice dev = m_Device;
|
||||
|
||||
if(m_CustomTexImg != VK_NULL_HANDLE)
|
||||
{
|
||||
if(width == m_CustomTexWidth && height == m_CustomTexHeight)
|
||||
return;
|
||||
|
||||
m_pDriver->vkDestroyRenderPass(dev, m_CustomTexRP, NULL);
|
||||
m_pDriver->vkDestroyFramebuffer(dev, m_CustomTexFB, NULL);
|
||||
m_pDriver->vkDestroyImageView(dev, m_CustomTexImgView, NULL);
|
||||
m_pDriver->vkDestroyImage(dev, m_CustomTexImg, NULL);
|
||||
}
|
||||
|
||||
m_CustomTexWidth = width;
|
||||
m_CustomTexHeight = height;
|
||||
|
||||
VkResult vkr = VK_SUCCESS;
|
||||
|
||||
VkImageCreateInfo imInfo = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
VK_IMAGE_TYPE_2D,
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
{width, height, 1},
|
||||
1,
|
||||
1,
|
||||
VK_SAMPLE_COUNT_1_BIT,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_SHARING_MODE_EXCLUSIVE,
|
||||
0,
|
||||
NULL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkCreateImage(m_Device, &imInfo, NULL, &m_CustomTexImg);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkMemoryRequirements mrq;
|
||||
m_pDriver->vkGetImageMemoryRequirements(m_Device, m_CustomTexImg, &mrq);
|
||||
|
||||
// if no memory is allocated, or it's not enough,
|
||||
// then allocate
|
||||
if(m_CustomTexMem == VK_NULL_HANDLE || mrq.size > m_CustomTexMemSize)
|
||||
{
|
||||
if(m_CustomTexMem != VK_NULL_HANDLE)
|
||||
m_pDriver->vkFreeMemory(m_Device, m_CustomTexMem, NULL);
|
||||
|
||||
VkMemoryAllocateInfo allocInfo = {
|
||||
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size,
|
||||
m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits),
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkAllocateMemory(m_Device, &allocInfo, NULL, &m_CustomTexMem);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
m_CustomTexMemSize = mrq.size;
|
||||
}
|
||||
|
||||
vkr = m_pDriver->vkBindImageMemory(m_Device, m_CustomTexImg, m_CustomTexMem, 0);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkImageViewCreateInfo viewInfo = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
m_CustomTexImg,
|
||||
VK_IMAGE_VIEW_TYPE_2D,
|
||||
imInfo.format,
|
||||
{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY},
|
||||
{
|
||||
VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1,
|
||||
},
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &m_CustomTexImgView);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
// need to update image layout into valid state
|
||||
|
||||
VkImageMemoryBarrier barrier = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
0,
|
||||
0, // MULTIDEVICE - need to actually pick the right queue family here maybe?
|
||||
Unwrap(m_CustomTexImg),
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
|
||||
|
||||
m_pDriver->m_ImageLayouts[GetResID(m_CustomTexImg)].subresourceStates[0].newLayout =
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkCommandBuffer cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
|
||||
|
||||
ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
|
||||
DoPipelineBarrier(cmd, 1, &barrier);
|
||||
|
||||
vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
#if defined(SINGLE_FLUSH_VALIDATE)
|
||||
m_pDriver->SubmitCmds();
|
||||
#endif
|
||||
|
||||
VkAttachmentDescription colDesc = {0,
|
||||
imInfo.format,
|
||||
imInfo.samples,
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
||||
|
||||
VkAttachmentReference colRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
||||
|
||||
VkSubpassDescription sub = {
|
||||
0, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
0, NULL, // inputs
|
||||
1, &colRef, // color
|
||||
NULL, // resolve
|
||||
NULL, // depth-stencil
|
||||
0, NULL, // preserve
|
||||
};
|
||||
|
||||
VkRenderPassCreateInfo rpinfo = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
1,
|
||||
&colDesc,
|
||||
1,
|
||||
&sub,
|
||||
0,
|
||||
NULL, // dependencies
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &m_CustomTexRP);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
// Create framebuffer rendering just to overlay image, no depth
|
||||
VkFramebufferCreateInfo fbinfo = {
|
||||
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
m_CustomTexRP,
|
||||
1,
|
||||
&m_CustomTexImgView,
|
||||
width,
|
||||
height,
|
||||
1,
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &m_CustomTexFB);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
|
||||
void VulkanDebugManager::CreateCustomShaderPipeline(ResourceId shader)
|
||||
{
|
||||
VkDevice dev = m_Device;
|
||||
|
||||
if(shader == ResourceId())
|
||||
return;
|
||||
|
||||
if(m_CustomTexPipeline != VK_NULL_HANDLE)
|
||||
{
|
||||
if(m_CustomTexShader == shader)
|
||||
return;
|
||||
|
||||
m_pDriver->vkDestroyPipeline(dev, m_CustomTexPipeline, NULL);
|
||||
}
|
||||
|
||||
m_CustomTexShader = shader;
|
||||
|
||||
// declare the pipeline creation info and all of its sub-structures
|
||||
// these are modified as appropriate for each pipeline we create
|
||||
VkPipelineShaderStageCreateInfo stages[2] = {
|
||||
{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
m_BlitVSModule, "main", NULL},
|
||||
{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
GetResourceManager()->GetCurrentHandle<VkShaderModule>(shader), "main", NULL},
|
||||
};
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vi = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL, // vertex bindings
|
||||
0,
|
||||
NULL, // vertex attributes
|
||||
};
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo ia = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
|
||||
false,
|
||||
};
|
||||
|
||||
VkRect2D scissor = {{0, 0}, {4096, 4096}};
|
||||
|
||||
VkPipelineViewportStateCreateInfo vp = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, NULL, 0, 1, NULL, 1, &scissor};
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rs = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
VK_POLYGON_MODE_FILL,
|
||||
VK_CULL_MODE_NONE,
|
||||
VK_FRONT_FACE_CLOCKWISE,
|
||||
false,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
};
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo msaa = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
VK_SAMPLE_COUNT_1_BIT,
|
||||
false,
|
||||
0.0f,
|
||||
NULL,
|
||||
false,
|
||||
false,
|
||||
};
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo ds = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
VK_COMPARE_OP_ALWAYS,
|
||||
false,
|
||||
false,
|
||||
{VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0},
|
||||
{VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0},
|
||||
0.0f,
|
||||
1.0f,
|
||||
};
|
||||
|
||||
VkPipelineColorBlendAttachmentState attState = {
|
||||
false,
|
||||
VK_BLEND_FACTOR_ONE,
|
||||
VK_BLEND_FACTOR_ZERO,
|
||||
VK_BLEND_OP_ADD,
|
||||
VK_BLEND_FACTOR_ONE,
|
||||
VK_BLEND_FACTOR_ZERO,
|
||||
VK_BLEND_OP_ADD,
|
||||
0xf,
|
||||
};
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo cb = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
false,
|
||||
VK_LOGIC_OP_NO_OP,
|
||||
1,
|
||||
&attState,
|
||||
{1.0f, 1.0f, 1.0f, 1.0f}};
|
||||
|
||||
VkDynamicState dynstates[] = {VK_DYNAMIC_STATE_VIEWPORT};
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dyn = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
ARRAY_COUNT(dynstates),
|
||||
dynstates,
|
||||
};
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipeInfo = {
|
||||
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
2,
|
||||
stages,
|
||||
&vi,
|
||||
&ia,
|
||||
NULL, // tess
|
||||
&vp,
|
||||
&rs,
|
||||
&msaa,
|
||||
&ds,
|
||||
&cb,
|
||||
&dyn,
|
||||
m_TexDisplayPipeLayout,
|
||||
m_CustomTexRP,
|
||||
0, // sub pass
|
||||
VK_NULL_HANDLE, // base pipeline handle
|
||||
-1, // base pipeline index
|
||||
};
|
||||
|
||||
VkResult vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL,
|
||||
&m_CustomTexPipeline);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
|
||||
FloatVector VulkanDebugManager::InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg,
|
||||
byte *end, bool &valid)
|
||||
{
|
||||
|
||||
@@ -124,6 +124,9 @@ public:
|
||||
uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y, uint32_t w,
|
||||
uint32_t h);
|
||||
|
||||
void CreateCustomShaderTex(uint32_t width, uint32_t height);
|
||||
void CreateCustomShaderPipeline(ResourceId shader);
|
||||
|
||||
struct GPUBuffer
|
||||
{
|
||||
enum CreateFlags
|
||||
@@ -195,6 +198,7 @@ public:
|
||||
VkWriteDescriptorSet m_TexDisplayDummyWrites[12];
|
||||
VkDescriptorImageInfo m_TexDisplayDummyInfos[12];
|
||||
VkDeviceMemory m_TexDisplayDummyMemory;
|
||||
VkShaderModule m_BlitVSModule;
|
||||
|
||||
VkDescriptorSet GetTexDisplayDescSet()
|
||||
{
|
||||
@@ -202,6 +206,16 @@ public:
|
||||
return m_TexDisplayDescSet[m_TexDisplayNextSet];
|
||||
}
|
||||
|
||||
uint32_t m_CustomTexWidth, m_CustomTexHeight;
|
||||
VkDeviceSize m_CustomTexMemSize;
|
||||
VkImage m_CustomTexImg;
|
||||
VkImageView m_CustomTexImgView;
|
||||
VkDeviceMemory m_CustomTexMem;
|
||||
VkFramebuffer m_CustomTexFB;
|
||||
VkRenderPass m_CustomTexRP;
|
||||
ResourceId m_CustomTexShader;
|
||||
VkPipeline m_CustomTexPipeline;
|
||||
|
||||
VkDeviceMemory m_PickPixelImageMem;
|
||||
VkImage m_PickPixelImage;
|
||||
VkImageView m_PickPixelImageView;
|
||||
|
||||
@@ -1211,6 +1211,29 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
|
||||
|
||||
data->RawOutput = cfg.rawoutput ? 1 : 0;
|
||||
|
||||
if(cfg.CustomShader != ResourceId())
|
||||
{
|
||||
// must match struct declared in user shader (see documentation / Shader Viewer window helper
|
||||
// menus)
|
||||
struct CustomTexDisplayUBOData
|
||||
{
|
||||
Vec4u texDim;
|
||||
uint32_t selectedMip;
|
||||
uint32_t texType;
|
||||
uint32_t padding[2];
|
||||
};
|
||||
|
||||
CustomTexDisplayUBOData *customData = (CustomTexDisplayUBOData *)data;
|
||||
|
||||
customData->texDim.x = iminfo.extent.width;
|
||||
customData->texDim.y = iminfo.extent.height;
|
||||
customData->texDim.z = iminfo.extent.depth;
|
||||
customData->texDim.w = iminfo.mipLevels;
|
||||
customData->selectedMip = cfg.mip;
|
||||
customData->padding[0] = customData->padding[1] = 0;
|
||||
customData->texType = (uint32_t)textype;
|
||||
}
|
||||
|
||||
GetDebugManager()->m_TexDisplayUBO.Unmap();
|
||||
|
||||
VkDescriptorImageInfo imdesc = {0};
|
||||
@@ -1288,10 +1311,20 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
|
||||
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkPipeline pipe = GetDebugManager()->m_TexDisplayPipeline;
|
||||
if(f32render)
|
||||
|
||||
if(cfg.CustomShader != ResourceId())
|
||||
{
|
||||
GetDebugManager()->CreateCustomShaderPipeline(cfg.CustomShader);
|
||||
pipe = GetDebugManager()->m_CustomTexPipeline;
|
||||
}
|
||||
else if(f32render)
|
||||
{
|
||||
pipe = GetDebugManager()->m_TexDisplayF32Pipeline;
|
||||
}
|
||||
else if(!cfg.rawoutput && cfg.CustomShader == ResourceId())
|
||||
{
|
||||
pipe = GetDebugManager()->m_TexDisplayBlendPipeline;
|
||||
}
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe));
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
@@ -4353,17 +4386,6 @@ void VulkanReplay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t
|
||||
RDCERR("Should never hit SetContextFilter");
|
||||
}
|
||||
|
||||
void VulkanReplay::FreeTargetResource(ResourceId id)
|
||||
{
|
||||
// won't get hit until BuildTargetShader is implemented
|
||||
VULKANNOTIMP("FreeTargetResource");
|
||||
}
|
||||
|
||||
void VulkanReplay::FreeCustomShader(ResourceId id)
|
||||
{
|
||||
VULKANNOTIMP("FreeCustomShader");
|
||||
}
|
||||
|
||||
MeshFormat VulkanReplay::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage)
|
||||
{
|
||||
return GetDebugManager()->GetPostVSBuffers(eventID, instID, stage);
|
||||
@@ -4896,16 +4918,114 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VulkanReplay::ReplaceResource(ResourceId from, ResourceId to)
|
||||
void VulkanReplay::BuildCustomShader(string source, string entry, const uint32_t compileFlags,
|
||||
ShaderStageType type, ResourceId *id, string *errors)
|
||||
{
|
||||
// won't get hit until BuildTargetShader is implemented
|
||||
VULKANNOTIMP("ReplaceResource");
|
||||
SPIRVShaderStage stage = eSPIRVInvalid;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case eShaderStage_Vertex: stage = eSPIRVVertex; break;
|
||||
case eShaderStage_Hull: stage = eSPIRVTessControl; break;
|
||||
case eShaderStage_Domain: stage = eSPIRVTessEvaluation; break;
|
||||
case eShaderStage_Geometry: stage = eSPIRVGeometry; break;
|
||||
case eShaderStage_Pixel: stage = eSPIRVFragment; break;
|
||||
case eShaderStage_Compute: stage = eSPIRVCompute; break;
|
||||
default:
|
||||
RDCERR("Unexpected type in BuildShader!");
|
||||
*id = ResourceId();
|
||||
return;
|
||||
}
|
||||
|
||||
vector<string> sources;
|
||||
sources.push_back(source);
|
||||
vector<uint32_t> spirv;
|
||||
|
||||
string output = CompileSPIRV(stage, sources, spirv);
|
||||
|
||||
if(spirv.empty())
|
||||
{
|
||||
*id = ResourceId();
|
||||
*errors = output;
|
||||
return;
|
||||
}
|
||||
|
||||
VkShaderModuleCreateInfo modinfo = {
|
||||
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
spirv.size() * sizeof(uint32_t),
|
||||
&spirv[0],
|
||||
};
|
||||
|
||||
VkShaderModule module;
|
||||
VkResult vkr = m_pDriver->vkCreateShaderModule(m_pDriver->GetDev(), &modinfo, NULL, &module);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
*id = GetResID(module);
|
||||
}
|
||||
|
||||
void VulkanReplay::RemoveReplacement(ResourceId id)
|
||||
void VulkanReplay::FreeCustomShader(ResourceId id)
|
||||
{
|
||||
// won't get hit until BuildTargetShader is implemented
|
||||
VULKANNOTIMP("RemoveReplacement");
|
||||
if(id == ResourceId())
|
||||
return;
|
||||
|
||||
m_pDriver->ReleaseResource(GetResourceManager()->GetCurrentResource(id));
|
||||
}
|
||||
|
||||
ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip)
|
||||
{
|
||||
if(shader == ResourceId() || texid == ResourceId())
|
||||
return ResourceId();
|
||||
|
||||
VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid];
|
||||
|
||||
GetDebugManager()->CreateCustomShaderTex(iminfo.extent.width, iminfo.extent.height);
|
||||
|
||||
int oldW = m_DebugWidth, oldH = m_DebugHeight;
|
||||
|
||||
m_DebugWidth = iminfo.extent.width;
|
||||
m_DebugHeight = iminfo.extent.height;
|
||||
|
||||
TextureDisplay disp;
|
||||
disp.Red = disp.Green = disp.Blue = disp.Alpha = true;
|
||||
disp.FlipY = false;
|
||||
disp.offx = 0.0f;
|
||||
disp.offy = 0.0f;
|
||||
disp.CustomShader = shader;
|
||||
disp.texid = texid;
|
||||
disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0);
|
||||
disp.HDRMul = -1.0f;
|
||||
disp.linearDisplayAsGamma = true;
|
||||
disp.mip = mip;
|
||||
disp.sampleIdx = 0;
|
||||
disp.overlay = eTexOverlay_None;
|
||||
disp.rangemin = 0.0f;
|
||||
disp.rangemax = 1.0f;
|
||||
disp.rawoutput = false;
|
||||
disp.scale = 1.0f;
|
||||
disp.sliceFace = 0;
|
||||
|
||||
VkClearValue clearval = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
|
||||
VkRenderPassBeginInfo rpbegin = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
NULL,
|
||||
Unwrap(GetDebugManager()->m_CustomTexRP),
|
||||
Unwrap(GetDebugManager()->m_CustomTexFB),
|
||||
{{
|
||||
0, 0,
|
||||
},
|
||||
{iminfo.extent.width, iminfo.extent.height}},
|
||||
1,
|
||||
&clearval,
|
||||
};
|
||||
|
||||
RenderTextureInternal(disp, rpbegin, false);
|
||||
|
||||
m_DebugWidth = oldW;
|
||||
m_DebugHeight = oldH;
|
||||
|
||||
return GetResID(GetDebugManager()->m_CustomTexImg);
|
||||
}
|
||||
|
||||
void VulkanReplay::BuildTargetShader(string source, string entry, const uint32_t compileFlags,
|
||||
@@ -4918,10 +5038,22 @@ void VulkanReplay::BuildTargetShader(string source, string entry, const uint32_t
|
||||
*id = ResourceId();
|
||||
}
|
||||
|
||||
void VulkanReplay::BuildCustomShader(string source, string entry, const uint32_t compileFlags,
|
||||
ShaderStageType type, ResourceId *id, string *errors)
|
||||
void VulkanReplay::ReplaceResource(ResourceId from, ResourceId to)
|
||||
{
|
||||
VULKANNOTIMP("BuildCustomShader");
|
||||
// won't get hit until BuildTargetShader is implemented
|
||||
VULKANNOTIMP("ReplaceResource");
|
||||
}
|
||||
|
||||
void VulkanReplay::RemoveReplacement(ResourceId id)
|
||||
{
|
||||
// won't get hit until BuildTargetShader is implemented
|
||||
VULKANNOTIMP("RemoveReplacement");
|
||||
}
|
||||
|
||||
void VulkanReplay::FreeTargetResource(ResourceId id)
|
||||
{
|
||||
// won't get hit until BuildTargetShader is implemented
|
||||
VULKANNOTIMP("FreeTargetResource");
|
||||
}
|
||||
|
||||
vector<PixelModification> VulkanReplay::PixelHistory(vector<EventUsage> events, ResourceId target,
|
||||
@@ -4953,12 +5085,6 @@ ShaderDebugTrace VulkanReplay::DebugThread(uint32_t eventID, uint32_t groupid[3]
|
||||
return ShaderDebugTrace();
|
||||
}
|
||||
|
||||
ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip)
|
||||
{
|
||||
VULKANNOTIMP("ApplyCustomShader");
|
||||
return ResourceId();
|
||||
}
|
||||
|
||||
ResourceId VulkanReplay::CreateProxyTexture(FetchTexture templateTex)
|
||||
{
|
||||
VULKANNOTIMP("CreateProxyTexture");
|
||||
|
||||
@@ -2041,6 +2041,17 @@ namespace renderdocui.Windows
|
||||
}
|
||||
}
|
||||
|
||||
private void InsertVulkanUBO()
|
||||
{
|
||||
CurrentScintilla.InsertText(0, String.Format("layout(binding = 0, std140) uniform RENDERDOC_Uniforms{0}" +
|
||||
"{{{0}" +
|
||||
" uvec4 TexDim;{0}" +
|
||||
" uint SelectedMip;{0}" +
|
||||
" int TextureType;{0}" +
|
||||
"}} RENDERDOC;{0}{0}", Environment.NewLine));
|
||||
}
|
||||
|
||||
|
||||
private void textureDimensionsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (CurrentScintilla == null)
|
||||
@@ -2050,6 +2061,8 @@ namespace renderdocui.Windows
|
||||
CurrentScintilla.InsertText(0, "uint4 RENDERDOC_TexDim; // xyz == width, height, depth. w == # mips" + Environment.NewLine + Environment.NewLine);
|
||||
else if (m_Core.APIProps.pipelineType == APIPipelineStateType.OpenGL)
|
||||
CurrentScintilla.InsertText(0, "uvec4 RENDERDOC_TexDim; // xyz == width, height, depth. w == # mips" + Environment.NewLine + Environment.NewLine);
|
||||
else if (m_Core.APIProps.pipelineType == APIPipelineStateType.Vulkan)
|
||||
InsertVulkanUBO();
|
||||
CurrentScintilla.CurrentPos = 0;
|
||||
}
|
||||
|
||||
@@ -2058,7 +2071,10 @@ namespace renderdocui.Windows
|
||||
if (CurrentScintilla == null)
|
||||
return;
|
||||
|
||||
CurrentScintilla.InsertText(0, "uint RENDERDOC_SelectedMip; // selected mip in UI" + Environment.NewLine + Environment.NewLine);
|
||||
if (m_Core.APIProps.pipelineType == APIPipelineStateType.Vulkan)
|
||||
InsertVulkanUBO();
|
||||
else
|
||||
CurrentScintilla.InsertText(0, "uint RENDERDOC_SelectedMip; // selected mip in UI" + Environment.NewLine + Environment.NewLine);
|
||||
CurrentScintilla.CurrentPos = 0;
|
||||
}
|
||||
|
||||
@@ -2071,6 +2087,8 @@ namespace renderdocui.Windows
|
||||
CurrentScintilla.InsertText(0, "uint RENDERDOC_TextureType; // 1 = 1D, 2 = 2D, 3 = 3D, 4 = Depth, 5 = Depth + Stencil, 6 = Depth (MS), 7 = Depth + Stencil (MS)" + Environment.NewLine + Environment.NewLine);
|
||||
else if (m_Core.APIProps.pipelineType == APIPipelineStateType.OpenGL)
|
||||
CurrentScintilla.InsertText(0, "uint RENDERDOC_TextureType; // 1 = 1D, 2 = 2D, 3 = 3D, 4 = Cube, 5 = 1DArray, 6 = 2DArray, 7 = CubeArray, 8 = Rect, 9 = Buffer, 10 = 2DMS" + Environment.NewLine + Environment.NewLine);
|
||||
else if (m_Core.APIProps.pipelineType == APIPipelineStateType.Vulkan)
|
||||
InsertVulkanUBO();
|
||||
CurrentScintilla.CurrentPos = 0;
|
||||
}
|
||||
|
||||
@@ -2157,6 +2175,27 @@ namespace renderdocui.Windows
|
||||
"layout (binding = 9) uniform samplerBuffer texBuffer;" + Environment.NewLine +
|
||||
"layout (binding = 10) uniform sampler2DMS tex2DMS;" + Environment.NewLine + Environment.NewLine);
|
||||
}
|
||||
else if (m_Core.APIProps.pipelineType == APIPipelineStateType.Vulkan)
|
||||
{
|
||||
CurrentScintilla.InsertText(0, "// Textures" + Environment.NewLine +
|
||||
"// Floating point samplers" + Environment.NewLine +
|
||||
"layout(binding = 6) uniform sampler1DArray tex1DArray;" + Environment.NewLine +
|
||||
"layout(binding = 7) uniform sampler2DArray tex2DArray;" + Environment.NewLine +
|
||||
"layout(binding = 8) uniform sampler3D tex3D;" + Environment.NewLine +
|
||||
"layout(binding = 9) uniform sampler2DMS tex2DMS;" + Environment.NewLine +
|
||||
"" + Environment.NewLine +
|
||||
"// Unsigned int samplers" + Environment.NewLine +
|
||||
"layout(binding = 11) uniform usampler1DArray texUInt1DArray;" + Environment.NewLine +
|
||||
"layout(binding = 12) uniform usampler2DArray texUInt2DArray;" + Environment.NewLine +
|
||||
"layout(binding = 13) uniform usampler3D texUInt3D;" + Environment.NewLine +
|
||||
"layout(binding = 14) uniform usampler2DMS texUInt2DMS;" + Environment.NewLine +
|
||||
"" + Environment.NewLine +
|
||||
"// Int samplers" + Environment.NewLine +
|
||||
"layout(binding = 16) uniform isampler1DArray texSInt1DArray;" + Environment.NewLine +
|
||||
"layout(binding = 17) uniform isampler2DArray texSInt2DArray;" + Environment.NewLine +
|
||||
"layout(binding = 18) uniform isampler3D texSInt3D;" + Environment.NewLine +
|
||||
"layout(binding = 19) uniform isampler2DMS texSInt2DMS;" + Environment.NewLine + Environment.NewLine);
|
||||
}
|
||||
CurrentScintilla.CurrentPos = 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user