From 1ed4b561e6d77ef3791f6935abb9d5d79c8abfc2 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 27 May 2021 14:18:05 +0100 Subject: [PATCH] Fix discard patterns to work correctly with multisampled UINT textures --- renderdoc/data/glsl/discard.frag | 52 ++++++++---- renderdoc/data/hlsl/misc.hlsl | 32 ++++++-- renderdoc/driver/d3d11/d3d11_debug.cpp | 28 ++++--- renderdoc/driver/d3d11/d3d11_debug.h | 3 +- renderdoc/driver/d3d12/d3d12_debug.cpp | 22 +++-- renderdoc/driver/d3d12/d3d12_debug.h | 3 +- renderdoc/driver/gl/gl_debug.cpp | 90 +++++++++++++++------ renderdoc/driver/gl/gl_replay.h | 2 +- renderdoc/driver/vulkan/vk_debug.cpp | 13 ++- renderdoc/driver/vulkan/vk_shader_cache.cpp | 3 +- renderdoc/replay/replay_driver.cpp | 8 +- util/test/demos/d3d11/d3d11_discard_zoo.cpp | 6 ++ util/test/demos/d3d12/d3d12_discard_zoo.cpp | 12 +++ util/test/demos/gl/gl_discard_zoo.cpp | 16 ++++ util/test/demos/vk/vk_discard_zoo.cpp | 4 + util/test/rdtest/shared/Discard_Zoo.py | 4 +- 16 files changed, 225 insertions(+), 73 deletions(-) diff --git a/renderdoc/data/glsl/discard.frag b/renderdoc/data/glsl/discard.frag index 8dc2622e7..4048b8c86 100644 --- a/renderdoc/data/glsl/discard.frag +++ b/renderdoc/data/glsl/discard.frag @@ -31,7 +31,8 @@ layout(set = 0, binding = 0, std140) uniform DiscardUBOData { - vec4 pattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; + vec4 floatpattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; + uvec4 intpattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; } Pattern; @@ -63,7 +64,8 @@ in vec2 uv; uniform DiscardUBOData { - vec4 pattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; + vec4 floatpattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; + uvec4 intpattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; } Pattern; @@ -71,14 +73,34 @@ uniform uint flags; #endif -FRAG_OUT(0) out vec4 col0; -FRAG_OUT(1) out vec4 col1; -FRAG_OUT(2) out vec4 col2; -FRAG_OUT(3) out vec4 col3; -FRAG_OUT(4) out vec4 col4; -FRAG_OUT(5) out vec4 col5; -FRAG_OUT(6) out vec4 col6; -FRAG_OUT(7) out vec4 col7; +#if defined(SHADER_BASETYPE) && SHADER_BASETYPE == 1 + +#define srcpattern intpattern +#define patternType uvec4 +#define valType uint + +#elif defined(SHADER_BASETYPE) && SHADER_BASETYPE == 2 + +#define srcpattern intpattern +#define patternType ivec4 +#define valType int + +#else + +#define srcpattern floatpattern +#define patternType vec4 +#define valType float + +#endif + +FRAG_OUT(0) out patternType col0; +FRAG_OUT(1) out patternType col1; +FRAG_OUT(2) out patternType col2; +FRAG_OUT(3) out patternType col3; +FRAG_OUT(4) out patternType col4; +FRAG_OUT(5) out patternType col5; +FRAG_OUT(6) out patternType col6; +FRAG_OUT(7) out patternType col7; void main() { @@ -91,18 +113,18 @@ void main() int idx = ((y * 64) + x); - float val = Pattern.pattern[idx / 4][idx % 4]; + valType val = valType(Pattern.srcpattern[idx / 4][idx % 4]); uint stencilPass = (flags & 0xfu); - if(stencilPass == 1u && val >= 0.5f) + if(stencilPass == 1u && float(val) >= 0.5f) discard; - else if(stencilPass == 2u && val < 0.5f) + else if(stencilPass == 2u && float(val) < 0.5f) discard; - gl_FragDepth = clamp(val, 0.0, 1.0); + gl_FragDepth = clamp(float(val), 0.0f, 1.0f); - vec4 vecval = vec4(val, val, val, val); + patternType vecval = patternType(val, val, val, val); col0 = col1 = col2 = col3 = col4 = col5 = col6 = col7 = vecval; } diff --git a/renderdoc/data/hlsl/misc.hlsl b/renderdoc/data/hlsl/misc.hlsl index bec7e1953..171dce3a6 100644 --- a/renderdoc/data/hlsl/misc.hlsl +++ b/renderdoc/data/hlsl/misc.hlsl @@ -87,7 +87,8 @@ float4 RENDERDOC_CheckerboardPS(float4 pos : SV_Position) : SV_Target0 cbuffer discarddata : register(b0) { - float4 pattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; + float4 floatpattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; + uint4 intpattern[(PATTERN_WIDTH * PATTERN_HEIGHT) / 4]; }; cbuffer discardopts : register(b1) @@ -95,14 +96,14 @@ cbuffer discardopts : register(b1) uint discardPass; }; -MultipleOutput RENDERDOC_DiscardPS(float4 pos : SV_Position, out float depth : SV_Depth) +float4 RENDERDOC_DiscardFloatPS(float4 pos : SV_Position, out float depth : SV_Depth) : SV_Target0 { uint x = uint(pos.x) % PATTERN_WIDTH; uint y = uint(pos.y) % PATTERN_HEIGHT; uint idx = ((y * 64) + x); - float val = pattern[idx / 4][idx % 4]; + float val = floatpattern[idx / 4][idx % 4]; if(discardPass == 1 && val >= 0.5f) clip(-1); @@ -111,9 +112,24 @@ MultipleOutput RENDERDOC_DiscardPS(float4 pos : SV_Position, out float depth : S depth = saturate(val); - MultipleOutput OUT = (MultipleOutput)0; - - OUT.col0 = OUT.col1 = OUT.col2 = OUT.col3 = OUT.col4 = OUT.col5 = OUT.col6 = OUT.col7 = val.xxxx; - - return OUT; + return val.xxxx; +} + +uint4 RENDERDOC_DiscardIntPS(float4 pos : SV_Position, out float depth : SV_Depth) : SV_Target0 +{ + uint x = uint(pos.x) % PATTERN_WIDTH; + uint y = uint(pos.y) % PATTERN_HEIGHT; + + uint idx = ((y * 64) + x); + + uint val = intpattern[idx / 4][idx % 4]; + + if(discardPass == 1 && val > 0) + clip(-1); + else if(discardPass == 2 && val == 0) + clip(-1); + + depth = saturate(float(val)); + + return val.xxxx; } diff --git a/renderdoc/driver/d3d11/d3d11_debug.cpp b/renderdoc/driver/d3d11/d3d11_debug.cpp index 12bf0588f..93ca37263 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.cpp +++ b/renderdoc/driver/d3d11/d3d11_debug.cpp @@ -288,7 +288,8 @@ void D3D11DebugManager::InitReplayResources() rdcstr hlsl = GetEmbeddedResource(misc_hlsl); m_DiscardVS = shaderCache->MakeVShader(hlsl.c_str(), "RENDERDOC_FullscreenVS", "vs_4_0"); - m_DiscardPS = shaderCache->MakePShader(hlsl.c_str(), "RENDERDOC_DiscardPS", "ps_4_0"); + m_DiscardFloatPS = shaderCache->MakePShader(hlsl.c_str(), "RENDERDOC_DiscardFloatPS", "ps_4_0"); + m_DiscardIntPS = shaderCache->MakePShader(hlsl.c_str(), "RENDERDOC_DiscardIntPS", "ps_4_0"); ResourceFormat fmt; fmt.type = ResourceFormatType::Regular; @@ -296,6 +297,8 @@ void D3D11DebugManager::InitReplayResources() fmt.compByteWidth = 4; fmt.compCount = 1; m_DiscardBytes = GetDiscardPattern(DiscardType::DiscardCall, fmt); + fmt.compType = CompType::SInt; + m_DiscardBytes.append(GetDiscardPattern(DiscardType::DiscardCall, fmt)); D3D11_DEPTH_STENCIL_DESC desc; @@ -355,7 +358,8 @@ void D3D11DebugManager::ShutdownResources() it->second->Release(); SAFE_RELEASE(m_DiscardVS); - SAFE_RELEASE(m_DiscardPS); + SAFE_RELEASE(m_DiscardFloatPS); + SAFE_RELEASE(m_DiscardIntPS); SAFE_RELEASE(m_DiscardDepthState); SAFE_RELEASE(m_DiscardRasterState); @@ -487,7 +491,16 @@ void D3D11DebugManager::FillWithDiscardPattern(DiscardType type, ID3D11Resource // depth-stencil resources can't be sub-copied, so we need to render to them if(IsDepthFormat(key.fmt) || key.samp.Count > 1) { - D3D11MarkerRegion::Set("Depth texture"); + D3D11MarkerRegion::Set("Depth/MSAA texture"); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = GetTypedFormat(key.fmt, CompType::Float); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Flags = 0; + dsvDesc.Format = GetDepthTypedFormat(key.fmt); + + bool intFormat = !IsDepthFormat(key.fmt) && (IsIntFormat(key.fmt) || IsUIntFormat(key.fmt)); D3D11RenderStateTracker tracker(m_pImmediateContext); @@ -496,16 +509,9 @@ void D3D11DebugManager::FillWithDiscardPattern(DiscardType type, ID3D11Resource m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_pImmediateContext->OMSetDepthStencilState(m_DiscardDepthState, 0); m_pImmediateContext->VSSetShader(m_DiscardVS, NULL, 0); - m_pImmediateContext->PSSetShader(m_DiscardPS, NULL, 0); + m_pImmediateContext->PSSetShader(intFormat ? m_DiscardIntPS : m_DiscardFloatPS, NULL, 0); m_pImmediateContext->RSSetState(m_DiscardRasterState); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = GetFloatTypedFormat(key.fmt); - - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Flags = 0; - dsvDesc.Format = GetDepthTypedFormat(key.fmt); - if(key.samp.Count > 1) { dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; diff --git a/renderdoc/driver/d3d11/d3d11_debug.h b/renderdoc/driver/d3d11/d3d11_debug.h index f56440d15..538d12a9f 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.h +++ b/renderdoc/driver/d3d11/d3d11_debug.h @@ -232,7 +232,8 @@ private: std::map m_DiscardPatterns; bytebuf m_DiscardBytes; ID3D11VertexShader *m_DiscardVS = NULL; - ID3D11PixelShader *m_DiscardPS = NULL; + ID3D11PixelShader *m_DiscardFloatPS = NULL; + ID3D11PixelShader *m_DiscardIntPS = NULL; ID3D11DepthStencilState *m_DiscardDepthState = NULL; ID3D11RasterizerState *m_DiscardRasterState = NULL; }; diff --git a/renderdoc/driver/d3d12/d3d12_debug.cpp b/renderdoc/driver/d3d12/d3d12_debug.cpp index 4a086a511..52ccaf159 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_debug.cpp @@ -284,8 +284,10 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper) shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_FullscreenVS", D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "vs_5_0", &m_FullscreenVS); - shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_DiscardPS", D3DCOMPILE_WARNINGS_ARE_ERRORS, - {}, "ps_5_0", &m_DiscardPS); + shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_DiscardFloatPS", + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &m_DiscardFloatPS); + shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_DiscardIntPS", + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &m_DiscardIntPS); } { @@ -387,6 +389,9 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper) fmt.compByteWidth = 4; fmt.compCount = 1; bytebuf pattern = GetDiscardPattern(DiscardType::DiscardCall, fmt); + fmt.compType = CompType::UInt; + pattern.append(GetDiscardPattern(DiscardType::DiscardCall, fmt)); + m_DiscardConstants = MakeCBuffer(pattern.size()); FillBuffer(m_DiscardConstants, 0, pattern.data(), pattern.size()); @@ -450,7 +455,8 @@ D3D12DebugManager::~D3D12DebugManager() SAFE_RELEASE(m_DiscardConstants); SAFE_RELEASE(m_DiscardRootSig); - SAFE_RELEASE(m_DiscardPS); + SAFE_RELEASE(m_DiscardFloatPS); + SAFE_RELEASE(m_DiscardIntPS); SAFE_RELEASE(m_DebugAlloc); SAFE_RELEASE(m_DebugList); @@ -777,7 +783,7 @@ void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, if(depth) fmt = GetDepthTypedFormat(fmt); else - fmt = GetFloatTypedFormat(fmt); + fmt = GetTypedFormat(fmt, CompType::Float); rdcpair key = {fmt, desc.SampleDesc.Count}; rdcpair stencilKey = {DXGI_FORMAT_UNKNOWN, desc.SampleDesc.Count}; @@ -796,6 +802,8 @@ void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, stencilpipe = m_DiscardPipes[stencilKey]; } + bool intFormat = !depth && (IsIntFormat(fmt) || IsUIntFormat(fmt)); + if(pipe == NULL) { D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc = {}; @@ -803,8 +811,10 @@ void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, pipeDesc.pRootSignature = m_DiscardRootSig; pipeDesc.VS.BytecodeLength = m_FullscreenVS->GetBufferSize(); pipeDesc.VS.pShaderBytecode = m_FullscreenVS->GetBufferPointer(); - pipeDesc.PS.BytecodeLength = m_DiscardPS->GetBufferSize(); - pipeDesc.PS.pShaderBytecode = m_DiscardPS->GetBufferPointer(); + pipeDesc.PS.BytecodeLength = + intFormat ? m_DiscardIntPS->GetBufferSize() : m_DiscardFloatPS->GetBufferSize(); + pipeDesc.PS.pShaderBytecode = + intFormat ? m_DiscardIntPS->GetBufferPointer() : m_DiscardFloatPS->GetBufferPointer(); pipeDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; pipeDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; pipeDesc.SampleMask = 0xFFFFFFFF; diff --git a/renderdoc/driver/d3d12/d3d12_debug.h b/renderdoc/driver/d3d12/d3d12_debug.h index 02003af8b..f27a47a2b 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.h +++ b/renderdoc/driver/d3d12/d3d12_debug.h @@ -230,7 +230,8 @@ private: ID3D12Fence *m_DebugFence = NULL; // Discard pattern rendering - ID3DBlob *m_DiscardPS = NULL; + ID3DBlob *m_DiscardFloatPS = NULL; + ID3DBlob *m_DiscardIntPS = NULL; ID3D12Resource *m_DiscardConstants = NULL; ID3D12RootSignature *m_DiscardRootSig = NULL; diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index f26eea82f..b45e8c0c7 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -545,28 +545,34 @@ void GLReplay::InitDebugData() BindUBO(DebugData.checkerProg, "CheckerboardUBOData", 0); - for(size_t numViews = 0; numViews < ARRAY_COUNT(DebugData.discardProg); numViews++) + for(size_t intIdx = 0; intIdx < 3; intIdx++) { - rdcstr defines; - - if(numViews > 0 && IsGLES && HasExt[OVR_multiview]) - defines = StringFormat::Fmt("#define NUM_VIEWS %zu", numViews + 1); - - rdcstr blitvs = - GenerateGLSLShader(GetEmbeddedResource(glsl_blit_vert), shaderType, glslBaseVer, defines); - - fs = GenerateGLSLShader(GetEmbeddedResource(glsl_discard_frag), shaderType, glslBaseVer); - DebugData.discardProg[numViews] = CreateShaderProgram(blitvs, fs); - - BindUBO(DebugData.discardProg[numViews], "DiscardUBOData", 0); - - if(!IsGLES) + for(size_t numViews = 0; numViews < ARRAY_COUNT(DebugData.discardProg[intIdx]); numViews++) { - rdcstr name = "col0"; - for(GLuint i = 0; i < 8; i++) + rdcstr defines; + + defines += rdcstr("#define SHADER_BASETYPE ") + ToStr(intIdx) + "\n"; + + if(numViews > 0 && IsGLES && HasExt[OVR_multiview]) + defines = StringFormat::Fmt("#define NUM_VIEWS %zu\n", numViews + 1); + + rdcstr blitvs = + GenerateGLSLShader(GetEmbeddedResource(glsl_blit_vert), shaderType, glslBaseVer, defines); + + fs = GenerateGLSLShader(GetEmbeddedResource(glsl_discard_frag), shaderType, glslBaseVer, + defines); + DebugData.discardProg[intIdx][numViews] = CreateShaderProgram(blitvs, fs); + + BindUBO(DebugData.discardProg[intIdx][numViews], "DiscardUBOData", 0); + + if(!IsGLES) { - name[3] = char('0' + i); - GL.glBindFragDataLocation(DebugData.discardProg[numViews], i, name.c_str()); + rdcstr name = "col0"; + for(GLuint i = 0; i < 8; i++) + { + name[3] = char('0' + i); + GL.glBindFragDataLocation(DebugData.discardProg[intIdx][numViews], i, name.c_str()); + } } } } @@ -578,6 +584,8 @@ void GLReplay::InitDebugData() fmt.compByteWidth = 4; fmt.compCount = 1; bytebuf pattern = GetDiscardPattern(DiscardType::InvalidateCall, fmt, 1, true); + fmt.compType = CompType::UInt; + pattern.append(GetDiscardPattern(DiscardType::InvalidateCall, fmt, 1, true)); drv.glGenBuffers(1, &DebugData.discardPatternBuffer); drv.glBindBuffer(eGL_UNIFORM_BUFFER, DebugData.discardPatternBuffer); drv.glNamedBufferDataEXT(DebugData.discardPatternBuffer, pattern.size(), pattern.data(), @@ -1155,9 +1163,10 @@ void GLReplay::DeleteDebugData() if(DebugData.overlayProg) drv.glDeleteProgram(DebugData.overlayProg); - for(size_t i = 0; i < ARRAY_COUNT(DebugData.discardProg); i++) - if(DebugData.discardProg[i]) - drv.glDeleteProgram(DebugData.discardProg[i]); + for(size_t b = 0; b < 3; b++) + for(size_t i = 0; i < ARRAY_COUNT(DebugData.discardProg[b]); i++) + if(DebugData.discardProg[b][i]) + drv.glDeleteProgram(DebugData.discardProg[b][i]); if(HasExt[ARB_transform_feedback2]) drv.glDeleteTransformFeedbacks(1, &DebugData.feedbackObj); @@ -1357,9 +1366,6 @@ void GLReplay::FillWithDiscardPattern(DiscardType type, GLuint framebuffer, GLsi &numviews); } - GLuint prog = DebugData.discardProg[RDCCLAMP(numviews, 1, 4) - 1]; - - drv.glUseProgram(prog); drv.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.discardPatternBuffer); drv.glDisable(eGL_BLEND); @@ -1384,6 +1390,8 @@ void GLReplay::FillWithDiscardPattern(DiscardType type, GLuint framebuffer, GLsi drv.glDepthMask(GL_FALSE); drv.glStencilMask(0); + int intIdx = -1; + // enable masks specified by attachments bool stencil = false; for(GLsizei i = 0; i < numAttachments; i++) @@ -1406,9 +1414,41 @@ void GLReplay::FillWithDiscardPattern(DiscardType type, GLuint framebuffer, GLsi else { drv.glColorMaski(attachments[i] - eGL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + if(intIdx == -1) + { + GLuint att; + drv.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, attachments[i], + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&att); + GLenum attType; + drv.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, attachments[i], + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, + (GLint *)&attType); + + ResourceId id = drv.GetResourceManager()->GetResID(attType == eGL_RENDERBUFFER + ? RenderbufferRes(drv.GetCtx(), att) + : TextureRes(drv.GetCtx(), att)); + + GLenum fmt = m_pDriver->m_Textures[id].internalFormat; + + if(IsUIntFormat(fmt)) + intIdx = 1; + else if(IsSIntFormat(fmt)) + intIdx = 2; + else + intIdx = 0; + } } } + if(intIdx == -1) + intIdx = 0; + + GLuint prog = DebugData.discardProg[intIdx][RDCCLAMP(numviews, 1, 4) - 1]; + + drv.glUseProgram(prog); + GLint loc = drv.glGetUniformLocation(prog, "flags"); uint32_t flags = 0U; diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 1d5de7990..25670967d 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -396,7 +396,7 @@ private: GLuint quadoverdrawFragShaderSPIRV; GLuint quadoverdrawResolveProg; - GLuint discardProg[4]; + GLuint discardProg[3][4]; GLuint discardPatternBuffer; ResourceId overlayTexId; diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 3cf6f977d..045c321eb 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -720,7 +720,6 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver) ResourceFormat fmt; fmt.type = ResourceFormatType::Regular; - fmt.compType = CompType::Float; fmt.compByteWidth = 4; fmt.compCount = 1; @@ -728,7 +727,10 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver) { CREATE_OBJECT(m_DiscardSet[i], m_DiscardPool, m_DiscardSetLayout); + fmt.compType = CompType::Float; bytebuf pattern = GetDiscardPattern(DiscardType(i), fmt); + fmt.compType = CompType::UInt; + pattern.append(GetDiscardPattern(DiscardType(i), fmt)); m_DiscardCB[i].Create(m_pDriver, m_Device, pattern.size(), 1, 0); @@ -1760,6 +1762,13 @@ void VulkanDebugManager::FillWithDiscardPattern(VkCommandBuffer cmd, DiscardType // create and cache a pipeline and RP that writes to this format and sample count if(passdata.pso == VK_NULL_HANDLE) { + BuiltinShaderBaseType baseType = BuiltinShaderBaseType::Float; + + if(IsSIntFormat(imInfo.format)) + baseType = BuiltinShaderBaseType::SInt; + else if(IsUIntFormat(imInfo.format)) + baseType = BuiltinShaderBaseType::UInt; + VkAttachmentReference attRef = { 0, depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, @@ -1803,7 +1812,7 @@ void VulkanDebugManager::FillWithDiscardPattern(VkCommandBuffer cmd, DiscardType passdata.rp, m_DiscardLayout, m_pDriver->GetShaderCache()->GetBuiltinModule(BuiltinShader::BlitVS), - m_pDriver->GetShaderCache()->GetBuiltinModule(BuiltinShader::DiscardFS), + m_pDriver->GetShaderCache()->GetBuiltinModule(BuiltinShader::DiscardFS, baseType), {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_STENCIL_REFERENCE}, imInfo.samples, false, // sampleRateShading diff --git a/renderdoc/driver/vulkan/vk_shader_cache.cpp b/renderdoc/driver/vulkan/vk_shader_cache.cpp index bf44d6411..1f0e1cf29 100644 --- a/renderdoc/driver/vulkan/vk_shader_cache.cpp +++ b/renderdoc/driver/vulkan/vk_shader_cache.cpp @@ -119,7 +119,8 @@ static const BuiltinShaderConfig builtinShaders[] = { BuiltinShaderConfig(BuiltinShader::ShaderDebugSampleVS, EmbeddedResource(glsl_shaderdebug_sample_vert), rdcspv::ShaderStage::Vertex), BuiltinShaderConfig(BuiltinShader::DiscardFS, EmbeddedResource(glsl_discard_frag), - rdcspv::ShaderStage::Fragment), + rdcspv::ShaderStage::Fragment, FeatureCheck::NoCheck, + BuiltinShaderFlags::BaseTypeParameterised), BuiltinShaderConfig( BuiltinShader::HistogramCS, EmbeddedResource(glsl_histogram_comp), rdcspv::ShaderStage::Compute, FeatureCheck::NoCheck, diff --git a/renderdoc/replay/replay_driver.cpp b/renderdoc/replay/replay_driver.cpp index 4f31f3080..c0c4a4e1b 100644 --- a/renderdoc/replay/replay_driver.cpp +++ b/renderdoc/replay/replay_driver.cpp @@ -1284,13 +1284,19 @@ bytebuf GetDiscardPattern(DiscardType type, const ResourceFormat &fmt, uint32_t ret.resize(rowPitch * DiscardPatternHeight); uint32_t *out = (uint32_t *)ret.data(); + uint32_t minVal = 0; + uint32_t maxVal = 0xffffffff; + + if(fmt.compType == CompType::UInt) + maxVal = (127u << 0) | (127u << 10) | (127u << 20) | (3u << 30); + for(int yi = 0; yi < (int)DiscardPatternHeight; yi++) { int y = invert ? DiscardPatternHeight - 1 - yi : yi; for(int x = 0; x < (int)DiscardPatternWidth; x++) { char c = pattern.c_str()[y * DiscardPatternWidth + x]; - *(out++) = (c == '#') ? 0xffffffff : 0x00000000; + *(out++) = (c == '#') ? maxVal : minVal; } out += (rowPitch - tightPitch); } diff --git a/util/test/demos/d3d11/d3d11_discard_zoo.cpp b/util/test/demos/d3d11/d3d11_discard_zoo.cpp index 81f6450f7..790248006 100644 --- a/util/test/demos/d3d11/d3d11_discard_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_discard_zoo.cpp @@ -198,6 +198,12 @@ RD_TEST(D3D11_Discard_Zoo, D3D11GraphicsTest) TEX_TEST("DiscardAll", MakeTexture(DXGI_FORMAT_R16G16B16A16_FLOAT, 300, 300).Multisampled(4).Array(5).RTV()); ctx1->DiscardResource(tex); + TEX_TEST("DiscardAll", + MakeTexture(DXGI_FORMAT_R16G16B16A16_UINT, 300, 300).Multisampled(4).Array(5).RTV()); + ctx1->DiscardResource(tex); + TEX_TEST("DiscardAll", + MakeTexture(DXGI_FORMAT_R16G16B16A16_SINT, 300, 300).Multisampled(4).Array(5).RTV()); + ctx1->DiscardResource(tex); // test depth textures TEX_TEST("DiscardAll", MakeTexture(DXGI_FORMAT_D32_FLOAT, 300, 300).DSV()); diff --git a/util/test/demos/d3d12/d3d12_discard_zoo.cpp b/util/test/demos/d3d12/d3d12_discard_zoo.cpp index 986bb0ab6..e1863b9d9 100644 --- a/util/test/demos/d3d12/d3d12_discard_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_discard_zoo.cpp @@ -436,6 +436,18 @@ float4 main(v2f IN) : SV_Target0 .RTV() .InitialState(D3D12_RESOURCE_STATE_RENDER_TARGET)); DiscardResource(cmd, tex); + TEX_TEST(L"DiscardAll", MakeTexture(DXGI_FORMAT_R16G16B16A16_UINT, 300, 300) + .Multisampled(4) + .Array(5) + .RTV() + .InitialState(D3D12_RESOURCE_STATE_RENDER_TARGET)); + DiscardResource(cmd, tex); + TEX_TEST(L"DiscardAll", MakeTexture(DXGI_FORMAT_R16G16B16A16_SINT, 300, 300) + .Multisampled(4) + .Array(5) + .RTV() + .InitialState(D3D12_RESOURCE_STATE_RENDER_TARGET)); + DiscardResource(cmd, tex); // test depth textures TEX_TEST(L"DiscardAll", MakeTexture(DXGI_FORMAT_D32_FLOAT, 300, 300) diff --git a/util/test/demos/gl/gl_discard_zoo.cpp b/util/test/demos/gl/gl_discard_zoo.cpp index e3b49b2a7..92dae9c3d 100644 --- a/util/test/demos/gl/gl_discard_zoo.cpp +++ b/util/test/demos/gl/gl_discard_zoo.cpp @@ -100,6 +100,18 @@ RD_TEST(GL_Discard_Zoo, OpenGLGraphicsTest) for(GLint m = 0; m < mips; m++) glClearTexImage(t, m, GL_STENCIL_INDEX, GL_UNSIGNED_INT, &stencil); } + else if(fmt == GL_RGBA16UI) + { + uint16_t green[] = {0, 127, 0, 1}; + for(GLint m = 0; m < mips; m++) + glClearTexImage(t, m, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, &green); + } + else if(fmt == GL_RGBA16I) + { + uint16_t green[] = {0, 127, 0, 1}; + for(GLint m = 0; m < mips; m++) + glClearTexImage(t, m, GL_RGBA_INTEGER, GL_SHORT, &green); + } else { Vec4f green(0.0f, 1.0f, 0.0f, 1.0f); @@ -328,6 +340,10 @@ RD_TEST(GL_Discard_Zoo, OpenGLGraphicsTest) Invalidate(tex); TEX_TEST("DiscardAll", MakeTex2DMS(GL_RGBA16F, 300, 300, 4, 5)); Invalidate(tex); + TEX_TEST("DiscardAll", MakeTex2DMS(GL_RGBA16UI, 300, 300, 4, 5)); + Invalidate(tex); + TEX_TEST("DiscardAll", MakeTex2DMS(GL_RGBA16I, 300, 300, 4, 5)); + Invalidate(tex); // test depth textures TEX_TEST("DiscardAll", MakeTex2D(GL_DEPTH_COMPONENT32F, 300, 300)); diff --git a/util/test/demos/vk/vk_discard_zoo.cpp b/util/test/demos/vk/vk_discard_zoo.cpp index f0a406b98..282e7aa1a 100644 --- a/util/test/demos/vk/vk_discard_zoo.cpp +++ b/util/test/demos/vk/vk_discard_zoo.cpp @@ -417,6 +417,10 @@ RD_TEST(VK_Discard_Zoo, VulkanGraphicsTest) DiscardImage(cmd, tex); TEX_TEST("DiscardAll", MakeTex2DMS(VK_FORMAT_R16G16B16A16_SFLOAT, 300, 300, 4, 5)); DiscardImage(cmd, tex); + TEX_TEST("DiscardAll", MakeTex2DMS(VK_FORMAT_R16G16B16A16_UINT, 300, 300, 4, 5)); + DiscardImage(cmd, tex); + TEX_TEST("DiscardAll", MakeTex2DMS(VK_FORMAT_R16G16B16A16_SINT, 300, 300, 4, 5)); + DiscardImage(cmd, tex); // test depth textures if(d32) diff --git a/util/test/rdtest/shared/Discard_Zoo.py b/util/test/rdtest/shared/Discard_Zoo.py index d6d6d2985..a6de43a89 100644 --- a/util/test/rdtest/shared/Discard_Zoo.py +++ b/util/test/rdtest/shared/Discard_Zoo.py @@ -40,7 +40,7 @@ class Discard_Zoo(rdtest.TestCase): elif fmt.type == rd.ResourceFormatType.BC6: maxval = 996.0 elif fmt.type == rd.ResourceFormatType.R10G10B10A2 and fmt.compType == rd.CompType.UInt: - maxval = [1023.0, 1023.0, 1023.0, 3.0] + maxval = [127.0, 127.0, 127.0, 3.0] elif fmt.type in [rd.ResourceFormatType.D16S8, rd.ResourceFormatType.D24S8, rd.ResourceFormatType.D32S8]: maxval = 1.0 fmt.compCount = 2 @@ -57,6 +57,8 @@ class Discard_Zoo(rdtest.TestCase): fmt.compCount = 2 elif fmt.compType == rd.CompType.UNorm or fmt.compType == rd.CompType.Depth: maxval = 1.0 + elif fmt.compType == rd.CompType.UInt or fmt.compType == rd.CompType.SInt: + maxval = 127.0 # ignore alpha in BC1 and BC6 if fmt.type == rd.ResourceFormatType.BC1 or fmt.type == rd.ResourceFormatType.BC6: