diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/file_sys/savedata_factory.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.h | 7 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 61 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 8 | ||||
| -rw-r--r-- | src/video_core/morton.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/rasterizer_accelerated.cpp | 63 | ||||
| -rw-r--r-- | src/video_core/rasterizer_accelerated.h | 31 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 50 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 223 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 222 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/surface.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/surface.h | 16 | ||||
| -rw-r--r-- | src/video_core/textures/texture.h | 1 |
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 { | |||
| 16 | constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; | 16 | constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; |
| 17 | 17 | ||
| 18 | namespace { | 18 | namespace { |
| 19 | |||
| 19 | void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) { | 20 | void 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 | |||
| 57 | bool 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 | ||
| 57 | std::string SaveDataDescriptor::DebugInfo() const { | 65 | std::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 | ||
| 53 | Tegra::Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) const { | 53 | Texture::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 | ||
| 67 | Texture::FullTextureInfo KeplerCompute::GetTextureInfo(const Texture::TextureHandle tex_handle, | 67 | Texture::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 | ||
| 73 | u32 KeplerCompute::AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const { | 71 | u32 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 | ||
| 763 | std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) const { | 763 | Texture::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 | |||
| 802 | Texture::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 | ||
| 820 | Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, | 767 | Texture::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 | ||
| 836 | u32 Maxwell3D::GetRegisterValue(u32 method) const { | 783 | u32 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 | |||
| 14 | namespace VideoCore { | ||
| 15 | |||
| 16 | namespace { | ||
| 17 | |||
| 18 | template <typename Map, typename Interval> | ||
| 19 | constexpr auto RangeFromInterval(Map& map, const Interval& interval) { | ||
| 20 | return boost::make_iterator_range(map.equal_range(interval)); | ||
| 21 | } | ||
| 22 | |||
| 23 | } // Anonymous namespace | ||
| 24 | |||
| 25 | RasterizerAccelerated::RasterizerAccelerated() = default; | ||
| 26 | |||
| 27 | RasterizerAccelerated::~RasterizerAccelerated() = default; | ||
| 28 | |||
| 29 | void 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 | |||
| 14 | namespace VideoCore { | ||
| 15 | |||
| 16 | /// Implements the shared part in GPU accelerated rasterizers in RasterizerInterface. | ||
| 17 | class RasterizerAccelerated : public RasterizerInterface { | ||
| 18 | public: | ||
| 19 | explicit RasterizerAccelerated(); | ||
| 20 | ~RasterizerAccelerated() override; | ||
| 21 | |||
| 22 | void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override; | ||
| 23 | |||
| 24 | private: | ||
| 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 | ||
| 345 | template <typename Map, typename Interval> | ||
| 346 | static constexpr auto RangeFromInterval(Map& map, const Interval& interval) { | ||
| 347 | return boost::make_iterator_range(map.equal_range(interval)); | ||
| 348 | } | ||
| 349 | |||
| 350 | void 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 | |||
| 381 | void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, | 343 | void 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 { | |||
| 52 | struct ScreenInfo; | 51 | struct ScreenInfo; |
| 53 | struct DrawParameters; | 52 | struct DrawParameters; |
| 54 | 53 | ||
| 55 | class RasterizerOpenGL : public VideoCore::RasterizerInterface { | 54 | class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { |
| 56 | public: | 55 | public: |
| 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 | ||
| 71 | void Enable(GLenum cap, bool& current_value, bool new_value) { | 72 | void 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 | ||
| 76 | void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { | 78 | void 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 | |||
| 83 | OpenGLState::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; | 86 | OpenGLState::OpenGLState() = default; |
| 178 | alpha_test.func = GL_ALWAYS; | ||
| 179 | alpha_test.ref = 0.0f; | ||
| 180 | } | ||
| 181 | 87 | ||
| 182 | void OpenGLState::SetDefaultViewports() { | 88 | void 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 | ||
| 201 | void OpenGLState::ApplyDefaultState() { | 95 | void 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 | |||
| 212 | void 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 | ||
| 221 | void OpenGLState::ApplyVertexArrayState() const { | 104 | void 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 | ||
| 227 | void OpenGLState::ApplyShaderProgram() const { | 110 | void 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 | ||
| 233 | void OpenGLState::ApplyProgramPipeline() const { | 116 | void 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 | ||
| 239 | void OpenGLState::ApplyClipDistances() const { | 122 | void 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 | ||
| 246 | void OpenGLState::ApplyPointSize() const { | 129 | void 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 | ||
| 252 | void OpenGLState::ApplyFragmentColorClamp() const { | 135 | void 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 | ||
| 259 | void OpenGLState::ApplyMultisample() const { | 142 | void 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 | ||
| 266 | void OpenGLState::ApplyDepthClamp() const { | 149 | void 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 | ||
| 279 | void OpenGLState::ApplySRgb() const { | 162 | void 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 | ||
| 290 | void OpenGLState::ApplyCulling() const { | 173 | void 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 | ||
| 302 | void OpenGLState::ApplyColorMask() const { | 185 | void 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 | ||
| 317 | void OpenGLState::ApplyDepth() const { | 205 | void 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 | ||
| 331 | void OpenGLState::ApplyPrimitiveRestart() const { | 219 | void 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 | ||
| 340 | void OpenGLState::ApplyStencilTest() const { | 228 | void 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 | ||
| 369 | void OpenGLState::ApplyViewport() const { | 262 | void 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 | ||
| 406 | void OpenGLState::ApplyGlobalBlending() const { | 299 | void 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 | ||
| 430 | void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const { | 323 | void 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 | ||
| 454 | void OpenGLState::ApplyBlending() const { | 347 | void 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 | ||
| 473 | void OpenGLState::ApplyLogicOp() const { | 371 | void 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 | ||
| 481 | void OpenGLState::ApplyPolygonOffset() const { | 379 | void 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 | ||
| 502 | void OpenGLState::ApplyAlphaTest() const { | 405 | void 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 | ||
| 510 | void OpenGLState::ApplyTextures() const { | 413 | void 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 | ||
| 516 | void OpenGLState::ApplySamplers() const { | 419 | void 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 | ||
| 522 | void OpenGLState::ApplyImages() const { | 425 | void 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 | ||
| 11 | namespace OpenGL { | 12 | namespace OpenGL { |
| 12 | 13 | ||
| 13 | namespace TextureUnits { | ||
| 14 | |||
| 15 | struct TextureUnit { | ||
| 16 | GLint id; | ||
| 17 | constexpr GLenum Enum() const { | ||
| 18 | return static_cast<GLenum>(GL_TEXTURE0 + id); | ||
| 19 | } | ||
| 20 | }; | ||
| 21 | |||
| 22 | constexpr TextureUnit MaxwellTexture(int unit) { | ||
| 23 | return TextureUnit{unit}; | ||
| 24 | } | ||
| 25 | |||
| 26 | constexpr TextureUnit LightingLUT{3}; | ||
| 27 | constexpr TextureUnit FogLUT{4}; | ||
| 28 | constexpr TextureUnit ProcTexNoiseLUT{5}; | ||
| 29 | constexpr TextureUnit ProcTexColorMap{6}; | ||
| 30 | constexpr TextureUnit ProcTexAlphaMap{7}; | ||
| 31 | constexpr TextureUnit ProcTexLUT{8}; | ||
| 32 | constexpr TextureUnit ProcTexDiffLUT{9}; | ||
| 33 | |||
| 34 | } // namespace TextureUnits | ||
| 35 | |||
| 36 | class OpenGLState { | 14 | class OpenGLState { |
| 37 | public: | 15 | public: |
| 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 | }; |
| 231 | static_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 { | |||
| 354 | static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); | 354 | static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); |
| 355 | 355 | ||
| 356 | struct FullTextureInfo { | 356 | struct FullTextureInfo { |
| 357 | u32 index; | ||
| 358 | TICEntry tic; | 357 | TICEntry tic; |
| 359 | TSCEntry tsc; | 358 | TSCEntry tsc; |
| 360 | }; | 359 | }; |