From 9e666179682d49cc440776edecd589c3dbafdbd5 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Fri, 20 Sep 2024 22:16:46 +0200 Subject: [PATCH] Support depth buffers --- .../Sources/kope/direct3d12/commandlist.cpp | 77 ++++++++++++++++--- .../Sources/kope/direct3d12/descriptorset.cpp | 12 ++- .../Sources/kope/direct3d12/device.cpp | 19 +++-- Sources/kope/graphics5/commandlist.h | 3 +- 4 files changed, 92 insertions(+), 19 deletions(-) diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp index 8ab913a48..9379cecb4 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp @@ -41,19 +41,78 @@ void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const render_target_views[render_target_index] = rtv; } - list->d3d12.list->OMSetRenderTargets((UINT)parameters->color_attachments_count, render_target_views, true, nullptr); + D3D12_CPU_DESCRIPTOR_HANDLE depth_stencil_view = {0}; - D3D12_VIEWPORT viewport = { - 0.0f, 0.0f, (FLOAT)parameters->color_attachments[0].texture->d3d12.width, (FLOAT)parameters->color_attachments[0].texture->d3d12.height, 0.0f, 1.0f}; - list->d3d12.list->RSSetViewports(1, &viewport); + if (parameters->depth_stencil_attachment.texture != NULL) { + kope_g5_texture *render_target = parameters->depth_stencil_attachment.texture; - D3D12_RECT scissor = {0, 0, (LONG)parameters->color_attachments[0].texture->d3d12.width, (LONG)parameters->color_attachments[0].texture->d3d12.height}; - list->d3d12.list->RSSetScissorRects(1, &scissor); + if (render_target->d3d12.in_flight_frame_index > 0) { + list->d3d12.blocking_frame_index = render_target->d3d12.in_flight_frame_index; + } + + if (render_target->d3d12.resource_state != D3D12_RESOURCE_STATE_DEPTH_WRITE) { + D3D12_RESOURCE_BARRIER barrier; + barrier.Transition.pResource = render_target->d3d12.resource; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)render_target->d3d12.resource_state; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_DEPTH_WRITE; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + list->d3d12.list->ResourceBarrier(1, &barrier); + + render_target->d3d12.resource_state = D3D12_RESOURCE_STATE_DEPTH_WRITE; + } + + D3D12_CPU_DESCRIPTOR_HANDLE dsv = list->d3d12.device->all_dsvs->GetCPUDescriptorHandleForHeapStart(); + dsv.ptr += render_target->d3d12.dsv_index * list->d3d12.device->dsv_increment; + + depth_stencil_view = dsv; + } + + if (parameters->color_attachments_count > 0) { + list->d3d12.list->OMSetRenderTargets((UINT)parameters->color_attachments_count, render_target_views, true, nullptr); + if (parameters->depth_stencil_attachment.texture != NULL) { + list->d3d12.list->OMSetRenderTargets((UINT)parameters->color_attachments_count, render_target_views, true, nullptr); + } + } + else if (parameters->depth_stencil_attachment.texture != NULL) { + list->d3d12.list->OMSetRenderTargets(0, NULL, TRUE, &depth_stencil_view); + } + + if (parameters->color_attachments_count > 0) { + D3D12_VIEWPORT viewport = { + 0.0f, 0.0f, (FLOAT)parameters->color_attachments[0].texture->d3d12.width, (FLOAT)parameters->color_attachments[0].texture->d3d12.height, + 0.0f, 1.0f}; + list->d3d12.list->RSSetViewports(1, &viewport); + + D3D12_RECT scissor = {0, 0, (LONG)parameters->color_attachments[0].texture->d3d12.width, (LONG)parameters->color_attachments[0].texture->d3d12.height}; + list->d3d12.list->RSSetScissorRects(1, &scissor); + } + else if (parameters->depth_stencil_attachment.texture != NULL) { + D3D12_VIEWPORT viewport = { + 0.0f, 0.0f, (FLOAT)parameters->depth_stencil_attachment.texture->d3d12.width, (FLOAT)parameters->depth_stencil_attachment.texture->d3d12.height, + 0.0f, 1.0f}; + list->d3d12.list->RSSetViewports(1, &viewport); + + D3D12_RECT scissor = {0, 0, (LONG)parameters->depth_stencil_attachment.texture->d3d12.width, + (LONG)parameters->depth_stencil_attachment.texture->d3d12.height}; + list->d3d12.list->RSSetScissorRects(1, &scissor); + } for (size_t render_target_index = 0; render_target_index < parameters->color_attachments_count; ++render_target_index) { - FLOAT color[4]; - memcpy(color, ¶meters->color_attachments[render_target_index].clear_value, sizeof(color)); - list->d3d12.list->ClearRenderTargetView(render_target_views[render_target_index], color, 0, NULL); + if (parameters->color_attachments[render_target_index].load_op == KOPE_G5_LOAD_OP_CLEAR) { + FLOAT color[4]; + memcpy(color, ¶meters->color_attachments[render_target_index].clear_value, sizeof(color)); + list->d3d12.list->ClearRenderTargetView(render_target_views[render_target_index], color, 0, NULL); + } + } + + if (parameters->depth_stencil_attachment.texture != NULL) { + if (parameters->depth_stencil_attachment.depth_load_op == KOPE_G5_LOAD_OP_CLEAR) { + list->d3d12.list->ClearDepthStencilView(depth_stencil_view, D3D12_CLEAR_FLAG_DEPTH, parameters->depth_stencil_attachment.depth_clear_value, 0, 0, + NULL); + } } } diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp index 1eeab7984..65e066f53 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp @@ -44,7 +44,17 @@ void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope D3D12_SHADER_RESOURCE_VIEW_DESC desc = {}; desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - desc.Format = (DXGI_FORMAT)texture->d3d12.format; + + DXGI_FORMAT format = (DXGI_FORMAT)texture->d3d12.format; + switch (format) { + case DXGI_FORMAT_D16_UNORM: + desc.Format = DXGI_FORMAT_R16_UNORM; + break; + default: + desc.Format = format; + break; + } + desc.Texture2D.MipLevels = 1; desc.Texture2D.MostDetailedMip = 0; desc.Texture2D.ResourceMinLODClamp = 0.0f; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp index c3232afda..1ad70659d 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp @@ -33,7 +33,7 @@ static void __stdcall myValidationMessageCallback(void *pUserData, NVAPI_D3D12_R } #endif -static void create_texture_views(kope_g5_device *device, const kope_g5_texture_parameters *parameters, kope_g5_texture *texture); +static void create_render_target_views(kope_g5_device *device, const kope_g5_texture_parameters *parameters, kope_g5_texture *texture); void kope_d3d12_device_create(kope_g5_device *device, const kope_g5_device_wishlist *wishlist) { #ifndef NDEBUG @@ -129,7 +129,7 @@ void kope_d3d12_device_create(kope_g5_device *device, const kope_g5_device_wishl device->d3d12.framebuffer_textures[i].d3d12.resource_state = D3D12_RESOURCE_STATE_PRESENT; - create_texture_views(device, ¶meters, &device->d3d12.framebuffer_textures[i]); + create_render_target_views(device, ¶meters, &device->d3d12.framebuffer_textures[i]); } device->d3d12.framebuffer_index = 0; @@ -417,7 +417,7 @@ static D3D12_DSV_DIMENSION convert_texture_dsv_dimension(kope_g5_texture_dimensi // D3D12_DSV_DIMENSION_TEXTURE2DARRAY = 4, D3D12_DSV_DIMENSION_TEXTURE2DMS = 5, D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY = 6 } -static void create_texture_views(kope_g5_device *device, const kope_g5_texture_parameters *parameters, kope_g5_texture *texture) { +static void create_render_target_views(kope_g5_device *device, const kope_g5_texture_parameters *parameters, kope_g5_texture *texture) { DXGI_FORMAT format = convert_texture_format(parameters->format); texture->d3d12.rtv_index = 0xffffffff; @@ -432,7 +432,7 @@ static void create_texture_views(kope_g5_device *device, const kope_g5_texture_p desc.ViewDimension = convert_texture_dsv_dimension(parameters->dimension); D3D12_CPU_DESCRIPTOR_HANDLE dsv = device->d3d12.all_dsvs->GetCPUDescriptorHandleForHeapStart(); - dsv.ptr += texture->d3d12.rtv_index * device->d3d12.dsv_increment; + dsv.ptr += texture->d3d12.dsv_index * device->d3d12.dsv_increment; device->d3d12.device->CreateDepthStencilView(texture->d3d12.resource, &desc, dsv); } @@ -478,13 +478,18 @@ void kope_d3d12_device_create_texture(kope_g5_device *device, const kope_g5_text D3D12_CLEAR_VALUE *optimizedClearValuePointer = NULL; if ((parameters->usage & KONG_G5_TEXTURE_USAGE_RENDER_ATTACHMENT) != 0) { - desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + if (kope_g5_texture_format_is_depth(parameters->format)) { + desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + } + else { + desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + } optimizedClearValue.Color[0] = 0.0f; optimizedClearValue.Color[1] = 0.0f; optimizedClearValue.Color[2] = 0.0f; optimizedClearValue.Color[3] = 1.0f; - optimizedClearValue.DepthStencil.Depth = 0.0f; + optimizedClearValue.DepthStencil.Depth = 1.0f; optimizedClearValue.DepthStencil.Stencil = 0; optimizedClearValue.Format = format; @@ -507,7 +512,7 @@ void kope_d3d12_device_create_texture(kope_g5_device *device, const kope_g5_text texture->d3d12.in_flight_frame_index = 0; - create_texture_views(device, parameters, texture); + create_render_target_views(device, parameters, texture); } kope_g5_texture *kope_d3d12_device_get_framebuffer(kope_g5_device *device) { diff --git a/Sources/kope/graphics5/commandlist.h b/Sources/kope/graphics5/commandlist.h index 94d539739..4872de786 100644 --- a/Sources/kope/graphics5/commandlist.h +++ b/Sources/kope/graphics5/commandlist.h @@ -74,8 +74,7 @@ typedef struct kope_g5_render_pass_depth_stencil_attachment { typedef struct kope_g5_render_pass_parameters { kope_g5_render_pass_color_attachment color_attachments[8]; size_t color_attachments_count; - kope_g5_render_pass_depth_stencil_attachment depth_stencil_attachments[8]; - size_t depth_stencil_attachments_count; + kope_g5_render_pass_depth_stencil_attachment depth_stencil_attachment; // GPUQuerySet occlusionQuerySet; // GPURenderPassTimestampWrites timestampWrites; } kope_g5_render_pass_parameters;