summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-06-07 17:23:25 -0400
committerGravatar GitHub2019-06-07 17:23:25 -0400
commitde33ad25f52960449a97caa2b25e37e6a35f0710 (patch)
tree5f70bb84aafac68b6c34c95fec033528bff26d4e
parentMerge pull request #2558 from ReinUsesLisp/shader-nodes (diff)
parentgl_buffer_cache: Remove unused ReserveMemory method (diff)
downloadyuzu-de33ad25f52960449a97caa2b25e37e6a35f0710.tar.gz
yuzu-de33ad25f52960449a97caa2b25e37e6a35f0710.tar.xz
yuzu-de33ad25f52960449a97caa2b25e37e6a35f0710.zip
Merge pull request #2514 from ReinUsesLisp/opengl-compat
video_core: Drop OpenGL core in favor of OpenGL compatibility
-rw-r--r--src/core/settings.cpp1
-rw-r--r--src/core/settings.h1
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h3
-rw-r--r--src/video_core/renderer_opengl/gl_primitive_assembler.cpp63
-rw-r--r--src/video_core/renderer_opengl/gl_primitive_assembler.h31
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp51
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h6
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp20
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h8
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_state.h7
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h9
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp2
-rw-r--r--src/video_core/textures/texture.h2
-rw-r--r--src/yuzu/bootmanager.cpp8
-rw-r--r--src/yuzu/configuration/config.cpp4
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp3
-rw-r--r--src/yuzu/configuration/configure_graphics.ui7
-rw-r--r--src/yuzu_cmd/config.cpp2
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp6
24 files changed, 45 insertions, 252 deletions
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index c1365879b..6d32ebea3 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -90,7 +90,6 @@ void LogSettings() {
90 LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); 90 LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor);
91 LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit); 91 LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit);
92 LogSetting("Renderer_FrameLimit", Settings::values.frame_limit); 92 LogSetting("Renderer_FrameLimit", Settings::values.frame_limit);
93 LogSetting("Renderer_UseCompatibilityProfile", Settings::values.use_compatibility_profile);
94 LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache); 93 LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache);
95 LogSetting("Renderer_UseAccurateGpuEmulation", Settings::values.use_accurate_gpu_emulation); 94 LogSetting("Renderer_UseAccurateGpuEmulation", Settings::values.use_accurate_gpu_emulation);
96 LogSetting("Renderer_UseAsynchronousGpuEmulation", 95 LogSetting("Renderer_UseAsynchronousGpuEmulation",
diff --git a/src/core/settings.h b/src/core/settings.h
index 5ff3634aa..b84390745 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -390,7 +390,6 @@ struct Values {
390 float resolution_factor; 390 float resolution_factor;
391 bool use_frame_limit; 391 bool use_frame_limit;
392 u16 frame_limit; 392 u16 frame_limit;
393 bool use_compatibility_profile;
394 bool use_disk_shader_cache; 393 bool use_disk_shader_cache;
395 bool use_accurate_gpu_emulation; 394 bool use_accurate_gpu_emulation;
396 bool use_asynchronous_gpu_emulation; 395 bool use_asynchronous_gpu_emulation;
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 24ce47682..2d4caa08d 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -42,8 +42,6 @@ add_library(video_core STATIC
42 renderer_opengl/gl_device.h 42 renderer_opengl/gl_device.h
43 renderer_opengl/gl_global_cache.cpp 43 renderer_opengl/gl_global_cache.cpp
44 renderer_opengl/gl_global_cache.h 44 renderer_opengl/gl_global_cache.h
45 renderer_opengl/gl_primitive_assembler.cpp
46 renderer_opengl/gl_primitive_assembler.h
47 renderer_opengl/gl_rasterizer.cpp 45 renderer_opengl/gl_rasterizer.cpp
48 renderer_opengl/gl_rasterizer.h 46 renderer_opengl/gl_rasterizer.h
49 renderer_opengl/gl_rasterizer_cache.cpp 47 renderer_opengl/gl_rasterizer_cache.cpp
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 25652e794..48b86f3bd 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -71,16 +71,6 @@ GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, std::size_t s
71 return uploaded_offset; 71 return uploaded_offset;
72} 72}
73 73
74std::tuple<u8*, GLintptr> OGLBufferCache::ReserveMemory(std::size_t size, std::size_t alignment) {
75 AlignBuffer(alignment);
76 u8* const uploaded_ptr = buffer_ptr;
77 const GLintptr uploaded_offset = buffer_offset;
78
79 buffer_ptr += size;
80 buffer_offset += size;
81 return std::make_tuple(uploaded_ptr, uploaded_offset);
82}
83
84bool OGLBufferCache::Map(std::size_t max_size) { 74bool OGLBufferCache::Map(std::size_t max_size) {
85 bool invalidate; 75 bool invalidate;
86 std::tie(buffer_ptr, buffer_offset_base, invalidate) = 76 std::tie(buffer_ptr, buffer_offset_base, invalidate) =
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index f9247a40e..f2347581b 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -61,9 +61,6 @@ public:
61 /// Uploads from a host memory. Returns host's buffer offset where it's been allocated. 61 /// Uploads from a host memory. Returns host's buffer offset where it's been allocated.
62 GLintptr UploadHostMemory(const void* raw_pointer, std::size_t size, std::size_t alignment = 4); 62 GLintptr UploadHostMemory(const void* raw_pointer, std::size_t size, std::size_t alignment = 4);
63 63
64 /// Reserves memory to be used by host's CPU. Returns mapped address and offset.
65 std::tuple<u8*, GLintptr> ReserveMemory(std::size_t size, std::size_t alignment = 4);
66
67 bool Map(std::size_t max_size); 64 bool Map(std::size_t max_size);
68 void Unmap(); 65 void Unmap();
69 66
diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
deleted file mode 100644
index c3e94d917..000000000
--- a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <array>
7#include "common/assert.h"
8#include "common/common_types.h"
9#include "core/core.h"
10#include "video_core/memory_manager.h"
11#include "video_core/renderer_opengl/gl_buffer_cache.h"
12#include "video_core/renderer_opengl/gl_primitive_assembler.h"
13
14namespace OpenGL {
15
16constexpr u32 TRIANGLES_PER_QUAD = 6;
17constexpr std::array<u32, TRIANGLES_PER_QUAD> QUAD_MAP = {0, 1, 2, 0, 2, 3};
18
19PrimitiveAssembler::PrimitiveAssembler(OGLBufferCache& buffer_cache) : buffer_cache(buffer_cache) {}
20
21PrimitiveAssembler::~PrimitiveAssembler() = default;
22
23std::size_t PrimitiveAssembler::CalculateQuadSize(u32 count) const {
24 ASSERT_MSG(count % 4 == 0, "Quad count is expected to be a multiple of 4");
25 return (count / 4) * TRIANGLES_PER_QUAD * sizeof(GLuint);
26}
27
28GLintptr PrimitiveAssembler::MakeQuadArray(u32 first, u32 count) {
29 const std::size_t size{CalculateQuadSize(count)};
30 auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(size);
31
32 for (u32 primitive = 0; primitive < count / 4; ++primitive) {
33 for (u32 i = 0; i < TRIANGLES_PER_QUAD; ++i) {
34 const u32 index = first + primitive * 4 + QUAD_MAP[i];
35 std::memcpy(dst_pointer, &index, sizeof(index));
36 dst_pointer += sizeof(index);
37 }
38 }
39
40 return index_offset;
41}
42
43GLintptr PrimitiveAssembler::MakeQuadIndexed(GPUVAddr gpu_addr, std::size_t index_size, u32 count) {
44 const std::size_t map_size{CalculateQuadSize(count)};
45 auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(map_size);
46
47 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
48 const u8* source{memory_manager.GetPointer(gpu_addr)};
49
50 for (u32 primitive = 0; primitive < count / 4; ++primitive) {
51 for (std::size_t i = 0; i < TRIANGLES_PER_QUAD; ++i) {
52 const u32 index = primitive * 4 + QUAD_MAP[i];
53 const u8* src_offset = source + (index * index_size);
54
55 std::memcpy(dst_pointer, src_offset, index_size);
56 dst_pointer += index_size;
57 }
58 }
59
60 return index_offset;
61}
62
63} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.h b/src/video_core/renderer_opengl/gl_primitive_assembler.h
deleted file mode 100644
index 4e87ce4d6..000000000
--- a/src/video_core/renderer_opengl/gl_primitive_assembler.h
+++ /dev/null
@@ -1,31 +0,0 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <glad/glad.h>
8
9#include "common/common_types.h"
10
11namespace OpenGL {
12
13class OGLBufferCache;
14
15class PrimitiveAssembler {
16public:
17 explicit PrimitiveAssembler(OGLBufferCache& buffer_cache);
18 ~PrimitiveAssembler();
19
20 /// Calculates the size required by MakeQuadArray and MakeQuadIndexed.
21 std::size_t CalculateQuadSize(u32 count) const;
22
23 GLintptr MakeQuadArray(u32 first, u32 count);
24
25 GLintptr MakeQuadIndexed(GPUVAddr gpu_addr, std::size_t index_size, u32 count);
26
27private:
28 OGLBufferCache& buffer_cache;
29};
30
31} // namespace OpenGL \ No newline at end of file
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index f9b6dfeea..ca410287a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -246,29 +246,6 @@ DrawParameters RasterizerOpenGL::SetupDraw() {
246 DrawParameters params{}; 246 DrawParameters params{};
247 params.current_instance = gpu.state.current_instance; 247 params.current_instance = gpu.state.current_instance;
248 248
249 if (regs.draw.topology == Maxwell::PrimitiveTopology::Quads) {
250 MICROPROFILE_SCOPE(OpenGL_PrimitiveAssembly);
251
252 params.use_indexed = true;
253 params.primitive_mode = GL_TRIANGLES;
254
255 if (is_indexed) {
256 params.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
257 params.count = (regs.index_array.count / 4) * 6;
258 params.index_buffer_offset = primitive_assembler.MakeQuadIndexed(
259 regs.index_array.IndexStart(), regs.index_array.FormatSizeInBytes(),
260 regs.index_array.count);
261 params.base_vertex = static_cast<GLint>(regs.vb_element_base);
262 } else {
263 // MakeQuadArray always generates u32 indexes
264 params.index_format = GL_UNSIGNED_INT;
265 params.count = (regs.vertex_buffer.count / 4) * 6;
266 params.index_buffer_offset = primitive_assembler.MakeQuadArray(
267 regs.vertex_buffer.first, regs.vertex_buffer.count);
268 }
269 return params;
270 }
271
272 params.use_indexed = is_indexed; 249 params.use_indexed = is_indexed;
273 params.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology); 250 params.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
274 251
@@ -686,30 +663,19 @@ void RasterizerOpenGL::DrawArrays() {
686 SyncCullMode(); 663 SyncCullMode();
687 SyncPrimitiveRestart(); 664 SyncPrimitiveRestart();
688 SyncScissorTest(state); 665 SyncScissorTest(state);
689 // Alpha Testing is synced on shaders.
690 SyncTransformFeedback(); 666 SyncTransformFeedback();
691 SyncPointState(); 667 SyncPointState();
692 CheckAlphaTests();
693 SyncPolygonOffset(); 668 SyncPolygonOffset();
694 // TODO(bunnei): Sync framebuffer_scale uniform here 669 SyncAlphaTest();
695 // TODO(bunnei): Sync scissorbox uniform(s) here
696 670
697 // Draw the vertex batch 671 // Draw the vertex batch
698 const bool is_indexed = accelerate_draw == AccelDraw::Indexed; 672 const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
699 673
700 std::size_t buffer_size = CalculateVertexArraysSize(); 674 std::size_t buffer_size = CalculateVertexArraysSize();
701 675
702 // Add space for index buffer (keeping in mind non-core primitives) 676 // Add space for index buffer
703 switch (regs.draw.topology) { 677 if (is_indexed) {
704 case Maxwell::PrimitiveTopology::Quads: 678 buffer_size = Common::AlignUp(buffer_size, 4) + CalculateIndexBufferSize();
705 buffer_size = Common::AlignUp(buffer_size, 4) +
706 primitive_assembler.CalculateQuadSize(regs.vertex_buffer.count);
707 break;
708 default:
709 if (is_indexed) {
710 buffer_size = Common::AlignUp(buffer_size, 4) + CalculateIndexBufferSize();
711 }
712 break;
713 } 679 }
714 680
715 // Uniform space for the 5 shader stages 681 // Uniform space for the 5 shader stages
@@ -1152,10 +1118,17 @@ void RasterizerOpenGL::SyncPolygonOffset() {
1152 state.polygon_offset.clamp = regs.polygon_offset_clamp; 1118 state.polygon_offset.clamp = regs.polygon_offset_clamp;
1153} 1119}
1154 1120
1155void RasterizerOpenGL::CheckAlphaTests() { 1121void RasterizerOpenGL::SyncAlphaTest() {
1156 const auto& regs = system.GPU().Maxwell3D().regs; 1122 const auto& regs = system.GPU().Maxwell3D().regs;
1157 UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1, 1123 UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1,
1158 "Alpha Testing is enabled with more than one rendertarget"); 1124 "Alpha Testing is enabled with more than one rendertarget");
1125
1126 state.alpha_test.enabled = regs.alpha_test_enabled;
1127 if (!state.alpha_test.enabled) {
1128 return;
1129 }
1130 state.alpha_test.func = MaxwellToGL::ComparisonOp(regs.alpha_test_func);
1131 state.alpha_test.ref = regs.alpha_test_ref;
1159} 1132}
1160 1133
1161} // namespace OpenGL 1134} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index d78094138..2817f65c9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -23,7 +23,6 @@
23#include "video_core/renderer_opengl/gl_buffer_cache.h" 23#include "video_core/renderer_opengl/gl_buffer_cache.h"
24#include "video_core/renderer_opengl/gl_device.h" 24#include "video_core/renderer_opengl/gl_device.h"
25#include "video_core/renderer_opengl/gl_global_cache.h" 25#include "video_core/renderer_opengl/gl_global_cache.h"
26#include "video_core/renderer_opengl/gl_primitive_assembler.h"
27#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 26#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
28#include "video_core/renderer_opengl/gl_resource_manager.h" 27#include "video_core/renderer_opengl/gl_resource_manager.h"
29#include "video_core/renderer_opengl/gl_sampler_cache.h" 28#include "video_core/renderer_opengl/gl_sampler_cache.h"
@@ -167,8 +166,8 @@ private:
167 /// Syncs the polygon offsets 166 /// Syncs the polygon offsets
168 void SyncPolygonOffset(); 167 void SyncPolygonOffset();
169 168
170 /// Check asserts for alpha testing. 169 /// Syncs the alpha test state to match the guest state
171 void CheckAlphaTests(); 170 void SyncAlphaTest();
172 171
173 /// Check for extension that are not strictly required 172 /// Check for extension that are not strictly required
174 /// but are needed for correct emulation 173 /// but are needed for correct emulation
@@ -197,7 +196,6 @@ private:
197 196
198 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 197 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
199 OGLBufferCache buffer_cache; 198 OGLBufferCache buffer_cache;
200 PrimitiveAssembler primitive_assembler{buffer_cache};
201 199
202 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER}; 200 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
203 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER}; 201 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index f2d0722af..739477cc9 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1467,27 +1467,9 @@ private:
1467 1467
1468 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, "Sample mask write is unimplemented"); 1468 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, "Sample mask write is unimplemented");
1469 1469
1470 code.AddLine("if (alpha_test[0] != 0) {{");
1471 ++code.scope;
1472 // We start on the register containing the alpha value in the first RT.
1473 u32 current_reg = 3;
1474 for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) {
1475 // TODO(Blinkhawk): verify the behavior of alpha testing on hardware when
1476 // multiple render targets are used.
1477 if (header.ps.IsColorComponentOutputEnabled(render_target, 0) ||
1478 header.ps.IsColorComponentOutputEnabled(render_target, 1) ||
1479 header.ps.IsColorComponentOutputEnabled(render_target, 2) ||
1480 header.ps.IsColorComponentOutputEnabled(render_target, 3)) {
1481 code.AddLine("if (!AlphaFunc({})) discard;", SafeGetRegister(current_reg));
1482 current_reg += 4;
1483 }
1484 }
1485 --code.scope;
1486 code.AddLine("}}");
1487
1488 // Write the color outputs using the data in the shader registers, disabled 1470 // Write the color outputs using the data in the shader registers, disabled
1489 // rendertargets/components are skipped in the register assignment. 1471 // rendertargets/components are skipped in the register assignment.
1490 current_reg = 0; 1472 u32 current_reg = 0;
1491 for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) { 1473 for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) {
1492 // TODO(Subv): Figure out how dual-source blending is configured in the Switch. 1474 // TODO(Subv): Figure out how dual-source blending is configured in the Switch.
1493 for (u32 component = 0; component < 4; ++component) { 1475 for (u32 component = 0; component < 4; ++component) {
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index c845b29aa..9148629ec 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -26,7 +26,6 @@ ProgramResult GenerateVertexShader(const Device& device, const ShaderSetup& setu
26layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config { 26layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config {
27 vec4 viewport_flip; 27 vec4 viewport_flip;
28 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding 28 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
29 uvec4 alpha_test;
30}; 29};
31 30
32)"; 31)";
@@ -78,7 +77,6 @@ ProgramResult GenerateGeometryShader(const Device& device, const ShaderSetup& se
78layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config { 77layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config {
79 vec4 viewport_flip; 78 vec4 viewport_flip;
80 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding 79 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
81 uvec4 alpha_test;
82}; 80};
83 81
84)"; 82)";
@@ -114,33 +112,8 @@ layout (location = 7) out vec4 FragColor7;
114layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config { 112layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config {
115 vec4 viewport_flip; 113 vec4 viewport_flip;
116 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding 114 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
117 uvec4 alpha_test;
118}; 115};
119 116
120bool AlphaFunc(in float value) {
121 float ref = uintBitsToFloat(alpha_test[2]);
122 switch (alpha_test[1]) {
123 case 1:
124 return false;
125 case 2:
126 return value < ref;
127 case 3:
128 return value == ref;
129 case 4:
130 return value <= ref;
131 case 5:
132 return value > ref;
133 case 6:
134 return value != ref;
135 case 7:
136 return value >= ref;
137 case 8:
138 return true;
139 default:
140 return false;
141 }
142}
143
144)"; 117)";
145 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 118 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
146 ProgramResult program = 119 ProgramResult program =
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index 05ab01dcb..b05f90f20 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -48,17 +48,6 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shade
48 viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; 48 viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f;
49 viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; 49 viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f;
50 50
51 auto func{static_cast<u32>(regs.alpha_test_func)};
52 // Normalize the gl variants of opCompare to be the same as the normal variants
53 const u32 op_gl_variant_base = static_cast<u32>(Maxwell3D::Regs::ComparisonOp::Never);
54 if (func >= op_gl_variant_base) {
55 func = func - op_gl_variant_base + 1U;
56 }
57
58 alpha_test.enabled = regs.alpha_test_enabled;
59 alpha_test.func = func;
60 alpha_test.ref = regs.alpha_test_ref;
61
62 instance_id = state.current_instance; 51 instance_id = state.current_instance;
63 52
64 // Assign in which stage the position has to be flipped 53 // Assign in which stage the position has to be flipped
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index cec18a832..6961e702a 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -27,14 +27,8 @@ struct MaxwellUniformData {
27 GLuint flip_stage; 27 GLuint flip_stage;
28 GLfloat y_direction; 28 GLfloat y_direction;
29 }; 29 };
30 struct alignas(16) {
31 GLuint enabled;
32 GLuint func;
33 GLfloat ref;
34 GLuint padding;
35 } alpha_test;
36}; 30};
37static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect"); 31static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect");
38static_assert(sizeof(MaxwellUniformData) < 16384, 32static_assert(sizeof(MaxwellUniformData) < 16384,
39 "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); 33 "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec");
40 34
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 7425fbe5d..d86e137ac 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -156,6 +156,10 @@ OpenGLState::OpenGLState() {
156 polygon_offset.factor = 0.0f; 156 polygon_offset.factor = 0.0f;
157 polygon_offset.units = 0.0f; 157 polygon_offset.units = 0.0f;
158 polygon_offset.clamp = 0.0f; 158 polygon_offset.clamp = 0.0f;
159
160 alpha_test.enabled = false;
161 alpha_test.func = GL_ALWAYS;
162 alpha_test.ref = 0.0f;
159} 163}
160 164
161void OpenGLState::ApplyDefaultState() { 165void OpenGLState::ApplyDefaultState() {
@@ -461,6 +465,14 @@ void OpenGLState::ApplyPolygonOffset() const {
461 } 465 }
462} 466}
463 467
468void OpenGLState::ApplyAlphaTest() const {
469 Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled);
470 if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref),
471 std::tie(alpha_test.func, alpha_test.ref))) {
472 glAlphaFunc(alpha_test.func, alpha_test.ref);
473 }
474}
475
464void OpenGLState::ApplyTextures() const { 476void OpenGLState::ApplyTextures() const {
465 bool has_delta{}; 477 bool has_delta{};
466 std::size_t first{}; 478 std::size_t first{};
@@ -533,6 +545,7 @@ void OpenGLState::Apply() const {
533 ApplyTextures(); 545 ApplyTextures();
534 ApplySamplers(); 546 ApplySamplers();
535 ApplyPolygonOffset(); 547 ApplyPolygonOffset();
548 ApplyAlphaTest();
536} 549}
537 550
538void OpenGLState::EmulateViewportWithScissor() { 551void OpenGLState::EmulateViewportWithScissor() {
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 41418a7b8..b0140495d 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -172,6 +172,12 @@ public:
172 GLfloat clamp; 172 GLfloat clamp;
173 } polygon_offset; 173 } polygon_offset;
174 174
175 struct {
176 bool enabled; // GL_ALPHA_TEST
177 GLenum func; // GL_ALPHA_TEST_FUNC
178 GLfloat ref; // GL_ALPHA_TEST_REF
179 } alpha_test;
180
175 std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE 181 std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE
176 182
177 OpenGLState(); 183 OpenGLState();
@@ -215,6 +221,7 @@ public:
215 void ApplySamplers() const; 221 void ApplySamplers() const;
216 void ApplyDepthClamp() const; 222 void ApplyDepthClamp() const;
217 void ApplyPolygonOffset() const; 223 void ApplyPolygonOffset() const;
224 void ApplyAlphaTest() const;
218 225
219 /// Set the initial OpenGL state 226 /// Set the initial OpenGL state
220 static void ApplyDefaultState(); 227 static void ApplyDefaultState();
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index ed7b5cff0..ea77dd211 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -128,6 +128,8 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) {
128 return GL_TRIANGLE_STRIP; 128 return GL_TRIANGLE_STRIP;
129 case Maxwell::PrimitiveTopology::TriangleFan: 129 case Maxwell::PrimitiveTopology::TriangleFan:
130 return GL_TRIANGLE_FAN; 130 return GL_TRIANGLE_FAN;
131 case Maxwell::PrimitiveTopology::Quads:
132 return GL_QUADS;
131 default: 133 default:
132 LOG_CRITICAL(Render_OpenGL, "Unimplemented topology={}", static_cast<u32>(topology)); 134 LOG_CRITICAL(Render_OpenGL, "Unimplemented topology={}", static_cast<u32>(topology));
133 UNREACHABLE(); 135 UNREACHABLE();
@@ -173,11 +175,8 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) {
173 return GL_CLAMP_TO_EDGE; 175 return GL_CLAMP_TO_EDGE;
174 case Tegra::Texture::WrapMode::Border: 176 case Tegra::Texture::WrapMode::Border:
175 return GL_CLAMP_TO_BORDER; 177 return GL_CLAMP_TO_BORDER;
176 case Tegra::Texture::WrapMode::ClampOGL: 178 case Tegra::Texture::WrapMode::Clamp:
177 // TODO(Subv): GL_CLAMP was removed as of OpenGL 3.1, to implement GL_CLAMP, we can use 179 return GL_CLAMP;
178 // GL_CLAMP_TO_BORDER to get the border color of the texture, and then sample the edge to
179 // manually mix them. However the shader part of this is not yet implemented.
180 return GL_CLAMP_TO_BORDER;
181 case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: 180 case Tegra::Texture::WrapMode::MirrorOnceClampToEdge:
182 return GL_MIRROR_CLAMP_TO_EDGE; 181 return GL_MIRROR_CLAMP_TO_EDGE;
183 case Tegra::Texture::WrapMode::MirrorOnceBorder: 182 case Tegra::Texture::WrapMode::MirrorOnceBorder:
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index 9fe1e3280..0bbbf6851 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -52,7 +52,7 @@ vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode) {
52 return vk::SamplerAddressMode::eClampToEdge; 52 return vk::SamplerAddressMode::eClampToEdge;
53 case Tegra::Texture::WrapMode::Border: 53 case Tegra::Texture::WrapMode::Border:
54 return vk::SamplerAddressMode::eClampToBorder; 54 return vk::SamplerAddressMode::eClampToBorder;
55 case Tegra::Texture::WrapMode::ClampOGL: 55 case Tegra::Texture::WrapMode::Clamp:
56 // TODO(Rodrigo): GL_CLAMP was removed as of OpenGL 3.1, to implement GL_CLAMP, we can use 56 // TODO(Rodrigo): GL_CLAMP was removed as of OpenGL 3.1, to implement GL_CLAMP, we can use
57 // eClampToBorder to get the border color of the texture, and then sample the edge to 57 // eClampToBorder to get the border color of the texture, and then sample the edge to
58 // manually mix them. However the shader part of this is not yet implemented. 58 // manually mix them. However the shader part of this is not yet implemented.
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index bea0d5bc2..219bfd559 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -251,7 +251,7 @@ enum class WrapMode : u32 {
251 Mirror = 1, 251 Mirror = 1,
252 ClampToEdge = 2, 252 ClampToEdge = 2,
253 Border = 3, 253 Border = 3,
254 ClampOGL = 4, 254 Clamp = 4,
255 MirrorOnceClampToEdge = 5, 255 MirrorOnceClampToEdge = 5,
256 MirrorOnceBorder = 6, 256 MirrorOnceBorder = 6,
257 MirrorOnceClampOGL = 7, 257 MirrorOnceClampOGL = 7,
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index afec33b61..07a720494 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -381,12 +381,8 @@ void GRenderWindow::InitRenderTarget() {
381 // WA_DontShowOnScreen, WA_DeleteOnClose 381 // WA_DontShowOnScreen, WA_DeleteOnClose
382 QSurfaceFormat fmt; 382 QSurfaceFormat fmt;
383 fmt.setVersion(4, 3); 383 fmt.setVersion(4, 3);
384 if (Settings::values.use_compatibility_profile) { 384 fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
385 fmt.setProfile(QSurfaceFormat::CompatibilityProfile); 385 fmt.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions);
386 fmt.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions);
387 } else {
388 fmt.setProfile(QSurfaceFormat::CoreProfile);
389 }
390 // TODO: expose a setting for buffer value (ie default/single/double/triple) 386 // TODO: expose a setting for buffer value (ie default/single/double/triple)
391 fmt.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior); 387 fmt.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior);
392 shared_context = std::make_unique<QOpenGLContext>(); 388 shared_context = std::make_unique<QOpenGLContext>();
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index b1942bedc..10e5c5c38 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -531,8 +531,6 @@ void Config::ReadRendererValues() {
531 Settings::values.use_frame_limit = 531 Settings::values.use_frame_limit =
532 ReadSetting(QStringLiteral("use_frame_limit"), true).toBool(); 532 ReadSetting(QStringLiteral("use_frame_limit"), true).toBool();
533 Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toInt(); 533 Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toInt();
534 Settings::values.use_compatibility_profile =
535 ReadSetting(QStringLiteral("use_compatibility_profile"), true).toBool();
536 Settings::values.use_disk_shader_cache = 534 Settings::values.use_disk_shader_cache =
537 ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool(); 535 ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool();
538 Settings::values.use_accurate_gpu_emulation = 536 Settings::values.use_accurate_gpu_emulation =
@@ -914,8 +912,6 @@ void Config::SaveRendererValues() {
914 static_cast<double>(Settings::values.resolution_factor), 1.0); 912 static_cast<double>(Settings::values.resolution_factor), 1.0);
915 WriteSetting(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); 913 WriteSetting(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true);
916 WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); 914 WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100);
917 WriteSetting(QStringLiteral("use_compatibility_profile"),
918 Settings::values.use_compatibility_profile, true);
919 WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache, 915 WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache,
920 true); 916 true);
921 WriteSetting(QStringLiteral("use_accurate_gpu_emulation"), 917 WriteSetting(QStringLiteral("use_accurate_gpu_emulation"),
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 02e91701a..902ef5cd4 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -75,8 +75,6 @@ void ConfigureGraphics::SetConfiguration() {
75 ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); 75 ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit);
76 ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked()); 76 ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked());
77 ui->frame_limit->setValue(Settings::values.frame_limit); 77 ui->frame_limit->setValue(Settings::values.frame_limit);
78 ui->use_compatibility_profile->setEnabled(runtime_lock);
79 ui->use_compatibility_profile->setChecked(Settings::values.use_compatibility_profile);
80 ui->use_disk_shader_cache->setEnabled(runtime_lock); 78 ui->use_disk_shader_cache->setEnabled(runtime_lock);
81 ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache); 79 ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache);
82 ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation); 80 ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation);
@@ -93,7 +91,6 @@ void ConfigureGraphics::ApplyConfiguration() {
93 ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex())); 91 ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex()));
94 Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked(); 92 Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked();
95 Settings::values.frame_limit = ui->frame_limit->value(); 93 Settings::values.frame_limit = ui->frame_limit->value();
96 Settings::values.use_compatibility_profile = ui->use_compatibility_profile->isChecked();
97 Settings::values.use_disk_shader_cache = ui->use_disk_shader_cache->isChecked(); 94 Settings::values.use_disk_shader_cache = ui->use_disk_shader_cache->isChecked();
98 Settings::values.use_accurate_gpu_emulation = ui->use_accurate_gpu_emulation->isChecked(); 95 Settings::values.use_accurate_gpu_emulation = ui->use_accurate_gpu_emulation->isChecked();
99 Settings::values.use_asynchronous_gpu_emulation = 96 Settings::values.use_asynchronous_gpu_emulation =
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index 0f6f6c003..15ab18ecd 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -50,13 +50,6 @@
50 </layout> 50 </layout>
51 </item> 51 </item>
52 <item> 52 <item>
53 <widget class="QCheckBox" name="use_compatibility_profile">
54 <property name="text">
55 <string>Use OpenGL compatibility profile</string>
56 </property>
57 </widget>
58 </item>
59 <item>
60 <widget class="QCheckBox" name="use_disk_shader_cache"> 53 <widget class="QCheckBox" name="use_disk_shader_cache">
61 <property name="text"> 54 <property name="text">
62 <string>Use disk shader cache</string> 55 <string>Use disk shader cache</string>
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 730956427..f3817bb87 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -349,8 +349,6 @@ void Config::ReadValues() {
349 Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true); 349 Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true);
350 Settings::values.frame_limit = 350 Settings::values.frame_limit =
351 static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); 351 static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));
352 Settings::values.use_compatibility_profile =
353 sdl2_config->GetBoolean("Renderer", "use_compatibility_profile", true);
354 Settings::values.use_disk_shader_cache = 352 Settings::values.use_disk_shader_cache =
355 sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false); 353 sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false);
356 Settings::values.use_accurate_gpu_emulation = 354 Settings::values.use_accurate_gpu_emulation =
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
index 904022137..e2d3df180 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
@@ -74,13 +74,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() {
74} 74}
75 75
76EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(bool fullscreen) : EmuWindow_SDL2(fullscreen) { 76EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(bool fullscreen) : EmuWindow_SDL2(fullscreen) {
77 const SDL_GLprofile profile = Settings::values.use_compatibility_profile
78 ? SDL_GL_CONTEXT_PROFILE_COMPATIBILITY
79 : SDL_GL_CONTEXT_PROFILE_CORE;
80
81 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); 77 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
82 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); 78 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
83 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile); 79 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
84 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 80 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
85 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 81 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
86 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 82 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);