summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Rodrigo Locatti2020-03-13 16:44:06 -0300
committerGravatar GitHub2020-03-13 16:44:06 -0300
commit244fe132199cb3c67dd9e612d2be856895f8a868 (patch)
treed0f968d06b2bbc6e378a5a0632cd2d6322fe4e6d /src
parentgl_shader_decompiler: Initialize gl_Position on vertex shaders (diff)
parentMerge pull request #3491 from ReinUsesLisp/polygon-modes (diff)
downloadyuzu-244fe132199cb3c67dd9e612d2be856895f8a868.tar.gz
yuzu-244fe132199cb3c67dd9e612d2be856895f8a868.tar.xz
yuzu-244fe132199cb3c67dd9e612d2be856895f8a868.zip
Merge branch 'master' into shader-purge
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/cubeb_sink.cpp20
-rw-r--r--src/core/frontend/framebuffer_layout.cpp4
-rw-r--r--src/core/frontend/framebuffer_layout.h16
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp4
-rw-r--r--src/video_core/engines/maxwell_3d.h22
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp44
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp31
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h29
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h11
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h13
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp9
-rw-r--r--src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp3
15 files changed, 177 insertions, 47 deletions
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index 7047ed9cf..c4e0e30fe 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -8,6 +8,7 @@
8#include "audio_core/cubeb_sink.h" 8#include "audio_core/cubeb_sink.h"
9#include "audio_core/stream.h" 9#include "audio_core/stream.h"
10#include "audio_core/time_stretch.h" 10#include "audio_core/time_stretch.h"
11#include "common/assert.h"
11#include "common/logging/log.h" 12#include "common/logging/log.h"
12#include "common/ring_buffer.h" 13#include "common/ring_buffer.h"
13#include "core/settings.h" 14#include "core/settings.h"
@@ -65,12 +66,25 @@ public:
65 void EnqueueSamples(u32 source_num_channels, const std::vector<s16>& samples) override { 66 void EnqueueSamples(u32 source_num_channels, const std::vector<s16>& samples) override {
66 if (source_num_channels > num_channels) { 67 if (source_num_channels > num_channels) {
67 // Downsample 6 channels to 2 68 // Downsample 6 channels to 2
69 ASSERT_MSG(source_num_channels == 6, "Channel count must be 6");
70
68 std::vector<s16> buf; 71 std::vector<s16> buf;
69 buf.reserve(samples.size() * num_channels / source_num_channels); 72 buf.reserve(samples.size() * num_channels / source_num_channels);
70 for (std::size_t i = 0; i < samples.size(); i += source_num_channels) { 73 for (std::size_t i = 0; i < samples.size(); i += source_num_channels) {
71 for (std::size_t ch = 0; ch < num_channels; ch++) { 74 // Downmixing implementation taken from the ATSC standard
72 buf.push_back(samples[i + ch]); 75 const s16 left{samples[i + 0]};
73 } 76 const s16 right{samples[i + 1]};
77 const s16 center{samples[i + 2]};
78 const s16 surround_left{samples[i + 4]};
79 const s16 surround_right{samples[i + 5]};
80 // Not used in the ATSC reference implementation
81 [[maybe_unused]] const s16 low_frequency_effects { samples[i + 3] };
82
83 constexpr s32 clev{707}; // center mixing level coefficient
84 constexpr s32 slev{707}; // surround mixing level coefficient
85
86 buf.push_back(left + (clev * center / 1000) + (slev * surround_left / 1000));
87 buf.push_back(right + (clev * center / 1000) + (slev * surround_right / 1000));
74 } 88 }
75 queue.Push(buf); 89 queue.Push(buf);
76 return; 90 return;
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 2dc795d56..68a0e0906 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -48,8 +48,8 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) {
48 u32 width, height; 48 u32 width, height;
49 49
50 if (Settings::values.use_docked_mode) { 50 if (Settings::values.use_docked_mode) {
51 width = ScreenDocked::WidthDocked * res_scale; 51 width = ScreenDocked::Width * res_scale;
52 height = ScreenDocked::HeightDocked * res_scale; 52 height = ScreenDocked::Height * res_scale;
53 } else { 53 } else {
54 width = ScreenUndocked::Width * res_scale; 54 width = ScreenUndocked::Width * res_scale;
55 height = ScreenUndocked::Height * res_scale; 55 height = ScreenUndocked::Height * res_scale;
diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h
index e9d0a40d3..15ecfb13d 100644
--- a/src/core/frontend/framebuffer_layout.h
+++ b/src/core/frontend/framebuffer_layout.h
@@ -8,15 +8,15 @@
8 8
9namespace Layout { 9namespace Layout {
10 10
11enum ScreenUndocked : u32 { 11namespace ScreenUndocked {
12 Width = 1280, 12constexpr u32 Width = 1280;
13 Height = 720, 13constexpr u32 Height = 720;
14}; 14} // namespace ScreenUndocked
15 15
16enum ScreenDocked : u32 { 16namespace ScreenDocked {
17 WidthDocked = 1920, 17constexpr u32 Width = 1920;
18 HeightDocked = 1080, 18constexpr u32 Height = 1080;
19}; 19} // namespace ScreenDocked
20 20
21enum class AspectRatio { 21enum class AspectRatio {
22 Default, 22 Default,
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 134152210..437bc5dee 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -191,8 +191,6 @@ void NVFlinger::Compose() {
191 // Search for a queued buffer and acquire it 191 // Search for a queued buffer and acquire it
192 auto buffer = buffer_queue.AcquireBuffer(); 192 auto buffer = buffer_queue.AcquireBuffer();
193 193
194 MicroProfileFlip();
195
196 if (!buffer) { 194 if (!buffer) {
197 continue; 195 continue;
198 } 196 }
@@ -206,6 +204,8 @@ void NVFlinger::Compose() {
206 gpu.WaitFence(fence.id, fence.value); 204 gpu.WaitFence(fence.id, fence.value);
207 } 205 }
208 206
207 MicroProfileFlip();
208
209 // Now send the buffer to the GPU for drawing. 209 // Now send the buffer to the GPU for drawing.
210 // TODO(Subv): Support more than just disp0. The display device selection is probably based 210 // TODO(Subv): Support more than just disp0. The display device selection is probably based
211 // on which display we're drawing (Default, Internal, External, etc) 211 // on which display we're drawing (Default, Internal, External, etc)
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 7000b0589..8752a1cfb 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -525,6 +525,12 @@ public:
525 FractionalEven = 2, 525 FractionalEven = 2,
526 }; 526 };
527 527
528 enum class PolygonMode : u32 {
529 Point = 0x1b00,
530 Line = 0x1b01,
531 Fill = 0x1b02,
532 };
533
528 struct RenderTargetConfig { 534 struct RenderTargetConfig {
529 u32 address_high; 535 u32 address_high;
530 u32 address_low; 536 u32 address_low;
@@ -728,7 +734,12 @@ public:
728 734
729 s32 clear_stencil; 735 s32 clear_stencil;
730 736
731 INSERT_UNION_PADDING_WORDS(0x7); 737 INSERT_UNION_PADDING_WORDS(0x2);
738
739 PolygonMode polygon_mode_front;
740 PolygonMode polygon_mode_back;
741
742 INSERT_UNION_PADDING_WORDS(0x3);
732 743
733 u32 polygon_offset_point_enable; 744 u32 polygon_offset_point_enable;
734 u32 polygon_offset_line_enable; 745 u32 polygon_offset_line_enable;
@@ -787,7 +798,11 @@ public:
787 BitField<12, 4, u32> viewport; 798 BitField<12, 4, u32> viewport;
788 } clear_flags; 799 } clear_flags;
789 800
790 INSERT_UNION_PADDING_WORDS(0x19); 801 INSERT_UNION_PADDING_WORDS(0x10);
802
803 u32 fill_rectangle;
804
805 INSERT_UNION_PADDING_WORDS(0x8);
791 806
792 std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; 807 std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
793 808
@@ -1451,6 +1466,8 @@ ASSERT_REG_POSITION(depth_mode, 0x35F);
1451ASSERT_REG_POSITION(clear_color[0], 0x360); 1466ASSERT_REG_POSITION(clear_color[0], 0x360);
1452ASSERT_REG_POSITION(clear_depth, 0x364); 1467ASSERT_REG_POSITION(clear_depth, 0x364);
1453ASSERT_REG_POSITION(clear_stencil, 0x368); 1468ASSERT_REG_POSITION(clear_stencil, 0x368);
1469ASSERT_REG_POSITION(polygon_mode_front, 0x36B);
1470ASSERT_REG_POSITION(polygon_mode_back, 0x36C);
1454ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370); 1471ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);
1455ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371); 1472ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);
1456ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); 1473ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372);
@@ -1464,6 +1481,7 @@ ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
1464ASSERT_REG_POSITION(depth_bounds, 0x3E7); 1481ASSERT_REG_POSITION(depth_bounds, 0x3E7);
1465ASSERT_REG_POSITION(zeta, 0x3F8); 1482ASSERT_REG_POSITION(zeta, 0x3F8);
1466ASSERT_REG_POSITION(clear_flags, 0x43E); 1483ASSERT_REG_POSITION(clear_flags, 0x43E);
1484ASSERT_REG_POSITION(fill_rectangle, 0x44F);
1467ASSERT_REG_POSITION(vertex_attrib_format, 0x458); 1485ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
1468ASSERT_REG_POSITION(rt_control, 0x487); 1486ASSERT_REG_POSITION(rt_control, 0x487);
1469ASSERT_REG_POSITION(zeta_width, 0x48a); 1487ASSERT_REG_POSITION(zeta_width, 0x48a);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 385a31ef6..8a2db8e36 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -484,6 +484,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
484 484
485 SyncViewport(); 485 SyncViewport();
486 SyncRasterizeEnable(); 486 SyncRasterizeEnable();
487 SyncPolygonModes();
487 SyncColorMask(); 488 SyncColorMask();
488 SyncFragmentColorClampState(); 489 SyncFragmentColorClampState();
489 SyncMultiSampleState(); 490 SyncMultiSampleState();
@@ -562,7 +563,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
562 bind_ubo_pushbuffer.Bind(); 563 bind_ubo_pushbuffer.Bind();
563 bind_ssbo_pushbuffer.Bind(); 564 bind_ssbo_pushbuffer.Bind();
564 565
565 program_manager.Update(); 566 program_manager.BindGraphicsPipeline();
566 567
567 if (texture_cache.TextureBarrier()) { 568 if (texture_cache.TextureBarrier()) {
568 glTextureBarrier(); 569 glTextureBarrier();
@@ -619,7 +620,7 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
619 auto kernel = shader_cache.GetComputeKernel(code_addr); 620 auto kernel = shader_cache.GetComputeKernel(code_addr);
620 SetupComputeTextures(kernel); 621 SetupComputeTextures(kernel);
621 SetupComputeImages(kernel); 622 SetupComputeImages(kernel);
622 glUseProgramStages(program_manager.GetHandle(), GL_COMPUTE_SHADER_BIT, kernel->GetHandle()); 623 program_manager.BindComputeShader(kernel->GetHandle());
623 624
624 const std::size_t buffer_size = 625 const std::size_t buffer_size =
625 Tegra::Engines::KeplerCompute::NumConstBuffers * 626 Tegra::Engines::KeplerCompute::NumConstBuffers *
@@ -1089,6 +1090,45 @@ void RasterizerOpenGL::SyncRasterizeEnable() {
1089 oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0); 1090 oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0);
1090} 1091}
1091 1092
1093void RasterizerOpenGL::SyncPolygonModes() {
1094 auto& gpu = system.GPU().Maxwell3D();
1095 auto& flags = gpu.dirty.flags;
1096 if (!flags[Dirty::PolygonModes]) {
1097 return;
1098 }
1099 flags[Dirty::PolygonModes] = false;
1100
1101 if (gpu.regs.fill_rectangle) {
1102 if (!GLAD_GL_NV_fill_rectangle) {
1103 LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
1104 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1105 return;
1106 }
1107
1108 flags[Dirty::PolygonModeFront] = true;
1109 flags[Dirty::PolygonModeBack] = true;
1110 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL_RECTANGLE_NV);
1111 return;
1112 }
1113
1114 if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) {
1115 flags[Dirty::PolygonModeFront] = false;
1116 flags[Dirty::PolygonModeBack] = false;
1117 glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
1118 return;
1119 }
1120
1121 if (flags[Dirty::PolygonModeFront]) {
1122 flags[Dirty::PolygonModeFront] = false;
1123 glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
1124 }
1125
1126 if (flags[Dirty::PolygonModeBack]) {
1127 flags[Dirty::PolygonModeBack] = false;
1128 glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back));
1129 }
1130}
1131
1092void RasterizerOpenGL::SyncColorMask() { 1132void RasterizerOpenGL::SyncColorMask() {
1093 auto& gpu = system.GPU().Maxwell3D(); 1133 auto& gpu = system.GPU().Maxwell3D();
1094 auto& flags = gpu.dirty.flags; 1134 auto& flags = gpu.dirty.flags;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index e83c5ebdc..e6424f5d2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -177,6 +177,9 @@ private:
177 /// Syncs the rasterizer enable state to match the guest state 177 /// Syncs the rasterizer enable state to match the guest state
178 void SyncRasterizeEnable(); 178 void SyncRasterizeEnable();
179 179
180 /// Syncs polygon modes to match the guest state
181 void SyncPolygonModes();
182
180 /// Syncs Color Mask 183 /// Syncs Color Mask
181 void SyncColorMask(); 184 void SyncColorMask();
182 185
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index 15f3cd066..9c7b0adbd 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -2,21 +2,29 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <glad/glad.h>
6
5#include "common/common_types.h" 7#include "common/common_types.h"
6#include "video_core/engines/maxwell_3d.h" 8#include "video_core/engines/maxwell_3d.h"
7#include "video_core/renderer_opengl/gl_shader_manager.h" 9#include "video_core/renderer_opengl/gl_shader_manager.h"
8 10
9namespace OpenGL::GLShader { 11namespace OpenGL::GLShader {
10 12
11using Tegra::Engines::Maxwell3D; 13ProgramManager::ProgramManager() = default;
12 14
13ProgramManager::~ProgramManager() = default; 15ProgramManager::~ProgramManager() = default;
14 16
15void ProgramManager::Create() { 17void ProgramManager::Create() {
16 pipeline.Create(); 18 graphics_pipeline.Create();
19 glBindProgramPipeline(graphics_pipeline.handle);
17} 20}
18 21
19void ProgramManager::Update() { 22void ProgramManager::BindGraphicsPipeline() {
23 if (!is_graphics_bound) {
24 is_graphics_bound = true;
25 glUseProgram(0);
26 }
27
20 // Avoid updating the pipeline when values have no changed 28 // Avoid updating the pipeline when values have no changed
21 if (old_state == current_state) { 29 if (old_state == current_state) {
22 return; 30 return;
@@ -25,16 +33,21 @@ void ProgramManager::Update() {
25 // Workaround for AMD bug 33 // Workaround for AMD bug
26 static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | 34 static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
27 GL_FRAGMENT_SHADER_BIT}; 35 GL_FRAGMENT_SHADER_BIT};
28 glUseProgramStages(pipeline.handle, all_used_stages, 0); 36 const GLuint handle = graphics_pipeline.handle;
29 37 glUseProgramStages(handle, all_used_stages, 0);
30 glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader); 38 glUseProgramStages(handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader);
31 glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader); 39 glUseProgramStages(handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader);
32 glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader); 40 glUseProgramStages(handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader);
33 41
34 old_state = current_state; 42 old_state = current_state;
35} 43}
36 44
37void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell) { 45void ProgramManager::BindComputeShader(GLuint program) {
46 is_graphics_bound = false;
47 glUseProgram(program);
48}
49
50void MaxwellUniformData::SetFromRegs(const Tegra::Engines::Maxwell3D& maxwell) {
38 const auto& regs = maxwell.regs; 51 const auto& regs = maxwell.regs;
39 52
40 // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value. 53 // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value.
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index e94cd75aa..d2e47f2a9 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -28,11 +28,16 @@ static_assert(sizeof(MaxwellUniformData) < 16384,
28 28
29class ProgramManager { 29class ProgramManager {
30public: 30public:
31 explicit ProgramManager();
31 ~ProgramManager(); 32 ~ProgramManager();
32 33
33 void Create(); 34 void Create();
34 35
35 void Update(); 36 /// Updates the graphics pipeline and binds it.
37 void BindGraphicsPipeline();
38
39 /// Binds a compute shader.
40 void BindComputeShader(GLuint program);
36 41
37 void UseVertexShader(GLuint program) { 42 void UseVertexShader(GLuint program) {
38 current_state.vertex_shader = program; 43 current_state.vertex_shader = program;
@@ -46,33 +51,27 @@ public:
46 current_state.fragment_shader = program; 51 current_state.fragment_shader = program;
47 } 52 }
48 53
49 GLuint GetHandle() const {
50 return pipeline.handle;
51 }
52
53 void UseTrivialFragmentShader() {
54 current_state.fragment_shader = 0;
55 }
56
57private: 54private:
58 struct PipelineState { 55 struct PipelineState {
59 bool operator==(const PipelineState& rhs) const { 56 bool operator==(const PipelineState& rhs) const noexcept {
60 return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader && 57 return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader &&
61 geometry_shader == rhs.geometry_shader; 58 geometry_shader == rhs.geometry_shader;
62 } 59 }
63 60
64 bool operator!=(const PipelineState& rhs) const { 61 bool operator!=(const PipelineState& rhs) const noexcept {
65 return !operator==(rhs); 62 return !operator==(rhs);
66 } 63 }
67 64
68 GLuint vertex_shader{}; 65 GLuint vertex_shader = 0;
69 GLuint fragment_shader{}; 66 GLuint fragment_shader = 0;
70 GLuint geometry_shader{}; 67 GLuint geometry_shader = 0;
71 }; 68 };
72 69
73 OGLPipeline pipeline; 70 OGLPipeline graphics_pipeline;
71 OGLPipeline compute_pipeline;
74 PipelineState current_state; 72 PipelineState current_state;
75 PipelineState old_state; 73 PipelineState old_state;
74 bool is_graphics_bound = true;
76}; 75};
77 76
78} // namespace OpenGL::GLShader 77} // namespace OpenGL::GLShader
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp
index 1e43c9ec0..3f3bdf812 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.cpp
+++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp
@@ -94,6 +94,15 @@ void SetupDirtyShaders(Tables& tables) {
94 Shaders); 94 Shaders);
95} 95}
96 96
97void SetupDirtyPolygonModes(Tables& tables) {
98 tables[0][OFF(polygon_mode_front)] = PolygonModeFront;
99 tables[0][OFF(polygon_mode_back)] = PolygonModeBack;
100
101 tables[1][OFF(polygon_mode_front)] = PolygonModes;
102 tables[1][OFF(polygon_mode_back)] = PolygonModes;
103 tables[0][OFF(fill_rectangle)] = PolygonModes;
104}
105
97void SetupDirtyDepthTest(Tables& tables) { 106void SetupDirtyDepthTest(Tables& tables) {
98 auto& table = tables[0]; 107 auto& table = tables[0];
99 table[OFF(depth_test_enable)] = DepthTest; 108 table[OFF(depth_test_enable)] = DepthTest;
@@ -211,6 +220,7 @@ void StateTracker::Initialize() {
211 SetupDirtyVertexArrays(tables); 220 SetupDirtyVertexArrays(tables);
212 SetupDirtyVertexFormat(tables); 221 SetupDirtyVertexFormat(tables);
213 SetupDirtyShaders(tables); 222 SetupDirtyShaders(tables);
223 SetupDirtyPolygonModes(tables);
214 SetupDirtyDepthTest(tables); 224 SetupDirtyDepthTest(tables);
215 SetupDirtyStencilTest(tables); 225 SetupDirtyStencilTest(tables);
216 SetupDirtyAlphaTest(tables); 226 SetupDirtyAlphaTest(tables);
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h
index e08482911..b882d75c3 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.h
+++ b/src/video_core/renderer_opengl/gl_state_tracker.h
@@ -59,6 +59,10 @@ enum : u8 {
59 Shaders, 59 Shaders,
60 ClipDistances, 60 ClipDistances,
61 61
62 PolygonModes,
63 PolygonModeFront,
64 PolygonModeBack,
65
62 ColorMask, 66 ColorMask,
63 FrontFace, 67 FrontFace,
64 CullTest, 68 CullTest,
@@ -111,6 +115,13 @@ public:
111 flags[OpenGL::Dirty::VertexInstance0 + 1] = true; 115 flags[OpenGL::Dirty::VertexInstance0 + 1] = true;
112 } 116 }
113 117
118 void NotifyPolygonModes() {
119 auto& flags = system.GPU().Maxwell3D().dirty.flags;
120 flags[OpenGL::Dirty::PolygonModes] = true;
121 flags[OpenGL::Dirty::PolygonModeFront] = true;
122 flags[OpenGL::Dirty::PolygonModeBack] = true;
123 }
124
114 void NotifyViewport0() { 125 void NotifyViewport0() {
115 auto& flags = system.GPU().Maxwell3D().dirty.flags; 126 auto& flags = system.GPU().Maxwell3D().dirty.flags;
116 flags[OpenGL::Dirty::Viewports] = true; 127 flags[OpenGL::Dirty::Viewports] = true;
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 494e38e7a..89f0e04ef 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -488,5 +488,18 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) {
488 return GL_COPY; 488 return GL_COPY;
489} 489}
490 490
491inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) {
492 switch (polygon_mode) {
493 case Maxwell::PolygonMode::Point:
494 return GL_POINT;
495 case Maxwell::PolygonMode::Line:
496 return GL_LINE;
497 case Maxwell::PolygonMode::Fill:
498 return GL_FILL;
499 }
500 UNREACHABLE_MSG("Invalid polygon mode={}", static_cast<int>(polygon_mode));
501 return GL_FILL;
502}
503
491} // namespace MaxwellToGL 504} // namespace MaxwellToGL
492} // namespace OpenGL 505} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index a51410660..12333e8c9 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -443,7 +443,6 @@ void RendererOpenGL::InitOpenGLObjects() {
443 443
444 // Create program pipeline 444 // Create program pipeline
445 program_manager.Create(); 445 program_manager.Create();
446 glBindProgramPipeline(program_manager.GetHandle());
447 446
448 // Generate VBO handle for drawing 447 // Generate VBO handle for drawing
449 vertex_buffer.Create(); 448 vertex_buffer.Create();
@@ -577,6 +576,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
577 576
578 // TODO: Signal state tracker about these changes 577 // TODO: Signal state tracker about these changes
579 state_tracker.NotifyScreenDrawVertexArray(); 578 state_tracker.NotifyScreenDrawVertexArray();
579 state_tracker.NotifyPolygonModes();
580 state_tracker.NotifyViewport0(); 580 state_tracker.NotifyViewport0();
581 state_tracker.NotifyScissor0(); 581 state_tracker.NotifyScissor0();
582 state_tracker.NotifyColorMask0(); 582 state_tracker.NotifyColorMask0();
@@ -596,7 +596,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
596 program_manager.UseVertexShader(vertex_program.handle); 596 program_manager.UseVertexShader(vertex_program.handle);
597 program_manager.UseGeometryShader(0); 597 program_manager.UseGeometryShader(0);
598 program_manager.UseFragmentShader(fragment_program.handle); 598 program_manager.UseFragmentShader(fragment_program.handle);
599 program_manager.Update(); 599 program_manager.BindGraphicsPipeline();
600 600
601 glEnable(GL_CULL_FACE); 601 glEnable(GL_CULL_FACE);
602 if (screen_info.display_srgb) { 602 if (screen_info.display_srgb) {
@@ -612,6 +612,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
612 glDisable(GL_ALPHA_TEST); 612 glDisable(GL_ALPHA_TEST);
613 glDisablei(GL_BLEND, 0); 613 glDisablei(GL_BLEND, 0);
614 glDisablei(GL_SCISSOR_TEST, 0); 614 glDisablei(GL_SCISSOR_TEST, 0);
615 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
615 glCullFace(GL_BACK); 616 glCullFace(GL_BACK);
616 glFrontFace(GL_CW); 617 glFrontFace(GL_CW);
617 glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 618 glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index b402fb268..2bcb17b56 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -854,7 +854,7 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::
854 854
855void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) { 855void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) {
856 MICROPROFILE_SCOPE(Vulkan_Images); 856 MICROPROFILE_SCOPE(Vulkan_Images);
857 const auto& gpu = system.GPU().KeplerCompute(); 857 const auto& gpu = system.GPU().Maxwell3D();
858 for (const auto& entry : entries.images) { 858 for (const auto& entry : entries.images) {
859 const auto tic = GetTextureInfo(gpu, entry, stage).tic; 859 const auto tic = GetTextureInfo(gpu, entry, stage).tic;
860 SetupImage(tic, entry); 860 SetupImage(tic, entry);
@@ -915,6 +915,13 @@ void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) {
915 915
916void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry, 916void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry,
917 const Tegra::Engines::ConstBufferInfo& buffer) { 917 const Tegra::Engines::ConstBufferInfo& buffer) {
918 if (!buffer.enabled) {
919 // Set values to zero to unbind buffers
920 update_descriptor_queue.AddBuffer(buffer_cache.GetEmptyBuffer(sizeof(float)), 0,
921 sizeof(float));
922 return;
923 }
924
918 // Align the size to avoid bad std140 interactions 925 // Align the size to avoid bad std140 interactions
919 const std::size_t size = 926 const std::size_t size =
920 Common::AlignUp(CalculateConstBufferSize(entry, buffer), 4 * sizeof(float)); 927 Common::AlignUp(CalculateConstBufferSize(entry, buffer), 4 * sizeof(float));
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
index 171d78afc..d9ea3cc21 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
@@ -73,7 +73,8 @@ VKBuffer* VKStagingBufferPool::TryGetReservedBuffer(std::size_t size, bool host_
73VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_visible) { 73VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_visible) {
74 const auto usage = 74 const auto usage =
75 vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst | 75 vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst |
76 vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndexBuffer; 76 vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eStorageBuffer |
77 vk::BufferUsageFlagBits::eIndexBuffer;
77 const u32 log2 = Common::Log2Ceil64(size); 78 const u32 log2 = Common::Log2Ceil64(size);
78 const vk::BufferCreateInfo buffer_ci({}, 1ULL << log2, usage, vk::SharingMode::eExclusive, 0, 79 const vk::BufferCreateInfo buffer_ci({}, 1ULL << log2, usage, vk::SharingMode::eExclusive, 0,
79 nullptr); 80 nullptr);