This commit is contained in:
goeiecool9999 2026-04-18 16:08:54 +00:00 committed by GitHub
commit 00442e7e99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 161 additions and 142 deletions

View File

@ -73,8 +73,8 @@ add_definitions(-DEMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH})
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# enable link time optimization for release builds
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)
#set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)#
#set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)#
if (MSVC)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT CemuBin)

View File

@ -14,6 +14,7 @@
#include "util/helpers/StringParser.h"
#include "config/ActiveSettings.h"
#include "Cafe/GameProfile/GameProfile.h"
#include "HW/Latte/Renderer/OpenGL/RendererShaderGL.h"
#include "util/containers/flat_hash_map.hpp"
#if ENABLE_METAL
#include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h"
@ -360,23 +361,15 @@ void LatteShader_CreateRendererShader(LatteDecompilerShader* shader, bool compil
}
// create shader
shader->shader = g_renderer->shader_create(shaderType, shader->baseHash, shader->auxHash, shaderSrc, true, shader->isCustomShader);
shader->shader = g_renderer->shader_create(shaderType, shader->baseHash, shader->auxHash, std::move(shaderSrc), true, shader->isCustomShader);
if (shader->shader == nullptr)
shader->hasError = true;
// after renderer shader creation we can throw away any intermediate info
LatteShader_CleanupAfterCompile(shader);
}
void LatteShader_FinishCompilation(LatteDecompilerShader* shader)
{
if (shader->hasError)
if (g_renderer->GetType() == RendererAPI::OpenGL)
{
cemuLog_logDebug(LogType::Force, "LatteShader_finishCompilation(): Skipped because of error in shader {:x}", shader->baseHash);
return;
RendererShaderGL* shaderGL = static_cast<RendererShaderGL*>(shader->shader);
shaderGL->SetDecompilerShader(shader);
}
shader->shader->WaitForCompiled();
LatteShader_prepareSeparableUniforms(shader);
// after renderer shader creation we can throw away any intermediate info
LatteShader_CleanupAfterCompile(shader);
}
@ -845,13 +838,6 @@ LatteDecompilerShader* LatteShader_CompileSeparableVertexShader(uint64 baseHash,
LatteShader_CreateRendererShader(vertexShader, false);
performanceMonitor.numCompiledVS++;
if (g_renderer->GetType() == RendererAPI::OpenGL)
{
if (vertexShader->shader)
vertexShader->shader->PreponeCompilation(true);
LatteShader_FinishCompilation(vertexShader);
}
LatteSHRC_RegisterShader(vertexShader, vertexShader->baseHash, vertexShader->auxHash);
return vertexShader;
}
@ -874,13 +860,6 @@ LatteDecompilerShader* LatteShader_CompileSeparableGeometryShader(uint64 baseHas
LatteShader_CreateRendererShader(geometryShader, false);
performanceMonitor.numCompiledGS++;
if (g_renderer->GetType() == RendererAPI::OpenGL)
{
if (geometryShader->shader)
geometryShader->shader->PreponeCompilation(true);
LatteShader_FinishCompilation(geometryShader);
}
LatteSHRC_RegisterShader(geometryShader, geometryShader->baseHash, geometryShader->auxHash);
return geometryShader;
}
@ -903,13 +882,6 @@ LatteDecompilerShader* LatteShader_CompileSeparablePixelShader(uint64 baseHash,
LatteShaderCache_writeSeparablePixelShader(_shaderBaseHash_ps, psAuxHash, pixelShaderPtr, pixelShaderSize, LatteGPUState.contextRegister, usesGeometryShader);
}
if (g_renderer->GetType() == RendererAPI::OpenGL)
{
if (pixelShader->shader)
pixelShader->shader->PreponeCompilation(true);
LatteShader_FinishCompilation(pixelShader);
}
LatteSHRC_RegisterShader(pixelShader, _shaderBaseHash_ps, psAuxHash);
return pixelShader;
}

View File

@ -100,7 +100,6 @@ void LatteShader_GetDecompilerOptions(struct LatteDecompilerOptions& options, La
LatteDecompilerShader* LatteShader_CreateShaderFromDecompilerOutput(LatteDecompilerOutput_t& decompilerOutput, uint64 baseHash, bool calculateAuxHash, uint64 optionalAuxHash, uint32* contextRegister);
void LatteShader_CreateRendererShader(LatteDecompilerShader* shader, bool compileAsync);
void LatteShader_FinishCompilation(LatteDecompilerShader* shader);
void LatteShader_prepareSeparableUniforms(LatteDecompilerShader* shader);

View File

@ -106,13 +106,24 @@ void LatteShaderCache_removeFromCompileQueue(sint32 index)
*/
void LatteShaderCache_updateCompileQueue(sint32 maxRemainingEntries)
{
// remove any shaders that are already done
for (size_t i = 0; i < shaderCompileQueue.count; i++)
{
auto shaderEntry = shaderCompileQueue.entry[i].shader;
if (!shaderEntry)
continue;
if (shaderEntry->shader->IsCompiled())
{
LatteShaderCache_removeFromCompileQueue(i);
}
}
while (true)
{
if (shaderCompileQueue.count <= maxRemainingEntries)
break;
auto shader = shaderCompileQueue.entry[0].shader;
if (shader)
LatteShader_FinishCompilation(shader);
shader->shader->PreponeCompilation();
LatteShaderCache_removeFromCompileQueue(0);
}
}

View File

@ -26,7 +26,7 @@ bool gxShader_checkIfSuccessfullyLinked(GLuint glProgram)
void LatteShader_prepareSeparableUniforms(LatteDecompilerShader* shader)
{
if (g_renderer->GetType() != RendererAPI::OpenGL)
if(shader->hasError)
return;
auto shaderGL = (RendererShaderGL*)shader->shader;

View File

@ -176,8 +176,8 @@ static RendererShaderMtl* rectsEmulationGS_generate(MetalRenderer* metalRenderer
gsSrc.append("}\r\n");
auto mtlShader = new RendererShaderMtl(metalRenderer, RendererShader::ShaderType::kGeometry, 0, 0, false, false, gsSrc);
mtlShader->PreponeCompilation(true);
auto mtlShader = new RendererShaderMtl(metalRenderer, RendererShader::ShaderType::kGeometry, 0, 0, false, false, std::move(gsSrc));
mtlShader->PreponeCompilation();
return mtlShader;
}
@ -321,11 +321,11 @@ bool MetalPipelineCompiler::Compile(bool forceCompile, bool isRenderThread, bool
{
// if some shader stages are not compiled yet, compile them now
if (m_vertexShaderMtl && !m_vertexShaderMtl->IsCompiled())
m_vertexShaderMtl->PreponeCompilation(isRenderThread);
m_vertexShaderMtl->PreponeCompilation();
if (m_geometryShaderMtl && !m_geometryShaderMtl->IsCompiled())
m_geometryShaderMtl->PreponeCompilation(isRenderThread);
m_geometryShaderMtl->PreponeCompilation();
if (m_pixelShaderMtl && !m_pixelShaderMtl->IsCompiled())
m_pixelShaderMtl->PreponeCompilation(isRenderThread);
m_pixelShaderMtl->PreponeCompilation();
}
else
{

View File

@ -996,9 +996,9 @@ void MetalRenderer::buffer_bindUniformBuffer(LatteConst::ShaderType shaderType,
m_state.m_uniformBufferOffsets[GetMtlGeneralShaderType(shaderType)][bufferIndex] = offset;
}
RendererShader* MetalRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool isGameShader, bool isGfxPackShader)
RendererShader* MetalRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, std::string&& source, bool isGameShader, bool isGfxPackShader)
{
return new RendererShaderMtl(this, type, baseHash, auxHash, isGameShader, isGfxPackShader, source);
return new RendererShaderMtl(this, type, baseHash, auxHash, isGameShader, isGfxPackShader, std::move(source));
}
void MetalRenderer::streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize)

View File

@ -241,7 +241,7 @@ public:
void buffer_bindUniformBuffer(LatteConst::ShaderType shaderType, uint32 bufferIndex, uint32 offset, uint32 size) override;
// shader
RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool compileAsync, bool isGfxPackSource) override;
RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, std::string&& source, bool compileAsync, bool isGfxPackSource) override;
// streamout
void streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) override;

View File

@ -213,8 +213,8 @@ void RendererShaderMtl::Shutdown()
shaderMtlThreadPool.StopThreads();
}
RendererShaderMtl::RendererShaderMtl(MetalRenderer* mtlRenderer, ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, const std::string& mslCode)
: RendererShader(type, baseHash, auxHash, isGameShader, isGfxPackShader), m_mtlr{mtlRenderer}, m_mslCode{mslCode}
RendererShaderMtl::RendererShaderMtl(MetalRenderer* mtlRenderer, ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, std::string&& mslCode)
: RendererShader(type, baseHash, auxHash, isGameShader, isGfxPackShader), m_mtlr{mtlRenderer}, m_mslCode{std::move(mslCode)}
{
// start async compilation
shaderMtlThreadPool.s_compilationQueueMutex.lock();
@ -231,7 +231,7 @@ RendererShaderMtl::~RendererShaderMtl()
m_function->release();
}
void RendererShaderMtl::PreponeCompilation(bool isRenderThread)
void RendererShaderMtl::PreponeCompilation()
{
shaderMtlThreadPool.s_compilationQueueMutex.lock();
bool isStillQueued = m_compilationState.hasState(COMPILATION_STATE::QUEUED);

View File

@ -28,7 +28,7 @@ public:
static void Initialize();
static void Shutdown();
RendererShaderMtl(class MetalRenderer* mtlRenderer, ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, const std::string& mslCode);
RendererShaderMtl(class MetalRenderer* mtlRenderer, ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, std::string&& mslCode);
virtual ~RendererShaderMtl();
MTL::Function* GetFunction() const
@ -36,7 +36,7 @@ public:
return m_function;
}
void PreponeCompilation(bool isRenderThread) override;
void PreponeCompilation() override;
bool IsCompiled() override;
bool WaitForCompiled() override;

View File

@ -1306,9 +1306,9 @@ void OpenGLRenderer::attributeStream_unbindVertexBuffer()
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
RendererShader* OpenGLRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool isGameShader, bool isGfxPackShader)
RendererShader* OpenGLRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, std::string&& source, bool isGameShader, bool isGfxPackShader)
{
return new RendererShaderGL(type, baseHash, auxHash, isGameShader, isGfxPackShader, source);
return new RendererShaderGL(type, baseHash, auxHash, isGameShader, isGfxPackShader, std::move(source));
}
void OpenGLRenderer::shader_bind(RendererShader* shader)

View File

@ -145,7 +145,7 @@ public:
void uniformData_update();
// shader
RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool isGameShader, bool isGfxPackShader) override;
RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, std::string&& source, bool isGameShader, bool isGfxPackShader) override;
void shader_bind(RendererShader* shader);
void shader_unbind(RendererShader::ShaderType shaderType);

View File

@ -867,8 +867,8 @@ RendererShaderGL* rectsEmulationGS_generateShaderGL(LatteDecompilerShader* verte
gsSrc.append("}\r\n");
auto glShader = new RendererShaderGL(RendererShader::ShaderType::kGeometry, 0, 0, false, false, gsSrc);
glShader->PreponeCompilation(true);
auto glShader = new RendererShaderGL(RendererShader::ShaderType::kGeometry, 0, 0, false, false, std::move(gsSrc));
glShader->PreponeCompilation();
return glShader;
}
@ -912,9 +912,20 @@ void OpenGLRenderer::draw_genericDrawHandler(uint32 baseVertex, uint32 baseInsta
{
beginPerfMonProfiling(performanceMonitor.gpuTime_dcStageShaderAndUniformMgr);
LatteSHRC_UpdateActiveShaders();
LatteDecompilerShader* vs = (LatteDecompilerShader*)LatteSHRC_GetActiveVertexShader();
LatteDecompilerShader* gs = (LatteDecompilerShader*)LatteSHRC_GetActiveGeometryShader();
LatteDecompilerShader* ps = (LatteDecompilerShader*)LatteSHRC_GetActivePixelShader();
LatteDecompilerShader* vs = LatteSHRC_GetActiveVertexShader();
LatteDecompilerShader* gs = LatteSHRC_GetActiveGeometryShader();
LatteDecompilerShader* ps = LatteSHRC_GetActivePixelShader();
for (auto& i : {vs, gs, ps})
{
if (!i)
continue;
if (!i->shader->IsCompiled())
{
i->shader->WaitForCompiled();
}
}
if (vs)
shader_bind(vs->shader);
else

View File

@ -2,6 +2,7 @@
#include "Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h"
#include "Cemu/FileCache/FileCache.h"
#include "HW/Latte/Core/LatteShader.h"
#include "config/ActiveSettings.h"
#include "config/LaunchSettings.h"
@ -42,7 +43,7 @@ bool RendererShaderGL::loadBinary()
m_program = 0;
return false;
}
m_isCompiled = true;
m_binaryLoaded = true;
return true;
}
@ -73,8 +74,8 @@ void RendererShaderGL::storeBinary()
}
}
RendererShaderGL::RendererShaderGL(ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, const std::string& glslSource)
: RendererShader(type, baseHash, auxHash, isGameShader, isGfxPackShader), m_glslSource(glslSource)
RendererShaderGL::RendererShaderGL(ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, std::string&& glslSource)
: RendererShader(type, baseHash, auxHash, isGameShader, isGfxPackShader), m_glslSource(std::move(glslSource))
{
GLenum glShaderType;
switch (type)
@ -109,19 +110,8 @@ RendererShaderGL::RendererShaderGL(ShaderType type, uint64 baseHash, uint64 auxH
glShaderSource(m_shader_object, 1, &c_str, &size);
glCompileShader(m_shader_object);
GLint log_length;
glGetShaderiv(m_shader_object, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0)
{
char log[2048]{};
GLsizei log_size;
glGetShaderInfoLog(m_shader_object, std::min<uint32>(log_length, sizeof(log) - 1), &log_size, log);
cemuLog_log(LogType::Force, "Error/Warning in shader:");
cemuLog_log(LogType::Force, log);
}
// set debug name
if (LaunchSettings::NSightModeEnabled())
if (LaunchSettings::NSightModeEnabled())
{
auto objNameStr = fmt::format("shader_{:016x}_{:016x}", m_baseHash, m_auxHash);
glObjectLabel(GL_SHADER, m_shader_object, objNameStr.size(), objNameStr.c_str());
@ -134,12 +124,6 @@ RendererShaderGL::RendererShaderGL(ShaderType type, uint64 baseHash, uint64 auxH
m_shader_attached = true;
glLinkProgram(m_program);
storeBinary();
// count shader compilation
if (!s_isLoadingShaders)
++g_compiled_shaders_total;
// we can throw away the GLSL code to conserve RAM
m_glslSource.clear();
m_glslSource.shrink_to_fit();
@ -157,7 +141,7 @@ RendererShaderGL::~RendererShaderGL()
glDeleteProgram(m_program);
}
void RendererShaderGL::PreponeCompilation(bool isRenderThread)
void RendererShaderGL::PreponeCompilation()
{
// the logic for initiating compilation is currently in the constructor
// here we only guarantee that it is finished before we return
@ -168,47 +152,74 @@ void RendererShaderGL::PreponeCompilation(bool isRenderThread)
bool RendererShaderGL::IsCompiled()
{
cemu_assert_debug(false);
return true;
if(m_isCompiled)
return true;
if(!glMaxShaderCompilerThreadsARB || m_binaryLoaded)
{
WaitForCompiled();
return true;
}
GLint isShaderComplete = 0, isProgramComplete = 0;
glGetShaderiv(m_shader_object, GL_COMPLETION_STATUS_ARB, &isShaderComplete);
if(!isShaderComplete)
return false;
glGetProgramiv(m_program, GL_COMPLETION_STATUS_ARB, &isProgramComplete);
if (isProgramComplete)
WaitForCompiled(); // since COMPLETION_STATUS == true, this should be very fast
return m_isCompiled;
}
bool RendererShaderGL::WaitForCompiled()
{
char infoLog[8 * 1024];
if (m_isCompiled)
return true;
if (m_binaryLoaded)
{
LatteShader_prepareSeparableUniforms(m_decompilerShader);
m_isCompiled = true;
return true;
}
char infoLog[8 * 1024];
GLint log_length;
// count shader compilation
if (!s_isLoadingShaders)
++g_compiled_shaders_total;
// check if compilation was successful
GLint compileStatus = GL_FALSE;
glGetShaderiv(m_shader_object, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus == 0)
if (compileStatus == GL_FALSE)
{
uint32 infoLogLength, tempLength;
glGetShaderiv(m_shader_object, GL_INFO_LOG_LENGTH, (GLint *)&infoLogLength);
if (infoLogLength != 0)
glGetShaderiv(m_shader_object, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0)
{
tempLength = sizeof(infoLog) - 1;
glGetShaderInfoLog(m_shader_object, std::min(infoLogLength, tempLength), (GLsizei*)&tempLength, (GLcharARB*)infoLog);
infoLog[tempLength] = '\0';
cemuLog_log(LogType::Force, "Compile error in shader. Log:");
glGetShaderInfoLog(m_shader_object, sizeof(infoLog), &log_length, infoLog);
cemuLog_log(LogType::Force, "Error/Warning in shader:");
cemuLog_log(LogType::Force, infoLog);
}
if (m_shader_object != 0)
glDeleteShader(m_shader_object);
if (m_program != 0)
glDeleteProgram(m_program);
m_program = m_shader_object = 0;
m_isCompiled = true;
return false;
}
// get shader binary
GLint linkStatus = GL_FALSE;
glGetProgramiv(m_program, GL_LINK_STATUS, &linkStatus);
if (linkStatus == 0)
if (linkStatus == GL_FALSE)
{
uint32 infoLogLength, tempLength;
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, (GLint *)&infoLogLength);
if (infoLogLength != 0)
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, (GLint *)&log_length);
if (log_length != 0)
{
tempLength = sizeof(infoLog) - 1;
glGetProgramInfoLog(m_program, std::min(infoLogLength, tempLength), (GLsizei*)&tempLength, (GLcharARB*)infoLog);
infoLog[tempLength] = '\0';
glGetProgramInfoLog(m_program, sizeof(infoLog), &log_length, (GLcharARB*)infoLog);
cemuLog_log(LogType::Force, "Link error in shader. Log:");
cemuLog_log(LogType::Force, infoLog);
}
@ -216,9 +227,19 @@ bool RendererShaderGL::WaitForCompiled()
return false;
}
/*glDetachShader(m_program, m_shader_object);
m_shader_attached = false;*/
glDetachShader(m_program, m_shader_object);
m_shader_attached = false;
glDeleteShader(m_shader_object);
m_shader_object = 0;
storeBinary();
m_isCompiled = true;
if (m_decompilerShader)
{
LatteShader_prepareSeparableUniforms(m_decompilerShader);
}
return true;
}
@ -246,6 +267,10 @@ void RendererShaderGL::SetUniform4iv(sint32 location, void* data, sint32 count)
{
glProgramUniform4iv(m_program, location, count, (const GLint*)data);
}
void RendererShaderGL::SetDecompilerShader(LatteDecompilerShader* decompilerShader)
{
m_decompilerShader = decompilerShader;
}
void RendererShaderGL::ShaderCacheLoading_begin(uint64 cacheTitleId)
{
@ -276,8 +301,8 @@ void RendererShaderGL::ShaderCacheLoading_begin(uint64 cacheTitleId)
{
const uint32 cacheMagic = GeneratePrecompiledCacheId();
const std::string cacheFilename = fmt::format("{:016x}_gl.bin", cacheTitleId);
s_programBinaryCache = FileCache::Open(ActiveSettings::GetCachePath("shaderCache/precompiled/{}", cacheFilename), true, cacheMagic);
if (s_programBinaryCache == nullptr)
s_programBinaryCache.reset(FileCache::Open(ActiveSettings::GetCachePath("shaderCache/precompiled/{}", cacheFilename), true, cacheMagic));
if (!s_programBinaryCache)
cemuLog_log(LogType::Force, "Unable to open OpenGL precompiled cache {}", cacheFilename);
}
s_isLoadingShaders = true;
@ -290,13 +315,10 @@ void RendererShaderGL::ShaderCacheLoading_end()
void RendererShaderGL::ShaderCacheLoading_Close()
{
if(s_programBinaryCache)
{
delete s_programBinaryCache;
s_programBinaryCache = nullptr;
}
s_programBinaryCache.reset();
g_compiled_shaders_total = 0;
g_compiled_shaders_async = 0;
}
FileCache* RendererShaderGL::s_programBinaryCache{};
std::unique_ptr<class FileCache> RendererShaderGL::s_programBinaryCache{};

View File

@ -6,11 +6,11 @@
class RendererShaderGL : public RendererShader
{
public:
RendererShaderGL(ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, const std::string& glslSource);
RendererShaderGL(ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, std::string&& glslSource);
virtual ~RendererShaderGL();
void PreponeCompilation(bool isRenderThread) override;
void PreponeCompilation() override;
bool IsCompiled() override;
bool WaitForCompiled() override;
@ -24,6 +24,8 @@ public:
void SetUniform2fv(sint32 location, void* data, sint32 count);
void SetUniform4iv(sint32 location, void* data, sint32 count);
void SetDecompilerShader(class LatteDecompilerShader* decompilerShader);
static void ShaderCacheLoading_begin(uint64 cacheTitleId);
static void ShaderCacheLoading_end();
static void ShaderCacheLoading_Close();
@ -31,6 +33,7 @@ public:
private:
GLuint m_program;
GLuint m_shader_object;
LatteDecompilerShader* m_decompilerShader = nullptr;
bool loadBinary();
void storeBinary();
@ -39,7 +42,8 @@ private:
bool m_shader_attached{ false };
bool m_isCompiled{ false };
bool m_binaryLoaded { false };
static class FileCache* s_programBinaryCache;
static std::unique_ptr<class FileCache> s_programBinaryCache;
};

View File

@ -131,7 +131,7 @@ public:
virtual void buffer_bindUniformBuffer(LatteConst::ShaderType shaderType, uint32 bufferIndex, uint32 offset, uint32 size) = 0;
// shader
virtual RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool compileAsync, bool isGfxPackSource) = 0;
virtual RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, std::string&& source, bool compileAsync, bool isGfxPackSource) = 0;
// streamout
virtual void streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) = 0;

View File

@ -251,11 +251,11 @@ RendererOutputShader::RendererOutputShader(const std::string& vertex_source, con
else
finalFragmentSrc = PrependFragmentPreamble(fragment_source);
m_vertex_shader.reset(g_renderer->shader_create(RendererShader::ShaderType::kVertex, 0, 0, vertex_source, false, false));
m_fragment_shader.reset(g_renderer->shader_create(RendererShader::ShaderType::kFragment, 0, 0, finalFragmentSrc, false, false));
m_vertex_shader.reset(g_renderer->shader_create(RendererShader::ShaderType::kVertex, 0, 0, std::string(vertex_source), false, false));
m_fragment_shader.reset(g_renderer->shader_create(RendererShader::ShaderType::kFragment, 0, 0, std::string(finalFragmentSrc), false, false));
m_vertex_shader->PreponeCompilation(true);
m_fragment_shader->PreponeCompilation(true);
m_vertex_shader->PreponeCompilation();
m_fragment_shader->PreponeCompilation();
if (!m_vertex_shader->WaitForCompiled())
throw std::exception();

View File

@ -14,7 +14,7 @@ public:
ShaderType GetType() const { return m_type; }
virtual void PreponeCompilation(bool isRenderThread) = 0; // if shader not yet compiled, compile it synchronously (if possible) or alternatively wait for compilation. After this function IsCompiled() is guaranteed to be true
virtual void PreponeCompilation() = 0; // if shader not yet compiled, compile it synchronously (if possible) or alternatively wait for compilation. After this function IsCompiled() is guaranteed to be true
virtual bool IsCompiled() = 0;
virtual bool WaitForCompiled() = 0;

View File

@ -174,7 +174,7 @@ public:
job->m_compilationState.setValue(RendererShaderVk::COMPILATION_STATE::COMPILING);
s_compilationQueueMutex.unlock();
// compile
job->CompileInternal(false);
job->CompileInternal();
++g_compiled_shaders_async;
// mark as compiled
cemu_assert_debug(job->m_compilationState.getValue() == RendererShaderVk::COMPILATION_STATE::COMPILING);
@ -195,8 +195,8 @@ private:
std::atomic<bool> m_threadsActive;
}ShaderVkThreadPool;
RendererShaderVk::RendererShaderVk(ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, const std::string& glslCode)
: RendererShader(type, baseHash, auxHash, isGameShader, isGfxPackShader), m_glslCode(glslCode)
RendererShaderVk::RendererShaderVk(ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, std::string&& glslCode)
: RendererShader(type, baseHash, auxHash, isGameShader, isGfxPackShader), m_glslCode(std::move(glslCode))
{
// start async compilation
ShaderVkThreadPool.s_compilationQueueMutex.lock();
@ -264,7 +264,7 @@ void RendererShaderVk::FinishCompilation()
m_glslCode.shrink_to_fit();
}
void RendererShaderVk::CompileInternal(bool isRenderThread)
void RendererShaderVk::CompileInternal()
{
const bool compileWithDebugInfo = ((VulkanRenderer*)g_renderer.get())->IsTracingToolEnabled();
@ -393,7 +393,7 @@ void RendererShaderVk::CompileInternal(bool isRenderThread)
FinishCompilation();
}
void RendererShaderVk::PreponeCompilation(bool isRenderThread)
void RendererShaderVk::PreponeCompilation()
{
ShaderVkThreadPool.s_compilationQueueMutex.lock();
bool isStillQueued = m_compilationState.hasState(COMPILATION_STATE::QUEUED);
@ -413,7 +413,7 @@ void RendererShaderVk::PreponeCompilation(bool isRenderThread)
else
{
// compile synchronously
CompileInternal(isRenderThread);
CompileInternal();
m_compilationState.setValue(COMPILATION_STATE::DONE);
}
}

View File

@ -25,7 +25,7 @@ public:
static void ShaderCacheLoading_end();
static void ShaderCacheLoading_Close();
RendererShaderVk(ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, const std::string& glslCode);
RendererShaderVk(ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, std::string&& glslCode);
virtual ~RendererShaderVk();
static void Init();
@ -49,12 +49,12 @@ public:
s_dependencyLock.unlock();
}
void PreponeCompilation(bool isRenderThread) override;
void PreponeCompilation() override;
bool IsCompiled() override;
bool WaitForCompiled() override;
private:
void CompileInternal(bool isRenderThread);
void CompileInternal();
void FinishCompilation();

View File

@ -157,8 +157,8 @@ RendererShaderVk* rectsEmulationGS_generate(LatteDecompilerShader* vertexShader,
gsSrc.append("}\r\n");
auto vkShader = new RendererShaderVk(RendererShader::ShaderType::kGeometry, 0, 0, false, false, gsSrc);
vkShader->PreponeCompilation(true);
auto vkShader = new RendererShaderVk(RendererShader::ShaderType::kGeometry, 0, 0, false, false, std::move(gsSrc));
vkShader->PreponeCompilation();
return vkShader;
}
@ -964,11 +964,11 @@ bool PipelineCompiler::Compile(bool forceCompile, bool isRenderThread, bool show
{
// if some shader stages are not compiled yet, compile them now
if (m_vkVertexShader && m_vkVertexShader->IsCompiled() == false)
m_vkVertexShader->PreponeCompilation(isRenderThread);
m_vkVertexShader->PreponeCompilation();
if (m_vkPixelShader && m_vkPixelShader->IsCompiled() == false)
m_vkPixelShader->PreponeCompilation(isRenderThread);
m_vkPixelShader->PreponeCompilation();
if (m_vkGeometryShader && m_vkGeometryShader->IsCompiled() == false)
m_vkGeometryShader->PreponeCompilation(isRenderThread);
m_vkGeometryShader->PreponeCompilation();
}
if (shaderStages.empty())

View File

@ -1293,9 +1293,9 @@ VkDeviceCreateInfo VulkanRenderer::CreateDeviceCreateInfo(const std::vector<VkDe
return createInfo;
}
RendererShader* VulkanRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool isGameShader, bool isGfxPackShader)
RendererShader* VulkanRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, std::string&& source, bool isGameShader, bool isGfxPackShader)
{
return new RendererShaderVk(type, baseHash, auxHash, isGameShader, isGfxPackShader, source);
return new RendererShaderVk(type, baseHash, auxHash, isGameShader, isGfxPackShader, std::move(source));
}
VulkanRenderer::QueueFamilyIndices VulkanRenderer::FindQueueFamilies(VkSurfaceKHR surface, VkPhysicalDevice device)

View File

@ -330,7 +330,7 @@ public:
std::pair<VkBuffer, uint32> buffer_genStrideWorkaroundVertexBuffer(MPTR buffer, uint32 size, uint32 oldStride);
void buffer_bindUniformBuffer(LatteConst::ShaderType shaderType, uint32 bufferIndex, uint32 offset, uint32 size) override;
RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool isGameShader, bool isGfxPackShader) override;
RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, std::string&& source, bool isGameShader, bool isGfxPackShader) override;
IndexAllocation indexData_reserveIndexMemory(uint32 size) override;
void indexData_releaseIndexMemory(IndexAllocation& allocation) override;

View File

@ -180,8 +180,8 @@ RendererShaderVk* _vkGenSurfaceCopyShader_vs()
"}\r\n";
std::string shaderStr(vsShaderSrc);
auto vkShader = new RendererShaderVk(RendererShader::ShaderType::kVertex, 0, 0, false, false, shaderStr);
vkShader->PreponeCompilation(true);
auto vkShader = new RendererShaderVk(RendererShader::ShaderType::kVertex, 0, 0, false, false, std::move(shaderStr));
vkShader->PreponeCompilation();
return vkShader;
}
@ -198,8 +198,8 @@ RendererShaderVk* _vkGenSurfaceCopyShader_ps_colorToDepth()
"}\r\n";
std::string shaderStr(psShaderSrc);
auto vkShader = new RendererShaderVk(RendererShader::ShaderType::kFragment, 0, 0, false, false, shaderStr);
vkShader->PreponeCompilation(true);
auto vkShader = new RendererShaderVk(RendererShader::ShaderType::kFragment, 0, 0, false, false, std::move(shaderStr));
vkShader->PreponeCompilation();
return vkShader;
}
@ -217,8 +217,8 @@ RendererShaderVk* _vkGenSurfaceCopyShader_ps_depthToColor()
"}\r\n";
std::string shaderStr(psShaderSrc);
auto vkShader = new RendererShaderVk(RendererShader::ShaderType::kFragment, 0, 0, false, false, shaderStr);
vkShader->PreponeCompilation(true);
auto vkShader = new RendererShaderVk(RendererShader::ShaderType::kFragment, 0, 0, false, false, std::move(shaderStr));
vkShader->PreponeCompilation();
return vkShader;
}