mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-30 09:35:40 +00:00
Core: Add Vulkan GPU renderer
This commit is contained in:
parent
3cd5b7ae74
commit
49d11988bf
|
@ -36,6 +36,8 @@ add_library(core
|
|||
gpu_hw_opengl.h
|
||||
gpu_hw_shadergen.cpp
|
||||
gpu_hw_shadergen.h
|
||||
gpu_hw_vulkan.cpp
|
||||
gpu_hw_vulkan.h
|
||||
gpu_sw.cpp
|
||||
gpu_sw.h
|
||||
gte.cpp
|
||||
|
@ -91,7 +93,7 @@ set(RECOMPILER_SRCS
|
|||
|
||||
target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_link_libraries(core PUBLIC Threads::Threads common imgui tinyxml2 zlib)
|
||||
target_link_libraries(core PUBLIC Threads::Threads common imgui tinyxml2 zlib vulkan-loader)
|
||||
target_link_libraries(core PRIVATE glad stb)
|
||||
|
||||
if(WIN32)
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
<ClCompile Include="gpu_commands.cpp" />
|
||||
<ClCompile Include="gpu_hw_d3d11.cpp" />
|
||||
<ClCompile Include="gpu_hw_shadergen.cpp" />
|
||||
<ClCompile Include="gpu_hw_vulkan.cpp" />
|
||||
<ClCompile Include="gpu_sw.cpp" />
|
||||
<ClCompile Include="gte.cpp" />
|
||||
<ClCompile Include="dma.cpp" />
|
||||
|
@ -105,6 +106,7 @@
|
|||
<ClInclude Include="game_list.h" />
|
||||
<ClInclude Include="gpu_hw_d3d11.h" />
|
||||
<ClInclude Include="gpu_hw_shadergen.h" />
|
||||
<ClInclude Include="gpu_hw_vulkan.h" />
|
||||
<ClInclude Include="gpu_sw.h" />
|
||||
<ClInclude Include="gte.h" />
|
||||
<ClInclude Include="cpu_types.h" />
|
||||
|
@ -296,7 +298,7 @@
|
|||
<PreprocessorDefinitions>WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -321,7 +323,7 @@
|
|||
<PreprocessorDefinitions>WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -346,7 +348,7 @@
|
|||
<PreprocessorDefinitions>WITH_RECOMPILER=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
|
@ -374,7 +376,7 @@
|
|||
<PreprocessorDefinitions>WITH_RECOMPILER=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
|
@ -401,7 +403,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -427,7 +429,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -454,7 +456,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
@ -480,7 +482,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
<ClCompile Include="namco_guncon.cpp" />
|
||||
<ClCompile Include="playstation_mouse.cpp" />
|
||||
<ClCompile Include="negcon.cpp" />
|
||||
<ClCompile Include="gpu_hw_vulkan.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="types.h" />
|
||||
|
@ -89,6 +90,7 @@
|
|||
<ClInclude Include="namco_guncon.h" />
|
||||
<ClInclude Include="playstation_mouse.h" />
|
||||
<ClInclude Include="negcon.h" />
|
||||
<ClInclude Include="gpu_hw_vulkan.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpu_core.inl" />
|
||||
|
|
|
@ -164,6 +164,9 @@ public:
|
|||
// gpu_hw_opengl.cpp
|
||||
static std::unique_ptr<GPU> CreateHardwareOpenGLRenderer();
|
||||
|
||||
// gpu_hw_vulkan.cpp
|
||||
static std::unique_ptr<GPU> CreateHardwareVulkanRenderer();
|
||||
|
||||
// gpu_sw.cpp
|
||||
static std::unique_ptr<GPU> CreateSoftwareRenderer();
|
||||
|
||||
|
@ -602,7 +605,7 @@ protected:
|
|||
void ClearTextureWindowChangedFlag() { texture_window_changed = false; }
|
||||
} m_draw_mode = {};
|
||||
|
||||
Common::Rectangle<u32> m_drawing_area;
|
||||
Common::Rectangle<u32> m_drawing_area{0, 0, VRAM_WIDTH, VRAM_HEIGHT};
|
||||
|
||||
struct DrawingOffset
|
||||
{
|
||||
|
|
|
@ -527,6 +527,36 @@ bool GPU_HW::UseVRAMCopyShader(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 w
|
|||
.Intersects(Common::Rectangle<u32>::FromExtents(dst_x, dst_y, width, height)));
|
||||
}
|
||||
|
||||
GPU_HW::VRAMFillUBOData GPU_HW::GetVRAMFillUBOData(u32 x, u32 y, u32 width, u32 height, u32 color) const
|
||||
{
|
||||
// drop precision unless true colour is enabled
|
||||
if (!m_true_color)
|
||||
color = RGBA5551ToRGBA8888(RGBA8888ToRGBA5551(color));
|
||||
|
||||
VRAMFillUBOData uniforms;
|
||||
std::tie(uniforms.u_fill_color[0], uniforms.u_fill_color[1], uniforms.u_fill_color[2], uniforms.u_fill_color[3]) =
|
||||
RGBA8ToFloat(color);
|
||||
uniforms.u_interlaced_displayed_field = GetActiveLineLSB();
|
||||
return uniforms;
|
||||
}
|
||||
|
||||
GPU_HW::VRAMCopyUBOData GPU_HW::GetVRAMCopyUBOData(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width,
|
||||
u32 height) const
|
||||
{
|
||||
const VRAMCopyUBOData uniforms = {src_x * m_resolution_scale,
|
||||
src_y * m_resolution_scale,
|
||||
dst_x * m_resolution_scale,
|
||||
dst_y * m_resolution_scale,
|
||||
((dst_x + width) % VRAM_WIDTH) * m_resolution_scale,
|
||||
((dst_y + height) % VRAM_HEIGHT) * m_resolution_scale,
|
||||
width * m_resolution_scale,
|
||||
height * m_resolution_scale,
|
||||
m_GPUSTAT.set_mask_while_drawing ? 1u : 0u,
|
||||
GetCurrentNormalizedBatchVertexDepthID()};
|
||||
|
||||
return uniforms;
|
||||
}
|
||||
|
||||
GPU_HW::BatchPrimitive GPU_HW::GetPrimitiveForCommand(RenderCommand rc)
|
||||
{
|
||||
if (rc.primitive == Primitive::Line)
|
||||
|
|
|
@ -14,9 +14,7 @@ public:
|
|||
enum class BatchPrimitive : u8
|
||||
{
|
||||
Lines = 0,
|
||||
LineStrip = 1,
|
||||
Triangles = 2,
|
||||
TriangleStrip = 3
|
||||
Triangles = 1
|
||||
};
|
||||
|
||||
enum class BatchRenderMode : u8
|
||||
|
@ -119,6 +117,12 @@ protected:
|
|||
u32 u_set_mask_while_drawing;
|
||||
};
|
||||
|
||||
struct VRAMFillUBOData
|
||||
{
|
||||
float u_fill_color[4];
|
||||
u32 u_interlaced_displayed_field;
|
||||
};
|
||||
|
||||
struct VRAMWriteUBOData
|
||||
{
|
||||
u32 u_base_coords[2];
|
||||
|
@ -230,6 +234,9 @@ protected:
|
|||
/// Returns true if the VRAM copy shader should be used (oversized copies, masking).
|
||||
bool UseVRAMCopyShader(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) const;
|
||||
|
||||
VRAMFillUBOData GetVRAMFillUBOData(u32 x, u32 y, u32 width, u32 height, u32 color) const;
|
||||
VRAMCopyUBOData GetVRAMCopyUBOData(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) const;
|
||||
|
||||
/// Handles quads with flipped texture coordinate directions.
|
||||
static void HandleFlippedQuadTextureCoordinates(BatchVertex* vertices);
|
||||
|
||||
|
|
|
@ -534,9 +534,8 @@ void GPU_HW_D3D11::DrawBatchVertices(BatchRenderMode render_mode, u32 base_verte
|
|||
{
|
||||
const bool textured = (m_batch.texture_mode != TextureMode::Disabled);
|
||||
|
||||
static constexpr std::array<D3D11_PRIMITIVE_TOPOLOGY, 4> d3d_primitives = {
|
||||
{D3D11_PRIMITIVE_TOPOLOGY_LINELIST, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
|
||||
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP}};
|
||||
static constexpr std::array<D3D11_PRIMITIVE_TOPOLOGY, 2> d3d_primitives = {
|
||||
{D3D11_PRIMITIVE_TOPOLOGY_LINELIST, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST}};
|
||||
m_context->IASetPrimitiveTopology(d3d_primitives[static_cast<u8>(m_batch.primitive)]);
|
||||
|
||||
m_context->VSSetShader(m_batch_vertex_shaders[BoolToUInt8(textured)].Get(), nullptr, 0);
|
||||
|
|
|
@ -535,7 +535,7 @@ void GPU_HW_OpenGL::DrawBatchVertices(BatchRenderMode render_mode, u32 base_vert
|
|||
|
||||
glDepthFunc(m_GPUSTAT.check_mask_before_draw ? GL_GEQUAL : GL_ALWAYS);
|
||||
|
||||
static constexpr std::array<GLenum, 4> gl_primitives = {{GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP}};
|
||||
static constexpr std::array<GLenum, 2> gl_primitives = {{GL_LINES, GL_TRIANGLES}};
|
||||
glDrawArrays(gl_primitives[static_cast<u8>(m_batch.primitive)], m_batch_base_vertex, num_vertices);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,11 @@ GPU_HW_ShaderGen::GPU_HW_ShaderGen(HostDisplay::RenderAPI render_api, u32 resolu
|
|||
{
|
||||
if (m_glsl)
|
||||
{
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGL || m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||
SetGLSLVersionString();
|
||||
|
||||
m_use_glsl_interface_blocks = (GLAD_GL_ES_VERSION_3_2 || GLAD_GL_VERSION_3_2);
|
||||
m_use_glsl_binding_layout = UseGLSLBindingLayout();
|
||||
m_use_glsl_interface_blocks = (IsVulkan() || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_VERSION_3_2);
|
||||
m_use_glsl_binding_layout = (IsVulkan() || UseGLSLBindingLayout());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +83,8 @@ void GPU_HW_ShaderGen::WriteHeader(std::stringstream& ss)
|
|||
{
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGL || m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||
ss << m_glsl_version_string << "\n\n";
|
||||
else if (m_render_api == HostDisplay::RenderAPI::Vulkan)
|
||||
ss << "#version 450 core\n\n";
|
||||
|
||||
// Extension enabling for OpenGL.
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||
|
@ -107,6 +110,7 @@ void GPU_HW_ShaderGen::WriteHeader(std::stringstream& ss)
|
|||
DefineMacro(ss, "API_OPENGL", m_render_api == HostDisplay::RenderAPI::OpenGL);
|
||||
DefineMacro(ss, "API_OPENGL_ES", m_render_api == HostDisplay::RenderAPI::OpenGLES);
|
||||
DefineMacro(ss, "API_D3D11", m_render_api == HostDisplay::RenderAPI::D3D11);
|
||||
DefineMacro(ss, "API_VULKAN", m_render_api == HostDisplay::RenderAPI::Vulkan);
|
||||
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||
{
|
||||
|
@ -219,9 +223,17 @@ float4 RGBA5551ToRGBA8(uint v)
|
|||
)";
|
||||
}
|
||||
|
||||
void GPU_HW_ShaderGen::DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members)
|
||||
void GPU_HW_ShaderGen::DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members,
|
||||
bool push_constant_on_vulkan)
|
||||
{
|
||||
if (m_glsl)
|
||||
if (IsVulkan())
|
||||
{
|
||||
if (push_constant_on_vulkan)
|
||||
ss << "layout(push_constant) uniform PushConstants\n";
|
||||
else
|
||||
ss << "layout(std140, set = 0, binding = 0) uniform UBOBlock\n";
|
||||
}
|
||||
else if (m_glsl)
|
||||
{
|
||||
if (m_use_glsl_binding_layout)
|
||||
ss << "layout(std140, binding = 1) uniform UBOBlock\n";
|
||||
|
@ -243,7 +255,9 @@ void GPU_HW_ShaderGen::DeclareTexture(std::stringstream& ss, const char* name, u
|
|||
{
|
||||
if (m_glsl)
|
||||
{
|
||||
if (m_use_glsl_binding_layout)
|
||||
if (IsVulkan())
|
||||
ss << "layout(set = 0, binding = " << (index + 1u) << ") ";
|
||||
else if (m_use_glsl_binding_layout)
|
||||
ss << "layout(binding = " << index << ") ";
|
||||
|
||||
ss << "uniform sampler2D " << name << ";\n";
|
||||
|
@ -260,7 +274,9 @@ void GPU_HW_ShaderGen::DeclareTextureBuffer(std::stringstream& ss, const char* n
|
|||
{
|
||||
if (m_glsl)
|
||||
{
|
||||
if (m_use_glsl_binding_layout)
|
||||
if (IsVulkan())
|
||||
ss << "layout(set = 0, binding = " << index << ") ";
|
||||
else if (m_use_glsl_binding_layout)
|
||||
ss << "layout(binding = " << index << ") ";
|
||||
|
||||
ss << "uniform " << (is_int ? (is_unsigned ? "u" : "i") : "") << "samplerBuffer " << name << ";\n";
|
||||
|
@ -296,6 +312,9 @@ void GPU_HW_ShaderGen::DeclareVertexEntryPoint(
|
|||
|
||||
if (m_use_glsl_interface_blocks)
|
||||
{
|
||||
if (IsVulkan())
|
||||
ss << "layout(location = 0) ";
|
||||
|
||||
ss << "out VertexData {\n";
|
||||
for (u32 i = 0; i < num_color_outputs; i++)
|
||||
ss << " float4 v_col" << i << ";\n";
|
||||
|
@ -321,7 +340,12 @@ void GPU_HW_ShaderGen::DeclareVertexEntryPoint(
|
|||
|
||||
ss << "#define v_pos gl_Position\n\n";
|
||||
if (declare_vertex_id)
|
||||
{
|
||||
if (IsVulkan())
|
||||
ss << "#define v_id uint(gl_VertexIndex)\n";
|
||||
else
|
||||
ss << "#define v_id uint(gl_VertexID)\n";
|
||||
}
|
||||
|
||||
ss << "\n";
|
||||
ss << "void main()\n";
|
||||
|
@ -366,6 +390,9 @@ void GPU_HW_ShaderGen::DeclareFragmentEntryPoint(
|
|||
{
|
||||
if (m_use_glsl_interface_blocks)
|
||||
{
|
||||
if (IsVulkan())
|
||||
ss << "layout(location = 0) ";
|
||||
|
||||
ss << "in VertexData {\n";
|
||||
for (u32 i = 0; i < num_color_inputs; i++)
|
||||
ss << " float4 v_col" << i << ";\n";
|
||||
|
@ -467,7 +494,8 @@ void GPU_HW_ShaderGen::WriteBatchUniformBuffer(std::stringstream& ss)
|
|||
DeclareUniformBuffer(ss,
|
||||
{"uint2 u_texture_window_mask", "uint2 u_texture_window_offset", "float u_src_alpha_factor",
|
||||
"float u_dst_alpha_factor", "uint u_interlaced_displayed_field", "uint u_base_vertex_depth_id",
|
||||
"bool u_check_mask_before_draw", "bool u_set_mask_while_drawing"});
|
||||
"bool u_check_mask_before_draw", "bool u_set_mask_while_drawing"},
|
||||
false);
|
||||
}
|
||||
|
||||
std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(bool textured)
|
||||
|
@ -507,6 +535,12 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(bool textured)
|
|||
#if API_OPENGL || API_OPENGL_ES
|
||||
pos_y += EPSILON;
|
||||
#endif
|
||||
|
||||
// NDC space Y flip in Vulkan.
|
||||
#if API_VULKAN
|
||||
pos_y = -pos_y;
|
||||
#endif
|
||||
|
||||
v_pos = float4(pos_x, pos_y, 0.0, 1.0);
|
||||
|
||||
#if API_D3D11
|
||||
|
@ -861,13 +895,18 @@ CONSTANT float2 WIDTH = (1.0 / float2(VRAM_SIZE)) * float2(RESOLUTION_SCALE, RES
|
|||
// GS is a pain, too different between HLSL and GLSL...
|
||||
if (m_glsl)
|
||||
{
|
||||
ss << R"(
|
||||
in VertexData {
|
||||
if (IsVulkan())
|
||||
ss << "layout(location = 0) ";
|
||||
|
||||
ss << R"(in VertexData {
|
||||
float4 v_col0;
|
||||
nointerpolation float v_depth;
|
||||
} in_data[];
|
||||
} in_data[];)";
|
||||
|
||||
out VertexData {
|
||||
if (IsVulkan())
|
||||
ss << "layout(location = 0) ";
|
||||
|
||||
ss << R"(out VertexData {
|
||||
float4 v_col0;
|
||||
nointerpolation float v_depth;
|
||||
} out_data;
|
||||
|
@ -968,8 +1007,8 @@ std::string GPU_HW_ShaderGen::GenerateScreenQuadVertexShader()
|
|||
{
|
||||
v_tex0 = float2(float((v_id << 1) & 2u), float(v_id & 2u));
|
||||
v_pos = float4(v_tex0 * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
|
||||
#if API_OPENGL || API_OPENGL_ES
|
||||
v_pos.y = -gl_Position.y;
|
||||
#if API_OPENGL || API_OPENGL_ES || API_VULKAN
|
||||
v_pos.y = -v_pos.y;
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
|
@ -981,7 +1020,7 @@ std::string GPU_HW_ShaderGen::GenerateFillFragmentShader()
|
|||
{
|
||||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
DeclareUniformBuffer(ss, {"float4 u_fill_color"});
|
||||
DeclareUniformBuffer(ss, {"float4 u_fill_color"}, true);
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1, true);
|
||||
|
||||
ss << R"(
|
||||
|
@ -999,7 +1038,7 @@ std::string GPU_HW_ShaderGen::GenerateInterlacedFillFragmentShader()
|
|||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
WriteCommonFunctions(ss);
|
||||
DeclareUniformBuffer(ss, {"float4 u_fill_color", "uint u_interlaced_displayed_field"});
|
||||
DeclareUniformBuffer(ss, {"float4 u_fill_color", "uint u_interlaced_displayed_field"}, true);
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, true);
|
||||
|
||||
ss << R"(
|
||||
|
@ -1019,7 +1058,7 @@ std::string GPU_HW_ShaderGen::GenerateCopyFragmentShader()
|
|||
{
|
||||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
DeclareUniformBuffer(ss, {"float4 u_src_rect"});
|
||||
DeclareUniformBuffer(ss, {"float4 u_src_rect"}, true);
|
||||
DeclareTexture(ss, "samp0", 0);
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1);
|
||||
|
||||
|
@ -1043,7 +1082,7 @@ std::string GPU_HW_ShaderGen::GenerateDisplayFragmentShader(bool depth_24bit,
|
|||
DefineMacro(ss, "INTERLEAVED", interlace_mode == GPU_HW::InterlacedRenderMode::InterleavedFields);
|
||||
|
||||
WriteCommonFunctions(ss);
|
||||
DeclareUniformBuffer(ss, {"uint2 u_vram_offset", "uint u_crop_left", "uint u_field_offset"});
|
||||
DeclareUniformBuffer(ss, {"uint2 u_vram_offset", "uint u_crop_left", "uint u_field_offset"}, true);
|
||||
DeclareTexture(ss, "samp0", 0);
|
||||
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1);
|
||||
|
@ -1093,7 +1132,7 @@ std::string GPU_HW_ShaderGen::GenerateVRAMReadFragmentShader()
|
|||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
WriteCommonFunctions(ss);
|
||||
DeclareUniformBuffer(ss, {"uint2 u_base_coords", "uint2 u_size"});
|
||||
DeclareUniformBuffer(ss, {"uint2 u_base_coords", "uint2 u_size"}, true);
|
||||
|
||||
DeclareTexture(ss, "samp0", 0);
|
||||
|
||||
|
@ -1146,8 +1185,10 @@ std::string GPU_HW_ShaderGen::GenerateVRAMWriteFragmentShader()
|
|||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
WriteCommonFunctions(ss);
|
||||
DeclareUniformBuffer(ss, {"uint2 u_base_coords", "uint2 u_size", "uint u_buffer_base_offset", "uint u_mask_or_bits",
|
||||
"float u_depth_value"});
|
||||
DeclareUniformBuffer(
|
||||
ss,
|
||||
{"uint2 u_base_coords", "uint2 u_size", "uint u_buffer_base_offset", "uint u_mask_or_bits", "float u_depth_value"},
|
||||
true);
|
||||
|
||||
DeclareTextureBuffer(ss, "samp0", 0, true, true);
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, true);
|
||||
|
@ -1176,8 +1217,10 @@ std::string GPU_HW_ShaderGen::GenerateVRAMCopyFragmentShader()
|
|||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
WriteCommonFunctions(ss);
|
||||
DeclareUniformBuffer(ss, {"uint2 u_src_coords", "uint2 u_dst_coords", "uint2 u_end_coords", "uint2 u_size",
|
||||
"bool u_set_mask_bit", "float u_depth_value"});
|
||||
DeclareUniformBuffer(ss,
|
||||
{"uint2 u_src_coords", "uint2 u_dst_coords", "uint2 u_end_coords", "uint2 u_size",
|
||||
"bool u_set_mask_bit", "float u_depth_value"},
|
||||
true);
|
||||
|
||||
DeclareTexture(ss, "samp0", 0);
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, true);
|
||||
|
|
|
@ -28,9 +28,12 @@ public:
|
|||
std::string GenerateVRAMUpdateDepthFragmentShader();
|
||||
|
||||
private:
|
||||
ALWAYS_INLINE bool IsVulkan() const { return (m_render_api == HostDisplay::RenderAPI::Vulkan); }
|
||||
|
||||
void SetGLSLVersionString();
|
||||
void WriteHeader(std::stringstream& ss);
|
||||
void DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members);
|
||||
void DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members,
|
||||
bool push_constant_on_vulkan);
|
||||
void DeclareTexture(std::stringstream& ss, const char* name, u32 index);
|
||||
void DeclareTextureBuffer(std::stringstream& ss, const char* name, u32 index, bool is_int, bool is_unsigned);
|
||||
void DeclareVertexEntryPoint(std::stringstream& ss, const std::initializer_list<const char*>& attributes,
|
||||
|
|
1191
src/core/gpu_hw_vulkan.cpp
Normal file
1191
src/core/gpu_hw_vulkan.cpp
Normal file
File diff suppressed because it is too large
Load diff
124
src/core/gpu_hw_vulkan.h
Normal file
124
src/core/gpu_hw_vulkan.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
#pragma once
|
||||
#include "common/dimensional_array.h"
|
||||
#include "common/vulkan/staging_texture.h"
|
||||
#include "common/vulkan/stream_buffer.h"
|
||||
#include "common/vulkan/texture.h"
|
||||
#include "gpu_hw.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
class GPU_HW_Vulkan : public GPU_HW
|
||||
{
|
||||
public:
|
||||
GPU_HW_Vulkan();
|
||||
~GPU_HW_Vulkan() override;
|
||||
|
||||
bool Initialize(HostDisplay* host_display, System* system, DMA* dma, InterruptController* interrupt_controller,
|
||||
Timers* timers) override;
|
||||
void Reset() override;
|
||||
|
||||
void ResetGraphicsAPIState() override;
|
||||
void RestoreGraphicsAPIState() override;
|
||||
void UpdateSettings() override;
|
||||
|
||||
protected:
|
||||
void UpdateDisplay() override;
|
||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
|
||||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
||||
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void UpdateVRAMReadTexture() override;
|
||||
void UpdateDepthBufferFromMaskBit() override;
|
||||
void SetScissorFromDrawingArea() override;
|
||||
void MapBatchVertexPointer(u32 required_vertices) override;
|
||||
void UnmapBatchVertexPointer(u32 used_vertices) override;
|
||||
void UploadUniformBuffer(const void* data, u32 data_size) override;
|
||||
void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) override;
|
||||
|
||||
private:
|
||||
enum : u32
|
||||
{
|
||||
MAX_PUSH_CONSTANTS_SIZE = 64,
|
||||
};
|
||||
void SetCapabilities();
|
||||
void DestroyResources();
|
||||
|
||||
ALWAYS_INLINE bool InRenderPass() const { return (m_current_render_pass != VK_NULL_HANDLE); }
|
||||
void BeginRenderPass(VkRenderPass render_pass, VkFramebuffer framebuffer, u32 x, u32 y, u32 width, u32 height);
|
||||
void BeginVRAMRenderPass();
|
||||
void EndRenderPass();
|
||||
|
||||
bool CreatePipelineLayouts();
|
||||
bool CreateSamplers();
|
||||
|
||||
bool CreateFramebuffer();
|
||||
void ClearFramebuffer();
|
||||
void DestroyFramebuffer();
|
||||
|
||||
bool CreateVertexBuffer();
|
||||
bool CreateUniformBuffer();
|
||||
bool CreateTextureBuffer();
|
||||
|
||||
bool CompilePipelines();
|
||||
void DestroyPipelines();
|
||||
|
||||
VkRenderPass m_current_render_pass = VK_NULL_HANDLE;
|
||||
|
||||
VkRenderPass m_vram_render_pass = VK_NULL_HANDLE;
|
||||
VkRenderPass m_vram_update_depth_render_pass = VK_NULL_HANDLE;
|
||||
VkRenderPass m_display_render_pass = VK_NULL_HANDLE;
|
||||
VkRenderPass m_vram_readback_render_pass = VK_NULL_HANDLE;
|
||||
|
||||
VkDescriptorSetLayout m_batch_descriptor_set_layout = VK_NULL_HANDLE;
|
||||
VkDescriptorSetLayout m_single_sampler_descriptor_set_layout = VK_NULL_HANDLE;
|
||||
VkDescriptorSetLayout m_vram_write_descriptor_set_layout = VK_NULL_HANDLE;
|
||||
|
||||
VkPipelineLayout m_batch_pipeline_layout = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_no_samplers_pipeline_layout = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_single_sampler_pipeline_layout = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_vram_write_pipeline_layout = VK_NULL_HANDLE;
|
||||
|
||||
Vulkan::Texture m_vram_texture;
|
||||
Vulkan::Texture m_vram_depth_texture;
|
||||
Vulkan::Texture m_vram_read_texture;
|
||||
Vulkan::Texture m_vram_readback_texture;
|
||||
Vulkan::StagingTexture m_vram_readback_staging_texture;
|
||||
Vulkan::Texture m_display_texture;
|
||||
|
||||
VkFramebuffer m_vram_framebuffer = VK_NULL_HANDLE;
|
||||
VkFramebuffer m_vram_update_depth_framebuffer = VK_NULL_HANDLE;
|
||||
VkFramebuffer m_vram_readback_framebuffer = VK_NULL_HANDLE;
|
||||
VkFramebuffer m_display_framebuffer = VK_NULL_HANDLE;
|
||||
|
||||
VkSampler m_point_sampler = VK_NULL_HANDLE;
|
||||
VkSampler m_linear_sampler = VK_NULL_HANDLE;
|
||||
|
||||
VkDescriptorSet m_batch_descriptor_set = VK_NULL_HANDLE;
|
||||
VkDescriptorSet m_vram_copy_descriptor_set = VK_NULL_HANDLE;
|
||||
VkDescriptorSet m_vram_read_descriptor_set = VK_NULL_HANDLE;
|
||||
VkDescriptorSet m_vram_write_descriptor_set = VK_NULL_HANDLE;
|
||||
|
||||
Vulkan::StreamBuffer m_vertex_stream_buffer;
|
||||
Vulkan::StreamBuffer m_uniform_stream_buffer;
|
||||
Vulkan::StreamBuffer m_texture_stream_buffer;
|
||||
|
||||
u32 m_current_uniform_buffer_offset = 0;
|
||||
VkBufferView m_texture_stream_buffer_view = VK_NULL_HANDLE;
|
||||
|
||||
// [primitive][depth_test][render_mode][texture_mode][transparency_mode][dithering][interlacing]
|
||||
DimensionalArray<VkPipeline, 2, 2, 5, 9, 4, 2, 2> m_batch_pipelines{};
|
||||
|
||||
// [interlaced]
|
||||
std::array<VkPipeline, 2> m_vram_fill_pipelines{};
|
||||
|
||||
// [depth_test]
|
||||
std::array<VkPipeline, 2> m_vram_write_pipelines{};
|
||||
std::array<VkPipeline, 2> m_vram_copy_pipelines{};
|
||||
|
||||
VkPipeline m_vram_readback_pipeline = VK_NULL_HANDLE;
|
||||
VkPipeline m_vram_update_depth_pipeline = VK_NULL_HANDLE;
|
||||
|
||||
// [depth_24][interlace_mode]
|
||||
DimensionalArray<VkPipeline, 3, 2> m_display_pipelines{};
|
||||
};
|
|
@ -314,6 +314,11 @@ void HostInterface::OnRunningGameChanged() {}
|
|||
|
||||
void HostInterface::OnControllerTypeChanged(u32 slot) {}
|
||||
|
||||
std::string HostInterface::GetShaderCacheDirectory()
|
||||
{
|
||||
return GetUserDirectoryRelativePath("cache");
|
||||
}
|
||||
|
||||
void HostInterface::SetDefaultSettings(SettingsInterface& si)
|
||||
{
|
||||
si.SetStringValue("Console", "Region", Settings::GetConsoleRegionName(ConsoleRegion::Auto));
|
||||
|
|
|
@ -114,6 +114,9 @@ protected:
|
|||
virtual void OnRunningGameChanged();
|
||||
virtual void OnControllerTypeChanged(u32 slot);
|
||||
|
||||
/// Returns the path to the shader cache directory.
|
||||
virtual std::string GetShaderCacheDirectory();
|
||||
|
||||
/// Restores all settings to defaults.
|
||||
virtual void SetDefaultSettings(SettingsInterface& si);
|
||||
|
||||
|
|
|
@ -288,6 +288,10 @@ bool System::CreateGPU(GPURenderer renderer)
|
|||
m_gpu = GPU::CreateHardwareOpenGLRenderer();
|
||||
break;
|
||||
|
||||
case GPURenderer::HardwareVulkan:
|
||||
m_gpu = GPU::CreateHardwareVulkanRenderer();
|
||||
break;
|
||||
|
||||
#ifdef WIN32
|
||||
case GPURenderer::HardwareD3D11:
|
||||
m_gpu = GPU::CreateHardwareD3D11Renderer();
|
||||
|
|
Loading…
Reference in a new issue