From ac5aa0d40cf311896b77d14142dbfb48ef8280f6 Mon Sep 17 00:00:00 2001 From: Caleb Cornett Date: Fri, 9 Feb 2024 16:37:08 -0600 Subject: [PATCH] Do some type shenanigans to allow depth textures to be sampled + fix viewport sizing logic --- src/Refresh_Driver_D3D11.c | 86 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/src/Refresh_Driver_D3D11.c b/src/Refresh_Driver_D3D11.c index 02b1c53..fbd4a65 100644 --- a/src/Refresh_Driver_D3D11.c +++ b/src/Refresh_Driver_D3D11.c @@ -612,6 +612,43 @@ static inline uint32_t D3D11_INTERNAL_NextHighestAlignment( return align * ((n + align - 1) / align); } +static DXGI_FORMAT D3D11_INTERNAL_GetTypelessFormat( + DXGI_FORMAT typedFormat +) { + switch (typedFormat) + { + case DXGI_FORMAT_D16_UNORM: + return DXGI_FORMAT_R16_TYPELESS; + case DXGI_FORMAT_D32_FLOAT: + return DXGI_FORMAT_R32_TYPELESS; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + return DXGI_FORMAT_R24G8_TYPELESS; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + return DXGI_FORMAT_R32G8X24_TYPELESS; + default: + Refresh_LogError("Cannot get typeless DXGI format of format %d", typedFormat); + return 0; + } +} + +static DXGI_FORMAT D3D11_INTERNAL_GetSampleableFormat( + DXGI_FORMAT format +) { + switch (format) + { + case DXGI_FORMAT_R16_TYPELESS: + return DXGI_FORMAT_R16_UNORM; + case DXGI_FORMAT_R32_TYPELESS: + return DXGI_FORMAT_R32_FLOAT; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + default: + return format; + } +} + /* Quit */ static void D3D11_DestroyDevice( @@ -1442,6 +1479,10 @@ static Refresh_Texture* D3D11_CreateTexture( isCompute = textureCreateInfo->usageFlags & REFRESH_TEXTUREUSAGE_COMPUTE_BIT; format = RefreshToD3D11_TextureFormat[textureCreateInfo->format]; + if (isDepthStencil) + { + format = D3D11_INTERNAL_GetTypelessFormat(format); + } if (textureCreateInfo->depth <= 1) { @@ -1489,7 +1530,7 @@ static Refresh_Texture* D3D11_CreateTexture( if (isSampler) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = format; + srvDesc.Format = D3D11_INTERNAL_GetSampleableFormat(format); if (textureCreateInfo->isCube) { @@ -2573,7 +2614,7 @@ static ID3D11DepthStencilView* D3D11_INTERNAL_FetchDSV( D3D11Renderer* renderer, Refresh_DepthStencilAttachmentInfo* info ) { - D3D11Texture *texture = (D3D11Texture*)info->texture; + D3D11Texture *texture = (D3D11Texture*) info->texture; D3D11TargetView *targetView; D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; ID3D11DepthStencilView *dsv; @@ -2648,6 +2689,8 @@ static void D3D11_BeginRenderPass( D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer; float clearColors[4]; D3D11_CLEAR_FLAG dsClearFlags; + uint32_t vpWidth = UINT_MAX; + uint32_t vpHeight = UINT_MAX; D3D11_VIEWPORT viewport; D3D11_RECT scissorRect; @@ -2726,11 +2769,46 @@ static void D3D11_BeginRenderPass( } } + /* The viewport cannot be larger than the smallest attachment. */ + for (uint32_t i = 0; i < colorAttachmentCount; i += 1) + { + D3D11Texture *texture = (D3D11Texture*) colorAttachmentInfos[i].texture; + uint32_t w = texture->width >> colorAttachmentInfos[i].level; + uint32_t h = texture->height >> colorAttachmentInfos[i].level; + + if (w < vpWidth) + { + vpWidth = w; + } + + if (h < vpHeight) + { + vpHeight = h; + } + } + + if (depthStencilAttachmentInfo != NULL) + { + D3D11Texture *texture = (D3D11Texture*) depthStencilAttachmentInfo->texture; + uint32_t w = texture->width >> depthStencilAttachmentInfo->level; + uint32_t h = texture->height >> depthStencilAttachmentInfo->level; + + if (w < vpWidth) + { + vpWidth = w; + } + + if (h < vpHeight) + { + vpHeight = h; + } + } + /* Set default viewport and scissor state */ viewport.TopLeftX = 0; viewport.TopLeftY = 0; - viewport.Width = (float) ((D3D11Texture*) colorAttachmentInfos[0].texture)->width; - viewport.Height = (float) ((D3D11Texture*) colorAttachmentInfos[0].texture)->height; + viewport.Width = (FLOAT) vpWidth; + viewport.Height = (FLOAT) vpHeight; viewport.MinDepth = 0; viewport.MaxDepth = 1;