From b030588669adf5df68b8d69685d148194626db81 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Tue, 6 Feb 2018 14:54:09 +0100 Subject: [PATCH] (D3D12) refactor d3d12_init_samplers, add support for wrap modes. --- gfx/common/d3d12_common.c | 91 +++++++++++++++++++++++---------------- gfx/common/d3d12_common.h | 28 ++++++++---- gfx/drivers/d3d12.c | 28 +++++++----- 3 files changed, 91 insertions(+), 56 deletions(-) diff --git a/gfx/common/d3d12_common.c b/gfx/common/d3d12_common.c index 030db4c7e1..678e73d782 100644 --- a/gfx/common/d3d12_common.c +++ b/gfx/common/d3d12_common.c @@ -260,24 +260,6 @@ static void d3d12_init_descriptor_heap(D3D12Device device, d3d12_descriptor_heap out->stride = D3D12GetDescriptorHandleIncrementSize(device, out->desc.Type); } -static void d3d12_init_sampler( - D3D12Device device, - d3d12_descriptor_heap_t* heap, - descriptor_heap_slot_t heap_index, - D3D12_FILTER filter, - D3D12_TEXTURE_ADDRESS_MODE address_mode, - D3D12_GPU_DESCRIPTOR_HANDLE* dst) -{ - D3D12_SAMPLER_DESC sampler_desc = { filter, address_mode, address_mode, address_mode }; - D3D12_CPU_DESCRIPTOR_HANDLE handle = { heap->cpu.ptr + heap_index * heap->stride }; - - sampler_desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; - sampler_desc.MaxLOD = D3D12_FLOAT32_MAX; - - D3D12CreateSampler(device, &sampler_desc, handle); - dst->ptr = heap->gpu.ptr + heap_index * heap->stride; -} - bool d3d12_init_descriptors(d3d12_video_t* d3d12) { D3D12_ROOT_SIGNATURE_DESC desc; @@ -354,23 +336,58 @@ bool d3d12_init_descriptors(d3d12_video_t* d3d12) d3d12_init_descriptor_heap(d3d12->device, &d3d12->pipe.srv_heap); d3d12->pipe.sampler_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - d3d12->pipe.sampler_heap.desc.NumDescriptors = SAMPLER_HEAP_SLOT_MAX; + d3d12->pipe.sampler_heap.desc.NumDescriptors = 2 * RARCH_WRAP_MAX; d3d12->pipe.sampler_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; d3d12_init_descriptor_heap(d3d12->device, &d3d12->pipe.sampler_heap); - d3d12_init_sampler( - d3d12->device, &d3d12->pipe.sampler_heap, SAMPLER_HEAP_SLOT_LINEAR, - D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_BORDER, - &d3d12->sampler_linear); - d3d12_init_sampler( - d3d12->device, &d3d12->pipe.sampler_heap, SAMPLER_HEAP_SLOT_NEAREST, - D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_BORDER, - &d3d12->sampler_nearest); return true; } -D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_enable_desc = +void d3d12_init_samplers(d3d12_video_t* d3d12) { + int i; + D3D12_SAMPLER_DESC desc = { D3D12_FILTER_MIN_MAG_MIP_POINT }; + desc.MaxAnisotropy = 1; + desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; + desc.MinLOD = -D3D12_FLOAT32_MAX; + desc.MaxLOD = D3D12_FLOAT32_MAX; + + for (i = 0; i < RARCH_WRAP_MAX; i++) + { + switch (i) + { + case RARCH_WRAP_BORDER: + desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER; + break; + + case RARCH_WRAP_EDGE: + desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + break; + + case RARCH_WRAP_REPEAT: + desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + break; + + case RARCH_WRAP_MIRRORED_REPEAT: + desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_MIRROR; + break; + } + desc.AddressV = desc.AddressU; + desc.AddressW = desc.AddressU; + + desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + d3d12->samplers[RARCH_FILTER_LINEAR][i] = d3d12_create_sampler( + d3d12->device, &desc, &d3d12->pipe.sampler_heap, + 0 * RARCH_WRAP_MAX + i); + + desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + d3d12->samplers[RARCH_FILTER_NEAREST][i] = d3d12_create_sampler( + d3d12->device, &desc, &d3d12->pipe.sampler_heap, + 1 * RARCH_WRAP_MAX + i); + } +} + +D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_enable_desc = { TRUE, FALSE, D3D12_BLEND_SRC_ALPHA, @@ -391,22 +408,22 @@ bool d3d12_init_pipeline( D3D12_GRAPHICS_PIPELINE_STATE_DESC* desc, D3D12PipelineState* out) { - if(vs_code) + if (vs_code) { - desc->VS.pShaderBytecode = D3DGetBufferPointer(vs_code); - desc->VS.BytecodeLength = D3DGetBufferSize(vs_code); + desc->VS.pShaderBytecode = D3DGetBufferPointer(vs_code); + desc->VS.BytecodeLength = D3DGetBufferSize(vs_code); } - if(ps_code) + if (ps_code) { - desc->PS.pShaderBytecode = D3DGetBufferPointer(ps_code); - desc->PS.BytecodeLength = D3DGetBufferSize(ps_code); + desc->PS.pShaderBytecode = D3DGetBufferPointer(ps_code); + desc->PS.BytecodeLength = D3DGetBufferSize(ps_code); } - if(gs_code) + if (gs_code) { - desc->GS.pShaderBytecode = D3DGetBufferPointer(gs_code); - desc->GS.BytecodeLength = D3DGetBufferSize(gs_code); + desc->GS.pShaderBytecode = D3DGetBufferPointer(gs_code); + desc->GS.BytecodeLength = D3DGetBufferSize(gs_code); } desc->SampleMask = UINT_MAX; diff --git a/gfx/common/d3d12_common.h b/gfx/common/d3d12_common.h index 4eb0c9055a..6db62700fb 100644 --- a/gfx/common/d3d12_common.h +++ b/gfx/common/d3d12_common.h @@ -1279,6 +1279,7 @@ typedef struct D3D12Resource upload_buffer; D3D12_RESOURCE_DESC desc; D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor; + D3D12_GPU_DESCRIPTOR_HANDLE sampler; D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout; UINT num_rows; UINT64 row_size_in_bytes; @@ -1331,7 +1332,6 @@ typedef struct D3D12Resource vbo; D3D12_VERTEX_BUFFER_VIEW vbo_view; d3d12_texture_t texture; - D3D12_GPU_DESCRIPTOR_HANDLE sampler; D3D12_VIEWPORT viewport; D3D12_RECT scissorRect; int rotation; @@ -1342,7 +1342,6 @@ typedef struct D3D12Resource vbo; D3D12_VERTEX_BUFFER_VIEW vbo_view; d3d12_texture_t texture; - D3D12_GPU_DESCRIPTOR_HANDLE sampler; float alpha; bool enabled; @@ -1352,8 +1351,7 @@ typedef struct D3D12Resource ubo; D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view; DXGI_FORMAT format; - D3D12_GPU_DESCRIPTOR_HANDLE sampler_linear; - D3D12_GPU_DESCRIPTOR_HANDLE sampler_nearest; + D3D12_GPU_DESCRIPTOR_HANDLE samplers[RARCH_FILTER_MAX][RARCH_WRAP_MAX]; math_matrix_4x4 mvp, mvp_no_rot; struct video_viewport vp; bool resize_chain; @@ -1374,10 +1372,6 @@ typedef enum } root_signature_parameter_index_t; typedef enum { - SAMPLER_HEAP_SLOT_LINEAR = 0, - SAMPLER_HEAP_SLOT_NEAREST, - SAMPLER_HEAP_SLOT_MAX, - SRV_HEAP_SLOT_FRAME_TEXTURE = 0, SRV_HEAP_SLOT_MENU_TEXTURE, SRV_HEAP_SLOT_CUSTOM, @@ -1391,6 +1385,7 @@ extern D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_enable_desc; bool d3d12_init_base(d3d12_video_t* d3d12); bool d3d12_init_descriptors(d3d12_video_t* d3d12); +void d3d12_init_samplers(d3d12_video_t* d3d12); bool d3d12_init_pipeline( D3D12Device device, @@ -1449,6 +1444,12 @@ d3d12_set_sampler(D3D12GraphicsCommandList cmd, D3D12_GPU_DESCRIPTOR_HANDLE samp D3D12SetGraphicsRootDescriptorTable(cmd, ROOT_ID_SAMPLER_T, sampler); } +static INLINE void d3d12_set_texture_and_sampler(D3D12GraphicsCommandList cmd, const d3d12_texture_t* texture) +{ + D3D12SetGraphicsRootDescriptorTable(cmd, ROOT_ID_TEXTURE_T, texture->gpu_descriptor); + D3D12SetGraphicsRootDescriptorTable(cmd, ROOT_ID_SAMPLER_T, texture->sampler); +} + static INLINE void d3d12_update_texture( int width, int height, @@ -1478,6 +1479,17 @@ d3d12_get_closest_match_texture2D(D3D12Device device, DXGI_FORMAT desired_format device, desired_format, D3D12_FORMAT_SUPPORT1_TEXTURE2D | D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE); } + +static INLINE D3D12_GPU_DESCRIPTOR_HANDLE d3d12_create_sampler( + D3D12Device device, D3D12_SAMPLER_DESC* desc, d3d12_descriptor_heap_t* heap, int slot) +{ + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle = {heap->gpu.ptr + slot * heap->stride}; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle = {heap->cpu.ptr + slot * heap->stride}; + + D3D12CreateSampler(device, desc, cpu_handle); + return gpu_handle; +} + #endif RETRO_END_DECLS diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index f240caa754..c1beed26cf 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -30,12 +30,16 @@ static void d3d12_set_filtering(void* data, unsigned index, bool smooth) { + int i; d3d12_video_t* d3d12 = (d3d12_video_t*)data; - if (smooth) - d3d12->frame.sampler = d3d12->sampler_linear; - else - d3d12->frame.sampler = d3d12->sampler_nearest; + for (i = 0; i < RARCH_WRAP_MAX; i++) + { + if (smooth) + d3d12->samplers[RARCH_FILTER_UNSPEC][i] = d3d12->samplers[RARCH_FILTER_LINEAR][i]; + else + d3d12->samplers[RARCH_FILTER_UNSPEC][i] = d3d12->samplers[RARCH_FILTER_NEAREST][i]; + } } static void d3d12_gfx_set_rotation(void* data, unsigned rotation) @@ -155,11 +159,12 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i if (!d3d12_init_swapchain(d3d12, video->width, video->height, main_window.hwnd)) goto error; + d3d12_init_samplers(d3d12); + d3d12_set_filtering(d3d12, 0, video->smooth); + d3d12_create_fullscreen_quad_vbo(d3d12->device, &d3d12->frame.vbo_view, &d3d12->frame.vbo); d3d12_create_fullscreen_quad_vbo(d3d12->device, &d3d12->menu.vbo_view, &d3d12->menu.vbo); - d3d12_set_filtering(d3d12, 0, video->smooth); - d3d12->keep_aspect = video->force_aspect; d3d12->chain.vsync = video->vsync; d3d12->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; @@ -277,7 +282,7 @@ static bool d3d12_gfx_frame( D3D12SetGraphicsRootConstantBufferView( d3d12->queue.cmd, ROOT_ID_UBO, d3d12->frame.ubo_view.BufferLocation); d3d12_set_texture(d3d12->queue.cmd, &d3d12->frame.texture); - d3d12_set_sampler(d3d12->queue.cmd, d3d12->frame.sampler); + d3d12_set_sampler(d3d12->queue.cmd, d3d12->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]); D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->frame.vbo_view); D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0); @@ -295,8 +300,7 @@ static bool d3d12_gfx_frame( D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect); } - d3d12_set_texture(d3d12->queue.cmd, &d3d12->menu.texture); - d3d12_set_sampler(d3d12->queue.cmd, d3d12->menu.sampler); + d3d12_set_texture_and_sampler(d3d12->queue.cmd, &d3d12->menu.texture); D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->menu.vbo_view); D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0); } @@ -462,8 +466,10 @@ static void d3d12_set_menu_texture_frame( v[3].color[3] = alpha; D3D12Unmap(d3d12->menu.vbo, 0, NULL); } - d3d12->menu.sampler = config_get_ptr()->bools.menu_linear_filter ? d3d12->sampler_linear - : d3d12->sampler_nearest; + + d3d12->menu.texture.sampler = config_get_ptr()->bools.menu_linear_filter + ? d3d12->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_DEFAULT] + : d3d12->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT]; } static void d3d12_set_menu_texture_enable(void* data, bool state, bool full_screen) {