gl_shader_cache: Move OGL shader compilation to the respective Pipeline constructor
This commit is contained in:
parent
39c29664f9
commit
413eb6983f
|
@ -7,6 +7,7 @@
|
||||||
#include "common/cityhash.h"
|
#include "common/cityhash.h"
|
||||||
#include "video_core/renderer_opengl/gl_compute_pipeline.h"
|
#include "video_core/renderer_opengl/gl_compute_pipeline.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||||
|
#include "video_core/renderer_opengl/gl_shader_util.h"
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
|
@ -39,10 +40,16 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
|
||||||
BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
|
BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
|
||||||
Tegra::Engines::KeplerCompute& kepler_compute_,
|
Tegra::Engines::KeplerCompute& kepler_compute_,
|
||||||
ProgramManager& program_manager_, const Shader::Info& info_,
|
ProgramManager& program_manager_, const Shader::Info& info_,
|
||||||
OGLProgram source_program_, OGLAssemblyProgram assembly_program_)
|
const std::string code)
|
||||||
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
|
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
|
||||||
kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_},
|
kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} {
|
||||||
source_program{std::move(source_program_)}, assembly_program{std::move(assembly_program_)} {
|
if (device.UseAssemblyShaders()) {
|
||||||
|
assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV);
|
||||||
|
} else {
|
||||||
|
source_program.handle = glCreateProgram();
|
||||||
|
AttachShader(GL_COMPUTE_SHADER, source_program.handle, code);
|
||||||
|
LinkProgram(source_program.handle);
|
||||||
|
}
|
||||||
std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
|
std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
|
||||||
uniform_buffer_sizes.begin());
|
uniform_buffer_sizes.begin());
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
|
BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
|
||||||
Tegra::Engines::KeplerCompute& kepler_compute_,
|
Tegra::Engines::KeplerCompute& kepler_compute_,
|
||||||
ProgramManager& program_manager_, const Shader::Info& info_,
|
ProgramManager& program_manager_, const Shader::Info& info_,
|
||||||
OGLProgram source_program_, OGLAssemblyProgram assembly_program_);
|
const std::string code);
|
||||||
|
|
||||||
void Configure();
|
void Configure();
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "shader_recompiler/shader_info.h"
|
#include "shader_recompiler/shader_info.h"
|
||||||
#include "video_core/renderer_opengl/gl_graphics_pipeline.h"
|
#include "video_core/renderer_opengl/gl_graphics_pipeline.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||||
|
#include "video_core/renderer_opengl/gl_shader_util.h"
|
||||||
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
||||||
#include "video_core/texture_cache/texture_cache.h"
|
#include "video_core/texture_cache/texture_cache.h"
|
||||||
|
|
||||||
|
@ -33,6 +34,40 @@ u32 AccumulateCount(const Range& range) {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLenum Stage(size_t stage_index) {
|
||||||
|
switch (stage_index) {
|
||||||
|
case 0:
|
||||||
|
return GL_VERTEX_SHADER;
|
||||||
|
case 1:
|
||||||
|
return GL_TESS_CONTROL_SHADER;
|
||||||
|
case 2:
|
||||||
|
return GL_TESS_EVALUATION_SHADER;
|
||||||
|
case 3:
|
||||||
|
return GL_GEOMETRY_SHADER;
|
||||||
|
case 4:
|
||||||
|
return GL_FRAGMENT_SHADER;
|
||||||
|
}
|
||||||
|
UNREACHABLE_MSG("{}", stage_index);
|
||||||
|
return GL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum AssemblyStage(size_t stage_index) {
|
||||||
|
switch (stage_index) {
|
||||||
|
case 0:
|
||||||
|
return GL_VERTEX_PROGRAM_NV;
|
||||||
|
case 1:
|
||||||
|
return GL_TESS_CONTROL_PROGRAM_NV;
|
||||||
|
case 2:
|
||||||
|
return GL_TESS_EVALUATION_PROGRAM_NV;
|
||||||
|
case 3:
|
||||||
|
return GL_GEOMETRY_PROGRAM_NV;
|
||||||
|
case 4:
|
||||||
|
return GL_FRAGMENT_PROGRAM_NV;
|
||||||
|
}
|
||||||
|
UNREACHABLE_MSG("{}", stage_index);
|
||||||
|
return GL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/// Translates hardware transform feedback indices
|
/// Translates hardware transform feedback indices
|
||||||
/// @param location Hardware location
|
/// @param location Hardware location
|
||||||
/// @return Pair of ARB_transform_feedback3 token stream first and third arguments
|
/// @return Pair of ARB_transform_feedback3 token stream first and third arguments
|
||||||
|
@ -82,20 +117,34 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
|
||||||
BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
|
BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
|
||||||
Tegra::Engines::Maxwell3D& maxwell3d_,
|
Tegra::Engines::Maxwell3D& maxwell3d_,
|
||||||
ProgramManager& program_manager_, StateTracker& state_tracker_,
|
ProgramManager& program_manager_, StateTracker& state_tracker_,
|
||||||
OGLProgram program_,
|
const std::array<std::string, 5> assembly_sources,
|
||||||
std::array<OGLAssemblyProgram, 5> assembly_programs_,
|
const std::array<std::string, 5> glsl_sources,
|
||||||
const std::array<const Shader::Info*, 5>& infos,
|
const std::array<const Shader::Info*, 5>& infos,
|
||||||
const VideoCommon::TransformFeedbackState* xfb_state)
|
const VideoCommon::TransformFeedbackState* xfb_state)
|
||||||
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
|
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
|
||||||
gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_},
|
maxwell3d{maxwell3d_}, program_manager{program_manager_}, state_tracker{state_tracker_} {
|
||||||
state_tracker{state_tracker_}, program{std::move(program_)}, assembly_programs{std::move(
|
|
||||||
assembly_programs_)} {
|
|
||||||
std::ranges::transform(infos, stage_infos.begin(),
|
std::ranges::transform(infos, stage_infos.begin(),
|
||||||
[](const Shader::Info* info) { return info ? *info : Shader::Info{}; });
|
[](const Shader::Info* info) { return info ? *info : Shader::Info{}; });
|
||||||
|
if (device.UseAssemblyShaders()) {
|
||||||
for (size_t stage = 0; stage < 5; ++stage) {
|
for (size_t stage = 0; stage < 5; ++stage) {
|
||||||
|
const auto code{assembly_sources[stage]};
|
||||||
|
if (code.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assembly_programs[stage] = CompileProgram(code, AssemblyStage(stage));
|
||||||
enabled_stages_mask |= (assembly_programs[stage].handle != 0 ? 1 : 0) << stage;
|
enabled_stages_mask |= (assembly_programs[stage].handle != 0 ? 1 : 0) << stage;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
program.handle = glCreateProgram();
|
||||||
|
for (size_t stage = 0; stage < 5; ++stage) {
|
||||||
|
const auto code{glsl_sources[stage]};
|
||||||
|
if (code.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AttachShader(Stage(stage), program.handle, code);
|
||||||
|
}
|
||||||
|
LinkProgram(program.handle);
|
||||||
|
}
|
||||||
u32 num_textures{};
|
u32 num_textures{};
|
||||||
u32 num_images{};
|
u32 num_images{};
|
||||||
u32 num_storage_buffers{};
|
u32 num_storage_buffers{};
|
||||||
|
|
|
@ -65,8 +65,8 @@ public:
|
||||||
BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
|
BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
|
||||||
Tegra::Engines::Maxwell3D& maxwell3d_,
|
Tegra::Engines::Maxwell3D& maxwell3d_,
|
||||||
ProgramManager& program_manager_, StateTracker& state_tracker_,
|
ProgramManager& program_manager_, StateTracker& state_tracker_,
|
||||||
OGLProgram program_,
|
const std::array<std::string, 5> assembly_sources,
|
||||||
std::array<OGLAssemblyProgram, 5> assembly_programs_,
|
const std::array<std::string, 5> glsl_sources,
|
||||||
const std::array<const Shader::Info*, 5>& infos,
|
const std::array<const Shader::Info*, 5>& infos,
|
||||||
const VideoCommon::TransformFeedbackState* xfb_state);
|
const VideoCommon::TransformFeedbackState* xfb_state);
|
||||||
|
|
||||||
|
|
|
@ -56,40 +56,6 @@ auto MakeSpan(Container& container) {
|
||||||
return std::span(container.data(), container.size());
|
return std::span(container.data(), container.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum Stage(size_t stage_index) {
|
|
||||||
switch (stage_index) {
|
|
||||||
case 0:
|
|
||||||
return GL_VERTEX_SHADER;
|
|
||||||
case 1:
|
|
||||||
return GL_TESS_CONTROL_SHADER;
|
|
||||||
case 2:
|
|
||||||
return GL_TESS_EVALUATION_SHADER;
|
|
||||||
case 3:
|
|
||||||
return GL_GEOMETRY_SHADER;
|
|
||||||
case 4:
|
|
||||||
return GL_FRAGMENT_SHADER;
|
|
||||||
}
|
|
||||||
UNREACHABLE_MSG("{}", stage_index);
|
|
||||||
return GL_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum AssemblyStage(size_t stage_index) {
|
|
||||||
switch (stage_index) {
|
|
||||||
case 0:
|
|
||||||
return GL_VERTEX_PROGRAM_NV;
|
|
||||||
case 1:
|
|
||||||
return GL_TESS_CONTROL_PROGRAM_NV;
|
|
||||||
case 2:
|
|
||||||
return GL_TESS_EVALUATION_PROGRAM_NV;
|
|
||||||
case 3:
|
|
||||||
return GL_GEOMETRY_PROGRAM_NV;
|
|
||||||
case 4:
|
|
||||||
return GL_FRAGMENT_PROGRAM_NV;
|
|
||||||
}
|
|
||||||
UNREACHABLE_MSG("{}", stage_index);
|
|
||||||
return GL_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
|
Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
|
||||||
const Shader::IR::Program& program,
|
const Shader::IR::Program& program,
|
||||||
bool glasm_use_storage_buffers, bool use_assembly_shaders) {
|
bool glasm_use_storage_buffers, bool use_assembly_shaders) {
|
||||||
|
@ -426,12 +392,10 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
||||||
std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{};
|
std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{};
|
||||||
|
|
||||||
OGLProgram source_program;
|
OGLProgram source_program;
|
||||||
std::array<OGLAssemblyProgram, 5> assembly_programs;
|
std::array<std::string, 5> assembly_sources;
|
||||||
|
std::array<std::string, 5> glsl_sources;
|
||||||
Shader::Backend::Bindings binding;
|
Shader::Backend::Bindings binding;
|
||||||
const bool use_glasm{device.UseAssemblyShaders()};
|
const bool use_glasm{device.UseAssemblyShaders()};
|
||||||
if (!use_glasm) {
|
|
||||||
source_program.handle = glCreateProgram();
|
|
||||||
}
|
|
||||||
const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0;
|
const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0;
|
||||||
for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) {
|
for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) {
|
||||||
if (key.unique_hashes[index] == 0) {
|
if (key.unique_hashes[index] == 0) {
|
||||||
|
@ -446,20 +410,14 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
||||||
const auto runtime_info{
|
const auto runtime_info{
|
||||||
MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)};
|
MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)};
|
||||||
if (use_glasm) {
|
if (use_glasm) {
|
||||||
const std::string code{EmitGLASM(profile, runtime_info, program, binding)};
|
assembly_sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding);
|
||||||
assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index));
|
|
||||||
} else {
|
} else {
|
||||||
const auto code{EmitGLSL(profile, runtime_info, program, binding)};
|
glsl_sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding);
|
||||||
AttachShader(Stage(stage_index), source_program.handle, code);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!use_glasm) {
|
|
||||||
LinkProgram(source_program.handle);
|
|
||||||
}
|
|
||||||
return std::make_unique<GraphicsPipeline>(
|
return std::make_unique<GraphicsPipeline>(
|
||||||
device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker,
|
device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker,
|
||||||
std::move(source_program), std::move(assembly_programs), infos,
|
assembly_sources, glsl_sources, infos, key.xfb_enabled != 0 ? &key.xfb_state : nullptr);
|
||||||
key.xfb_enabled != 0 ? &key.xfb_state : nullptr);
|
|
||||||
|
|
||||||
} catch (Shader::Exception& exception) {
|
} catch (Shader::Exception& exception) {
|
||||||
LOG_ERROR(Render_OpenGL, "{}", exception.what());
|
LOG_ERROR(Render_OpenGL, "{}", exception.what());
|
||||||
|
@ -496,21 +454,10 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools&
|
||||||
}
|
}
|
||||||
Shader::RuntimeInfo info;
|
Shader::RuntimeInfo info;
|
||||||
info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();
|
info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();
|
||||||
|
const std::string code{device.UseAssemblyShaders() ? EmitGLASM(profile, info, program)
|
||||||
OGLAssemblyProgram asm_program;
|
: EmitGLSL(profile, program)};
|
||||||
OGLProgram source_program;
|
|
||||||
if (device.UseAssemblyShaders()) {
|
|
||||||
const std::string code{EmitGLASM(profile, info, program)};
|
|
||||||
asm_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV);
|
|
||||||
} else {
|
|
||||||
const auto code{EmitGLSL(profile, program)};
|
|
||||||
source_program.handle = glCreateProgram();
|
|
||||||
AttachShader(GL_COMPUTE_SHADER, source_program.handle, code);
|
|
||||||
LinkProgram(source_program.handle);
|
|
||||||
}
|
|
||||||
return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory,
|
return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory,
|
||||||
kepler_compute, program_manager, program.info,
|
kepler_compute, program_manager, program.info, code);
|
||||||
std::move(source_program), std::move(asm_program));
|
|
||||||
} catch (Shader::Exception& exception) {
|
} catch (Shader::Exception& exception) {
|
||||||
LOG_ERROR(Render_OpenGL, "{}", exception.what());
|
LOG_ERROR(Render_OpenGL, "{}", exception.what());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
Reference in New Issue