summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.cpp17
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.h2
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_device.h11
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp64
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h1
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp40
7 files changed, 105 insertions, 38 deletions
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index 2d6442d74..c63e87a56 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -5,6 +5,7 @@
5#include <cstring> 5#include <cstring>
6 6
7#include "common/cityhash.h" 7#include "common/cityhash.h"
8#include "common/settings.h" // for enum class Settings::ShaderBackend
8#include "video_core/renderer_opengl/gl_compute_pipeline.h" 9#include "video_core/renderer_opengl/gl_compute_pipeline.h"
9#include "video_core/renderer_opengl/gl_shader_manager.h" 10#include "video_core/renderer_opengl/gl_shader_manager.h"
10#include "video_core/renderer_opengl/gl_shader_util.h" 11#include "video_core/renderer_opengl/gl_shader_util.h"
@@ -40,15 +41,23 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
40 BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, 41 BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
41 Tegra::Engines::KeplerCompute& kepler_compute_, 42 Tegra::Engines::KeplerCompute& kepler_compute_,
42 ProgramManager& program_manager_, const Shader::Info& info_, 43 ProgramManager& program_manager_, const Shader::Info& info_,
43 std::string code) 44 std::string code, std::vector<u32> code_v)
44 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_}, 45 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
45 kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} { 46 kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} {
46 if (device.UseAssemblyShaders()) { 47 switch (device.GetShaderBackend()) {
47 assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV); 48 case Settings::ShaderBackend::GLSL:
48 } else {
49 source_program.handle = glCreateProgram(); 49 source_program.handle = glCreateProgram();
50 AttachShader(GL_COMPUTE_SHADER, source_program.handle, code); 50 AttachShader(GL_COMPUTE_SHADER, source_program.handle, code);
51 LinkProgram(source_program.handle); 51 LinkProgram(source_program.handle);
52 break;
53 case Settings::ShaderBackend::GLASM:
54 assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV);
55 break;
56 case Settings::ShaderBackend::SPIRV:
57 source_program.handle = glCreateProgram();
58 AttachShader(GL_COMPUTE_SHADER, source_program.handle, code_v);
59 LinkProgram(source_program.handle);
60 break;
52 } 61 }
53 std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(), 62 std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
54 uniform_buffer_sizes.begin()); 63 uniform_buffer_sizes.begin());
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.h b/src/video_core/renderer_opengl/gl_compute_pipeline.h
index b5fc45f26..50c676365 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.h
@@ -54,7 +54,7 @@ public:
54 BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, 54 BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
55 Tegra::Engines::KeplerCompute& kepler_compute_, 55 Tegra::Engines::KeplerCompute& kepler_compute_,
56 ProgramManager& program_manager_, const Shader::Info& info_, 56 ProgramManager& program_manager_, const Shader::Info& info_,
57 std::string code); 57 std::string code, std::vector<u32> code_v);
58 58
59 void Configure(); 59 void Configure();
60 60
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index c4eeed53b..99f8769fc 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -177,6 +177,11 @@ Device::Device() {
177 GLAD_GL_NV_gpu_program5 && GLAD_GL_NV_compute_program5 && GLAD_GL_NV_transform_feedback && 177 GLAD_GL_NV_gpu_program5 && GLAD_GL_NV_compute_program5 && GLAD_GL_NV_transform_feedback &&
178 GLAD_GL_NV_transform_feedback2; 178 GLAD_GL_NV_transform_feedback2;
179 179
180 shader_backend = (Settings::values.shader_backend.GetValue() ==
181 Settings::ShaderBackend::GLASM) == use_assembly_shaders
182 ? Settings::values.shader_backend.GetValue()
183 : Settings::ShaderBackend::GLSL;
184
180 // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation. 185 // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation.
181 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && 186 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() &&
182 !(is_amd || (is_intel && !is_linux)); 187 !(is_amd || (is_intel && !is_linux));
@@ -188,8 +193,7 @@ Device::Device() {
188 LOG_INFO(Render_OpenGL, "Renderer_BrokenTextureViewFormats: {}", 193 LOG_INFO(Render_OpenGL, "Renderer_BrokenTextureViewFormats: {}",
189 has_broken_texture_view_formats); 194 has_broken_texture_view_formats);
190 195
191 if (Settings::values.shader_backend.GetValue() == Settings::ShaderBackend::GLASM && 196 if (shader_backend == Settings::ShaderBackend::GLASM && !use_assembly_shaders) {
192 !use_assembly_shaders) {
193 LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported"); 197 LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported");
194 } 198 }
195 199
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index 45ddf5e01..ee992aed4 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -8,6 +8,10 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "shader_recompiler/stage.h" 9#include "shader_recompiler/stage.h"
10 10
11namespace Settings {
12enum class ShaderBackend : u32;
13};
14
11namespace OpenGL { 15namespace OpenGL {
12 16
13class Device { 17class Device {
@@ -148,6 +152,10 @@ public:
148 return need_fastmath_off; 152 return need_fastmath_off;
149 } 153 }
150 154
155 Settings::ShaderBackend GetShaderBackend() const {
156 return shader_backend;
157 }
158
151private: 159private:
152 static bool TestVariableAoffi(); 160 static bool TestVariableAoffi();
153 static bool TestPreciseBug(); 161 static bool TestPreciseBug();
@@ -159,6 +167,9 @@ private:
159 u32 max_varyings{}; 167 u32 max_varyings{};
160 u32 max_compute_shared_memory_size{}; 168 u32 max_compute_shared_memory_size{};
161 u32 max_glasm_storage_buffer_blocks{}; 169 u32 max_glasm_storage_buffer_blocks{};
170
171 Settings::ShaderBackend shader_backend{};
172
162 bool has_warp_intrinsics{}; 173 bool has_warp_intrinsics{};
163 bool has_shader_ballot{}; 174 bool has_shader_ballot{};
164 bool has_vertex_viewport_layer{}; 175 bool has_vertex_viewport_layer{};
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index a93b03cf7..1f19b5825 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -3,7 +3,11 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <array>
7#include <string>
8#include <vector>
6 9
10#include "common/settings.h" // for enum class Settings::ShaderBackend
7#include "common/thread_worker.h" 11#include "common/thread_worker.h"
8#include "shader_recompiler/shader_info.h" 12#include "shader_recompiler/shader_info.h"
9#include "video_core/renderer_opengl/gl_graphics_pipeline.h" 13#include "video_core/renderer_opengl/gl_graphics_pipeline.h"
@@ -179,7 +183,8 @@ GraphicsPipeline::GraphicsPipeline(
179 Tegra::MemoryManager& gpu_memory_, Tegra::Engines::Maxwell3D& maxwell3d_, 183 Tegra::MemoryManager& gpu_memory_, Tegra::Engines::Maxwell3D& maxwell3d_,
180 ProgramManager& program_manager_, StateTracker& state_tracker_, ShaderWorker* thread_worker, 184 ProgramManager& program_manager_, StateTracker& state_tracker_, ShaderWorker* thread_worker,
181 VideoCore::ShaderNotify* shader_notify, std::array<std::string, 5> sources, 185 VideoCore::ShaderNotify* shader_notify, std::array<std::string, 5> sources,
182 const std::array<const Shader::Info*, 5>& infos, const GraphicsPipelineKey& key_) 186 std::array<std::vector<u32>, 5> sources_spirv, const std::array<const Shader::Info*, 5>& infos,
187 const GraphicsPipelineKey& key_)
183 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, 188 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
184 gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_}, 189 gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_},
185 state_tracker{state_tracker_}, key{key_} { 190 state_tracker{state_tracker_}, key{key_} {
@@ -232,29 +237,44 @@ GraphicsPipeline::GraphicsPipeline(
232 if (key.xfb_enabled && device.UseAssemblyShaders()) { 237 if (key.xfb_enabled && device.UseAssemblyShaders()) {
233 GenerateTransformFeedbackState(); 238 GenerateTransformFeedbackState();
234 } 239 }
235 auto func{[this, device, sources, shader_notify](ShaderContext::Context*) mutable { 240 auto func{
236 if (!device.UseAssemblyShaders()) { 241 [this, device, sources, sources_spirv, shader_notify](ShaderContext::Context*) mutable {
237 program.handle = glCreateProgram(); 242 if (!device.UseAssemblyShaders()) {
238 } 243 program.handle = glCreateProgram();
239 for (size_t stage = 0; stage < 5; ++stage) {
240 const auto code{sources[stage]};
241 if (code.empty()) {
242 continue;
243 } 244 }
244 if (device.UseAssemblyShaders()) { 245 for (size_t stage = 0; stage < 5; ++stage) {
245 assembly_programs[stage] = CompileProgram(code, AssemblyStage(stage)); 246 switch (device.GetShaderBackend()) {
246 } else { 247 case Settings::ShaderBackend::GLSL: {
247 AttachShader(Stage(stage), program.handle, code); 248 const auto code{sources[stage]};
249 if (code.empty()) {
250 continue;
251 }
252 AttachShader(Stage(stage), program.handle, code);
253 } break;
254 case Settings::ShaderBackend::GLASM: {
255 const auto code{sources[stage]};
256 if (code.empty()) {
257 continue;
258 }
259 assembly_programs[stage] = CompileProgram(code, AssemblyStage(stage));
260 } break;
261 case Settings::ShaderBackend::SPIRV: {
262 const auto code{sources_spirv[stage]};
263 if (code.empty()) {
264 continue;
265 }
266 AttachShader(Stage(stage), program.handle, code);
267 } break;
268 }
248 } 269 }
249 } 270 if (!device.UseAssemblyShaders()) {
250 if (!device.UseAssemblyShaders()) { 271 LinkProgram(program.handle);
251 LinkProgram(program.handle); 272 }
252 } 273 if (shader_notify) {
253 if (shader_notify) { 274 shader_notify->MarkShaderComplete();
254 shader_notify->MarkShaderComplete(); 275 }
255 } 276 is_built.store(true, std::memory_order_relaxed);
256 is_built.store(true, std::memory_order_relaxed); 277 }};
257 }};
258 if (thread_worker) { 278 if (thread_worker) {
259 thread_worker->QueueWork(std::move(func)); 279 thread_worker->QueueWork(std::move(func));
260 } else { 280 } else {
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index f82d712f8..5f5d57385 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -78,6 +78,7 @@ public:
78 ProgramManager& program_manager_, StateTracker& state_tracker_, 78 ProgramManager& program_manager_, StateTracker& state_tracker_,
79 ShaderWorker* thread_worker, VideoCore::ShaderNotify* shader_notify, 79 ShaderWorker* thread_worker, VideoCore::ShaderNotify* shader_notify,
80 std::array<std::string, 5> sources, 80 std::array<std::string, 5> sources,
81 std::array<std::vector<u32>, 5> sources_spirv,
81 const std::array<const Shader::Info*, 5>& infos, 82 const std::array<const Shader::Info*, 5>& infos,
82 const GraphicsPipelineKey& key_); 83 const GraphicsPipelineKey& key_);
83 84
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index af8e9f44d..cde0f54c9 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -15,6 +15,7 @@
15#include "common/fs/path_util.h" 15#include "common/fs/path_util.h"
16#include "common/logging/log.h" 16#include "common/logging/log.h"
17#include "common/scope_exit.h" 17#include "common/scope_exit.h"
18#include "common/settings.h"
18#include "common/thread_worker.h" 19#include "common/thread_worker.h"
19#include "core/core.h" 20#include "core/core.h"
20#include "shader_recompiler/backend/glasm/emit_glasm.h" 21#include "shader_recompiler/backend/glasm/emit_glasm.h"
@@ -415,6 +416,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
415 416
416 OGLProgram source_program; 417 OGLProgram source_program;
417 std::array<std::string, 5> sources; 418 std::array<std::string, 5> sources;
419 std::array<std::vector<u32>, 5> sources_spirv;
418 Shader::Backend::Bindings binding; 420 Shader::Backend::Bindings binding;
419 Shader::IR::Program* previous_program{}; 421 Shader::IR::Program* previous_program{};
420 const bool use_glasm{device.UseAssemblyShaders()}; 422 const bool use_glasm{device.UseAssemblyShaders()};
@@ -431,17 +433,23 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
431 433
432 const auto runtime_info{ 434 const auto runtime_info{
433 MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)}; 435 MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)};
434 if (use_glasm) { 436 switch (device.GetShaderBackend()) {
435 sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); 437 case Settings::ShaderBackend::GLSL:
436 } else {
437 sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); 438 sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding);
439 break;
440 case Settings::ShaderBackend::GLASM:
441 sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding);
442 break;
443 case Settings::ShaderBackend::SPIRV:
444 sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding);
445 break;
438 } 446 }
439 previous_program = &program; 447 previous_program = &program;
440 } 448 }
441 auto* const thread_worker{build_in_parallel ? workers.get() : nullptr}; 449 auto* const thread_worker{build_in_parallel ? workers.get() : nullptr};
442 return std::make_unique<GraphicsPipeline>(device, texture_cache, buffer_cache, gpu_memory, 450 return std::make_unique<GraphicsPipeline>(
443 maxwell3d, program_manager, state_tracker, 451 device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker,
444 thread_worker, &shader_notify, sources, infos, key); 452 thread_worker, &shader_notify, sources, sources_spirv, infos, key);
445 453
446} catch (Shader::Exception& exception) { 454} catch (Shader::Exception& exception) {
447 LOG_ERROR(Render_OpenGL, "{}", exception.what()); 455 LOG_ERROR(Render_OpenGL, "{}", exception.what());
@@ -478,10 +486,24 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
478 } 486 }
479 Shader::RuntimeInfo info; 487 Shader::RuntimeInfo info;
480 info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks(); 488 info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();
481 const std::string code{device.UseAssemblyShaders() ? EmitGLASM(profile, info, program) 489
482 : EmitGLSL(profile, program)}; 490 std::string code{};
491 std::vector<u32> code_spirv;
492 switch (device.GetShaderBackend()) {
493 case Settings::ShaderBackend::GLSL:
494 code = EmitGLSL(profile, program);
495 break;
496 case Settings::ShaderBackend::GLASM:
497 code = EmitGLASM(profile, info, program);
498 break;
499 case Settings::ShaderBackend::SPIRV:
500 code_spirv = EmitSPIRV(profile, program);
501 break;
502 }
503
483 return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory, 504 return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory,
484 kepler_compute, program_manager, program.info, code); 505 kepler_compute, program_manager, program.info, code,
506 code_spirv);
485} catch (Shader::Exception& exception) { 507} catch (Shader::Exception& exception) {
486 LOG_ERROR(Render_OpenGL, "{}", exception.what()); 508 LOG_ERROR(Render_OpenGL, "{}", exception.what());
487 return nullptr; 509 return nullptr;