From 16d83989e52d18e6f9bf80501c56b36f542784ba Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 5 Nov 2019 00:27:22 +1000 Subject: [PATCH] GPU/HW: Support line drawing at >1x scale in D3D11 via GS --- src/core/gpu_hw_d3d11.cpp | 17 +++++++++++ src/core/gpu_hw_d3d11.h | 1 + src/core/gpu_hw_shadergen.cpp | 54 +++++++++++++++++++++++++++++++++++ src/core/gpu_hw_shadergen.h | 1 + 4 files changed, 73 insertions(+) diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index 403c6644e..b915a3de4 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -92,6 +92,8 @@ void GPU_HW_D3D11::Reset() void GPU_HW_D3D11::ResetGraphicsAPIState() { GPU_HW::ResetGraphicsAPIState(); + + m_context->GSSetShader(nullptr, nullptr, 0); } void GPU_HW_D3D11::RestoreGraphicsAPIState() @@ -403,6 +405,15 @@ bool GPU_HW_D3D11::CompileShaders() } } + m_batch_line_expand_geometry_shader.Reset(); + if (m_resolution_scale > 1) + { + m_batch_line_expand_geometry_shader = D3D11::ShaderCompiler::CompileAndCreateGeometryShader( + m_device.Get(), shadergen.GenerateBatchLineExpandGeometryShader(), debug); + if (!m_batch_line_expand_geometry_shader) + return false; + } + m_copy_pixel_shader = D3D11::ShaderCompiler::CompileAndCreatePixelShader(m_device.Get(), shadergen.GenerateCopyFragmentShader(), debug); if (!m_copy_pixel_shader) @@ -490,6 +501,7 @@ void GPU_HW_D3D11::DrawUtilityShader(ID3D11PixelShader* shader, const void* unif m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->VSSetShader(m_screen_quad_vertex_shader.Get(), nullptr, 0); + m_context->GSSetShader(nullptr, nullptr, 0); m_context->PSSetShader(shader, nullptr, 0); m_context->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu); @@ -507,6 +519,11 @@ void GPU_HW_D3D11::SetDrawState(BatchRenderMode render_mode) m_context->VSSetShader(m_batch_vertex_shaders[BoolToUInt8(textured)].Get(), nullptr, 0); + m_context->GSSetShader((m_batch.primitive < GPU_HW::BatchPrimitive::Triangles && m_resolution_scale > 1) ? + m_batch_line_expand_geometry_shader.Get() : + nullptr, + nullptr, 0); + m_context->PSSetShader(m_batch_pixel_shaders[static_cast(render_mode)][static_cast(m_batch.texture_mode)] [BoolToUInt8(m_batch.dithering)] .Get(), diff --git a/src/core/gpu_hw_d3d11.h b/src/core/gpu_hw_d3d11.h index a4d082b72..03a7bb4b0 100644 --- a/src/core/gpu_hw_d3d11.h +++ b/src/core/gpu_hw_d3d11.h @@ -106,6 +106,7 @@ private: std::array, 2> m_batch_vertex_shaders; // [textured] std::array, 2>, 9>, 4> m_batch_pixel_shaders; // [render_mode][texture_mode][dithering] + ComPtr m_batch_line_expand_geometry_shader; ComPtr m_screen_quad_vertex_shader; ComPtr m_copy_pixel_shader; diff --git a/src/core/gpu_hw_shadergen.cpp b/src/core/gpu_hw_shadergen.cpp index 85543441d..7105a3ca9 100644 --- a/src/core/gpu_hw_shadergen.cpp +++ b/src/core/gpu_hw_shadergen.cpp @@ -502,6 +502,60 @@ int4 SampleFromVRAM(int4 texpage, float2 coord) return ss.str(); } +std::string GPU_HW_ShaderGen::GenerateBatchLineExpandGeometryShader() +{ + std::stringstream ss; + WriteHeader(ss); + WriteCommonFunctions(ss); + + // GS is a pain, too different between HLSL and GLSL... + if (m_glsl) + { + } + else + { + ss << R"( +CONSTANT float2 OFFSET = (1.0 / float2(VRAM_SIZE)) * float2(RESOLUTION_SCALE, RESOLUTION_SCALE); + +struct Vertex +{ + float4 col0 : COLOR0; + float4 pos : SV_Position; +}; + +[maxvertexcount(4)] +void main(line Vertex input[2], inout TriangleStream output) +{ + Vertex v; + + // top-left + v.col0 = input[0].col0; + v.pos = input[0].pos + float4(-OFFSET.x, +OFFSET.y, 0.0, 0.0); + output.Append(v); + + // top-right + v.col0 = input[0].col0; + v.pos = input[0].pos + float4(+OFFSET.x, +OFFSET.y, 0.0, 0.0); + output.Append(v); + + // bottom-left + v.col0 = input[1].col0; + v.pos = input[1].pos + float4(-OFFSET.x, -OFFSET.y, 0.0, 0.0); + output.Append(v); + + // bottom-right + v.col0 = input[1].col0; + v.pos = input[1].pos + float4(+OFFSET.x, -OFFSET.y, 0.0, 0.0); + output.Append(v); + + output.RestartStrip(); +} +)"; + } + + return ss.str(); +} + std::string GPU_HW_ShaderGen::GenerateScreenQuadVertexShader() { std::stringstream ss; diff --git a/src/core/gpu_hw_shadergen.h b/src/core/gpu_hw_shadergen.h index 547ec1259..d21cb165b 100644 --- a/src/core/gpu_hw_shadergen.h +++ b/src/core/gpu_hw_shadergen.h @@ -21,6 +21,7 @@ public: std::string GenerateBatchVertexShader(bool textured); std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode transparency, GPU::TextureMode texture_mode, bool dithering); + std::string GenerateBatchLineExpandGeometryShader(); std::string GenerateScreenQuadVertexShader(); std::string GenerateFillFragmentShader(); std::string GenerateCopyFragmentShader();