diff --git a/gfx/common/d3d12_common.h b/gfx/common/d3d12_common.h index 936d50ff77..0d72221f8c 100644 --- a/gfx/common/d3d12_common.h +++ b/gfx/common/d3d12_common.h @@ -20,6 +20,8 @@ #include "dxgi_common.h" #include +typedef const ID3D12PipelineState* D3D12PipelineStateRef; + /* auto-generated */ typedef ID3D12Object* D3D12Object; @@ -318,9 +320,9 @@ D3D12OMSetStencilRef(D3D12GraphicsCommandList graphics_command_list, UINT stenci graphics_command_list->lpVtbl->OMSetStencilRef(graphics_command_list, stencil_ref); } static INLINE void D3D12SetPipelineState( - D3D12GraphicsCommandList graphics_command_list, D3D12PipelineState pipeline_state) + D3D12GraphicsCommandList graphics_command_list, D3D12PipelineStateRef pipeline_state) { - graphics_command_list->lpVtbl->SetPipelineState(graphics_command_list, pipeline_state); + graphics_command_list->lpVtbl->SetPipelineState(graphics_command_list, (D3D12PipelineState)pipeline_state); } static INLINE void D3D12ResourceBarrier( D3D12GraphicsCommandList graphics_command_list, @@ -1396,7 +1398,9 @@ typedef struct struct { - D3D12PipelineState pipe; + D3D12PipelineStateRef pipe; + D3D12PipelineState pipe_blend; + D3D12PipelineState pipe_noblend; D3D12PipelineState pipe_font; D3D12Resource vbo; D3D12_VERTEX_BUFFER_VIEW vbo_view; diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index b06dbdd8e9..f36dc9039f 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1261,13 +1261,13 @@ static uintptr_t d3d11_gfx_load_texture( texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; /* fallthrough */ case TEXTURE_FILTER_LINEAR: - texture->sampler = d3d11->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_DEFAULT]; + texture->sampler = d3d11->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_EDGE]; break; case TEXTURE_FILTER_MIPMAP_NEAREST: texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; /* fallthrough */ case TEXTURE_FILTER_NEAREST: - texture->sampler = d3d11->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT]; + texture->sampler = d3d11->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_EDGE]; break; } diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index 3798c29890..a59eef879c 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -162,13 +162,18 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12) if (!d3d_compile(shader, sizeof(shader), NULL, "GSMain", "gs_5_0", &gs_code)) goto error; - // desc.BlendState.RenderTarget[0].BlendEnable = false; - desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; - desc.InputLayout.pInputElementDescs = inputElementDesc; - desc.InputLayout.NumElements = countof(inputElementDesc); + desc.BlendState.RenderTarget[0].BlendEnable = false; + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + desc.InputLayout.pInputElementDescs = inputElementDesc; + desc.InputLayout.NumElements = countof(inputElementDesc); if (!d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe)) + d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_noblend)) + goto error; + + desc.BlendState.RenderTarget[0].BlendEnable = true; + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_blend)) goto error; Release(ps_code); @@ -335,7 +340,8 @@ static void d3d12_gfx_free(void* data) font_driver_free_osd(); - Release(d3d12->sprites.vbo); + Release(d3d12->sprites.vbo); + Release(d3d12->menu_pipeline_vbo); Release(d3d12->frame.ubo); Release(d3d12->frame.vbo); @@ -360,7 +366,8 @@ static void d3d12_gfx_free(void* data) for (i = 0; i < GFX_MAX_SHADERS; i++) Release(d3d12->pipes[i]); - Release(d3d12->sprites.pipe); + Release(d3d12->sprites.pipe_blend); + Release(d3d12->sprites.pipe_noblend); Release(d3d12->sprites.pipe_font); Release(d3d12->queue.fence); @@ -602,6 +609,7 @@ static bool d3d12_gfx_frame( D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport); D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect); + d3d12->sprites.pipe = d3d12->sprites.pipe_noblend; D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe); D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_POINTLIST); D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view); @@ -808,12 +816,12 @@ static uintptr_t d3d12_gfx_load_texture( case TEXTURE_FILTER_MIPMAP_LINEAR: /* fallthrough */ case TEXTURE_FILTER_LINEAR: - texture->sampler = d3d12->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_DEFAULT]; + texture->sampler = d3d12->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_EDGE]; break; case TEXTURE_FILTER_MIPMAP_NEAREST: /* fallthrough */ case TEXTURE_FILTER_NEAREST: - texture->sampler = d3d12->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT]; + texture->sampler = d3d12->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_EDGE]; break; } diff --git a/menu/drivers_display/menu_display_d3d11.c b/menu/drivers_display/menu_display_d3d11.c index 111b9befb8..de84203aab 100644 --- a/menu/drivers_display/menu_display_d3d11.c +++ b/menu/drivers_display/menu_display_d3d11.c @@ -50,6 +50,7 @@ static void menu_display_d3d11_viewport(void* data) {} static void menu_display_d3d11_draw(void* data) { + int vertex_count; d3d11_video_t* d3d11 = (d3d11_video_t*)video_driver_get_ptr(false); menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data; @@ -74,57 +75,98 @@ static void menu_display_d3d11_draw(void* data) return; } - if (!d3d11->sprites.enabled) + if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color) + vertex_count = draw->coords->vertices; + else + vertex_count = 1; + + if (!d3d11->sprites.enabled || vertex_count > d3d11->sprites.capacity) return; - if (d3d11->sprites.offset + 1 > d3d11->sprites.capacity) + if (d3d11->sprites.offset + vertex_count > d3d11->sprites.capacity) d3d11->sprites.offset = 0; { D3D11_MAPPED_SUBRESOURCE mapped_vbo; - d3d11_sprite_t* v = NULL; + d3d11_sprite_t* sprite = NULL; D3D11MapBuffer( d3d11->context, d3d11->sprites.vbo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo); - v = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset; + sprite = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset; - v->pos.x = draw->x / (float)d3d11->viewport.Width; - v->pos.y = (d3d11->viewport.Height - draw->y - draw->height) / (float)d3d11->viewport.Height; - v->pos.w = draw->width / (float)d3d11->viewport.Width; - v->pos.h = draw->height / (float)d3d11->viewport.Height; + if (vertex_count == 1) + { + sprite->pos.x = draw->x / (float)d3d11->viewport.Width; + sprite->pos.y = + (d3d11->viewport.Height - draw->y - draw->height) / (float)d3d11->viewport.Height; + sprite->pos.w = draw->width / (float)d3d11->viewport.Width; + sprite->pos.h = draw->height / (float)d3d11->viewport.Height; - v->coords.u = 0.0f; - v->coords.v = 0.0f; - v->coords.w = 1.0f; - v->coords.h = 1.0f; + sprite->coords.u = 0.0f; + sprite->coords.v = 0.0f; + sprite->coords.w = 1.0f; + sprite->coords.h = 1.0f; - if (draw->scale_factor) - v->params.scaling = draw->scale_factor; + if (draw->scale_factor) + sprite->params.scaling = draw->scale_factor; + else + sprite->params.scaling = 1.0f; + + sprite->params.rotation = draw->rotation; + + sprite->colors[3] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1], + 0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]); + sprite->colors[2] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5], + 0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]); + sprite->colors[1] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9], + 0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]); + sprite->colors[0] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13], + 0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]); + } else - v->params.scaling = 1.0f; + { + int i; + const float* vertex = draw->coords->vertex; + const float* tex_coord = draw->coords->tex_coord; + const float* color = draw->coords->color; - v->params.rotation = draw->rotation; + for (i = 0; i < vertex_count; i++) + { + d3d11_vertex_t* v = (d3d11_vertex_t*)sprite; + v->position[0] = *vertex++; + v->position[1] = *vertex++; + v->texcoord[0] = *tex_coord++; + v->texcoord[1] = *tex_coord++; + v->color[0] = *color++; + v->color[1] = *color++; + v->color[2] = *color++; + v->color[3] = *color++; - v->colors[3] = DXGI_COLOR_RGBA( - 0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1], - 0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]); - v->colors[2] = DXGI_COLOR_RGBA( - 0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5], - 0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]); - v->colors[1] = DXGI_COLOR_RGBA( - 0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9], - 0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]); - v->colors[0] = DXGI_COLOR_RGBA( - 0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13], - 0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]); + sprite++; + } + + d3d11_set_shader(d3d11->context, &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]); + D3D11SetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + } D3D11UnmapBuffer(d3d11->context, d3d11->sprites.vbo, 0); } d3d11_set_texture_and_sampler(d3d11->context, 0, (d3d11_texture_t*)draw->texture); - D3D11Draw(d3d11->context, 1, d3d11->sprites.offset); - d3d11->sprites.offset++; + D3D11Draw(d3d11->context, vertex_count, d3d11->sprites.offset); + d3d11->sprites.offset += vertex_count; + + if (vertex_count > 1) + { + d3d11_set_shader(d3d11->context, &d3d11->sprites.shader); + D3D11SetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + } + return; } diff --git a/menu/drivers_display/menu_display_d3d12.c b/menu/drivers_display/menu_display_d3d12.c index 122ad20c4a..8006b728f6 100644 --- a/menu/drivers_display/menu_display_d3d12.c +++ b/menu/drivers_display/menu_display_d3d12.c @@ -38,7 +38,7 @@ static void menu_display_d3d12_blend_begin(void) { d3d12_video_t* d3d12 = (d3d12_video_t*)video_driver_get_ptr(false); - /*todo: d3d12->sprites.pipe_blend */ + d3d12->sprites.pipe = d3d12->sprites.pipe_blend; D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe); } @@ -46,7 +46,7 @@ static void menu_display_d3d12_blend_end(void) { d3d12_video_t* d3d12 = (d3d12_video_t*)video_driver_get_ptr(false); - /*todo: d3d12->sprites.pipe_noblend */ + d3d12->sprites.pipe = d3d12->sprites.pipe_noblend; D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe); } @@ -54,6 +54,7 @@ static void menu_display_d3d12_viewport(void* data) {} static void menu_display_d3d12_draw(void* data) { + int vertex_count; d3d12_video_t* d3d12 = (d3d12_video_t*)video_driver_get_ptr(false); menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data; @@ -76,51 +77,84 @@ static void menu_display_d3d12_draw(void* data) return; } - if (!d3d12->sprites.enabled) + if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color) + vertex_count = draw->coords->vertices; + else + vertex_count = 1; + + if (!d3d12->sprites.enabled || vertex_count > d3d12->sprites.capacity) return; - if (d3d12->sprites.offset + 1 > d3d12->sprites.capacity) + if (d3d12->sprites.offset + vertex_count > d3d12->sprites.capacity) d3d12->sprites.offset = 0; { - d3d12_sprite_t* v; + d3d12_sprite_t* sprite; D3D12_RANGE range = { 0, 0 }; - D3D12Map(d3d12->sprites.vbo, 0, &range, (void**)&v); - v += d3d12->sprites.offset; + D3D12Map(d3d12->sprites.vbo, 0, &range, (void**)&sprite); + sprite += d3d12->sprites.offset; - v->pos.x = draw->x / (float)d3d12->chain.viewport.Width; - v->pos.y = (d3d12->chain.viewport.Height - draw->y - draw->height) / - (float)d3d12->chain.viewport.Height; - v->pos.w = draw->width / (float)d3d12->chain.viewport.Width; - v->pos.h = draw->height / (float)d3d12->chain.viewport.Height; + if (vertex_count == 1) + { - v->coords.u = 0.0f; - v->coords.v = 0.0f; - v->coords.w = 1.0f; - v->coords.h = 1.0f; + sprite->pos.x = draw->x / (float)d3d12->chain.viewport.Width; + sprite->pos.y = (d3d12->chain.viewport.Height - draw->y - draw->height) / + (float)d3d12->chain.viewport.Height; + sprite->pos.w = draw->width / (float)d3d12->chain.viewport.Width; + sprite->pos.h = draw->height / (float)d3d12->chain.viewport.Height; - if (draw->scale_factor) - v->params.scaling = draw->scale_factor; + sprite->coords.u = 0.0f; + sprite->coords.v = 0.0f; + sprite->coords.w = 1.0f; + sprite->coords.h = 1.0f; + + if (draw->scale_factor) + sprite->params.scaling = draw->scale_factor; + else + sprite->params.scaling = 1.0f; + + sprite->params.rotation = draw->rotation; + + sprite->colors[3] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1], + 0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]); + sprite->colors[2] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5], + 0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]); + sprite->colors[1] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9], + 0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]); + sprite->colors[0] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13], + 0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]); + } else - v->params.scaling = 1.0f; + { + int i; + const float* vertex = draw->coords->vertex; + const float* tex_coord = draw->coords->tex_coord; + const float* color = draw->coords->color; - v->params.rotation = draw->rotation; + for (i = 0; i < vertex_count; i++) + { + d3d12_vertex_t* v = (d3d12_vertex_t*)sprite; + v->position[0] = *vertex++; + v->position[1] = *vertex++; + v->texcoord[0] = *tex_coord++; + v->texcoord[1] = *tex_coord++; + v->color[0] = *color++; + v->color[1] = *color++; + v->color[2] = *color++; + v->color[3] = *color++; - v->colors[3] = DXGI_COLOR_RGBA( - 0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1], - 0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]); - v->colors[2] = DXGI_COLOR_RGBA( - 0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5], - 0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]); - v->colors[1] = DXGI_COLOR_RGBA( - 0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9], - 0xFF * draw->coords->color[10], 0xFF * draw->coords->color[12]); - v->colors[0] = DXGI_COLOR_RGBA( - 0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13], - 0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]); + sprite++; + } + D3D12SetPipelineState(d3d12->queue.cmd, d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]); + D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + } - range.Begin = d3d12->sprites.offset * sizeof(*v); - range.End = (d3d12->sprites.offset + 1) * sizeof(*v); + range.Begin = d3d12->sprites.offset * sizeof(*sprite); + range.End = (d3d12->sprites.offset + vertex_count) * sizeof(*sprite); D3D12Unmap(d3d12->sprites.vbo, 0, &range); } @@ -129,10 +163,21 @@ static void menu_display_d3d12_draw(void* data) if (texture->dirty) d3d12_upload_texture(d3d12->queue.cmd, texture); d3d12_set_texture_and_sampler(d3d12->queue.cmd, texture); + + D3D12SetGraphicsRootDescriptorTable( + d3d12->queue.cmd, ROOT_ID_SAMPLER_T, + d3d12->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_BORDER]); + } + + D3D12DrawInstanced(d3d12->queue.cmd, vertex_count, 1, d3d12->sprites.offset, 0); + d3d12->sprites.offset += vertex_count; + + if (vertex_count > 1) + { + D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe); + D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_POINTLIST); } - D3D12DrawInstanced(d3d12->queue.cmd, 1, 1, d3d12->sprites.offset, 0); - d3d12->sprites.offset++; return; } @@ -187,7 +232,7 @@ static void menu_display_d3d12_draw_pipeline(void* data) d3d12->ubo_values.time += 0.01f; { - D3D12_RANGE read_range = { 0, 0 }; + D3D12_RANGE read_range = { 0, 0 }; d3d12_uniform_t* mapped_ubo; D3D12Map(d3d12->ubo, 0, &read_range, (void**)&mapped_ubo); *mapped_ubo = d3d12->ubo_values;