summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/file_sys/savedata_factory.cpp12
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/engines/kepler_compute.cpp12
-rw-r--r--src/video_core/engines/kepler_compute.h7
-rw-r--r--src/video_core/engines/maxwell_3d.cpp61
-rw-r--r--src/video_core/engines/maxwell_3d.h8
-rw-r--r--src/video_core/morton.cpp2
-rw-r--r--src/video_core/rasterizer_accelerated.cpp63
-rw-r--r--src/video_core/rasterizer_accelerated.h31
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp50
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h11
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp223
-rw-r--r--src/video_core/renderer_opengl/gl_state.h222
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp1
-rw-r--r--src/video_core/surface.cpp8
-rw-r--r--src/video_core/surface.h16
-rw-r--r--src/video_core/textures/texture.h1
17 files changed, 308 insertions, 422 deletions
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index fc8755c78..e2a7eaf7b 100644
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -16,6 +16,7 @@ namespace FileSys {
16constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; 16constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size";
17 17
18namespace { 18namespace {
19
19void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) { 20void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) {
20 if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { 21 if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) {
21 if (meta.zero_1 != 0) { 22 if (meta.zero_1 != 0) {
@@ -52,6 +53,13 @@ void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) {
52 meta.user_id[1], meta.user_id[0]); 53 meta.user_id[1], meta.user_id[0]);
53 } 54 }
54} 55}
56
57bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataDescriptor& desc) {
58 return desc.type == SaveDataType::CacheStorage || desc.type == SaveDataType::TemporaryStorage ||
59 (space == SaveDataSpaceId::NandUser && ///< Normal Save Data -- Current Title & User
60 desc.type == SaveDataType::SaveData && desc.title_id == 0 && desc.save_id == 0);
61}
62
55} // Anonymous namespace 63} // Anonymous namespace
56 64
57std::string SaveDataDescriptor::DebugInfo() const { 65std::string SaveDataDescriptor::DebugInfo() const {
@@ -96,6 +104,10 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
96 104
97 auto out = dir->GetDirectoryRelative(save_directory); 105 auto out = dir->GetDirectoryRelative(save_directory);
98 106
107 if (out == nullptr && ShouldSaveDataBeAutomaticallyCreated(space, meta)) {
108 return Create(space, meta);
109 }
110
99 // Return an error if the save data doesn't actually exist. 111 // Return an error if the save data doesn't actually exist.
100 if (out == nullptr) { 112 if (out == nullptr) {
101 // TODO(Subv): Find out correct error code. 113 // TODO(Subv): Find out correct error code.
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index cb6eda1b8..c911c6ec4 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -36,6 +36,8 @@ add_library(video_core STATIC
36 memory_manager.h 36 memory_manager.h
37 morton.cpp 37 morton.cpp
38 morton.h 38 morton.h
39 rasterizer_accelerated.cpp
40 rasterizer_accelerated.h
39 rasterizer_cache.cpp 41 rasterizer_cache.cpp
40 rasterizer_cache.h 42 rasterizer_cache.h
41 rasterizer_interface.h 43 rasterizer_interface.h
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp
index 91adef360..3a39aeabe 100644
--- a/src/video_core/engines/kepler_compute.cpp
+++ b/src/video_core/engines/kepler_compute.cpp
@@ -50,7 +50,7 @@ void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) {
50 } 50 }
51} 51}
52 52
53Tegra::Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) const { 53Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) const {
54 const std::bitset<8> cbuf_mask = launch_description.const_buffer_enable_mask.Value(); 54 const std::bitset<8> cbuf_mask = launch_description.const_buffer_enable_mask.Value();
55 ASSERT(cbuf_mask[regs.tex_cb_index]); 55 ASSERT(cbuf_mask[regs.tex_cb_index]);
56 56
@@ -61,13 +61,11 @@ Tegra::Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) co
61 ASSERT(address < texinfo.Address() + texinfo.size); 61 ASSERT(address < texinfo.Address() + texinfo.size);
62 62
63 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(address)}; 63 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(address)};
64 return GetTextureInfo(tex_handle, offset); 64 return GetTextureInfo(tex_handle);
65} 65}
66 66
67Texture::FullTextureInfo KeplerCompute::GetTextureInfo(const Texture::TextureHandle tex_handle, 67Texture::FullTextureInfo KeplerCompute::GetTextureInfo(Texture::TextureHandle tex_handle) const {
68 std::size_t offset) const { 68 return Texture::FullTextureInfo{GetTICEntry(tex_handle.tic_id), GetTSCEntry(tex_handle.tsc_id)};
69 return Texture::FullTextureInfo{static_cast<u32>(offset), GetTICEntry(tex_handle.tic_id),
70 GetTSCEntry(tex_handle.tsc_id)};
71} 69}
72 70
73u32 KeplerCompute::AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const { 71u32 KeplerCompute::AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const {
@@ -89,7 +87,7 @@ SamplerDescriptor KeplerCompute::AccessBindlessSampler(ShaderType stage, u64 con
89 const GPUVAddr tex_info_address = tex_info_buffer.Address() + offset; 87 const GPUVAddr tex_info_address = tex_info_buffer.Address() + offset;
90 88
91 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(tex_info_address)}; 89 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(tex_info_address)};
92 const Texture::FullTextureInfo tex_info = GetTextureInfo(tex_handle, offset); 90 const Texture::FullTextureInfo tex_info = GetTextureInfo(tex_handle);
93 SamplerDescriptor result = SamplerDescriptor::FromTicTexture(tex_info.tic.texture_type.Value()); 91 SamplerDescriptor result = SamplerDescriptor::FromTicTexture(tex_info.tic.texture_type.Value());
94 result.is_shadow.Assign(tex_info.tsc.depth_compare_enabled.Value()); 92 result.is_shadow.Assign(tex_info.tsc.depth_compare_enabled.Value());
95 return result; 93 return result;
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h
index 8e7182727..b185c98c7 100644
--- a/src/video_core/engines/kepler_compute.h
+++ b/src/video_core/engines/kepler_compute.h
@@ -196,11 +196,10 @@ public:
196 /// Write the value to the register identified by method. 196 /// Write the value to the register identified by method.
197 void CallMethod(const GPU::MethodCall& method_call); 197 void CallMethod(const GPU::MethodCall& method_call);
198 198
199 Tegra::Texture::FullTextureInfo GetTexture(std::size_t offset) const; 199 Texture::FullTextureInfo GetTexture(std::size_t offset) const;
200 200
201 /// Given a Texture Handle, returns the TSC and TIC entries. 201 /// Given a texture handle, returns the TSC and TIC entries.
202 Texture::FullTextureInfo GetTextureInfo(const Texture::TextureHandle tex_handle, 202 Texture::FullTextureInfo GetTextureInfo(Texture::TextureHandle tex_handle) const;
203 std::size_t offset) const;
204 203
205 u32 AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const override; 204 u32 AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const override;
206 205
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 514ed93fa..2bed6cb38 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -760,61 +760,8 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
760 return tsc_entry; 760 return tsc_entry;
761} 761}
762 762
763std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) const { 763Texture::FullTextureInfo Maxwell3D::GetTextureInfo(Texture::TextureHandle tex_handle) const {
764 std::vector<Texture::FullTextureInfo> textures; 764 return Texture::FullTextureInfo{GetTICEntry(tex_handle.tic_id), GetTSCEntry(tex_handle.tsc_id)};
765
766 auto& fragment_shader = state.shader_stages[static_cast<std::size_t>(stage)];
767 auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index];
768 ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0);
769
770 GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size;
771
772 // Offset into the texture constbuffer where the texture info begins.
773 static constexpr std::size_t TextureInfoOffset = 0x20;
774
775 for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset;
776 current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) {
777
778 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(current_texture)};
779
780 Texture::FullTextureInfo tex_info{};
781 // TODO(Subv): Use the shader to determine which textures are actually accessed.
782 tex_info.index =
783 static_cast<u32>(current_texture - tex_info_buffer.address - TextureInfoOffset) /
784 sizeof(Texture::TextureHandle);
785
786 // Load the TIC data.
787 auto tic_entry = GetTICEntry(tex_handle.tic_id);
788 // TODO(Subv): Workaround for BitField's move constructor being deleted.
789 std::memcpy(&tex_info.tic, &tic_entry, sizeof(tic_entry));
790
791 // Load the TSC data
792 auto tsc_entry = GetTSCEntry(tex_handle.tsc_id);
793 // TODO(Subv): Workaround for BitField's move constructor being deleted.
794 std::memcpy(&tex_info.tsc, &tsc_entry, sizeof(tsc_entry));
795
796 textures.push_back(tex_info);
797 }
798
799 return textures;
800}
801
802Texture::FullTextureInfo Maxwell3D::GetTextureInfo(const Texture::TextureHandle tex_handle,
803 std::size_t offset) const {
804 Texture::FullTextureInfo tex_info{};
805 tex_info.index = static_cast<u32>(offset);
806
807 // Load the TIC data.
808 auto tic_entry = GetTICEntry(tex_handle.tic_id);
809 // TODO(Subv): Workaround for BitField's move constructor being deleted.
810 std::memcpy(&tex_info.tic, &tic_entry, sizeof(tic_entry));
811
812 // Load the TSC data
813 auto tsc_entry = GetTSCEntry(tex_handle.tsc_id);
814 // TODO(Subv): Workaround for BitField's move constructor being deleted.
815 std::memcpy(&tex_info.tsc, &tsc_entry, sizeof(tsc_entry));
816
817 return tex_info;
818} 765}
819 766
820Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, 767Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage,
@@ -830,7 +777,7 @@ Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage,
830 777
831 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(tex_info_address)}; 778 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(tex_info_address)};
832 779
833 return GetTextureInfo(tex_handle, offset); 780 return GetTextureInfo(tex_handle);
834} 781}
835 782
836u32 Maxwell3D::GetRegisterValue(u32 method) const { 783u32 Maxwell3D::GetRegisterValue(u32 method) const {
@@ -867,7 +814,7 @@ SamplerDescriptor Maxwell3D::AccessBindlessSampler(ShaderType stage, u64 const_b
867 const GPUVAddr tex_info_address = tex_info_buffer.address + offset; 814 const GPUVAddr tex_info_address = tex_info_buffer.address + offset;
868 815
869 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(tex_info_address)}; 816 const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(tex_info_address)};
870 const Texture::FullTextureInfo tex_info = GetTextureInfo(tex_handle, offset); 817 const Texture::FullTextureInfo tex_info = GetTextureInfo(tex_handle);
871 SamplerDescriptor result = SamplerDescriptor::FromTicTexture(tex_info.tic.texture_type.Value()); 818 SamplerDescriptor result = SamplerDescriptor::FromTicTexture(tex_info.tic.texture_type.Value());
872 result.is_shadow.Assign(tex_info.tsc.depth_compare_enabled.Value()); 819 result.is_shadow.Assign(tex_info.tsc.depth_compare_enabled.Value());
873 return result; 820 return result;
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 987ad77b2..8cc842684 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1250,12 +1250,8 @@ public:
1250 1250
1251 void FlushMMEInlineDraw(); 1251 void FlushMMEInlineDraw();
1252 1252
1253 /// Given a Texture Handle, returns the TSC and TIC entries. 1253 /// Given a texture handle, returns the TSC and TIC entries.
1254 Texture::FullTextureInfo GetTextureInfo(const Texture::TextureHandle tex_handle, 1254 Texture::FullTextureInfo GetTextureInfo(Texture::TextureHandle tex_handle) const;
1255 std::size_t offset) const;
1256
1257 /// Returns a list of enabled textures for the specified shader stage.
1258 std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const;
1259 1255
1260 /// Returns the texture information for a specific texture in a specific shader stage. 1256 /// Returns the texture information for a specific texture in a specific shader stage.
1261 Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const; 1257 Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const;
diff --git a/src/video_core/morton.cpp b/src/video_core/morton.cpp
index fe5f08ace..2f2fe6859 100644
--- a/src/video_core/morton.cpp
+++ b/src/video_core/morton.cpp
@@ -112,6 +112,7 @@ static constexpr ConversionArray morton_to_linear_fns = {
112 MortonCopy<true, PixelFormat::ASTC_2D_8X6_SRGB>, 112 MortonCopy<true, PixelFormat::ASTC_2D_8X6_SRGB>,
113 MortonCopy<true, PixelFormat::ASTC_2D_6X5>, 113 MortonCopy<true, PixelFormat::ASTC_2D_6X5>,
114 MortonCopy<true, PixelFormat::ASTC_2D_6X5_SRGB>, 114 MortonCopy<true, PixelFormat::ASTC_2D_6X5_SRGB>,
115 MortonCopy<true, PixelFormat::E5B9G9R9F>,
115 MortonCopy<true, PixelFormat::Z32F>, 116 MortonCopy<true, PixelFormat::Z32F>,
116 MortonCopy<true, PixelFormat::Z16>, 117 MortonCopy<true, PixelFormat::Z16>,
117 MortonCopy<true, PixelFormat::Z24S8>, 118 MortonCopy<true, PixelFormat::Z24S8>,
@@ -192,6 +193,7 @@ static constexpr ConversionArray linear_to_morton_fns = {
192 nullptr, 193 nullptr,
193 nullptr, 194 nullptr,
194 nullptr, 195 nullptr,
196 MortonCopy<false, PixelFormat::E5B9G9R9F>,
195 MortonCopy<false, PixelFormat::Z32F>, 197 MortonCopy<false, PixelFormat::Z32F>,
196 MortonCopy<false, PixelFormat::Z16>, 198 MortonCopy<false, PixelFormat::Z16>,
197 MortonCopy<false, PixelFormat::Z24S8>, 199 MortonCopy<false, PixelFormat::Z24S8>,
diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp
new file mode 100644
index 000000000..b230dcc18
--- /dev/null
+++ b/src/video_core/rasterizer_accelerated.cpp
@@ -0,0 +1,63 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <mutex>
6
7#include <boost/icl/interval_map.hpp>
8
9#include "common/assert.h"
10#include "common/common_types.h"
11#include "core/memory.h"
12#include "video_core/rasterizer_accelerated.h"
13
14namespace VideoCore {
15
16namespace {
17
18template <typename Map, typename Interval>
19constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
20 return boost::make_iterator_range(map.equal_range(interval));
21}
22
23} // Anonymous namespace
24
25RasterizerAccelerated::RasterizerAccelerated() = default;
26
27RasterizerAccelerated::~RasterizerAccelerated() = default;
28
29void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
30 std::lock_guard lock{pages_mutex};
31 const u64 page_start{addr >> Memory::PAGE_BITS};
32 const u64 page_end{(addr + size + Memory::PAGE_SIZE - 1) >> Memory::PAGE_BITS};
33
34 // Interval maps will erase segments if count reaches 0, so if delta is negative we have to
35 // subtract after iterating
36 const auto pages_interval = CachedPageMap::interval_type::right_open(page_start, page_end);
37 if (delta > 0) {
38 cached_pages.add({pages_interval, delta});
39 }
40
41 for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) {
42 const auto interval = pair.first & pages_interval;
43 const int count = pair.second;
44
45 const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS;
46 const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS;
47 const u64 interval_size = interval_end_addr - interval_start_addr;
48
49 if (delta > 0 && count == delta) {
50 Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, true);
51 } else if (delta < 0 && count == -delta) {
52 Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, false);
53 } else {
54 ASSERT(count >= 0);
55 }
56 }
57
58 if (delta < 0) {
59 cached_pages.add({pages_interval, delta});
60 }
61}
62
63} // namespace VideoCore
diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h
new file mode 100644
index 000000000..8f7e3547e
--- /dev/null
+++ b/src/video_core/rasterizer_accelerated.h
@@ -0,0 +1,31 @@
1// Copyright 2019 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 <mutex>
8
9#include <boost/icl/interval_map.hpp>
10
11#include "common/common_types.h"
12#include "video_core/rasterizer_interface.h"
13
14namespace VideoCore {
15
16/// Implements the shared part in GPU accelerated rasterizers in RasterizerInterface.
17class RasterizerAccelerated : public RasterizerInterface {
18public:
19 explicit RasterizerAccelerated();
20 ~RasterizerAccelerated() override;
21
22 void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override;
23
24private:
25 using CachedPageMap = boost::icl::interval_map<u64, int>;
26 CachedPageMap cached_pages;
27
28 std::mutex pages_mutex;
29};
30
31} // namespace VideoCore
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 9431d64ac..6a4d2c83a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -68,8 +68,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
68 ScreenInfo& info) 68 ScreenInfo& info)
69 : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, 69 : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device},
70 system{system}, screen_info{info}, buffer_cache{*this, system, STREAM_BUFFER_SIZE} { 70 system{system}, screen_info{info}, buffer_cache{*this, system, STREAM_BUFFER_SIZE} {
71 OpenGLState::ApplyDefaultState();
72
73 shader_program_manager = std::make_unique<GLShader::ProgramManager>(); 71 shader_program_manager = std::make_unique<GLShader::ProgramManager>();
74 state.draw.shader_program = 0; 72 state.draw.shader_program = 0;
75 state.Apply(); 73 state.Apply();
@@ -342,42 +340,6 @@ std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const {
342 static_cast<std::size_t>(regs.index_array.FormatSizeInBytes()); 340 static_cast<std::size_t>(regs.index_array.FormatSizeInBytes());
343} 341}
344 342
345template <typename Map, typename Interval>
346static constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
347 return boost::make_iterator_range(map.equal_range(interval));
348}
349
350void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
351 std::lock_guard lock{pages_mutex};
352 const u64 page_start{addr >> Memory::PAGE_BITS};
353 const u64 page_end{(addr + size + Memory::PAGE_SIZE - 1) >> Memory::PAGE_BITS};
354
355 // Interval maps will erase segments if count reaches 0, so if delta is negative we have to
356 // subtract after iterating
357 const auto pages_interval = CachedPageMap::interval_type::right_open(page_start, page_end);
358 if (delta > 0)
359 cached_pages.add({pages_interval, delta});
360
361 for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) {
362 const auto interval = pair.first & pages_interval;
363 const int count = pair.second;
364
365 const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS;
366 const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS;
367 const u64 interval_size = interval_end_addr - interval_start_addr;
368
369 if (delta > 0 && count == delta)
370 Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, true);
371 else if (delta < 0 && count == -delta)
372 Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, false);
373 else
374 ASSERT(count >= 0);
375 }
376
377 if (delta < 0)
378 cached_pages.add({pages_interval, delta});
379}
380
381void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, 343void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
382 const VideoCore::DiskResourceLoadCallback& callback) { 344 const VideoCore::DiskResourceLoadCallback& callback) {
383 shader_cache.LoadDiskCache(stop_loading, callback); 345 shader_cache.LoadDiskCache(stop_loading, callback);
@@ -969,7 +931,7 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag
969 931
970 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { 932 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
971 const auto& entry = entries[bindpoint]; 933 const auto& entry = entries[bindpoint];
972 const auto texture = [&]() { 934 const auto texture = [&] {
973 if (!entry.IsBindless()) { 935 if (!entry.IsBindless()) {
974 return maxwell3d.GetStageTexture(stage, entry.GetOffset()); 936 return maxwell3d.GetStageTexture(stage, entry.GetOffset());
975 } 937 }
@@ -977,7 +939,7 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag
977 Tegra::Texture::TextureHandle tex_handle; 939 Tegra::Texture::TextureHandle tex_handle;
978 Tegra::Engines::ShaderType shader_type = static_cast<Tegra::Engines::ShaderType>(stage); 940 Tegra::Engines::ShaderType shader_type = static_cast<Tegra::Engines::ShaderType>(stage);
979 tex_handle.raw = maxwell3d.AccessConstBuffer32(shader_type, cbuf.first, cbuf.second); 941 tex_handle.raw = maxwell3d.AccessConstBuffer32(shader_type, cbuf.first, cbuf.second);
980 return maxwell3d.GetTextureInfo(tex_handle, entry.GetOffset()); 942 return maxwell3d.GetTextureInfo(tex_handle);
981 }(); 943 }();
982 944
983 if (SetupTexture(base_bindings.sampler + bindpoint, texture, entry)) { 945 if (SetupTexture(base_bindings.sampler + bindpoint, texture, entry)) {
@@ -1000,7 +962,7 @@ TextureBufferUsage RasterizerOpenGL::SetupComputeTextures(const Shader& kernel)
1000 962
1001 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { 963 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
1002 const auto& entry = entries[bindpoint]; 964 const auto& entry = entries[bindpoint];
1003 const auto texture = [&]() { 965 const auto texture = [&] {
1004 if (!entry.IsBindless()) { 966 if (!entry.IsBindless()) {
1005 return compute.GetTexture(entry.GetOffset()); 967 return compute.GetTexture(entry.GetOffset());
1006 } 968 }
@@ -1008,7 +970,7 @@ TextureBufferUsage RasterizerOpenGL::SetupComputeTextures(const Shader& kernel)
1008 Tegra::Texture::TextureHandle tex_handle; 970 Tegra::Texture::TextureHandle tex_handle;
1009 tex_handle.raw = compute.AccessConstBuffer32(Tegra::Engines::ShaderType::Compute, 971 tex_handle.raw = compute.AccessConstBuffer32(Tegra::Engines::ShaderType::Compute,
1010 cbuf.first, cbuf.second); 972 cbuf.first, cbuf.second);
1011 return compute.GetTextureInfo(tex_handle, entry.GetOffset()); 973 return compute.GetTextureInfo(tex_handle);
1012 }(); 974 }();
1013 975
1014 if (SetupTexture(bindpoint, texture, entry)) { 976 if (SetupTexture(bindpoint, texture, entry)) {
@@ -1046,7 +1008,7 @@ void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
1046 const auto& entries = shader->GetShaderEntries().images; 1008 const auto& entries = shader->GetShaderEntries().images;
1047 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { 1009 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
1048 const auto& entry = entries[bindpoint]; 1010 const auto& entry = entries[bindpoint];
1049 const auto tic = [&]() { 1011 const auto tic = [&] {
1050 if (!entry.IsBindless()) { 1012 if (!entry.IsBindless()) {
1051 return compute.GetTexture(entry.GetOffset()).tic; 1013 return compute.GetTexture(entry.GetOffset()).tic;
1052 } 1014 }
@@ -1054,7 +1016,7 @@ void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
1054 Tegra::Texture::TextureHandle tex_handle; 1016 Tegra::Texture::TextureHandle tex_handle;
1055 tex_handle.raw = compute.AccessConstBuffer32(Tegra::Engines::ShaderType::Compute, 1017 tex_handle.raw = compute.AccessConstBuffer32(Tegra::Engines::ShaderType::Compute,
1056 cbuf.first, cbuf.second); 1018 cbuf.first, cbuf.second);
1057 return compute.GetTextureInfo(tex_handle, entry.GetOffset()).tic; 1019 return compute.GetTextureInfo(tex_handle).tic;
1058 }(); 1020 }();
1059 SetupImage(bindpoint, tic, entry); 1021 SetupImage(bindpoint, tic, entry);
1060 } 1022 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index c24a02d71..bd6fe5c3a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -9,17 +9,16 @@
9#include <cstddef> 9#include <cstddef>
10#include <map> 10#include <map>
11#include <memory> 11#include <memory>
12#include <mutex>
13#include <optional> 12#include <optional>
14#include <tuple> 13#include <tuple>
15#include <utility> 14#include <utility>
16 15
17#include <boost/icl/interval_map.hpp>
18#include <glad/glad.h> 16#include <glad/glad.h>
19 17
20#include "common/common_types.h" 18#include "common/common_types.h"
21#include "video_core/engines/const_buffer_info.h" 19#include "video_core/engines/const_buffer_info.h"
22#include "video_core/engines/maxwell_3d.h" 20#include "video_core/engines/maxwell_3d.h"
21#include "video_core/rasterizer_accelerated.h"
23#include "video_core/rasterizer_cache.h" 22#include "video_core/rasterizer_cache.h"
24#include "video_core/rasterizer_interface.h" 23#include "video_core/rasterizer_interface.h"
25#include "video_core/renderer_opengl/gl_buffer_cache.h" 24#include "video_core/renderer_opengl/gl_buffer_cache.h"
@@ -52,7 +51,7 @@ namespace OpenGL {
52struct ScreenInfo; 51struct ScreenInfo;
53struct DrawParameters; 52struct DrawParameters;
54 53
55class RasterizerOpenGL : public VideoCore::RasterizerInterface { 54class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
56public: 55public:
57 explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, 56 explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
58 ScreenInfo& info); 57 ScreenInfo& info);
@@ -73,7 +72,6 @@ public:
73 const Tegra::Engines::Fermi2D::Config& copy_config) override; 72 const Tegra::Engines::Fermi2D::Config& copy_config) override;
74 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 73 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
75 u32 pixel_stride) override; 74 u32 pixel_stride) override;
76 void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override;
77 void LoadDiskResources(const std::atomic_bool& stop_loading, 75 void LoadDiskResources(const std::atomic_bool& stop_loading,
78 const VideoCore::DiskResourceLoadCallback& callback) override; 76 const VideoCore::DiskResourceLoadCallback& callback) override;
79 77
@@ -228,11 +226,6 @@ private:
228 AccelDraw accelerate_draw = AccelDraw::Disabled; 226 AccelDraw accelerate_draw = AccelDraw::Disabled;
229 227
230 OGLFramebuffer clear_framebuffer; 228 OGLFramebuffer clear_framebuffer;
231
232 using CachedPageMap = boost::icl::interval_map<u64, int>;
233 CachedPageMap cached_pages;
234
235 std::mutex pages_mutex;
236}; 229};
237 230
238} // namespace OpenGL 231} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index bf86b5a0b..f25148362 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -2,6 +2,7 @@
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 <algorithm>
5#include <iterator> 6#include <iterator>
6#include <glad/glad.h> 7#include <glad/glad.h>
7#include "common/assert.h" 8#include "common/assert.h"
@@ -69,147 +70,29 @@ void Enable(GLenum cap, GLuint index, bool enable) {
69} 70}
70 71
71void Enable(GLenum cap, bool& current_value, bool new_value) { 72void Enable(GLenum cap, bool& current_value, bool new_value) {
72 if (UpdateValue(current_value, new_value)) 73 if (UpdateValue(current_value, new_value)) {
73 Enable(cap, new_value); 74 Enable(cap, new_value);
75 }
74} 76}
75 77
76void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { 78void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
77 if (UpdateValue(current_value, new_value)) 79 if (UpdateValue(current_value, new_value)) {
78 Enable(cap, index, new_value); 80 Enable(cap, index, new_value);
79}
80
81} // namespace
82
83OpenGLState::OpenGLState() {
84 // These all match default OpenGL values
85 framebuffer_srgb.enabled = false;
86
87 multisample_control.alpha_to_coverage = false;
88 multisample_control.alpha_to_one = false;
89
90 cull.enabled = false;
91 cull.mode = GL_BACK;
92 cull.front_face = GL_CCW;
93
94 depth.test_enabled = false;
95 depth.test_func = GL_LESS;
96 depth.write_mask = GL_TRUE;
97
98 primitive_restart.enabled = false;
99 primitive_restart.index = 0;
100
101 for (auto& item : color_mask) {
102 item.red_enabled = GL_TRUE;
103 item.green_enabled = GL_TRUE;
104 item.blue_enabled = GL_TRUE;
105 item.alpha_enabled = GL_TRUE;
106 } 81 }
82}
107 83
108 const auto ResetStencil = [](auto& config) { 84} // Anonymous namespace
109 config.test_func = GL_ALWAYS;
110 config.test_ref = 0;
111 config.test_mask = 0xFFFFFFFF;
112 config.write_mask = 0xFFFFFFFF;
113 config.action_depth_fail = GL_KEEP;
114 config.action_depth_pass = GL_KEEP;
115 config.action_stencil_fail = GL_KEEP;
116 };
117 stencil.test_enabled = false;
118 ResetStencil(stencil.front);
119 ResetStencil(stencil.back);
120
121 for (auto& item : viewports) {
122 item.x = 0;
123 item.y = 0;
124 item.width = 0;
125 item.height = 0;
126 item.depth_range_near = 0.0f;
127 item.depth_range_far = 1.0f;
128 item.scissor.enabled = false;
129 item.scissor.x = 0;
130 item.scissor.y = 0;
131 item.scissor.width = 0;
132 item.scissor.height = 0;
133 }
134
135 for (auto& item : blend) {
136 item.enabled = true;
137 item.rgb_equation = GL_FUNC_ADD;
138 item.a_equation = GL_FUNC_ADD;
139 item.src_rgb_func = GL_ONE;
140 item.dst_rgb_func = GL_ZERO;
141 item.src_a_func = GL_ONE;
142 item.dst_a_func = GL_ZERO;
143 }
144
145 independant_blend.enabled = false;
146
147 blend_color.red = 0.0f;
148 blend_color.green = 0.0f;
149 blend_color.blue = 0.0f;
150 blend_color.alpha = 0.0f;
151
152 logic_op.enabled = false;
153 logic_op.operation = GL_COPY;
154
155 draw.read_framebuffer = 0;
156 draw.draw_framebuffer = 0;
157 draw.vertex_array = 0;
158 draw.shader_program = 0;
159 draw.program_pipeline = 0;
160
161 clip_distance = {};
162
163 point.size = 1;
164
165 fragment_color_clamp.enabled = false;
166
167 depth_clamp.far_plane = false;
168 depth_clamp.near_plane = false;
169
170 polygon_offset.fill_enable = false;
171 polygon_offset.line_enable = false;
172 polygon_offset.point_enable = false;
173 polygon_offset.factor = 0.0f;
174 polygon_offset.units = 0.0f;
175 polygon_offset.clamp = 0.0f;
176 85
177 alpha_test.enabled = false; 86OpenGLState::OpenGLState() = default;
178 alpha_test.func = GL_ALWAYS;
179 alpha_test.ref = 0.0f;
180}
181 87
182void OpenGLState::SetDefaultViewports() { 88void OpenGLState::SetDefaultViewports() {
183 for (auto& item : viewports) { 89 viewports.fill(Viewport{});
184 item.x = 0;
185 item.y = 0;
186 item.width = 0;
187 item.height = 0;
188 item.depth_range_near = 0.0f;
189 item.depth_range_far = 1.0f;
190 item.scissor.enabled = false;
191 item.scissor.x = 0;
192 item.scissor.y = 0;
193 item.scissor.width = 0;
194 item.scissor.height = 0;
195 }
196 90
197 depth_clamp.far_plane = false; 91 depth_clamp.far_plane = false;
198 depth_clamp.near_plane = false; 92 depth_clamp.near_plane = false;
199} 93}
200 94
201void OpenGLState::ApplyDefaultState() { 95void OpenGLState::ApplyFramebufferState() {
202 glEnable(GL_BLEND);
203 glDisable(GL_FRAMEBUFFER_SRGB);
204 glDisable(GL_CULL_FACE);
205 glDisable(GL_DEPTH_TEST);
206 glDisable(GL_PRIMITIVE_RESTART);
207 glDisable(GL_STENCIL_TEST);
208 glDisable(GL_COLOR_LOGIC_OP);
209 glDisable(GL_SCISSOR_TEST);
210}
211
212void OpenGLState::ApplyFramebufferState() const {
213 if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) { 96 if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) {
214 glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); 97 glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
215 } 98 }
@@ -218,52 +101,52 @@ void OpenGLState::ApplyFramebufferState() const {
218 } 101 }
219} 102}
220 103
221void OpenGLState::ApplyVertexArrayState() const { 104void OpenGLState::ApplyVertexArrayState() {
222 if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) { 105 if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) {
223 glBindVertexArray(draw.vertex_array); 106 glBindVertexArray(draw.vertex_array);
224 } 107 }
225} 108}
226 109
227void OpenGLState::ApplyShaderProgram() const { 110void OpenGLState::ApplyShaderProgram() {
228 if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { 111 if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
229 glUseProgram(draw.shader_program); 112 glUseProgram(draw.shader_program);
230 } 113 }
231} 114}
232 115
233void OpenGLState::ApplyProgramPipeline() const { 116void OpenGLState::ApplyProgramPipeline() {
234 if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) { 117 if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) {
235 glBindProgramPipeline(draw.program_pipeline); 118 glBindProgramPipeline(draw.program_pipeline);
236 } 119 }
237} 120}
238 121
239void OpenGLState::ApplyClipDistances() const { 122void OpenGLState::ApplyClipDistances() {
240 for (std::size_t i = 0; i < clip_distance.size(); ++i) { 123 for (std::size_t i = 0; i < clip_distance.size(); ++i) {
241 Enable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i), cur_state.clip_distance[i], 124 Enable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i), cur_state.clip_distance[i],
242 clip_distance[i]); 125 clip_distance[i]);
243 } 126 }
244} 127}
245 128
246void OpenGLState::ApplyPointSize() const { 129void OpenGLState::ApplyPointSize() {
247 if (UpdateValue(cur_state.point.size, point.size)) { 130 if (UpdateValue(cur_state.point.size, point.size)) {
248 glPointSize(point.size); 131 glPointSize(point.size);
249 } 132 }
250} 133}
251 134
252void OpenGLState::ApplyFragmentColorClamp() const { 135void OpenGLState::ApplyFragmentColorClamp() {
253 if (UpdateValue(cur_state.fragment_color_clamp.enabled, fragment_color_clamp.enabled)) { 136 if (UpdateValue(cur_state.fragment_color_clamp.enabled, fragment_color_clamp.enabled)) {
254 glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, 137 glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB,
255 fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE); 138 fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE);
256 } 139 }
257} 140}
258 141
259void OpenGLState::ApplyMultisample() const { 142void OpenGLState::ApplyMultisample() {
260 Enable(GL_SAMPLE_ALPHA_TO_COVERAGE, cur_state.multisample_control.alpha_to_coverage, 143 Enable(GL_SAMPLE_ALPHA_TO_COVERAGE, cur_state.multisample_control.alpha_to_coverage,
261 multisample_control.alpha_to_coverage); 144 multisample_control.alpha_to_coverage);
262 Enable(GL_SAMPLE_ALPHA_TO_ONE, cur_state.multisample_control.alpha_to_one, 145 Enable(GL_SAMPLE_ALPHA_TO_ONE, cur_state.multisample_control.alpha_to_one,
263 multisample_control.alpha_to_one); 146 multisample_control.alpha_to_one);
264} 147}
265 148
266void OpenGLState::ApplyDepthClamp() const { 149void OpenGLState::ApplyDepthClamp() {
267 if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane && 150 if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane &&
268 depth_clamp.near_plane == cur_state.depth_clamp.near_plane) { 151 depth_clamp.near_plane == cur_state.depth_clamp.near_plane) {
269 return; 152 return;
@@ -276,7 +159,7 @@ void OpenGLState::ApplyDepthClamp() const {
276 Enable(GL_DEPTH_CLAMP, depth_clamp.far_plane || depth_clamp.near_plane); 159 Enable(GL_DEPTH_CLAMP, depth_clamp.far_plane || depth_clamp.near_plane);
277} 160}
278 161
279void OpenGLState::ApplySRgb() const { 162void OpenGLState::ApplySRgb() {
280 if (cur_state.framebuffer_srgb.enabled == framebuffer_srgb.enabled) 163 if (cur_state.framebuffer_srgb.enabled == framebuffer_srgb.enabled)
281 return; 164 return;
282 cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled; 165 cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled;
@@ -287,7 +170,7 @@ void OpenGLState::ApplySRgb() const {
287 } 170 }
288} 171}
289 172
290void OpenGLState::ApplyCulling() const { 173void OpenGLState::ApplyCulling() {
291 Enable(GL_CULL_FACE, cur_state.cull.enabled, cull.enabled); 174 Enable(GL_CULL_FACE, cur_state.cull.enabled, cull.enabled);
292 175
293 if (UpdateValue(cur_state.cull.mode, cull.mode)) { 176 if (UpdateValue(cur_state.cull.mode, cull.mode)) {
@@ -299,7 +182,12 @@ void OpenGLState::ApplyCulling() const {
299 } 182 }
300} 183}
301 184
302void OpenGLState::ApplyColorMask() const { 185void OpenGLState::ApplyColorMask() {
186 if (!dirty.color_mask) {
187 return;
188 }
189 dirty.color_mask = false;
190
303 for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { 191 for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) {
304 const auto& updated = color_mask[i]; 192 const auto& updated = color_mask[i];
305 auto& current = cur_state.color_mask[i]; 193 auto& current = cur_state.color_mask[i];
@@ -314,7 +202,7 @@ void OpenGLState::ApplyColorMask() const {
314 } 202 }
315} 203}
316 204
317void OpenGLState::ApplyDepth() const { 205void OpenGLState::ApplyDepth() {
318 Enable(GL_DEPTH_TEST, cur_state.depth.test_enabled, depth.test_enabled); 206 Enable(GL_DEPTH_TEST, cur_state.depth.test_enabled, depth.test_enabled);
319 207
320 if (cur_state.depth.test_func != depth.test_func) { 208 if (cur_state.depth.test_func != depth.test_func) {
@@ -328,7 +216,7 @@ void OpenGLState::ApplyDepth() const {
328 } 216 }
329} 217}
330 218
331void OpenGLState::ApplyPrimitiveRestart() const { 219void OpenGLState::ApplyPrimitiveRestart() {
332 Enable(GL_PRIMITIVE_RESTART, cur_state.primitive_restart.enabled, primitive_restart.enabled); 220 Enable(GL_PRIMITIVE_RESTART, cur_state.primitive_restart.enabled, primitive_restart.enabled);
333 221
334 if (cur_state.primitive_restart.index != primitive_restart.index) { 222 if (cur_state.primitive_restart.index != primitive_restart.index) {
@@ -337,7 +225,12 @@ void OpenGLState::ApplyPrimitiveRestart() const {
337 } 225 }
338} 226}
339 227
340void OpenGLState::ApplyStencilTest() const { 228void OpenGLState::ApplyStencilTest() {
229 if (!dirty.stencil_state) {
230 return;
231 }
232 dirty.stencil_state = false;
233
341 Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled); 234 Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled);
342 235
343 const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) { 236 const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) {
@@ -366,7 +259,7 @@ void OpenGLState::ApplyStencilTest() const {
366 ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back); 259 ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back);
367} 260}
368 261
369void OpenGLState::ApplyViewport() const { 262void OpenGLState::ApplyViewport() {
370 for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) { 263 for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) {
371 const auto& updated = viewports[i]; 264 const auto& updated = viewports[i];
372 auto& current = cur_state.viewports[i]; 265 auto& current = cur_state.viewports[i];
@@ -403,7 +296,7 @@ void OpenGLState::ApplyViewport() const {
403 } 296 }
404} 297}
405 298
406void OpenGLState::ApplyGlobalBlending() const { 299void OpenGLState::ApplyGlobalBlending() {
407 const Blend& updated = blend[0]; 300 const Blend& updated = blend[0];
408 Blend& current = cur_state.blend[0]; 301 Blend& current = cur_state.blend[0];
409 302
@@ -427,7 +320,7 @@ void OpenGLState::ApplyGlobalBlending() const {
427 } 320 }
428} 321}
429 322
430void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const { 323void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) {
431 const Blend& updated = blend[target]; 324 const Blend& updated = blend[target];
432 Blend& current = cur_state.blend[target]; 325 Blend& current = cur_state.blend[target];
433 326
@@ -451,7 +344,12 @@ void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const {
451 } 344 }
452} 345}
453 346
454void OpenGLState::ApplyBlending() const { 347void OpenGLState::ApplyBlending() {
348 if (!dirty.blend_state) {
349 return;
350 }
351 dirty.blend_state = false;
352
455 if (independant_blend.enabled) { 353 if (independant_blend.enabled) {
456 const bool force = independant_blend.enabled != cur_state.independant_blend.enabled; 354 const bool force = independant_blend.enabled != cur_state.independant_blend.enabled;
457 for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) { 355 for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) {
@@ -470,7 +368,7 @@ void OpenGLState::ApplyBlending() const {
470 } 368 }
471} 369}
472 370
473void OpenGLState::ApplyLogicOp() const { 371void OpenGLState::ApplyLogicOp() {
474 Enable(GL_COLOR_LOGIC_OP, cur_state.logic_op.enabled, logic_op.enabled); 372 Enable(GL_COLOR_LOGIC_OP, cur_state.logic_op.enabled, logic_op.enabled);
475 373
476 if (UpdateValue(cur_state.logic_op.operation, logic_op.operation)) { 374 if (UpdateValue(cur_state.logic_op.operation, logic_op.operation)) {
@@ -478,7 +376,12 @@ void OpenGLState::ApplyLogicOp() const {
478 } 376 }
479} 377}
480 378
481void OpenGLState::ApplyPolygonOffset() const { 379void OpenGLState::ApplyPolygonOffset() {
380 if (!dirty.polygon_offset) {
381 return;
382 }
383 dirty.polygon_offset = false;
384
482 Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable, 385 Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable,
483 polygon_offset.fill_enable); 386 polygon_offset.fill_enable);
484 Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable, 387 Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable,
@@ -499,7 +402,7 @@ void OpenGLState::ApplyPolygonOffset() const {
499 } 402 }
500} 403}
501 404
502void OpenGLState::ApplyAlphaTest() const { 405void OpenGLState::ApplyAlphaTest() {
503 Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled); 406 Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled);
504 if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref), 407 if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref),
505 std::tie(alpha_test.func, alpha_test.ref))) { 408 std::tie(alpha_test.func, alpha_test.ref))) {
@@ -507,19 +410,19 @@ void OpenGLState::ApplyAlphaTest() const {
507 } 410 }
508} 411}
509 412
510void OpenGLState::ApplyTextures() const { 413void OpenGLState::ApplyTextures() {
511 if (const auto update = UpdateArray(cur_state.textures, textures)) { 414 if (const auto update = UpdateArray(cur_state.textures, textures)) {
512 glBindTextures(update->first, update->second, textures.data() + update->first); 415 glBindTextures(update->first, update->second, textures.data() + update->first);
513 } 416 }
514} 417}
515 418
516void OpenGLState::ApplySamplers() const { 419void OpenGLState::ApplySamplers() {
517 if (const auto update = UpdateArray(cur_state.samplers, samplers)) { 420 if (const auto update = UpdateArray(cur_state.samplers, samplers)) {
518 glBindSamplers(update->first, update->second, samplers.data() + update->first); 421 glBindSamplers(update->first, update->second, samplers.data() + update->first);
519 } 422 }
520} 423}
521 424
522void OpenGLState::ApplyImages() const { 425void OpenGLState::ApplyImages() {
523 if (const auto update = UpdateArray(cur_state.images, images)) { 426 if (const auto update = UpdateArray(cur_state.images, images)) {
524 glBindImageTextures(update->first, update->second, images.data() + update->first); 427 glBindImageTextures(update->first, update->second, images.data() + update->first);
525 } 428 }
@@ -535,32 +438,20 @@ void OpenGLState::Apply() {
535 ApplyPointSize(); 438 ApplyPointSize();
536 ApplyFragmentColorClamp(); 439 ApplyFragmentColorClamp();
537 ApplyMultisample(); 440 ApplyMultisample();
538 if (dirty.color_mask) { 441 ApplyColorMask();
539 ApplyColorMask();
540 dirty.color_mask = false;
541 }
542 ApplyDepthClamp(); 442 ApplyDepthClamp();
543 ApplyViewport(); 443 ApplyViewport();
544 if (dirty.stencil_state) { 444 ApplyStencilTest();
545 ApplyStencilTest();
546 dirty.stencil_state = false;
547 }
548 ApplySRgb(); 445 ApplySRgb();
549 ApplyCulling(); 446 ApplyCulling();
550 ApplyDepth(); 447 ApplyDepth();
551 ApplyPrimitiveRestart(); 448 ApplyPrimitiveRestart();
552 if (dirty.blend_state) { 449 ApplyBlending();
553 ApplyBlending();
554 dirty.blend_state = false;
555 }
556 ApplyLogicOp(); 450 ApplyLogicOp();
557 ApplyTextures(); 451 ApplyTextures();
558 ApplySamplers(); 452 ApplySamplers();
559 ApplyImages(); 453 ApplyImages();
560 if (dirty.polygon_offset) { 454 ApplyPolygonOffset();
561 ApplyPolygonOffset();
562 dirty.polygon_offset = false;
563 }
564 ApplyAlphaTest(); 455 ApplyAlphaTest();
565} 456}
566 457
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index c358d3b38..cca25206b 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -5,168 +5,146 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <type_traits>
8#include <glad/glad.h> 9#include <glad/glad.h>
9#include "video_core/engines/maxwell_3d.h" 10#include "video_core/engines/maxwell_3d.h"
10 11
11namespace OpenGL { 12namespace OpenGL {
12 13
13namespace TextureUnits {
14
15struct TextureUnit {
16 GLint id;
17 constexpr GLenum Enum() const {
18 return static_cast<GLenum>(GL_TEXTURE0 + id);
19 }
20};
21
22constexpr TextureUnit MaxwellTexture(int unit) {
23 return TextureUnit{unit};
24}
25
26constexpr TextureUnit LightingLUT{3};
27constexpr TextureUnit FogLUT{4};
28constexpr TextureUnit ProcTexNoiseLUT{5};
29constexpr TextureUnit ProcTexColorMap{6};
30constexpr TextureUnit ProcTexAlphaMap{7};
31constexpr TextureUnit ProcTexLUT{8};
32constexpr TextureUnit ProcTexDiffLUT{9};
33
34} // namespace TextureUnits
35
36class OpenGLState { 14class OpenGLState {
37public: 15public:
38 struct { 16 struct {
39 bool enabled; // GL_FRAMEBUFFER_SRGB 17 bool enabled = false; // GL_FRAMEBUFFER_SRGB
40 } framebuffer_srgb; 18 } framebuffer_srgb;
41 19
42 struct { 20 struct {
43 bool alpha_to_coverage; // GL_ALPHA_TO_COVERAGE 21 bool alpha_to_coverage = false; // GL_ALPHA_TO_COVERAGE
44 bool alpha_to_one; // GL_ALPHA_TO_ONE 22 bool alpha_to_one = false; // GL_ALPHA_TO_ONE
45 } multisample_control; 23 } multisample_control;
46 24
47 struct { 25 struct {
48 bool enabled; // GL_CLAMP_FRAGMENT_COLOR_ARB 26 bool enabled = false; // GL_CLAMP_FRAGMENT_COLOR_ARB
49 } fragment_color_clamp; 27 } fragment_color_clamp;
50 28
51 struct { 29 struct {
52 bool far_plane; 30 bool far_plane = false;
53 bool near_plane; 31 bool near_plane = false;
54 } depth_clamp; // GL_DEPTH_CLAMP 32 } depth_clamp; // GL_DEPTH_CLAMP
55 33
56 struct { 34 struct {
57 bool enabled; // GL_CULL_FACE 35 bool enabled = false; // GL_CULL_FACE
58 GLenum mode; // GL_CULL_FACE_MODE 36 GLenum mode = GL_BACK; // GL_CULL_FACE_MODE
59 GLenum front_face; // GL_FRONT_FACE 37 GLenum front_face = GL_CCW; // GL_FRONT_FACE
60 } cull; 38 } cull;
61 39
62 struct { 40 struct {
63 bool test_enabled; // GL_DEPTH_TEST 41 bool test_enabled = false; // GL_DEPTH_TEST
64 GLenum test_func; // GL_DEPTH_FUNC 42 GLboolean write_mask = GL_TRUE; // GL_DEPTH_WRITEMASK
65 GLboolean write_mask; // GL_DEPTH_WRITEMASK 43 GLenum test_func = GL_LESS; // GL_DEPTH_FUNC
66 } depth; 44 } depth;
67 45
68 struct { 46 struct {
69 bool enabled; 47 bool enabled = false;
70 GLuint index; 48 GLuint index = 0;
71 } primitive_restart; // GL_PRIMITIVE_RESTART 49 } primitive_restart; // GL_PRIMITIVE_RESTART
72 50
73 struct ColorMask { 51 struct ColorMask {
74 GLboolean red_enabled; 52 GLboolean red_enabled = GL_TRUE;
75 GLboolean green_enabled; 53 GLboolean green_enabled = GL_TRUE;
76 GLboolean blue_enabled; 54 GLboolean blue_enabled = GL_TRUE;
77 GLboolean alpha_enabled; 55 GLboolean alpha_enabled = GL_TRUE;
78 }; 56 };
79 std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> 57 std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets>
80 color_mask; // GL_COLOR_WRITEMASK 58 color_mask; // GL_COLOR_WRITEMASK
81 struct { 59 struct {
82 bool test_enabled; // GL_STENCIL_TEST 60 bool test_enabled = false; // GL_STENCIL_TEST
83 struct { 61 struct {
84 GLenum test_func; // GL_STENCIL_FUNC 62 GLenum test_func = GL_ALWAYS; // GL_STENCIL_FUNC
85 GLint test_ref; // GL_STENCIL_REF 63 GLint test_ref = 0; // GL_STENCIL_REF
86 GLuint test_mask; // GL_STENCIL_VALUE_MASK 64 GLuint test_mask = 0xFFFFFFFF; // GL_STENCIL_VALUE_MASK
87 GLuint write_mask; // GL_STENCIL_WRITEMASK 65 GLuint write_mask = 0xFFFFFFFF; // GL_STENCIL_WRITEMASK
88 GLenum action_stencil_fail; // GL_STENCIL_FAIL 66 GLenum action_stencil_fail = GL_KEEP; // GL_STENCIL_FAIL
89 GLenum action_depth_fail; // GL_STENCIL_PASS_DEPTH_FAIL 67 GLenum action_depth_fail = GL_KEEP; // GL_STENCIL_PASS_DEPTH_FAIL
90 GLenum action_depth_pass; // GL_STENCIL_PASS_DEPTH_PASS 68 GLenum action_depth_pass = GL_KEEP; // GL_STENCIL_PASS_DEPTH_PASS
91 } front, back; 69 } front, back;
92 } stencil; 70 } stencil;
93 71
94 struct Blend { 72 struct Blend {
95 bool enabled; // GL_BLEND 73 bool enabled = false; // GL_BLEND
96 GLenum rgb_equation; // GL_BLEND_EQUATION_RGB 74 GLenum rgb_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_RGB
97 GLenum a_equation; // GL_BLEND_EQUATION_ALPHA 75 GLenum a_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_ALPHA
98 GLenum src_rgb_func; // GL_BLEND_SRC_RGB 76 GLenum src_rgb_func = GL_ONE; // GL_BLEND_SRC_RGB
99 GLenum dst_rgb_func; // GL_BLEND_DST_RGB 77 GLenum dst_rgb_func = GL_ZERO; // GL_BLEND_DST_RGB
100 GLenum src_a_func; // GL_BLEND_SRC_ALPHA 78 GLenum src_a_func = GL_ONE; // GL_BLEND_SRC_ALPHA
101 GLenum dst_a_func; // GL_BLEND_DST_ALPHA 79 GLenum dst_a_func = GL_ZERO; // GL_BLEND_DST_ALPHA
102 }; 80 };
103 std::array<Blend, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> blend; 81 std::array<Blend, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> blend;
104 82
105 struct { 83 struct {
106 bool enabled; 84 bool enabled = false;
107 } independant_blend; 85 } independant_blend;
108 86
109 struct { 87 struct {
110 GLclampf red; 88 GLclampf red = 0.0f;
111 GLclampf green; 89 GLclampf green = 0.0f;
112 GLclampf blue; 90 GLclampf blue = 0.0f;
113 GLclampf alpha; 91 GLclampf alpha = 0.0f;
114 } blend_color; // GL_BLEND_COLOR 92 } blend_color; // GL_BLEND_COLOR
115 93
116 struct { 94 struct {
117 bool enabled; // GL_LOGIC_OP_MODE 95 bool enabled = false; // GL_LOGIC_OP_MODE
118 GLenum operation; 96 GLenum operation = GL_COPY;
119 } logic_op; 97 } logic_op;
120 98
121 std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures{}; 99 std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures = {};
122 std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers{}; 100 std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers = {};
123 std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images{}; 101 std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images = {};
124 102
125 struct { 103 struct {
126 GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING 104 GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
127 GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING 105 GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
128 GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING 106 GLuint vertex_array = 0; // GL_VERTEX_ARRAY_BINDING
129 GLuint shader_program; // GL_CURRENT_PROGRAM 107 GLuint shader_program = 0; // GL_CURRENT_PROGRAM
130 GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING 108 GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
131 } draw; 109 } draw;
132 110
133 struct viewport { 111 struct Viewport {
134 GLint x; 112 GLint x = 0;
135 GLint y; 113 GLint y = 0;
136 GLint width; 114 GLint width = 0;
137 GLint height; 115 GLint height = 0;
138 GLfloat depth_range_near; // GL_DEPTH_RANGE 116 GLfloat depth_range_near = 0.0f; // GL_DEPTH_RANGE
139 GLfloat depth_range_far; // GL_DEPTH_RANGE 117 GLfloat depth_range_far = 1.0f; // GL_DEPTH_RANGE
140 struct { 118 struct {
141 bool enabled; // GL_SCISSOR_TEST 119 bool enabled = false; // GL_SCISSOR_TEST
142 GLint x; 120 GLint x = 0;
143 GLint y; 121 GLint y = 0;
144 GLsizei width; 122 GLsizei width = 0;
145 GLsizei height; 123 GLsizei height = 0;
146 } scissor; 124 } scissor;
147 }; 125 };
148 std::array<viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports; 126 std::array<Viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports;
149 127
150 struct { 128 struct {
151 float size; // GL_POINT_SIZE 129 float size = 1.0f; // GL_POINT_SIZE
152 } point; 130 } point;
153 131
154 struct { 132 struct {
155 bool point_enable; 133 bool point_enable = false;
156 bool line_enable; 134 bool line_enable = false;
157 bool fill_enable; 135 bool fill_enable = false;
158 GLfloat units; 136 GLfloat units = 0.0f;
159 GLfloat factor; 137 GLfloat factor = 0.0f;
160 GLfloat clamp; 138 GLfloat clamp = 0.0f;
161 } polygon_offset; 139 } polygon_offset;
162 140
163 struct { 141 struct {
164 bool enabled; // GL_ALPHA_TEST 142 bool enabled = false; // GL_ALPHA_TEST
165 GLenum func; // GL_ALPHA_TEST_FUNC 143 GLenum func = GL_ALWAYS; // GL_ALPHA_TEST_FUNC
166 GLfloat ref; // GL_ALPHA_TEST_REF 144 GLfloat ref = 0.0f; // GL_ALPHA_TEST_REF
167 } alpha_test; 145 } alpha_test;
168 146
169 std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE 147 std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE
170 148
171 OpenGLState(); 149 OpenGLState();
172 150
@@ -179,34 +157,31 @@ public:
179 /// Apply this state as the current OpenGL state 157 /// Apply this state as the current OpenGL state
180 void Apply(); 158 void Apply();
181 159
182 void ApplyFramebufferState() const; 160 void ApplyFramebufferState();
183 void ApplyVertexArrayState() const; 161 void ApplyVertexArrayState();
184 void ApplyShaderProgram() const; 162 void ApplyShaderProgram();
185 void ApplyProgramPipeline() const; 163 void ApplyProgramPipeline();
186 void ApplyClipDistances() const; 164 void ApplyClipDistances();
187 void ApplyPointSize() const; 165 void ApplyPointSize();
188 void ApplyFragmentColorClamp() const; 166 void ApplyFragmentColorClamp();
189 void ApplyMultisample() const; 167 void ApplyMultisample();
190 void ApplySRgb() const; 168 void ApplySRgb();
191 void ApplyCulling() const; 169 void ApplyCulling();
192 void ApplyColorMask() const; 170 void ApplyColorMask();
193 void ApplyDepth() const; 171 void ApplyDepth();
194 void ApplyPrimitiveRestart() const; 172 void ApplyPrimitiveRestart();
195 void ApplyStencilTest() const; 173 void ApplyStencilTest();
196 void ApplyViewport() const; 174 void ApplyViewport();
197 void ApplyTargetBlending(std::size_t target, bool force) const; 175 void ApplyTargetBlending(std::size_t target, bool force);
198 void ApplyGlobalBlending() const; 176 void ApplyGlobalBlending();
199 void ApplyBlending() const; 177 void ApplyBlending();
200 void ApplyLogicOp() const; 178 void ApplyLogicOp();
201 void ApplyTextures() const; 179 void ApplyTextures();
202 void ApplySamplers() const; 180 void ApplySamplers();
203 void ApplyImages() const; 181 void ApplyImages();
204 void ApplyDepthClamp() const; 182 void ApplyDepthClamp();
205 void ApplyPolygonOffset() const; 183 void ApplyPolygonOffset();
206 void ApplyAlphaTest() const; 184 void ApplyAlphaTest();
207
208 /// Set the initial OpenGL state
209 static void ApplyDefaultState();
210 185
211 /// Resets any references to the given resource 186 /// Resets any references to the given resource
212 OpenGLState& UnbindTexture(GLuint handle); 187 OpenGLState& UnbindTexture(GLuint handle);
@@ -253,5 +228,6 @@ private:
253 bool color_mask; 228 bool color_mask;
254 } dirty{}; 229 } dirty{};
255}; 230};
231static_assert(std::is_trivially_copyable_v<OpenGLState>);
256 232
257} // namespace OpenGL 233} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 2f9bfd7e4..55b3e58b2 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -131,6 +131,7 @@ constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format
131 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X6_SRGB 131 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X6_SRGB
132 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_6X5 132 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_6X5
133 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_6X5_SRGB 133 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_6X5_SRGB
134 {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, ComponentType::Float, false}, // E5B9G9R9F
134 135
135 // Depth formats 136 // Depth formats
136 {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F 137 {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index 9a3c05288..621136b6e 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -315,6 +315,14 @@ PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
315 break; 315 break;
316 } 316 }
317 break; 317 break;
318 case Tegra::Texture::TextureFormat::E5B9G9R9_SHAREDEXP:
319 switch (component_type) {
320 case Tegra::Texture::ComponentType::FLOAT:
321 return PixelFormat::E5B9G9R9F;
322 default:
323 break;
324 }
325 break;
318 case Tegra::Texture::TextureFormat::ZF32: 326 case Tegra::Texture::TextureFormat::ZF32:
319 return PixelFormat::Z32F; 327 return PixelFormat::Z32F;
320 case Tegra::Texture::TextureFormat::Z16: 328 case Tegra::Texture::TextureFormat::Z16:
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index 97668f802..d3bcd38c5 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -86,19 +86,20 @@ enum class PixelFormat {
86 ASTC_2D_8X6_SRGB = 68, 86 ASTC_2D_8X6_SRGB = 68,
87 ASTC_2D_6X5 = 69, 87 ASTC_2D_6X5 = 69,
88 ASTC_2D_6X5_SRGB = 70, 88 ASTC_2D_6X5_SRGB = 70,
89 E5B9G9R9F = 71,
89 90
90 MaxColorFormat, 91 MaxColorFormat,
91 92
92 // Depth formats 93 // Depth formats
93 Z32F = 71, 94 Z32F = 72,
94 Z16 = 72, 95 Z16 = 73,
95 96
96 MaxDepthFormat, 97 MaxDepthFormat,
97 98
98 // DepthStencil formats 99 // DepthStencil formats
99 Z24S8 = 73, 100 Z24S8 = 74,
100 S8Z24 = 74, 101 S8Z24 = 75,
101 Z32FS8 = 75, 102 Z32FS8 = 76,
102 103
103 MaxDepthStencilFormat, 104 MaxDepthStencilFormat,
104 105
@@ -207,6 +208,7 @@ constexpr std::array<u32, MaxPixelFormat> compression_factor_shift_table = {{
207 2, // ASTC_2D_8X6_SRGB 208 2, // ASTC_2D_8X6_SRGB
208 2, // ASTC_2D_6X5 209 2, // ASTC_2D_6X5
209 2, // ASTC_2D_6X5_SRGB 210 2, // ASTC_2D_6X5_SRGB
211 0, // E5B9G9R9F
210 0, // Z32F 212 0, // Z32F
211 0, // Z16 213 0, // Z16
212 0, // Z24S8 214 0, // Z24S8
@@ -302,6 +304,7 @@ constexpr std::array<u32, MaxPixelFormat> block_width_table = {{
302 8, // ASTC_2D_8X6_SRGB 304 8, // ASTC_2D_8X6_SRGB
303 6, // ASTC_2D_6X5 305 6, // ASTC_2D_6X5
304 6, // ASTC_2D_6X5_SRGB 306 6, // ASTC_2D_6X5_SRGB
307 1, // E5B9G9R9F
305 1, // Z32F 308 1, // Z32F
306 1, // Z16 309 1, // Z16
307 1, // Z24S8 310 1, // Z24S8
@@ -389,6 +392,7 @@ constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
389 6, // ASTC_2D_8X6_SRGB 392 6, // ASTC_2D_8X6_SRGB
390 5, // ASTC_2D_6X5 393 5, // ASTC_2D_6X5
391 5, // ASTC_2D_6X5_SRGB 394 5, // ASTC_2D_6X5_SRGB
395 1, // E5B9G9R9F
392 1, // Z32F 396 1, // Z32F
393 1, // Z16 397 1, // Z16
394 1, // Z24S8 398 1, // Z24S8
@@ -476,6 +480,7 @@ constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
476 128, // ASTC_2D_8X6_SRGB 480 128, // ASTC_2D_8X6_SRGB
477 128, // ASTC_2D_6X5 481 128, // ASTC_2D_6X5
478 128, // ASTC_2D_6X5_SRGB 482 128, // ASTC_2D_6X5_SRGB
483 32, // E5B9G9R9F
479 32, // Z32F 484 32, // Z32F
480 16, // Z16 485 16, // Z16
481 32, // Z24S8 486 32, // Z24S8
@@ -578,6 +583,7 @@ constexpr std::array<SurfaceCompression, MaxPixelFormat> compression_type_table
578 SurfaceCompression::Converted, // ASTC_2D_8X6_SRGB 583 SurfaceCompression::Converted, // ASTC_2D_8X6_SRGB
579 SurfaceCompression::Converted, // ASTC_2D_6X5 584 SurfaceCompression::Converted, // ASTC_2D_6X5
580 SurfaceCompression::Converted, // ASTC_2D_6X5_SRGB 585 SurfaceCompression::Converted, // ASTC_2D_6X5_SRGB
586 SurfaceCompression::None, // E5B9G9R9F
581 SurfaceCompression::None, // Z32F 587 SurfaceCompression::None, // Z32F
582 SurfaceCompression::None, // Z16 588 SurfaceCompression::None, // Z16
583 SurfaceCompression::None, // Z24S8 589 SurfaceCompression::None, // Z24S8
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index e36bc2c04..0429af9c1 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -354,7 +354,6 @@ struct TSCEntry {
354static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); 354static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size");
355 355
356struct FullTextureInfo { 356struct FullTextureInfo {
357 u32 index;
358 TICEntry tic; 357 TICEntry tic;
359 TSCEntry tsc; 358 TSCEntry tsc;
360}; 359};