From bde21b0c73e85b2513d7f2ad032242060a3fe6ed Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 19 Jul 2016 20:40:11 +0200 Subject: [PATCH] Render custom shaders at the selected mip level. Refs #302 --- renderdoc/driver/d3d11/d3d11_analyse.cpp | 33 ++++++++++----- renderdoc/driver/gl/gl_debug.cpp | 2 +- renderdoc/driver/gl/gl_replay.cpp | 19 +++++---- renderdoc/driver/vulkan/vk_debug.cpp | 52 ++++++++++++++++++------ renderdoc/driver/vulkan/vk_debug.h | 4 +- renderdoc/driver/vulkan/vk_replay.cpp | 10 ++--- renderdoc/replay/replay_output.cpp | 2 - renderdocui/Windows/TextureViewer.cs | 5 ++- 8 files changed, 84 insertions(+), 43 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index fca59680f..d0dd23dda 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -2988,6 +2988,23 @@ ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId te CreateCustomShaderTex(details.texWidth, details.texHeight); + { + D3D11_RENDER_TARGET_VIEW_DESC desc; + + desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipSlice = mip; + + WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)m_CustomShaderTex; + HRESULT hr = m_pDevice->CreateRenderTargetView(wrapped->GetReal(), &desc, &m_CustomShaderRTV); + + if(FAILED(hr)) + { + RDCERR("Failed to create custom shader rtv %08x", hr); + return m_CustomShaderResourceId; + } + } + m_pImmediateContext->OMSetRenderTargets(1, &m_CustomShaderRTV, NULL); float clr[] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -2998,8 +3015,8 @@ ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId te viewport.TopLeftX = 0; viewport.TopLeftY = 0; - viewport.Width = (float)details.texWidth; - viewport.Height = (float)details.texHeight; + viewport.Width = (float)RDCMAX(1U, details.texWidth >> mip); + viewport.Height = (float)RDCMAX(1U, details.texHeight >> mip); m_pImmediateContext->RSSetViewports(1, &viewport); @@ -3013,7 +3030,7 @@ ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId te disp.typeHint = typeHint; disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0); disp.HDRMul = -1.0f; - disp.linearDisplayAsGamma = true; + disp.linearDisplayAsGamma = false; disp.mip = mip; disp.sampleIdx = 0; disp.overlay = eTexOverlay_None; @@ -3023,7 +3040,7 @@ ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId te disp.scale = 1.0f; disp.sliceFace = 0; - SetOutputDimensions(details.texWidth, details.texHeight); + SetOutputDimensions(RDCMAX(1U, details.texWidth >> mip), RDCMAX(1U, details.texHeight >> mip)); RenderTexture(disp, true); @@ -3037,7 +3054,7 @@ void D3D11DebugManager::CreateCustomShaderTex(uint32_t w, uint32_t h) texdesc.ArraySize = 1; texdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; texdesc.CPUAccessFlags = 0; - texdesc.MipLevels = 1; + texdesc.MipLevels = CalcNumMips((int)w, (int)h, 1); texdesc.MiscFlags = 0; texdesc.SampleDesc.Count = 1; texdesc.SampleDesc.Quality = 0; @@ -3066,12 +3083,6 @@ void D3D11DebugManager::CreateCustomShaderTex(uint32_t w, uint32_t h) } else { - WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)m_CustomShaderTex; - hr = m_pDevice->CreateRenderTargetView(wrapped->GetReal(), NULL, &m_CustomShaderRTV); - - if(FAILED(hr)) - RDCERR("Failed to create custom shader rtv %08x", hr); - m_CustomShaderResourceId = GetIDForResource(m_CustomShaderTex); } } diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 989f6cd6c..42c18e12c 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -1489,7 +1489,7 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) gl.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); // need to ensure texture is mipmap complete by clamping TEXTURE_MAX_LEVEL. - if(clampmaxlevel != maxlevel) + if(clampmaxlevel != maxlevel && cfg.texid != DebugData.CustomShaderTexID) { gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&clampmaxlevel); } diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 59339efa7..b5f215f7c 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -2604,12 +2604,13 @@ ResourceId GLReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint m_pDriver->glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.customFBO); m_pDriver->glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_2D, - DebugData.customTex, 0); + DebugData.customTex, mip); - m_pDriver->glViewport(0, 0, texDetails.width, texDetails.height); + m_pDriver->glViewport(0, 0, RDCMAX(1, texDetails.width >> mip), + RDCMAX(1, texDetails.height >> mip)); - DebugData.outWidth = float(texDetails.width); - DebugData.outHeight = float(texDetails.height); + DebugData.outWidth = float(RDCMAX(1, texDetails.width >> mip)); + DebugData.outHeight = float(RDCMAX(1, texDetails.height >> mip)); float clr[] = {0.0f, 0.8f, 0.0f, 0.0f}; m_pDriver->glClearBufferfv(eGL_COLOR, 0, clr); @@ -2624,7 +2625,7 @@ ResourceId GLReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint disp.typeHint = typeHint; disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0); disp.HDRMul = -1.0f; - disp.linearDisplayAsGamma = true; + disp.linearDisplayAsGamma = false; disp.mip = mip; disp.sampleIdx = 0; disp.overlay = eTexOverlay_None; @@ -2656,14 +2657,16 @@ void GLReplay::CreateCustomShaderTex(uint32_t w, uint32_t h) DebugData.customTex = 0; } + uint32_t mips = CalcNumMips((int)w, (int)h, 1); + m_pDriver->glGenTextures(1, &DebugData.customTex); m_pDriver->glBindTexture(eGL_TEXTURE_2D, DebugData.customTex); - m_pDriver->glTextureStorage2DEXT(DebugData.customTex, eGL_TEXTURE_2D, 1, eGL_RGBA16F, (GLsizei)w, - (GLsizei)h); + m_pDriver->glTextureStorage2DEXT(DebugData.customTex, eGL_TEXTURE_2D, mips, eGL_RGBA16F, + (GLsizei)w, (GLsizei)h); m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_BASE_LEVEL, 0); - m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 1); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, mips); m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 23ccef8f6..549aef37f 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -255,7 +255,7 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev) m_CustomTexWidth = m_CustomTexHeight = 0; m_CustomTexImg = VK_NULL_HANDLE; - m_CustomTexImgView = VK_NULL_HANDLE; + RDCEraseEl(m_CustomTexImgView); m_CustomTexMemSize = 0; m_CustomTexMem = VK_NULL_HANDLE; m_CustomTexFB = VK_NULL_HANDLE; @@ -2168,7 +2168,8 @@ VulkanDebugManager::~VulkanDebugManager() 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); + for(size_t i = 0; i < ARRAY_COUNT(m_CustomTexImgView); i++) + m_pDriver->vkDestroyImageView(dev, m_CustomTexImgView[i], NULL); m_pDriver->vkFreeMemory(dev, m_CustomTexMem, NULL); m_pDriver->vkDestroyPipeline(dev, m_CustomTexPipeline, NULL); @@ -2440,26 +2441,47 @@ void VulkanDebugManager::RemoveReplacement(ResourceId id) } } -void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height) +void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height, uint32_t mip) { VkDevice dev = m_Device; + VkResult vkr = VK_SUCCESS; + if(m_CustomTexImg != VK_NULL_HANDLE) { if(width == m_CustomTexWidth && height == m_CustomTexHeight) + { + // recreate framebuffer for this mip + + // Create framebuffer rendering just to overlay image, no depth + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + m_CustomTexRP, + 1, + &m_CustomTexImgView[mip], + RDCMAX(1U, width >> mip), + RDCMAX(1U, height >> mip), + 1, + }; + + vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &m_CustomTexFB); + RDCASSERTEQUAL(vkr, VK_SUCCESS); return; + } m_pDriver->vkDestroyRenderPass(dev, m_CustomTexRP, NULL); m_pDriver->vkDestroyFramebuffer(dev, m_CustomTexFB, NULL); - m_pDriver->vkDestroyImageView(dev, m_CustomTexImgView, NULL); + for(size_t i = 0; i < ARRAY_COUNT(m_CustomTexImgView); i++) + m_pDriver->vkDestroyImageView(dev, m_CustomTexImgView[i], NULL); + RDCEraseEl(m_CustomTexImgView); 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, @@ -2467,7 +2489,7 @@ void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height) VK_IMAGE_TYPE_2D, VK_FORMAT_R16G16B16A16_SFLOAT, {width, height, 1}, - 1, + CalcNumMips((int)width, (int)height, 1), 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, @@ -2520,8 +2542,12 @@ void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height) }, }; - vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &m_CustomTexImgView); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + for(uint32_t i = 0; i < imInfo.mipLevels; i++) + { + viewInfo.subresourceRange.baseMipLevel = i; + vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &m_CustomTexImgView[i]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } // need to update image layout into valid state @@ -2535,7 +2561,7 @@ void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height) 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}}; + {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, 1}}; m_pDriver->m_ImageLayouts[GetResID(m_CustomTexImg)].subresourceStates[0].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; @@ -2599,9 +2625,9 @@ void VulkanDebugManager::CreateCustomShaderTex(uint32_t width, uint32_t height) 0, m_CustomTexRP, 1, - &m_CustomTexImgView, - width, - height, + &m_CustomTexImgView[mip], + RDCMAX(1U, width >> mip), + RDCMAX(1U, height >> mip), 1, }; diff --git a/renderdoc/driver/vulkan/vk_debug.h b/renderdoc/driver/vulkan/vk_debug.h index e7537949d..a31a52d0a 100644 --- a/renderdoc/driver/vulkan/vk_debug.h +++ b/renderdoc/driver/vulkan/vk_debug.h @@ -126,7 +126,7 @@ public: uint32_t PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t x, uint32_t y, uint32_t w, uint32_t h); - void CreateCustomShaderTex(uint32_t width, uint32_t height); + void CreateCustomShaderTex(uint32_t width, uint32_t height, uint32_t mip); void CreateCustomShaderPipeline(ResourceId shader); void ReplaceResource(ResourceId from, ResourceId to); @@ -214,7 +214,7 @@ public: uint32_t m_CustomTexWidth, m_CustomTexHeight; VkDeviceSize m_CustomTexMemSize; VkImage m_CustomTexImg; - VkImageView m_CustomTexImgView; + VkImageView m_CustomTexImgView[16]; VkDeviceMemory m_CustomTexMem; VkFramebuffer m_CustomTexFB; VkRenderPass m_CustomTexRP; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index dce5ca83b..1e47c5914 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -5234,12 +5234,12 @@ ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; - GetDebugManager()->CreateCustomShaderTex(iminfo.extent.width, iminfo.extent.height); + GetDebugManager()->CreateCustomShaderTex(iminfo.extent.width, iminfo.extent.height, mip); int oldW = m_DebugWidth, oldH = m_DebugHeight; - m_DebugWidth = iminfo.extent.width; - m_DebugHeight = iminfo.extent.height; + m_DebugWidth = RDCMAX(1U, iminfo.extent.width >> mip); + m_DebugHeight = RDCMAX(1U, iminfo.extent.height >> mip); TextureDisplay disp; disp.Red = disp.Green = disp.Blue = disp.Alpha = true; @@ -5251,7 +5251,7 @@ ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, disp.typeHint = typeHint; disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0); disp.HDRMul = -1.0f; - disp.linearDisplayAsGamma = true; + disp.linearDisplayAsGamma = false; disp.mip = mip; disp.sampleIdx = 0; disp.overlay = eTexOverlay_None; @@ -5270,7 +5270,7 @@ ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, {{ 0, 0, }, - {iminfo.extent.width, iminfo.extent.height}}, + {m_DebugWidth, m_DebugHeight}}, 1, &clearval, }; diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index 1841a318a..5a79b30bc 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -536,8 +536,6 @@ void ReplayOutput::DisplayTex() texDisplay.typeHint = eCompType_None; texDisplay.CustomShader = ResourceId(); texDisplay.sliceFace = 0; - texDisplay.mip = 0; - texDisplay.linearDisplayAsGamma = false; } float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; diff --git a/renderdocui/Windows/TextureViewer.cs b/renderdocui/Windows/TextureViewer.cs index c7ae2fc0f..ad5ff6400 100644 --- a/renderdocui/Windows/TextureViewer.cs +++ b/renderdocui/Windows/TextureViewer.cs @@ -2116,9 +2116,12 @@ namespace renderdocui.Windows else gammaDisplay.Enabled = false; - m_TexDisplay.linearDisplayAsGamma = gammaDisplay.Checked; + m_TexDisplay.linearDisplayAsGamma = !gammaDisplay.Enabled || gammaDisplay.Checked; } + if (tex != null && tex.format.srgbCorrected) + m_TexDisplay.linearDisplayAsGamma = false; + bool dsv = false; if(tex != null) dsv = ((tex.creationFlags & TextureCreationFlags.DSV) != 0) || (tex.format.compType == FormatComponentType.Depth);