Skip to content

Commit

Permalink
Create samplers properly
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Sep 10, 2024
1 parent bcb31dd commit 9d89cbe
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,75 @@
#include "d3d12unit.h"

#include <kope/graphics5/device.h>

#include <assert.h>

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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
44 changes: 44 additions & 0 deletions Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
30 changes: 3 additions & 27 deletions Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern "C" {
#endif

typedef struct kope_d3d12_sampler {
int nothing;
uint32_t sampler_index;
} kope_d3d12_sampler;

#ifdef __cplusplus
Expand Down
4 changes: 4 additions & 0 deletions Sources/kope/graphics5/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
33 changes: 32 additions & 1 deletion Sources/kope/graphics5/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "api.h"
#include "buffer.h"
#include "commandlist.h"
#include "sampler.h"

#ifdef KOPE_DIRECT3D12
#include <kope/direct3d12/device_structs.h>
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion Sources/kope/graphics5/sampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9d89cbe

Please sign in to comment.