summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp62
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h100
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.cpp57
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.h6
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp11
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h3
-rw-r--r--src/video_core/renderer_opengl/util_shaders.cpp19
9 files changed, 154 insertions, 116 deletions
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index c63e87a56..aa1cc592f 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -46,17 +46,13 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
46 kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} { 46 kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} {
47 switch (device.GetShaderBackend()) { 47 switch (device.GetShaderBackend()) {
48 case Settings::ShaderBackend::GLSL: 48 case Settings::ShaderBackend::GLSL:
49 source_program.handle = glCreateProgram(); 49 source_program = CreateProgram(code, GL_COMPUTE_SHADER);
50 AttachShader(GL_COMPUTE_SHADER, source_program.handle, code);
51 LinkProgram(source_program.handle);
52 break; 50 break;
53 case Settings::ShaderBackend::GLASM: 51 case Settings::ShaderBackend::GLASM:
54 assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV); 52 assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV);
55 break; 53 break;
56 case Settings::ShaderBackend::SPIRV: 54 case Settings::ShaderBackend::SPIRV:
57 source_program.handle = glCreateProgram(); 55 source_program = CreateProgram(code_v, GL_COMPUTE_SHADER);
58 AttachShader(GL_COMPUTE_SHADER, source_program.handle, code_v);
59 LinkProgram(source_program.handle);
60 break; 56 break;
61 } 57 }
62 std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(), 58 std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
@@ -154,7 +150,7 @@ void ComputePipeline::Configure() {
154 if (assembly_program.handle != 0) { 150 if (assembly_program.handle != 0) {
155 program_manager.BindComputeAssemblyProgram(assembly_program.handle); 151 program_manager.BindComputeAssemblyProgram(assembly_program.handle);
156 } else { 152 } else {
157 program_manager.BindProgram(source_program.handle); 153 program_manager.BindComputeProgram(source_program.handle);
158 } 154 }
159 buffer_cache.UnbindComputeTextureBuffers(); 155 buffer_cache.UnbindComputeTextureBuffers();
160 size_t texbuf_index{}; 156 size_t texbuf_index{};
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 1f19b5825..c8b2d833d 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -237,44 +237,32 @@ GraphicsPipeline::GraphicsPipeline(
237 if (key.xfb_enabled && device.UseAssemblyShaders()) { 237 if (key.xfb_enabled && device.UseAssemblyShaders()) {
238 GenerateTransformFeedbackState(); 238 GenerateTransformFeedbackState();
239 } 239 }
240 auto func{ 240 auto func{[this, device, sources, sources_spirv,
241 [this, device, sources, sources_spirv, shader_notify](ShaderContext::Context*) mutable { 241 shader_notify](ShaderContext::Context*) mutable {
242 if (!device.UseAssemblyShaders()) { 242 for (size_t stage = 0; stage < 5; ++stage) {
243 program.handle = glCreateProgram(); 243 switch (device.GetShaderBackend()) {
244 } 244 case Settings::ShaderBackend::GLSL:
245 for (size_t stage = 0; stage < 5; ++stage) { 245 if (!sources[stage].empty()) {
246 switch (device.GetShaderBackend()) { 246 source_programs[stage] = CreateProgram(sources[stage], Stage(stage));
247 case Settings::ShaderBackend::GLSL: {
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 } 247 }
248 break;
249 case Settings::ShaderBackend::GLASM:
250 if (!sources[stage].empty()) {
251 assembly_programs[stage] = CompileProgram(sources[stage], AssemblyStage(stage));
252 }
253 break;
254 case Settings::ShaderBackend::SPIRV:
255 if (!sources_spirv[stage].empty()) {
256 source_programs[stage] = CreateProgram(sources_spirv[stage], Stage(stage));
257 }
258 break;
269 } 259 }
270 if (!device.UseAssemblyShaders()) { 260 }
271 LinkProgram(program.handle); 261 if (shader_notify) {
272 } 262 shader_notify->MarkShaderComplete();
273 if (shader_notify) { 263 }
274 shader_notify->MarkShaderComplete(); 264 is_built = true;
275 } 265 }};
276 is_built.store(true, std::memory_order_relaxed);
277 }};
278 if (thread_worker) { 266 if (thread_worker) {
279 thread_worker->QueueWork(std::move(func)); 267 thread_worker->QueueWork(std::move(func));
280 } else { 268 } else {
@@ -449,7 +437,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
449 if (assembly_programs[0].handle != 0) { 437 if (assembly_programs[0].handle != 0) {
450 program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask); 438 program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask);
451 } else { 439 } else {
452 program_manager.BindProgram(program.handle); 440 program_manager.BindSourcePrograms(source_programs);
453 } 441 }
454 const ImageId* views_it{image_view_ids.data()}; 442 const ImageId* views_it{image_view_ids.data()};
455 GLsizei texture_binding = 0; 443 GLsizei texture_binding = 0;
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index 5f5d57385..5e34b9537 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -129,7 +129,7 @@ private:
129 129
130 void (*configure_func)(GraphicsPipeline*, bool){}; 130 void (*configure_func)(GraphicsPipeline*, bool){};
131 131
132 OGLProgram program; 132 std::array<OGLProgram, 5> source_programs;
133 std::array<OGLAssemblyProgram, 5> assembly_programs; 133 std::array<OGLAssemblyProgram, 5> assembly_programs;
134 u32 enabled_stages_mask{}; 134 u32 enabled_stages_mask{};
135 135
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index 88b734bcb..d7ef0775d 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -24,34 +24,68 @@ class ProgramManager {
24 24
25public: 25public:
26 explicit ProgramManager(const Device& device) { 26 explicit ProgramManager(const Device& device) {
27 glCreateProgramPipelines(1, &pipeline.handle);
27 if (device.UseAssemblyShaders()) { 28 if (device.UseAssemblyShaders()) {
28 glEnable(GL_COMPUTE_PROGRAM_NV); 29 glEnable(GL_COMPUTE_PROGRAM_NV);
29 } 30 }
30 } 31 }
31 32
32 void BindProgram(GLuint program) { 33 void BindComputeProgram(GLuint program) {
33 if (current_source_program == program) {
34 return;
35 }
36 current_source_program = program;
37 glUseProgram(program); 34 glUseProgram(program);
35 is_compute_bound = true;
38 } 36 }
39 37
40 void BindComputeAssemblyProgram(GLuint program) { 38 void BindComputeAssemblyProgram(GLuint program) {
41 if (current_compute_assembly_program != program) { 39 if (current_assembly_compute_program != program) {
42 current_compute_assembly_program = program; 40 current_assembly_compute_program = program;
43 glBindProgramARB(GL_COMPUTE_PROGRAM_NV, program); 41 glBindProgramARB(GL_COMPUTE_PROGRAM_NV, program);
44 } 42 }
45 if (current_source_program != 0) { 43 UnbindPipeline();
46 current_source_program = 0; 44 }
47 glUseProgram(0); 45
46 void BindSourcePrograms(std::span<const OGLProgram, NUM_STAGES> programs) {
47 static constexpr std::array<GLenum, 5> stage_enums{
48 GL_VERTEX_SHADER_BIT, GL_TESS_CONTROL_SHADER_BIT, GL_TESS_EVALUATION_SHADER_BIT,
49 GL_GEOMETRY_SHADER_BIT, GL_FRAGMENT_SHADER_BIT,
50 };
51 for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
52 if (current_programs[stage] != programs[stage].handle) {
53 current_programs[stage] = programs[stage].handle;
54 glUseProgramStages(pipeline.handle, stage_enums[stage], programs[stage].handle);
55 }
56 }
57 BindPipeline();
58 }
59
60 void BindPresentPrograms(GLuint vertex, GLuint fragment) {
61 if (current_programs[0] != vertex) {
62 current_programs[0] = vertex;
63 glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, vertex);
64 }
65 if (current_programs[4] != fragment) {
66 current_programs[4] = fragment;
67 glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fragment);
68 }
69 glUseProgramStages(
70 pipeline.handle,
71 GL_TESS_CONTROL_SHADER_BIT | GL_TESS_EVALUATION_SHADER_BIT | GL_GEOMETRY_SHADER_BIT, 0);
72 current_programs[1] = 0;
73 current_programs[2] = 0;
74 current_programs[3] = 0;
75
76 if (current_stage_mask != 0) {
77 current_stage_mask = 0;
78 for (const GLenum program_type : ASSEMBLY_PROGRAM_ENUMS) {
79 glDisable(program_type);
80 }
48 } 81 }
82 BindPipeline();
49 } 83 }
50 84
51 void BindAssemblyPrograms(std::span<const OGLAssemblyProgram, NUM_STAGES> programs, 85 void BindAssemblyPrograms(std::span<const OGLAssemblyProgram, NUM_STAGES> programs,
52 u32 stage_mask) { 86 u32 stage_mask) {
53 const u32 changed_mask = current_assembly_mask ^ stage_mask; 87 const u32 changed_mask = current_stage_mask ^ stage_mask;
54 current_assembly_mask = stage_mask; 88 current_stage_mask = stage_mask;
55 89
56 if (changed_mask != 0) { 90 if (changed_mask != 0) {
57 for (size_t stage = 0; stage < NUM_STAGES; ++stage) { 91 for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
@@ -65,25 +99,47 @@ public:
65 } 99 }
66 } 100 }
67 for (size_t stage = 0; stage < NUM_STAGES; ++stage) { 101 for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
68 if (current_assembly_programs[stage] != programs[stage].handle) { 102 if (current_programs[stage] != programs[stage].handle) {
69 current_assembly_programs[stage] = programs[stage].handle; 103 current_programs[stage] = programs[stage].handle;
70 glBindProgramARB(ASSEMBLY_PROGRAM_ENUMS[stage], programs[stage].handle); 104 glBindProgramARB(ASSEMBLY_PROGRAM_ENUMS[stage], programs[stage].handle);
71 } 105 }
72 } 106 }
73 if (current_source_program != 0) { 107 UnbindPipeline();
74 current_source_program = 0;
75 glUseProgram(0);
76 }
77 } 108 }
78 109
79 void RestoreGuestCompute() {} 110 void RestoreGuestCompute() {}
80 111
81private: 112private:
82 GLuint current_source_program = 0; 113 void BindPipeline() {
114 if (!is_pipeline_bound) {
115 is_pipeline_bound = true;
116 glBindProgramPipeline(pipeline.handle);
117 }
118 UnbindCompute();
119 }
120
121 void UnbindPipeline() {
122 if (is_pipeline_bound) {
123 is_pipeline_bound = false;
124 glBindProgramPipeline(0);
125 }
126 UnbindCompute();
127 }
128
129 void UnbindCompute() {
130 if (is_compute_bound) {
131 is_compute_bound = false;
132 glUseProgram(0);
133 }
134 }
135
136 OGLPipeline pipeline;
137 bool is_pipeline_bound{};
138 bool is_compute_bound{};
83 139
84 u32 current_assembly_mask = 0; 140 u32 current_stage_mask = 0;
85 std::array<GLuint, NUM_STAGES> current_assembly_programs{}; 141 std::array<GLuint, NUM_STAGES> current_programs{};
86 GLuint current_compute_assembly_program = 0; 142 GLuint current_assembly_compute_program = 0;
87}; 143};
88 144
89} // namespace OpenGL 145} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp
index 5109985f1..d432072ad 100644
--- a/src/video_core/renderer_opengl/gl_shader_util.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_util.cpp
@@ -13,6 +13,33 @@
13 13
14namespace OpenGL { 14namespace OpenGL {
15 15
16static OGLProgram LinkSeparableProgram(GLuint shader) {
17 OGLProgram program;
18 program.handle = glCreateProgram();
19 glProgramParameteri(program.handle, GL_PROGRAM_SEPARABLE, GL_TRUE);
20 glAttachShader(program.handle, shader);
21 glLinkProgram(program.handle);
22 if (!Settings::values.renderer_debug) {
23 return program;
24 }
25 GLint link_status{};
26 glGetProgramiv(program.handle, GL_LINK_STATUS, &link_status);
27
28 GLint log_length{};
29 glGetProgramiv(program.handle, GL_INFO_LOG_LENGTH, &log_length);
30 if (log_length == 0) {
31 return program;
32 }
33 std::string log(log_length, 0);
34 glGetProgramInfoLog(program.handle, log_length, nullptr, log.data());
35 if (link_status == GL_FALSE) {
36 LOG_ERROR(Render_OpenGL, "{}", log);
37 } else {
38 LOG_WARNING(Render_OpenGL, "{}", log);
39 }
40 return program;
41}
42
16static void LogShader(GLuint shader, std::string_view code = {}) { 43static void LogShader(GLuint shader, std::string_view code = {}) {
17 GLint shader_status{}; 44 GLint shader_status{};
18 glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_status); 45 glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_status);
@@ -36,7 +63,7 @@ static void LogShader(GLuint shader, std::string_view code = {}) {
36 } 63 }
37} 64}
38 65
39void AttachShader(GLenum stage, GLuint program, std::string_view code) { 66OGLProgram CreateProgram(std::string_view code, GLenum stage) {
40 OGLShader shader; 67 OGLShader shader;
41 shader.handle = glCreateShader(stage); 68 shader.handle = glCreateShader(stage);
42 69
@@ -44,45 +71,23 @@ void AttachShader(GLenum stage, GLuint program, std::string_view code) {
44 const GLchar* const code_ptr = code.data(); 71 const GLchar* const code_ptr = code.data();
45 glShaderSource(shader.handle, 1, &code_ptr, &length); 72 glShaderSource(shader.handle, 1, &code_ptr, &length);
46 glCompileShader(shader.handle); 73 glCompileShader(shader.handle);
47 glAttachShader(program, shader.handle);
48 if (Settings::values.renderer_debug) { 74 if (Settings::values.renderer_debug) {
49 LogShader(shader.handle, code); 75 LogShader(shader.handle, code);
50 } 76 }
77 return LinkSeparableProgram(shader.handle);
51} 78}
52 79
53void AttachShader(GLenum stage, GLuint program, std::span<const u32> code) { 80OGLProgram CreateProgram(std::span<const u32> code, GLenum stage) {
54 OGLShader shader; 81 OGLShader shader;
55 shader.handle = glCreateShader(stage); 82 shader.handle = glCreateShader(stage);
56 83
57 glShaderBinary(1, &shader.handle, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, code.data(), 84 glShaderBinary(1, &shader.handle, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, code.data(),
58 static_cast<GLsizei>(code.size_bytes())); 85 static_cast<GLsizei>(code.size_bytes()));
59 glSpecializeShader(shader.handle, "main", 0, nullptr, nullptr); 86 glSpecializeShader(shader.handle, "main", 0, nullptr, nullptr);
60 glAttachShader(program, shader.handle);
61 if (Settings::values.renderer_debug) { 87 if (Settings::values.renderer_debug) {
62 LogShader(shader.handle); 88 LogShader(shader.handle);
63 } 89 }
64} 90 return LinkSeparableProgram(shader.handle);
65
66void LinkProgram(GLuint program) {
67 glLinkProgram(program);
68 if (!Settings::values.renderer_debug) {
69 return;
70 }
71 GLint link_status{};
72 glGetProgramiv(program, GL_LINK_STATUS, &link_status);
73
74 GLint log_length{};
75 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
76 if (log_length == 0) {
77 return;
78 }
79 std::string log(log_length, 0);
80 glGetProgramInfoLog(program, log_length, nullptr, log.data());
81 if (link_status == GL_FALSE) {
82 LOG_ERROR(Render_OpenGL, "{}", log);
83 } else {
84 LOG_WARNING(Render_OpenGL, "{}", log);
85 }
86} 91}
87 92
88OGLAssemblyProgram CompileProgram(std::string_view code, GLenum target) { 93OGLAssemblyProgram CompileProgram(std::string_view code, GLenum target) {
diff --git a/src/video_core/renderer_opengl/gl_shader_util.h b/src/video_core/renderer_opengl/gl_shader_util.h
index ff5aa024f..4e1a2a8e1 100644
--- a/src/video_core/renderer_opengl/gl_shader_util.h
+++ b/src/video_core/renderer_opengl/gl_shader_util.h
@@ -17,11 +17,9 @@
17 17
18namespace OpenGL { 18namespace OpenGL {
19 19
20void AttachShader(GLenum stage, GLuint program, std::string_view code); 20OGLProgram CreateProgram(std::string_view code, GLenum stage);
21 21
22void AttachShader(GLenum stage, GLuint program, std::span<const u32> code); 22OGLProgram CreateProgram(std::span<const u32> code, GLenum stage);
23
24void LinkProgram(GLuint program);
25 23
26OGLAssemblyProgram CompileProgram(std::string_view code, GLenum target); 24OGLAssemblyProgram CompileProgram(std::string_view code, GLenum target);
27 25
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index c9cfa6366..d15167e19 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -251,10 +251,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
251 251
252void RendererOpenGL::InitOpenGLObjects() { 252void RendererOpenGL::InitOpenGLObjects() {
253 // Create shader programs 253 // Create shader programs
254 present_program.handle = glCreateProgram(); 254 present_vertex = CreateProgram(HostShaders::OPENGL_PRESENT_VERT, GL_VERTEX_SHADER);
255 AttachShader(GL_VERTEX_SHADER, present_program.handle, HostShaders::OPENGL_PRESENT_VERT); 255 present_fragment = CreateProgram(HostShaders::OPENGL_PRESENT_FRAG, GL_FRAGMENT_SHADER);
256 AttachShader(GL_FRAGMENT_SHADER, present_program.handle, HostShaders::OPENGL_PRESENT_FRAG);
257 LinkProgram(present_program.handle);
258 256
259 // Generate presentation sampler 257 // Generate presentation sampler
260 present_sampler.Create(); 258 present_sampler.Create();
@@ -340,8 +338,9 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
340 // Set projection matrix 338 // Set projection matrix
341 const std::array ortho_matrix = 339 const std::array ortho_matrix =
342 MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); 340 MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
343 program_manager.BindProgram(present_program.handle); 341 program_manager.BindPresentPrograms(present_vertex.handle, present_fragment.handle);
344 glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data()); 342 glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE,
343 ortho_matrix.data());
345 344
346 const auto& texcoords = screen_info.display_texcoords; 345 const auto& texcoords = screen_info.display_texcoords;
347 auto left = texcoords.left; 346 auto left = texcoords.left;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index b3ee55665..d455f572f 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -110,7 +110,8 @@ private:
110 // OpenGL object IDs 110 // OpenGL object IDs
111 OGLSampler present_sampler; 111 OGLSampler present_sampler;
112 OGLBuffer vertex_buffer; 112 OGLBuffer vertex_buffer;
113 OGLProgram present_program; 113 OGLProgram present_vertex;
114 OGLProgram present_fragment;
114 OGLFramebuffer screenshot_framebuffer; 115 OGLFramebuffer screenshot_framebuffer;
115 116
116 // GPU address of the vertex buffer 117 // GPU address of the vertex buffer
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp
index 8aa0683c8..37a4d1d9d 100644
--- a/src/video_core/renderer_opengl/util_shaders.cpp
+++ b/src/video_core/renderer_opengl/util_shaders.cpp
@@ -42,12 +42,7 @@ using VideoCore::Surface::BytesPerBlock;
42 42
43namespace { 43namespace {
44OGLProgram MakeProgram(std::string_view source) { 44OGLProgram MakeProgram(std::string_view source) {
45 OGLProgram program; 45 return CreateProgram(source, GL_COMPUTE_SHADER);
46 OGLShader shader;
47 program.handle = glCreateProgram();
48 AttachShader(GL_COMPUTE_SHADER, program.handle, source);
49 LinkProgram(program.handle);
50 return program;
51} 46}
52 47
53size_t NumPixelsInCopy(const VideoCommon::ImageCopy& copy) { 48size_t NumPixelsInCopy(const VideoCommon::ImageCopy& copy) {
@@ -84,7 +79,7 @@ void UtilShaders::ASTCDecode(Image& image, const ImageBufferMap& map,
84 .width = VideoCore::Surface::DefaultBlockWidth(image.info.format), 79 .width = VideoCore::Surface::DefaultBlockWidth(image.info.format),
85 .height = VideoCore::Surface::DefaultBlockHeight(image.info.format), 80 .height = VideoCore::Surface::DefaultBlockHeight(image.info.format),
86 }; 81 };
87 program_manager.BindProgram(astc_decoder_program.handle); 82 program_manager.BindComputeProgram(astc_decoder_program.handle);
88 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); 83 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle);
89 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_ENC_BUFFER, astc_buffer.handle); 84 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_ENC_BUFFER, astc_buffer.handle);
90 85
@@ -132,7 +127,7 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map,
132 static constexpr GLuint BINDING_INPUT_BUFFER = 1; 127 static constexpr GLuint BINDING_INPUT_BUFFER = 1;
133 static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; 128 static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
134 129
135 program_manager.BindProgram(block_linear_unswizzle_2d_program.handle); 130 program_manager.BindComputeProgram(block_linear_unswizzle_2d_program.handle);
136 glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); 131 glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
137 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); 132 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle);
138 133
@@ -171,7 +166,7 @@ void UtilShaders::BlockLinearUpload3D(Image& image, const ImageBufferMap& map,
171 static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; 166 static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
172 167
173 glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); 168 glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
174 program_manager.BindProgram(block_linear_unswizzle_3d_program.handle); 169 program_manager.BindComputeProgram(block_linear_unswizzle_3d_program.handle);
175 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); 170 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle);
176 171
177 const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format)); 172 const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format));
@@ -220,7 +215,7 @@ void UtilShaders::PitchUpload(Image& image, const ImageBufferMap& map,
220 UNIMPLEMENTED_IF_MSG(!std::has_single_bit(bytes_per_block), 215 UNIMPLEMENTED_IF_MSG(!std::has_single_bit(bytes_per_block),
221 "Non-power of two images are not implemented"); 216 "Non-power of two images are not implemented");
222 217
223 program_manager.BindProgram(pitch_unswizzle_program.handle); 218 program_manager.BindComputeProgram(pitch_unswizzle_program.handle);
224 glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); 219 glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
225 glUniform2ui(LOC_ORIGIN, 0, 0); 220 glUniform2ui(LOC_ORIGIN, 0, 0);
226 glUniform2i(LOC_DESTINATION, 0, 0); 221 glUniform2i(LOC_DESTINATION, 0, 0);
@@ -248,7 +243,7 @@ void UtilShaders::CopyBC4(Image& dst_image, Image& src_image, std::span<const Im
248 static constexpr GLuint LOC_SRC_OFFSET = 0; 243 static constexpr GLuint LOC_SRC_OFFSET = 0;
249 static constexpr GLuint LOC_DST_OFFSET = 1; 244 static constexpr GLuint LOC_DST_OFFSET = 1;
250 245
251 program_manager.BindProgram(copy_bc4_program.handle); 246 program_manager.BindComputeProgram(copy_bc4_program.handle);
252 247
253 for (const ImageCopy& copy : copies) { 248 for (const ImageCopy& copy : copies) {
254 ASSERT(copy.src_subresource.base_layer == 0); 249 ASSERT(copy.src_subresource.base_layer == 0);
@@ -284,7 +279,7 @@ void UtilShaders::CopyBGR(Image& dst_image, Image& src_image,
284 break; 279 break;
285 case 4: { 280 case 4: {
286 // BGRA8 copy 281 // BGRA8 copy
287 program_manager.BindProgram(copy_bgra_program.handle); 282 program_manager.BindComputeProgram(copy_bgra_program.handle);
288 constexpr GLenum FORMAT = GL_RGBA8; 283 constexpr GLenum FORMAT = GL_RGBA8;
289 for (const ImageCopy& copy : copies) { 284 for (const ImageCopy& copy : copies) {
290 ASSERT(copy.src_offset == zero_offset); 285 ASSERT(copy.src_offset == zero_offset);