From 9d89cbe49156659eb2e8d0c97fb15a2fb394155e Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Tue, 10 Sep 2024 21:22:41 +0200 Subject: [PATCH] Create samplers properly --- .../Sources/kope/direct3d12/d3d12unit.cpp | 70 +++++++++++++++++++ .../Sources/kope/direct3d12/descriptorset.cpp | 19 ++--- .../Sources/kope/direct3d12/device.cpp | 44 ++++++++++++ .../kope/direct3d12/device_functions.h | 2 + .../Sources/kope/direct3d12/device_structs.h | 3 + .../Sources/kope/direct3d12/pipeline.cpp | 30 +------- .../kope/direct3d12/pipeline_structs.h | 15 +--- .../Sources/kope/direct3d12/sampler_structs.h | 2 +- Sources/kope/graphics5/device.c | 4 ++ Sources/kope/graphics5/device.h | 33 ++++++++- Sources/kope/graphics5/sampler.h | 2 +- 11 files changed, 168 insertions(+), 56 deletions(-) diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/d3d12unit.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/d3d12unit.cpp index 375a4f2b7..f12428b7c 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/d3d12unit.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/d3d12unit.cpp @@ -1,5 +1,75 @@ #include "d3d12unit.h" +#include + +#include + +static D3D12_COMPARISON_FUNC convert_compare_function(kope_g5_compare_function fun) { + switch (fun) { + case KOPE_G5_COMPARE_FUNCTION_NEVER: + return D3D12_COMPARISON_FUNC_NEVER; + case KOPE_G5_COMPARE_FUNCTION_LESS: + return D3D12_COMPARISON_FUNC_LESS; + case KOPE_G5_COMPARE_FUNCTION_EQUAL: + return D3D12_COMPARISON_FUNC_EQUAL; + case KOPE_G5_COMPARE_FUNCTION_LESS_EQUAL: + return D3D12_COMPARISON_FUNC_LESS_EQUAL; + case KOPE_G5_COMPARE_FUNCTION_GREATER: + return D3D12_COMPARISON_FUNC_GREATER; + case KOPE_G5_COMPARE_FUNCTION_NOT_EQUAL: + return D3D12_COMPARISON_FUNC_NOT_EQUAL; + case KOPE_G5_COMPARE_FUNCTION_GREATER_EQUAL: + return D3D12_COMPARISON_FUNC_GREATER_EQUAL; + case KOPE_G5_COMPARE_FUNCTION_ALWAYS: + return D3D12_COMPARISON_FUNC_ALWAYS; + default: + assert(false); + return D3D12_COMPARISON_FUNC_ALWAYS; + } +} + +static D3D12_FILTER convert_filter(kope_g5_filter_mode minification, kope_g5_filter_mode magnification, kope_g5_mipmap_filter_mode mipmap) { + switch (minification) { + case KOPE_G5_FILTER_MODE_NEAREST: + switch (magnification) { + case KOPE_G5_FILTER_MODE_NEAREST: + switch (mipmap) { + case KOPE_G5_MIPMAP_FILTER_MODE_NEAREST: + return D3D12_FILTER_MIN_MAG_MIP_POINT; + case KOPE_G5_MIPMAP_FILTER_MODE_LINEAR: + return D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR; + } + case KOPE_G5_FILTER_MODE_LINEAR: + switch (mipmap) { + case KOPE_G5_MIPMAP_FILTER_MODE_NEAREST: + return D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + case KOPE_G5_MIPMAP_FILTER_MODE_LINEAR: + return D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR; + } + } + case KOPE_G5_FILTER_MODE_LINEAR: + switch (magnification) { + case KOPE_G5_FILTER_MODE_NEAREST: + switch (mipmap) { + case KOPE_G5_MIPMAP_FILTER_MODE_NEAREST: + return D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT; + case KOPE_G5_MIPMAP_FILTER_MODE_LINEAR: + return D3D12_FILTER_MIN_MAG_MIP_LINEAR; + } + case KOPE_G5_FILTER_MODE_LINEAR: + switch (mipmap) { + case KOPE_G5_MIPMAP_FILTER_MODE_NEAREST: + return D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; + case KOPE_G5_MIPMAP_FILTER_MODE_LINEAR: + return D3D12_FILTER_MIN_MAG_MIP_LINEAR; + } + } + } + + assert(false); + return D3D12_FILTER_MIN_MAG_MIP_POINT; +} + #include "buffer.cpp" #include "commandlist.cpp" #include "descriptorset.cpp" diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp index 5085538ff..4c5f388b7 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp @@ -26,18 +26,11 @@ void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope } void kope_d3d12_descriptor_set_set_sampler(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_sampler *sampler, uint32_t index) { - D3D12_SAMPLER_DESC desc = {}; - desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; - desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - desc.MinLOD = 0.0f; - desc.MaxLOD = 1.0f; - desc.MipLODBias = 0.0f; - desc.MaxAnisotropy = 1; - desc.ComparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; + D3D12_CPU_DESCRIPTOR_HANDLE src_handle = device->d3d12.all_samplers->GetCPUDescriptorHandleForHeapStart(); + src_handle.ptr += sampler->d3d12.sampler_index * device->d3d12.sampler_increment; - D3D12_CPU_DESCRIPTOR_HANDLE descriptor_handle = device->d3d12.sampler_heap->GetCPUDescriptorHandleForHeapStart(); - descriptor_handle.ptr += (set->sampler_allocation.offset + index) * device->d3d12.sampler_increment; - device->d3d12.device->CreateSampler(&desc, descriptor_handle); + D3D12_CPU_DESCRIPTOR_HANDLE dst_handle = device->d3d12.sampler_heap->GetCPUDescriptorHandleForHeapStart(); + dst_handle.ptr += (set->sampler_allocation.offset + index) * device->d3d12.sampler_increment; + + device->d3d12.device->CopyDescriptorsSimple(1, dst_handle, src_handle, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); } diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp index 9c49a6f4e..16bef75e1 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp @@ -78,6 +78,16 @@ void kope_d3d12_device_create(kope_g5_device *device, const kope_g5_device_wishl device->d3d12.dsv_increment = device->d3d12.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); } + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.NumDescriptors = KOPE_INDEX_ALLOCATOR_SIZE; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + kinc_microsoft_affirm(device->d3d12.device->CreateDescriptorHeap(&desc, IID_GRAPHICS_PPV_ARGS(&device->d3d12.all_samplers))); + + kope_index_allocator_init(&device->d3d12.sampler_index_allocator); + } + for (int i = 0; i < KOPE_D3D12_FRAME_COUNT; ++i) { device->d3d12.swap_chain->GetBuffer(i, IID_GRAPHICS_PPV_ARGS(&device->d3d12.framebuffer_textures[i].d3d12.resource)); @@ -502,3 +512,37 @@ void kope_d3d12_device_create_descriptor_set(kope_g5_device *device, uint32_t de } set->sampler_count = sampler_count; } + +static D3D12_TEXTURE_ADDRESS_MODE convert_address_mode(kope_g5_address_mode mode) { + switch (mode) { + case KOPE_G5_ADDRESS_MODE_CLAMP_TO_EDGE: + return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + case KOPE_G5_ADDRESS_MODE_REPEAT: + return D3D12_TEXTURE_ADDRESS_MODE_WRAP; + case KOPE_G5_ADDRESS_MODE_MIRROR_REPEAT: + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR; + default: + assert(false); + return D3D12_TEXTURE_ADDRESS_MODE_WRAP; + } +} + +void kope_d3d12_device_create_sampler(kope_g5_device *device, const kope_g5_sampler_parameters *parameters, kope_g5_sampler *sampler) { + sampler->d3d12.sampler_index = kope_index_allocator_allocate(&device->d3d12.sampler_index_allocator); + + D3D12_SAMPLER_DESC desc = {}; + desc.Filter = + parameters->max_anisotropy > 1 ? D3D12_FILTER_ANISOTROPIC : convert_filter(parameters->min_filter, parameters->mag_filter, parameters->mipmap_filter); + desc.AddressU = convert_address_mode(parameters->address_mode_u); + desc.AddressV = convert_address_mode(parameters->address_mode_v); + desc.AddressW = convert_address_mode(parameters->address_mode_w); + desc.MinLOD = parameters->lod_min_clamp; + desc.MaxLOD = parameters->lod_max_clamp; + desc.MipLODBias = 0.0f; + desc.MaxAnisotropy = parameters->max_anisotropy; + desc.ComparisonFunc = convert_compare_function(parameters->compare); + + D3D12_CPU_DESCRIPTOR_HANDLE descriptor_handle = device->d3d12.all_samplers->GetCPUDescriptorHandleForHeapStart(); + descriptor_handle.ptr += sampler->d3d12.sampler_index * device->d3d12.sampler_increment; + device->d3d12.device->CreateSampler(&desc, descriptor_handle); +} diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h index e3c0e5836..dd9de9f39 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h @@ -23,6 +23,8 @@ void kope_d3d12_device_create_texture(kope_g5_device *device, const kope_g5_text void kope_d3d12_device_create_descriptor_set(kope_g5_device *device, uint32_t descriptor_count, uint32_t sampler_count, kope_d3d12_descriptor_set *set); +void kope_d3d12_device_create_sampler(kope_g5_device *device, const kope_g5_sampler_parameters *parameters, kope_g5_sampler *sampler); + kope_g5_texture *kope_d3d12_device_get_framebuffer(kope_g5_device *device); void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list); diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h index 277c7bba6..3ab69465b 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h @@ -44,6 +44,9 @@ typedef struct kope_d3d12_device { struct ID3D12DescriptorHeap *sampler_heap; oa_allocator_t sampler_heap_allocator; + struct ID3D12DescriptorHeap *all_samplers; + kope_index_allocator sampler_index_allocator; + kope_g5_command_list management_list; } kope_d3d12_device; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline.cpp index 1937d2591..8f1797a87 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline.cpp @@ -71,30 +71,6 @@ static D3D12_CULL_MODE convert_cull_mode(kope_d3d12_cull_mode mode) { } } -static D3D12_COMPARISON_FUNC convert_compare_function(kope_d3d12_compare_function fun) { - switch (fun) { - case KOPE_D3D12_COMPARE_FUNCTION_NEVER: - return D3D12_COMPARISON_FUNC_NEVER; - case KOPE_D3D12_COMPARE_FUNCTION_LESS: - return D3D12_COMPARISON_FUNC_LESS; - case KOPE_D3D12_COMPARE_FUNCTION_EQUAL: - return D3D12_COMPARISON_FUNC_EQUAL; - case KOPE_D3D12_COMPARE_FUNCTION_LESS_EQUAL: - return D3D12_COMPARISON_FUNC_LESS_EQUAL; - case KOPE_D3D12_COMPARE_FUNCTION_GREATER: - return D3D12_COMPARISON_FUNC_GREATER; - case KOPE_D3D12_COMPARE_FUNCTION_NOT_EQUAL: - return D3D12_COMPARISON_FUNC_NOT_EQUAL; - case KOPE_D3D12_COMPARE_FUNCTION_GREATER_EQUAL: - return D3D12_COMPARISON_FUNC_GREATER_EQUAL; - case KOPE_D3D12_COMPARE_FUNCTION_ALWAYS: - return D3D12_COMPARISON_FUNC_ALWAYS; - default: - assert(false); - return D3D12_COMPARISON_FUNC_ALWAYS; - } -} - D3D12_STENCIL_OP convert_stencil_operation(kope_d3d12_stencil_operation operation) { switch (operation) { case KOPE_D3D12_STENCIL_OPERATION_KEEP: @@ -284,15 +260,15 @@ void kope_d3d12_pipeline_init(kope_d3d12_device *device, kope_d3d12_pipeline *pi desc.DSVFormat = convert_texture_format(parameters->depth_stencil.format); - desc.DepthStencilState.DepthEnable = parameters->depth_stencil.depth_compare != KOPE_D3D12_COMPARE_FUNCTION_ALWAYS; + desc.DepthStencilState.DepthEnable = parameters->depth_stencil.depth_compare != KOPE_G5_COMPARE_FUNCTION_ALWAYS; desc.DepthStencilState.DepthWriteMask = parameters->depth_stencil.depth_write_enabled ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; desc.DepthStencilState.DepthFunc = convert_compare_function(parameters->depth_stencil.depth_compare); - desc.DepthStencilState.StencilEnable = parameters->depth_stencil.stencil_front.compare != KOPE_D3D12_COMPARE_FUNCTION_ALWAYS || + desc.DepthStencilState.StencilEnable = parameters->depth_stencil.stencil_front.compare != KOPE_G5_COMPARE_FUNCTION_ALWAYS || parameters->depth_stencil.stencil_front.pass_op != KOPE_D3D12_STENCIL_OPERATION_KEEP || parameters->depth_stencil.stencil_front.fail_op != KOPE_D3D12_STENCIL_OPERATION_KEEP || parameters->depth_stencil.stencil_front.depth_fail_op != KOPE_D3D12_STENCIL_OPERATION_KEEP || - parameters->depth_stencil.stencil_back.compare != KOPE_D3D12_COMPARE_FUNCTION_ALWAYS || + parameters->depth_stencil.stencil_back.compare != KOPE_G5_COMPARE_FUNCTION_ALWAYS || parameters->depth_stencil.stencil_back.pass_op != KOPE_D3D12_STENCIL_OPERATION_KEEP || parameters->depth_stencil.stencil_back.fail_op != KOPE_D3D12_STENCIL_OPERATION_KEEP || parameters->depth_stencil.stencil_back.depth_fail_op != KOPE_D3D12_STENCIL_OPERATION_KEEP; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline_structs.h index 9cbc60225..6639eb9b3 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline_structs.h @@ -94,17 +94,6 @@ typedef struct kope_d3d12_primitive_state { bool unclipped_depth; } kope_d3d12_primitive_state; -typedef enum kope_d3d12_compare_function { - KOPE_D3D12_COMPARE_FUNCTION_NEVER, - KOPE_D3D12_COMPARE_FUNCTION_LESS, - KOPE_D3D12_COMPARE_FUNCTION_EQUAL, - KOPE_D3D12_COMPARE_FUNCTION_LESS_EQUAL, - KOPE_D3D12_COMPARE_FUNCTION_GREATER, - KOPE_D3D12_COMPARE_FUNCTION_NOT_EQUAL, - KOPE_D3D12_COMPARE_FUNCTION_GREATER_EQUAL, - KOPE_D3D12_COMPARE_FUNCTION_ALWAYS -} kope_d3d12_compare_function; - typedef enum kope_d3d12_stencil_operation { KOPE_D3D12_STENCIL_OPERATION_KEEP, KOPE_D3D12_STENCIL_OPERATION_ZERO, @@ -117,7 +106,7 @@ typedef enum kope_d3d12_stencil_operation { } kope_d3d12_stencil_operation; typedef struct kope_d3d12_stencil_face_state { - kope_d3d12_compare_function compare; + kope_g5_compare_function compare; kope_d3d12_stencil_operation fail_op; kope_d3d12_stencil_operation depth_fail_op; kope_d3d12_stencil_operation pass_op; @@ -126,7 +115,7 @@ typedef struct kope_d3d12_stencil_face_state { typedef struct kope_d3d12_depth_stencil_state { kope_g5_texture_format format; bool depth_write_enabled; - kope_d3d12_compare_function depth_compare; + kope_g5_compare_function depth_compare; kope_d3d12_stencil_face_state stencil_front; kope_d3d12_stencil_face_state stencil_back; uint32_t stencil_read_mask; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/sampler_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/sampler_structs.h index ac4f6a5b9..a0fbc9cfc 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/sampler_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/sampler_structs.h @@ -8,7 +8,7 @@ extern "C" { #endif typedef struct kope_d3d12_sampler { - int nothing; + uint32_t sampler_index; } kope_d3d12_sampler; #ifdef __cplusplus diff --git a/Sources/kope/graphics5/device.c b/Sources/kope/graphics5/device.c index 32fc90b01..c522ec0f6 100644 --- a/Sources/kope/graphics5/device.c +++ b/Sources/kope/graphics5/device.c @@ -154,3 +154,7 @@ bool kope_g5_texture_format_is_depth(kope_g5_texture_format format) { } return false; } + +void kope_g5_device_create_sampler(kope_g5_device *device, const kope_g5_sampler_parameters *parameters, kope_g5_sampler *sampler) { + KOPE_G5_CALL3(device_create_sampler, device, parameters, sampler); +} diff --git a/Sources/kope/graphics5/device.h b/Sources/kope/graphics5/device.h index c638e8326..8c5181663 100644 --- a/Sources/kope/graphics5/device.h +++ b/Sources/kope/graphics5/device.h @@ -6,6 +6,7 @@ #include "api.h" #include "buffer.h" #include "commandlist.h" +#include "sampler.h" #ifdef KOPE_DIRECT3D12 #include @@ -129,7 +130,37 @@ KOPE_FUNC void kope_g5_device_create_texture(kope_g5_device *device, const kope_ KOPE_FUNC kope_g5_texture *kope_g5_device_get_framebuffer(kope_g5_device *device); -KOPE_FUNC void kope_g5_device_create_sampler(void *descriptor); +typedef enum kope_g5_address_mode { KOPE_G5_ADDRESS_MODE_CLAMP_TO_EDGE, KOPE_G5_ADDRESS_MODE_REPEAT, KOPE_G5_ADDRESS_MODE_MIRROR_REPEAT } kope_g5_address_mode; + +typedef enum kope_g5_filter_mode { KOPE_G5_FILTER_MODE_NEAREST, KOPE_G5_FILTER_MODE_LINEAR } kope_g5_filter_mode; + +typedef enum kope_g5_mipmap_filter_mode { KOPE_G5_MIPMAP_FILTER_MODE_NEAREST, KOPE_G5_MIPMAP_FILTER_MODE_LINEAR } kope_g5_mipmap_filter_mode; + +typedef enum kope_g5_compare_function { + KOPE_G5_COMPARE_FUNCTION_NEVER, + KOPE_G5_COMPARE_FUNCTION_LESS, + KOPE_G5_COMPARE_FUNCTION_EQUAL, + KOPE_G5_COMPARE_FUNCTION_LESS_EQUAL, + KOPE_G5_COMPARE_FUNCTION_GREATER, + KOPE_G5_COMPARE_FUNCTION_NOT_EQUAL, + KOPE_G5_COMPARE_FUNCTION_GREATER_EQUAL, + KOPE_G5_COMPARE_FUNCTION_ALWAYS +} kope_g5_compare_function; + +typedef struct kope_g5_sampler_parameters { + kope_g5_address_mode address_mode_u; + kope_g5_address_mode address_mode_v; + kope_g5_address_mode address_mode_w; + kope_g5_filter_mode mag_filter; + kope_g5_filter_mode min_filter; + kope_g5_mipmap_filter_mode mipmap_filter; + float lod_min_clamp; + float lod_max_clamp; + kope_g5_compare_function compare; + uint16_t max_anisotropy; +} kope_g5_sampler_parameters; + +KOPE_FUNC void kope_g5_device_create_sampler(kope_g5_device *device, const kope_g5_sampler_parameters *parameters, kope_g5_sampler *sampler); KOPE_FUNC void kope_g5_device_create_command_list(kope_g5_device *device, kope_g5_command_list *list); diff --git a/Sources/kope/graphics5/sampler.h b/Sources/kope/graphics5/sampler.h index 8343d2dd3..cba669a64 100644 --- a/Sources/kope/graphics5/sampler.h +++ b/Sources/kope/graphics5/sampler.h @@ -18,7 +18,7 @@ extern "C" { #endif typedef struct kope_g5_sampler { - KOPE_G5_IMPL(texture); + KOPE_G5_IMPL(sampler); } kope_g5_sampler; #ifdef __cplusplus