GPU/HW: Add loading bar to shader compilation

This commit is contained in:
Connor McLaughlin 2020-09-12 00:23:13 +10:00
parent 6f250a4ff7
commit 3625834ea7
3 changed files with 103 additions and 6 deletions

View file

@ -2,6 +2,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/d3d11/shader_compiler.h" #include "common/d3d11/shader_compiler.h"
#include "common/log.h" #include "common/log.h"
#include "common/timer.h"
#include "gpu_hw_shadergen.h" #include "gpu_hw_shadergen.h"
#include "host_display.h" #include "host_display.h"
#include "host_interface.h" #include "host_interface.h"
@ -332,7 +333,8 @@ bool GPU_HW_D3D11::CreateStateObjects()
for (u8 transparency_mode = 0; transparency_mode < 5; transparency_mode++) for (u8 transparency_mode = 0; transparency_mode < 5; transparency_mode++)
{ {
bl_desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); bl_desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT());
if (transparency_mode != static_cast<u8>(TransparencyMode::Disabled) || m_texture_filtering != GPUTextureFilter::Nearest) if (transparency_mode != static_cast<u8>(TransparencyMode::Disabled) ||
m_texture_filtering != GPUTextureFilter::Nearest)
{ {
bl_desc.RenderTarget[0].BlendEnable = TRUE; bl_desc.RenderTarget[0].BlendEnable = TRUE;
bl_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; bl_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
@ -372,7 +374,19 @@ bool GPU_HW_D3D11::CompileShaders()
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_scaled_dithering, GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_scaled_dithering,
m_texture_filtering, m_using_uv_limits, m_supports_dual_source_blend); m_texture_filtering, m_using_uv_limits, m_supports_dual_source_blend);
g_host_interface->DisplayLoadingScreen("Compiling shaders..."); Common::Timer compile_time;
const int progress_total = 1 + 1 + 2 + (4 * 9 * 2 * 2) + 7 + (2 * 3);
int progress_value = 0;
#define UPDATE_PROGRESS() \
do \
{ \
progress_value++; \
if (compile_time.GetTimeSeconds() >= 1.0f) \
{ \
compile_time.Reset(); \
g_host_interface->DisplayLoadingScreen("Compiling Shaders", 0, progress_total, progress_value); \
} \
} while (0)
// input layout // input layout
{ {
@ -400,17 +414,23 @@ bool GPU_HW_D3D11::CompileShaders()
} }
} }
UPDATE_PROGRESS();
m_screen_quad_vertex_shader = m_screen_quad_vertex_shader =
m_shader_cache.GetVertexShader(m_device.Get(), shadergen.GenerateScreenQuadVertexShader()); m_shader_cache.GetVertexShader(m_device.Get(), shadergen.GenerateScreenQuadVertexShader());
if (!m_screen_quad_vertex_shader) if (!m_screen_quad_vertex_shader)
return false; return false;
UPDATE_PROGRESS();
for (u8 textured = 0; textured < 2; textured++) for (u8 textured = 0; textured < 2; textured++)
{ {
const std::string vs = shadergen.GenerateBatchVertexShader(ConvertToBoolUnchecked(textured)); const std::string vs = shadergen.GenerateBatchVertexShader(ConvertToBoolUnchecked(textured));
m_batch_vertex_shaders[textured] = m_shader_cache.GetVertexShader(m_device.Get(), vs); m_batch_vertex_shaders[textured] = m_shader_cache.GetVertexShader(m_device.Get(), vs);
if (!m_batch_vertex_shaders[textured]) if (!m_batch_vertex_shaders[textured])
return false; return false;
UPDATE_PROGRESS();
} }
for (u8 render_mode = 0; render_mode < 4; render_mode++) for (u8 render_mode = 0; render_mode < 4; render_mode++)
@ -429,6 +449,8 @@ bool GPU_HW_D3D11::CompileShaders()
m_shader_cache.GetPixelShader(m_device.Get(), ps); m_shader_cache.GetPixelShader(m_device.Get(), ps);
if (!m_batch_pixel_shaders[render_mode][texture_mode][dithering][interlacing]) if (!m_batch_pixel_shaders[render_mode][texture_mode][dithering][interlacing])
return false; return false;
UPDATE_PROGRESS();
} }
} }
} }
@ -438,33 +460,47 @@ bool GPU_HW_D3D11::CompileShaders()
if (!m_copy_pixel_shader) if (!m_copy_pixel_shader)
return false; return false;
UPDATE_PROGRESS();
m_vram_fill_pixel_shader = m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateFillFragmentShader()); m_vram_fill_pixel_shader = m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateFillFragmentShader());
if (!m_vram_fill_pixel_shader) if (!m_vram_fill_pixel_shader)
return false; return false;
UPDATE_PROGRESS();
m_vram_interlaced_fill_pixel_shader = m_vram_interlaced_fill_pixel_shader =
m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateInterlacedFillFragmentShader()); m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateInterlacedFillFragmentShader());
if (!m_vram_interlaced_fill_pixel_shader) if (!m_vram_interlaced_fill_pixel_shader)
return false; return false;
UPDATE_PROGRESS();
m_vram_read_pixel_shader = m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateVRAMReadFragmentShader()); m_vram_read_pixel_shader = m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateVRAMReadFragmentShader());
if (!m_vram_read_pixel_shader) if (!m_vram_read_pixel_shader)
return false; return false;
UPDATE_PROGRESS();
m_vram_write_pixel_shader = m_vram_write_pixel_shader =
m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateVRAMWriteFragmentShader(false)); m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateVRAMWriteFragmentShader(false));
if (!m_vram_write_pixel_shader) if (!m_vram_write_pixel_shader)
return false; return false;
UPDATE_PROGRESS();
m_vram_copy_pixel_shader = m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateVRAMCopyFragmentShader()); m_vram_copy_pixel_shader = m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateVRAMCopyFragmentShader());
if (!m_vram_copy_pixel_shader) if (!m_vram_copy_pixel_shader)
return false; return false;
UPDATE_PROGRESS();
m_vram_update_depth_pixel_shader = m_vram_update_depth_pixel_shader =
m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateVRAMUpdateDepthFragmentShader()); m_shader_cache.GetPixelShader(m_device.Get(), shadergen.GenerateVRAMUpdateDepthFragmentShader());
if (!m_vram_update_depth_pixel_shader) if (!m_vram_update_depth_pixel_shader)
return false; return false;
UPDATE_PROGRESS();
for (u8 depth_24bit = 0; depth_24bit < 2; depth_24bit++) for (u8 depth_24bit = 0; depth_24bit < 2; depth_24bit++)
{ {
for (u8 interlacing = 0; interlacing < 3; interlacing++) for (u8 interlacing = 0; interlacing < 3; interlacing++)
@ -474,9 +510,15 @@ bool GPU_HW_D3D11::CompileShaders()
m_display_pixel_shaders[depth_24bit][interlacing] = m_shader_cache.GetPixelShader(m_device.Get(), ps); m_display_pixel_shaders[depth_24bit][interlacing] = m_shader_cache.GetPixelShader(m_device.Get(), ps);
if (!m_display_pixel_shaders[depth_24bit][interlacing]) if (!m_display_pixel_shaders[depth_24bit][interlacing])
return false; return false;
UPDATE_PROGRESS();
} }
} }
UPDATE_PROGRESS();
#undef UPDATE_PROGRESS
return true; return true;
} }

View file

@ -1,6 +1,7 @@
#include "gpu_hw_opengl.h" #include "gpu_hw_opengl.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/log.h" #include "common/log.h"
#include "common/timer.h"
#include "gpu_hw_shadergen.h" #include "gpu_hw_shadergen.h"
#include "host_display.h" #include "host_display.h"
#include "system.h" #include "system.h"
@ -358,7 +359,19 @@ bool GPU_HW_OpenGL::CompilePrograms()
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_scaled_dithering, GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_scaled_dithering,
m_texture_filtering, m_using_uv_limits, m_supports_dual_source_blend); m_texture_filtering, m_using_uv_limits, m_supports_dual_source_blend);
g_host_interface->DisplayLoadingScreen("Compiling Shaders..."); Common::Timer compile_time;
const int progress_total = (4 * 9 * 2 * 2) + (2 * 3) + 5;
int progress_value = 0;
#define UPDATE_PROGRESS() \
do \
{ \
progress_value++; \
if (compile_time.GetTimeSeconds() >= 1.0f) \
{ \
compile_time.Reset(); \
g_host_interface->DisplayLoadingScreen("Compiling Shaders", 0, progress_total, progress_value); \
} \
} while (0)
for (u32 render_mode = 0; render_mode < 4; render_mode++) for (u32 render_mode = 0; render_mode < 4; render_mode++)
{ {
@ -416,6 +429,8 @@ bool GPU_HW_OpenGL::CompilePrograms()
} }
m_render_programs[render_mode][texture_mode][dithering][interlacing] = std::move(*prog); m_render_programs[render_mode][texture_mode][dithering][interlacing] = std::move(*prog);
UPDATE_PROGRESS();
} }
} }
} }
@ -444,6 +459,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
prog->Uniform1i("samp0", 0); prog->Uniform1i("samp0", 0);
} }
m_display_programs[depth_24bit][interlaced] = std::move(*prog); m_display_programs[depth_24bit][interlaced] = std::move(*prog);
UPDATE_PROGRESS();
} }
} }
@ -460,6 +476,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
prog->BindUniformBlock("UBOBlock", 1); prog->BindUniformBlock("UBOBlock", 1);
m_vram_interlaced_fill_program = std::move(*prog); m_vram_interlaced_fill_program = std::move(*prog);
UPDATE_PROGRESS();
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {}, prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
shadergen.GenerateVRAMReadFragmentShader(), shadergen.GenerateVRAMReadFragmentShader(),
@ -477,6 +494,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
prog->Uniform1i("samp0", 0); prog->Uniform1i("samp0", 0);
} }
m_vram_read_program = std::move(*prog); m_vram_read_program = std::move(*prog);
UPDATE_PROGRESS();
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {}, prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
shadergen.GenerateVRAMCopyFragmentShader(), shadergen.GenerateVRAMCopyFragmentShader(),
@ -494,6 +512,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
prog->Uniform1i("samp0", 0); prog->Uniform1i("samp0", 0);
} }
m_vram_copy_program = std::move(*prog); m_vram_copy_program = std::move(*prog);
UPDATE_PROGRESS();
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {}, prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
shadergen.GenerateVRAMUpdateDepthFragmentShader()); shadergen.GenerateVRAMUpdateDepthFragmentShader());
@ -503,6 +522,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
prog->Bind(); prog->Bind();
prog->Uniform1i("samp0", 0); prog->Uniform1i("samp0", 0);
m_vram_update_depth_program = std::move(*prog); m_vram_update_depth_program = std::move(*prog);
UPDATE_PROGRESS();
if (m_supports_texture_buffer || m_use_ssbo_for_vram_writes) if (m_supports_texture_buffer || m_use_ssbo_for_vram_writes)
{ {
@ -524,6 +544,9 @@ bool GPU_HW_OpenGL::CompilePrograms()
m_vram_write_program = std::move(*prog); m_vram_write_program = std::move(*prog);
} }
UPDATE_PROGRESS();
#undef UPDATE_PROGRESS
return true; return true;
} }

View file

@ -2,6 +2,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/log.h" #include "common/log.h"
#include "common/scope_guard.h" #include "common/scope_guard.h"
#include "common/timer.h"
#include "common/vulkan/builders.h" #include "common/vulkan/builders.h"
#include "common/vulkan/context.h" #include "common/vulkan/context.h"
#include "common/vulkan/shader_cache.h" #include "common/vulkan/shader_cache.h"
@ -579,14 +580,26 @@ bool GPU_HW_Vulkan::CreateTextureBuffer()
bool GPU_HW_Vulkan::CompilePipelines() bool GPU_HW_Vulkan::CompilePipelines()
{ {
g_host_interface->DisplayLoadingScreen("Compiling Shaders...");
VkDevice device = g_vulkan_context->GetDevice(); VkDevice device = g_vulkan_context->GetDevice();
VkPipelineCache pipeline_cache = g_vulkan_shader_cache->GetPipelineCache(); VkPipelineCache pipeline_cache = g_vulkan_shader_cache->GetPipelineCache();
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_scaled_dithering, GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_scaled_dithering,
m_texture_filtering, m_using_uv_limits, m_supports_dual_source_blend); m_texture_filtering, m_using_uv_limits, m_supports_dual_source_blend);
Common::Timer compile_time;
const int progress_total = 2 + (4 * 9 * 2 * 2) + (2 * 4 * 5 * 9 * 2 * 2) + 1 + 2 + 2 + 2 + 2 + (2 * 3);
int progress_value = 0;
#define UPDATE_PROGRESS() \
do \
{ \
progress_value++; \
if (compile_time.GetTimeSeconds() >= 1.0f) \
{ \
compile_time.Reset(); \
g_host_interface->DisplayLoadingScreen("Compiling Shaders", 0, progress_total, progress_value); \
} \
} while (0)
// vertex shaders - [textured] // vertex shaders - [textured]
// fragment shaders - [render_mode][texture_mode][dithering][interlacing] // fragment shaders - [render_mode][texture_mode][dithering][interlacing]
DimensionalArray<VkShaderModule, 2> batch_vertex_shaders{}; DimensionalArray<VkShaderModule, 2> batch_vertex_shaders{};
@ -604,6 +617,7 @@ bool GPU_HW_Vulkan::CompilePipelines()
return false; return false;
batch_vertex_shaders[textured] = shader; batch_vertex_shaders[textured] = shader;
UPDATE_PROGRESS();
} }
for (u8 render_mode = 0; render_mode < 4; render_mode++) for (u8 render_mode = 0; render_mode < 4; render_mode++)
@ -623,6 +637,7 @@ bool GPU_HW_Vulkan::CompilePipelines()
return false; return false;
batch_fragment_shaders[render_mode][texture_mode][dithering][interlacing] = shader; batch_fragment_shaders[render_mode][texture_mode][dithering][interlacing] = shader;
UPDATE_PROGRESS();
} }
} }
} }
@ -630,7 +645,7 @@ bool GPU_HW_Vulkan::CompilePipelines()
Vulkan::GraphicsPipelineBuilder gpbuilder; Vulkan::GraphicsPipelineBuilder gpbuilder;
// [primitive][depth_test][render_mode][texture_mode][transparency_mode][dithering][interlacing] // [depth_test][render_mode][texture_mode][transparency_mode][dithering][interlacing]
for (u8 depth_test = 0; depth_test < 2; depth_test++) for (u8 depth_test = 0; depth_test < 2; depth_test++)
{ {
for (u8 render_mode = 0; render_mode < 4; render_mode++) for (u8 render_mode = 0; render_mode < 4; render_mode++)
@ -692,6 +707,7 @@ bool GPU_HW_Vulkan::CompilePipelines()
m_batch_pipelines[depth_test][render_mode][texture_mode][transparency_mode][dithering][interlacing] = m_batch_pipelines[depth_test][render_mode][texture_mode][transparency_mode][dithering][interlacing] =
pipeline; pipeline;
UPDATE_PROGRESS();
} }
} }
} }
@ -706,6 +722,8 @@ bool GPU_HW_Vulkan::CompilePipelines()
if (fullscreen_quad_vertex_shader == VK_NULL_HANDLE) if (fullscreen_quad_vertex_shader == VK_NULL_HANDLE)
return false; return false;
UPDATE_PROGRESS();
Common::ScopeGuard fullscreen_quad_vertex_shader_guard([&fullscreen_quad_vertex_shader]() { Common::ScopeGuard fullscreen_quad_vertex_shader_guard([&fullscreen_quad_vertex_shader]() {
vkDestroyShaderModule(g_vulkan_context->GetDevice(), fullscreen_quad_vertex_shader, nullptr); vkDestroyShaderModule(g_vulkan_context->GetDevice(), fullscreen_quad_vertex_shader, nullptr);
}); });
@ -736,6 +754,8 @@ bool GPU_HW_Vulkan::CompilePipelines()
vkDestroyShaderModule(device, fs, nullptr); vkDestroyShaderModule(device, fs, nullptr);
if (m_vram_fill_pipelines[interlaced] == VK_NULL_HANDLE) if (m_vram_fill_pipelines[interlaced] == VK_NULL_HANDLE)
return false; return false;
UPDATE_PROGRESS();
} }
} }
@ -758,6 +778,8 @@ bool GPU_HW_Vulkan::CompilePipelines()
vkDestroyShaderModule(device, fs, nullptr); vkDestroyShaderModule(device, fs, nullptr);
return false; return false;
} }
UPDATE_PROGRESS();
} }
vkDestroyShaderModule(device, fs, nullptr); vkDestroyShaderModule(device, fs, nullptr);
@ -782,6 +804,8 @@ bool GPU_HW_Vulkan::CompilePipelines()
vkDestroyShaderModule(device, fs, nullptr); vkDestroyShaderModule(device, fs, nullptr);
return false; return false;
} }
UPDATE_PROGRESS();
} }
vkDestroyShaderModule(device, fs, nullptr); vkDestroyShaderModule(device, fs, nullptr);
@ -804,6 +828,8 @@ bool GPU_HW_Vulkan::CompilePipelines()
vkDestroyShaderModule(device, fs, nullptr); vkDestroyShaderModule(device, fs, nullptr);
if (m_vram_update_depth_pipeline == VK_NULL_HANDLE) if (m_vram_update_depth_pipeline == VK_NULL_HANDLE)
return false; return false;
UPDATE_PROGRESS();
} }
gpbuilder.Clear(); gpbuilder.Clear();
@ -827,6 +853,8 @@ bool GPU_HW_Vulkan::CompilePipelines()
vkDestroyShaderModule(device, fs, nullptr); vkDestroyShaderModule(device, fs, nullptr);
if (m_vram_readback_pipeline == VK_NULL_HANDLE) if (m_vram_readback_pipeline == VK_NULL_HANDLE)
return false; return false;
UPDATE_PROGRESS();
} }
gpbuilder.Clear(); gpbuilder.Clear();
@ -856,10 +884,14 @@ bool GPU_HW_Vulkan::CompilePipelines()
vkDestroyShaderModule(device, fs, nullptr); vkDestroyShaderModule(device, fs, nullptr);
if (m_display_pipelines[depth_24][interlace_mode] == VK_NULL_HANDLE) if (m_display_pipelines[depth_24][interlace_mode] == VK_NULL_HANDLE)
return false; return false;
UPDATE_PROGRESS();
} }
} }
} }
#undef UPDATE_PROGRESS
return true; return true;
} }