Skip to content

Commit

Permalink
Rework rtv/dsv descriptor management and support cubemaps
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Sep 21, 2024
1 parent 7c480fa commit a2aa227
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const kope_g5_render_pass_parameters *parameters) {
list->d3d12.compute_pipeline_set = false;

D3D12_CPU_DESCRIPTOR_HANDLE render_target_views[8] = {0};
D3D12_CPU_DESCRIPTOR_HANDLE render_target_views = list->d3d12.rtv_descriptors->GetCPUDescriptorHandleForHeapStart();

for (size_t render_target_index = 0; render_target_index < parameters->color_attachments_count; ++render_target_index) {
kope_g5_texture *render_target = parameters->color_attachments[render_target_index].texture;
Expand All @@ -35,13 +35,24 @@ void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const
render_target->d3d12.resource_state = D3D12_RESOURCE_STATE_RENDER_TARGET;
}

D3D12_CPU_DESCRIPTOR_HANDLE rtv = list->d3d12.device->all_rtvs->GetCPUDescriptorHandleForHeapStart();
rtv.ptr += render_target->d3d12.rtv_index * list->d3d12.device->rtv_increment;
D3D12_RENDER_TARGET_VIEW_DESC desc = {};
desc.Format = DXGI_FORMAT_UNKNOWN;
if (parameters->color_attachments[render_target_index].depth_slice != 0) {
desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
desc.Texture2DArray.FirstArraySlice = parameters->color_attachments[render_target_index].depth_slice;
desc.Texture2DArray.ArraySize = 1;
}
else {
desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
}

D3D12_CPU_DESCRIPTOR_HANDLE render_target_view = render_target_views;
render_target_view.ptr += render_target_index * list->d3d12.rtv_increment;

render_target_views[render_target_index] = rtv;
list->d3d12.device->device->CreateRenderTargetView(render_target->d3d12.resource, &desc, render_target_view);
}

D3D12_CPU_DESCRIPTOR_HANDLE depth_stencil_view = {0};
D3D12_CPU_DESCRIPTOR_HANDLE depth_stencil_view = list->d3d12.dsv_descriptor->GetCPUDescriptorHandleForHeapStart();

if (parameters->depth_stencil_attachment.texture != NULL) {
kope_g5_texture *render_target = parameters->depth_stencil_attachment.texture;
Expand All @@ -64,16 +75,19 @@ void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const
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;
D3D12_DEPTH_STENCIL_VIEW_DESC desc = {};
desc.Format = (DXGI_FORMAT)render_target->d3d12.format;
desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;

depth_stencil_view = dsv;
list->d3d12.device->device->CreateDepthStencilView(render_target->d3d12.resource, &desc, depth_stencil_view);
}

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);
list->d3d12.list->OMSetRenderTargets((UINT)parameters->color_attachments_count, &render_target_views, TRUE, &depth_stencil_view);
}
else {
list->d3d12.list->OMSetRenderTargets((UINT)parameters->color_attachments_count, &render_target_views, TRUE, nullptr);
}
}
else if (parameters->depth_stencil_attachment.texture != NULL) {
Expand Down Expand Up @@ -102,9 +116,12 @@ void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const

for (size_t render_target_index = 0; render_target_index < parameters->color_attachments_count; ++render_target_index) {
if (parameters->color_attachments[render_target_index].load_op == KOPE_G5_LOAD_OP_CLEAR) {
D3D12_CPU_DESCRIPTOR_HANDLE render_target_view = render_target_views;
render_target_view.ptr += render_target_index * list->d3d12.rtv_increment;

FLOAT color[4];
memcpy(color, &parameters->color_attachments[render_target_index].clear_value, sizeof(color));
list->d3d12.list->ClearRenderTargetView(render_target_views[render_target_index], color, 0, NULL);
list->d3d12.list->ClearRenderTargetView(render_target_view, color, 0, NULL);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ typedef struct kope_d3d12_command_list {
struct ID3D12Fence *fence;
HANDLE event;

struct ID3D12DescriptorHeap *rtv_descriptors;
uint32_t rtv_increment;

struct ID3D12DescriptorHeap *dsv_descriptor;
uint32_t dsv_increment;

// set when a framebuffer is attached to a render-pass so we don't render into it during scan-out
uint64_t blocking_frame_index;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,30 @@ void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope
device->d3d12.device->CreateShaderResourceView(texture->d3d12.resource, &desc, descriptor_handle);
}

void kope_d3d12_descriptor_set_set_texture_cube_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t index) {
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {};
desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;

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;

D3D12_CPU_DESCRIPTOR_HANDLE descriptor_handle = device->d3d12.descriptor_heap->GetCPUDescriptorHandleForHeapStart();
descriptor_handle.ptr += (set->descriptor_allocation.offset + index) * device->d3d12.cbv_srv_uav_increment;
device->d3d12.device->CreateShaderResourceView(texture->d3d12.resource, &desc, descriptor_handle);
}

void kope_d3d12_descriptor_set_set_texture_view_uav(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t index) {
D3D12_UNORDERED_ACCESS_VIEW_DESC desc = {};
desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ void kope_d3d12_descriptor_set_set_buffer_view_cbv(kope_g5_device *device, kope_
void kope_d3d12_descriptor_set_set_buffer_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_buffer *buffer, uint32_t index);
void kope_d3d12_descriptor_set_set_bvh_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_raytracing_hierarchy *bvh, uint32_t index);
void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t index);
void kope_d3d12_descriptor_set_set_texture_cube_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t index);
void kope_d3d12_descriptor_set_set_texture_view_uav(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t index);
void kope_d3d12_descriptor_set_set_sampler(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_sampler *sampler, uint32_t index);

Expand Down
131 changes: 26 additions & 105 deletions Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ static void __stdcall myValidationMessageCallback(void *pUserData, NVAPI_D3D12_R
}
#endif

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
ID3D12Debug *debug = NULL;
Expand Down Expand Up @@ -81,30 +79,6 @@ void kope_d3d12_device_create(kope_g5_device *device, const kope_g5_device_wishl
device->d3d12.cbv_srv_uav_increment = device->d3d12.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
device->d3d12.sampler_increment = device->d3d12.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);

{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.NumDescriptors = KOPE_INDEX_ALLOCATOR_SIZE;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
kinc_microsoft_affirm(device->d3d12.device->CreateDescriptorHeap(&desc, IID_GRAPHICS_PPV_ARGS(&device->d3d12.all_rtvs)));

kope_index_allocator_init(&device->d3d12.rtv_index_allocator);

device->d3d12.rtv_increment = device->d3d12.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
}

{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.NumDescriptors = KOPE_INDEX_ALLOCATOR_SIZE;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
kinc_microsoft_affirm(device->d3d12.device->CreateDescriptorHeap(&desc, IID_GRAPHICS_PPV_ARGS(&device->d3d12.all_dsvs)));

kope_index_allocator_init(&device->d3d12.dsv_index_allocator);

device->d3d12.dsv_increment = device->d3d12.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
}

{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.NumDescriptors = KOPE_INDEX_ALLOCATOR_SIZE;
Expand All @@ -131,8 +105,6 @@ void kope_d3d12_device_create(kope_g5_device *device, const kope_g5_device_wishl
parameters.usage = KONG_G5_TEXTURE_USAGE_RENDER_ATTACHMENT;

device->d3d12.framebuffer_textures[i].d3d12.resource_state = D3D12_RESOURCE_STATE_PRESENT;

create_render_target_views(device, &parameters, &device->d3d12.framebuffer_textures[i]);
}

device->d3d12.framebuffer_index = 0;
Expand Down Expand Up @@ -270,6 +242,26 @@ void kope_d3d12_device_create_command_list(kope_g5_device *device, kope_g5_comma

list->d3d12.ray_pipe = NULL;

{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.NumDescriptors = D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
kinc_microsoft_affirm(device->d3d12.device->CreateDescriptorHeap(&desc, IID_GRAPHICS_PPV_ARGS(&list->d3d12.rtv_descriptors)));

list->d3d12.rtv_increment = device->d3d12.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
}

{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.NumDescriptors = 1;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
kinc_microsoft_affirm(device->d3d12.device->CreateDescriptorHeap(&desc, IID_GRAPHICS_PPV_ARGS(&list->d3d12.dsv_descriptor)));

list->d3d12.dsv_increment = device->d3d12.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
}

list->d3d12.blocking_frame_index = 0;

list->d3d12.presenting = false;
Expand Down Expand Up @@ -385,75 +377,6 @@ static D3D12_RESOURCE_DIMENSION convert_texture_dimension(kope_g5_texture_dimens
return D3D12_RESOURCE_DIMENSION_TEXTURE2D;
}

static D3D12_RTV_DIMENSION convert_texture_rtv_dimension(kope_g5_texture_dimension dimension) {
switch (dimension) {
case KOPE_G5_TEXTURE_DIMENSION_1D:
return D3D12_RTV_DIMENSION_TEXTURE1D;
case KOPE_G5_TEXTURE_DIMENSION_2D:
return D3D12_RTV_DIMENSION_TEXTURE2D;
case KOPE_G5_TEXTURE_DIMENSION_3D:
return D3D12_RTV_DIMENSION_TEXTURE3D;
}

assert(false);
return D3D12_RTV_DIMENSION_TEXTURE2D;

// D3D12_RTV_DIMENSION_TEXTURE1D = 2, D3D12_RTV_DIMENSION_TEXTURE1DARRAY = 3, D3D12_RTV_DIMENSION_TEXTURE2D = 4, D3D12_RTV_DIMENSION_TEXTURE2DARRAY = 5,
// D3D12_RTV_DIMENSION_TEXTURE2DMS = 6, D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY = 7, D3D12_RTV_DIMENSION_TEXTURE3D = 8
}

static D3D12_DSV_DIMENSION convert_texture_dsv_dimension(kope_g5_texture_dimension dimension) {
switch (dimension) {
case KOPE_G5_TEXTURE_DIMENSION_1D:
return D3D12_DSV_DIMENSION_TEXTURE1D;
case KOPE_G5_TEXTURE_DIMENSION_2D:
return D3D12_DSV_DIMENSION_TEXTURE2D;
case KOPE_G5_TEXTURE_DIMENSION_3D:
assert(false);
return D3D12_DSV_DIMENSION_TEXTURE2D;
}

assert(false);
return D3D12_DSV_DIMENSION_TEXTURE2D;

// D3D12_DSV_DIMENSION_UNKNOWN = 0, D3D12_DSV_DIMENSION_TEXTURE1D = 1, D3D12_DSV_DIMENSION_TEXTURE1DARRAY = 2, D3D12_DSV_DIMENSION_TEXTURE2D = 3,
// D3D12_DSV_DIMENSION_TEXTURE2DARRAY = 4, D3D12_DSV_DIMENSION_TEXTURE2DMS = 5, D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY = 6
}

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;
texture->d3d12.dsv_index = 0xffffffff;

if (parameters->usage & KONG_G5_TEXTURE_USAGE_RENDER_ATTACHMENT) {
if (kope_g5_texture_format_is_depth(parameters->format)) {
texture->d3d12.dsv_index = kope_index_allocator_allocate(&device->d3d12.dsv_index_allocator);

D3D12_DEPTH_STENCIL_VIEW_DESC desc = {};
desc.Format = format;
desc.ViewDimension = convert_texture_dsv_dimension(parameters->dimension);

D3D12_CPU_DESCRIPTOR_HANDLE dsv = device->d3d12.all_dsvs->GetCPUDescriptorHandleForHeapStart();
dsv.ptr += texture->d3d12.dsv_index * device->d3d12.dsv_increment;

device->d3d12.device->CreateDepthStencilView(texture->d3d12.resource, &desc, dsv);
}
else {
texture->d3d12.rtv_index = kope_index_allocator_allocate(&device->d3d12.rtv_index_allocator);

D3D12_RENDER_TARGET_VIEW_DESC desc = {};
desc.Format = format;
desc.ViewDimension = convert_texture_rtv_dimension(parameters->dimension);

D3D12_CPU_DESCRIPTOR_HANDLE rtv = device->d3d12.all_rtvs->GetCPUDescriptorHandleForHeapStart();
rtv.ptr += texture->d3d12.rtv_index * device->d3d12.rtv_increment;

device->d3d12.device->CreateRenderTargetView(texture->d3d12.resource, &desc, rtv);
}
}
}

void kope_d3d12_device_create_texture(kope_g5_device *device, const kope_g5_texture_parameters *parameters, kope_g5_texture *texture) {
DXGI_FORMAT format = convert_texture_format(parameters->format);

Expand Down Expand Up @@ -483,17 +406,17 @@ void kope_d3d12_device_create_texture(kope_g5_device *device, const kope_g5_text
if ((parameters->usage & KONG_G5_TEXTURE_USAGE_RENDER_ATTACHMENT) != 0) {
if (kope_g5_texture_format_is_depth(parameters->format)) {
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
optimizedClearValue.DepthStencil.Depth = 1.0f;
optimizedClearValue.DepthStencil.Stencil = 0;
}
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.Color[0] = 0.0f;
optimizedClearValue.Color[1] = 0.0f;
optimizedClearValue.Color[2] = 0.0f;
optimizedClearValue.Color[3] = 1.0f;
optimizedClearValue.DepthStencil.Depth = 1.0f;
optimizedClearValue.DepthStencil.Stencil = 0;
optimizedClearValue.Format = format;

optimizedClearValuePointer = &optimizedClearValue;
Expand All @@ -514,8 +437,6 @@ void kope_d3d12_device_create_texture(kope_g5_device *device, const kope_g5_text
texture->d3d12.height = parameters->height;

texture->d3d12.in_flight_frame_index = 0;

create_render_target_views(device, parameters, texture);
}

kope_g5_texture *kope_d3d12_device_get_framebuffer(kope_g5_device *device) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,6 @@ typedef struct kope_d3d12_device {
struct ID3D12CommandQueue *queue;
struct IDXGISwapChain *swap_chain;

struct ID3D12DescriptorHeap *all_rtvs;
kope_index_allocator rtv_index_allocator;
uint32_t rtv_increment;

struct ID3D12DescriptorHeap *all_dsvs;
kope_index_allocator dsv_index_allocator;
uint32_t dsv_increment;

uint32_t cbv_srv_uav_increment;
uint32_t sampler_increment;

Expand Down

0 comments on commit a2aa227

Please sign in to comment.