diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/hex_util.cpp | 4 | ||||
-rw-r--r-- | src/common/hex_util.h | 4 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 3 | ||||
-rw-r--r-- | src/core/crypto/key_manager.cpp | 8 | ||||
-rw-r--r-- | src/core/file_sys/registered_cache.cpp | 18 | ||||
-rw-r--r-- | src/core/hle/service/am/am.cpp | 13 | ||||
-rw-r--r-- | src/core/hle/service/am/am.h | 1 | ||||
-rw-r--r-- | src/core/loader/nca.cpp | 14 | ||||
-rw-r--r-- | src/core/loader/nca.h | 17 | ||||
-rw-r--r-- | src/core/loader/xci.cpp | 14 | ||||
-rw-r--r-- | src/core/loader/xci.h | 12 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 12 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 3 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 18 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 24 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 2 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 2 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.cpp | 7 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.h | 5 |
20 files changed, 114 insertions, 69 deletions
diff --git a/src/common/hex_util.cpp b/src/common/hex_util.cpp index ae17c89d4..609144def 100644 --- a/src/common/hex_util.cpp +++ b/src/common/hex_util.cpp @@ -4,6 +4,8 @@ #include "common/hex_util.h" +namespace Common { + u8 ToHexNibble(char c1) { if (c1 >= 65 && c1 <= 70) return c1 - 55; @@ -25,3 +27,5 @@ std::array<u8, 32> operator""_array32(const char* str, size_t len) { throw std::logic_error("Not of correct size."); return HexStringToArray<32>(str); } + +} // namespace Common diff --git a/src/common/hex_util.h b/src/common/hex_util.h index 13d586015..5fb79bb72 100644 --- a/src/common/hex_util.h +++ b/src/common/hex_util.h @@ -10,6 +10,8 @@ #include <fmt/format.h> #include "common/common_types.h" +namespace Common { + u8 ToHexNibble(char c1); template <size_t Size, bool le = false> @@ -35,3 +37,5 @@ std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) { std::array<u8, 0x10> operator"" _array16(const char* str, size_t len); std::array<u8, 0x20> operator"" _array32(const char* str, size_t len); + +} // namespace Common diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 20e5200a8..2c817d7d1 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -134,6 +134,9 @@ std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { config.dczid_el0 = 4; config.ctr_el0 = 0x8444c004; + // Unpredictable instructions + config.define_unpredictable_behaviour = true; + return std::make_unique<Dynarmic::A64::Jit>(config); } diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 94d92579f..db8b22c85 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -52,20 +52,20 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { out[1].erase(std::remove(out[1].begin(), out[1].end(), ' '), out[1].end()); if (is_title_keys) { - auto rights_id_raw = HexStringToArray<16>(out[0]); + auto rights_id_raw = Common::HexStringToArray<16>(out[0]); u128 rights_id{}; std::memcpy(rights_id.data(), rights_id_raw.data(), rights_id_raw.size()); - Key128 key = HexStringToArray<16>(out[1]); + Key128 key = Common::HexStringToArray<16>(out[1]); SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]); } else { std::transform(out[0].begin(), out[0].end(), out[0].begin(), ::tolower); if (s128_file_id.find(out[0]) != s128_file_id.end()) { const auto index = s128_file_id.at(out[0]); - Key128 key = HexStringToArray<16>(out[1]); + Key128 key = Common::HexStringToArray<16>(out[1]); SetKey(index.type, key, index.field1, index.field2); } else if (s256_file_id.find(out[0]) != s256_file_id.end()) { const auto index = s256_file_id.at(out[0]); - Key256 key = HexStringToArray<32>(out[1]); + Key256 key = Common::HexStringToArray<32>(out[1]); SetKey(index.type, key, index.field1, index.field2); } } diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index a5e935f64..d25eeee34 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -37,11 +37,12 @@ static bool FollowsNcaIdFormat(std::string_view name) { static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bool second_hex_upper, bool within_two_digit) { if (!within_two_digit) - return fmt::format("/{}.nca", HexArrayToString(nca_id, second_hex_upper)); + return fmt::format("/{}.nca", Common::HexArrayToString(nca_id, second_hex_upper)); Core::Crypto::SHA256Hash hash{}; mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0); - return fmt::format("/000000{:02X}/{}.nca", hash[0], HexArrayToString(nca_id, second_hex_upper)); + return fmt::format("/000000{:02X}/{}.nca", hash[0], + Common::HexArrayToString(nca_id, second_hex_upper)); } static std::string GetCNMTName(TitleType type, u64 title_id) { @@ -170,7 +171,7 @@ std::vector<NcaID> RegisteredCache::AccumulateFiles() const { std::vector<NcaID> ids; for (const auto& d2_dir : dir->GetSubdirectories()) { if (FollowsNcaIdFormat(d2_dir->GetName())) { - ids.push_back(HexStringToArray<0x10, true>(d2_dir->GetName().substr(0, 0x20))); + ids.push_back(Common::HexStringToArray<0x10, true>(d2_dir->GetName().substr(0, 0x20))); continue; } @@ -181,20 +182,21 @@ std::vector<NcaID> RegisteredCache::AccumulateFiles() const { if (!FollowsNcaIdFormat(nca_dir->GetName())) continue; - ids.push_back(HexStringToArray<0x10, true>(nca_dir->GetName().substr(0, 0x20))); + ids.push_back(Common::HexStringToArray<0x10, true>(nca_dir->GetName().substr(0, 0x20))); } for (const auto& nca_file : d2_dir->GetFiles()) { if (!FollowsNcaIdFormat(nca_file->GetName())) continue; - ids.push_back(HexStringToArray<0x10, true>(nca_file->GetName().substr(0, 0x20))); + ids.push_back( + Common::HexStringToArray<0x10, true>(nca_file->GetName().substr(0, 0x20))); } } for (const auto& d2_file : dir->GetFiles()) { if (FollowsNcaIdFormat(d2_file->GetName())) - ids.push_back(HexStringToArray<0x10, true>(d2_file->GetName().substr(0, 0x20))); + ids.push_back(Common::HexStringToArray<0x10, true>(d2_file->GetName().substr(0, 0x20))); } return ids; } @@ -339,7 +341,7 @@ std::vector<RegisteredCacheEntry> RegisteredCache::ListEntriesFilter( } static std::shared_ptr<NCA> GetNCAFromXCIForID(std::shared_ptr<XCI> xci, const NcaID& id) { - const auto filename = fmt::format("{}.nca", HexArrayToString(id, false)); + const auto filename = fmt::format("{}.nca", Common::HexArrayToString(id, false)); const auto iter = std::find_if(xci->GetNCAs().begin(), xci->GetNCAs().end(), [&filename](std::shared_ptr<NCA> nca) { return nca->GetName() == filename; }); @@ -361,7 +363,7 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci, bool overw // Install Metadata File const auto meta_id_raw = (*meta_iter)->GetName().substr(0, 32); - const auto meta_id = HexStringToArray<16>(meta_id_raw); + const auto meta_id = Common::HexStringToArray<16>(meta_id_raw); const auto res = RawInstallNCA(*meta_iter, copy, overwrite_if_exists, meta_id); if (res != InstallResult::Success) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 762763463..966602b31 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -306,7 +306,8 @@ ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter" {52, nullptr, "SwitchLcdBacklight"}, {55, nullptr, "IsInControllerFirmwareUpdateSection"}, {60, nullptr, "GetDefaultDisplayResolution"}, - {61, nullptr, "GetDefaultDisplayResolutionChangeEvent"}, + {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, + "GetDefaultDisplayResolutionChangeEvent"}, {62, nullptr, "GetHdcpAuthenticationState"}, {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"}, }; @@ -341,6 +342,16 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); } +void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) { + event->Signal(); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(event); + + LOG_WARNING(Service_AM, "(STUBBED) called"); +} + void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { const bool use_docked_mode{Settings::values.use_docked_mode}; IPC::ResponseBuilder rb{ctx, 3}; diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 862f338ac..5de1857d8 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -110,6 +110,7 @@ private: void GetEventHandle(Kernel::HLERequestContext& ctx); void ReceiveMessage(Kernel::HLERequestContext& ctx); void GetCurrentFocusState(Kernel::HLERequestContext& ctx); + void GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx); void GetOperationMode(Kernel::HLERequestContext& ctx); void GetPerformanceMode(Kernel::HLERequestContext& ctx); diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 8498cc94b..9d50c7d42 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -3,28 +3,22 @@ // Refer to the license.txt file included. #include <utility> -#include <vector> #include "common/file_util.h" #include "common/logging/log.h" -#include "common/string_util.h" -#include "common/swap.h" -#include "core/core.h" #include "core/file_sys/content_archive.h" -#include "core/file_sys/program_metadata.h" -#include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/resource_limit.h" #include "core/hle/service/filesystem/filesystem.h" +#include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nca.h" -#include "core/loader/nso.h" -#include "core/memory.h" namespace Loader { AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_) : AppLoader(std::move(file_)), nca(std::make_unique<FileSys::NCA>(file)) {} +AppLoader_NCA::~AppLoader_NCA() = default; + FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { FileSys::NCA nca(file); @@ -83,6 +77,4 @@ ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { return ResultStatus::Success; } -AppLoader_NCA::~AppLoader_NCA() = default; - } // namespace Loader diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index 7f7d8ea0b..326f84857 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -4,20 +4,24 @@ #pragma once -#include <string> #include "common/common_types.h" -#include "core/file_sys/content_archive.h" -#include "core/file_sys/program_metadata.h" +#include "core/file_sys/vfs.h" #include "core/hle/kernel/object.h" #include "core/loader/loader.h" -#include "deconstructed_rom_directory.h" + +namespace FileSys { +class NCA; +} namespace Loader { +class AppLoader_DeconstructedRomDirectory; + /// Loads an NCA file class AppLoader_NCA final : public AppLoader { public: explicit AppLoader_NCA(FileSys::VirtualFile file); + ~AppLoader_NCA() override; /** * Returns the type of the file @@ -35,12 +39,7 @@ public: ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; ResultStatus ReadProgramId(u64& out_program_id) override; - ~AppLoader_NCA(); - private: - FileSys::ProgramMetadata metadata; - - FileSys::NCAHeader header; std::unique_ptr<FileSys::NCA> nca; std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader; }; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 5d67fb186..4c4979545 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -4,22 +4,14 @@ #include <vector> -#include "common/file_util.h" -#include "common/logging/log.h" -#include "common/string_util.h" -#include "common/swap.h" -#include "core/core.h" +#include "common/common_types.h" +#include "core/file_sys/card_image.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/control_metadata.h" -#include "core/file_sys/program_metadata.h" #include "core/file_sys/romfs.h" -#include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/resource_limit.h" -#include "core/hle/service/filesystem/filesystem.h" -#include "core/loader/nso.h" +#include "core/loader/nca.h" #include "core/loader/xci.h" -#include "core/memory.h" namespace Loader { diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 973833050..cc4287e17 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -6,12 +6,18 @@ #include <memory> #include "common/common_types.h" -#include "core/file_sys/card_image.h" +#include "core/file_sys/vfs.h" #include "core/loader/loader.h" -#include "core/loader/nca.h" + +namespace FileSys { +class NACP; +class XCI; +} // namespace FileSys namespace Loader { +class AppLoader_NCA; + /// Loads an XCI file class AppLoader_XCI final : public AppLoader { public: @@ -37,8 +43,6 @@ public: ResultStatus ReadTitle(std::string& title) override; private: - FileSys::ProgramMetadata metadata; - std::unique_ptr<FileSys::XCI> xci; std::unique_ptr<AppLoader_NCA> nca_loader; diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index a46ed4bd7..68f91cc75 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -222,6 +222,18 @@ void Maxwell3D::DrawArrays() { debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); } + // Both instance configuration registers can not be set at the same time. + ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, + "Illegal combination of instancing parameters"); + + if (regs.draw.instance_next) { + // Increment the current instance *before* drawing. + state.current_instance += 1; + } else if (!regs.draw.instance_cont) { + // Reset the current instance to 0. + state.current_instance = 0; + } + const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; rasterizer.AccelerateDrawBatch(is_indexed); diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 1b30ce018..771eb5abc 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -638,6 +638,8 @@ public: union { u32 vertex_begin_gl; BitField<0, 16, PrimitiveTopology> topology; + BitField<26, 1, u32> instance_next; + BitField<27, 1, u32> instance_cont; }; } draw; @@ -830,6 +832,7 @@ public: }; std::array<ShaderStageInfo, Regs::MaxShaderStage> shader_stages; + u32 current_instance = 0; ///< Current instance to be used to simulate instanced rendering. }; State state{}; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 9d1549fe9..93eadde7a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -124,7 +124,7 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset, vertex_array.stride); - ASSERT_MSG(vertex_array.divisor == 0, "Vertex buffer divisor unimplemented"); + ASSERT_MSG(vertex_array.divisor == 0, "Instanced vertex arrays are not supported"); } // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index b6947b97b..ac4db82cf 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -142,14 +142,16 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RG32UI {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // R32UI + // Depth formats + {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, ComponentType::UNorm, + false}, // Z16 + // DepthStencil formats {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, false}, // Z24S8 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, - false}, // S8Z24 - {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F - {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, ComponentType::UNorm, - false}, // Z16 + false}, // S8Z24 {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, ComponentType::Float, false}, // Z32FS8 }}; @@ -283,10 +285,10 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU MortonCopy<true, PixelFormat::RG8S>, MortonCopy<true, PixelFormat::RG32UI>, MortonCopy<true, PixelFormat::R32UI>, - MortonCopy<true, PixelFormat::Z24S8>, - MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>, + MortonCopy<true, PixelFormat::Z24S8>, + MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32FS8>, // clang-format on }; @@ -339,10 +341,10 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU MortonCopy<false, PixelFormat::RG8S>, MortonCopy<false, PixelFormat::RG32UI>, MortonCopy<false, PixelFormat::R32UI>, - MortonCopy<false, PixelFormat::Z24S8>, - MortonCopy<false, PixelFormat::S8Z24>, MortonCopy<false, PixelFormat::Z32F>, MortonCopy<false, PixelFormat::Z16>, + MortonCopy<false, PixelFormat::Z24S8>, + MortonCopy<false, PixelFormat::S8Z24>, MortonCopy<false, PixelFormat::Z32FS8>, // clang-format on }; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 55cf3782c..beec01746 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -68,11 +68,15 @@ struct SurfaceParams { MaxColorFormat, + // Depth formats + Z32F = 42, + Z16 = 43, + + MaxDepthFormat, + // DepthStencil formats - Z24S8 = 42, - S8Z24 = 43, - Z32F = 44, - Z16 = 45, + Z24S8 = 44, + S8Z24 = 45, Z32FS8 = 46, MaxDepthStencilFormat, @@ -153,10 +157,10 @@ struct SurfaceParams { 1, // RG8S 1, // RG32UI 1, // R32UI - 1, // Z24S8 - 1, // S8Z24 1, // Z32F 1, // Z16 + 1, // Z24S8 + 1, // S8Z24 1, // Z32FS8 }}; @@ -211,10 +215,10 @@ struct SurfaceParams { 16, // RG8S 64, // RG32UI 32, // R32UI - 32, // Z24S8 - 32, // S8Z24 32, // Z32F 16, // Z16 + 32, // Z24S8 + 32, // S8Z24 64, // Z32FS8 }}; @@ -587,6 +591,10 @@ struct SurfaceParams { return SurfaceType::ColorTexture; } + if (static_cast<size_t>(pixel_format) < static_cast<size_t>(PixelFormat::MaxDepthFormat)) { + return SurfaceType::Depth; + } + if (static_cast<size_t>(pixel_format) < static_cast<size_t>(PixelFormat::MaxDepthStencilFormat)) { return SurfaceType::DepthStencil; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e0dfdbb9f..07006b55e 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -541,7 +541,7 @@ private: // vertex shader, and what's the value of the fourth element when inside a Tess Eval // shader. ASSERT(stage == Maxwell3D::Regs::ShaderStage::Vertex); - return "vec4(0, 0, uintBitsToFloat(gl_InstanceID), uintBitsToFloat(gl_VertexID))"; + return "vec4(0, 0, uintBitsToFloat(instance_id.x), uintBitsToFloat(gl_VertexID))"; default: const u32 index{static_cast<u32>(attribute) - static_cast<u32>(Attribute::Index::Attribute_0)}; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 129c777d1..57e0e1726 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -38,6 +38,7 @@ out vec4 position; layout (std140) uniform vs_config { vec4 viewport_flip; + uvec4 instance_id; }; void main() { @@ -90,6 +91,7 @@ out vec4 color; layout (std140) uniform fs_config { vec4 viewport_flip; + uvec4 instance_id; }; void main() { diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 415d42fda..f0886caac 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -37,11 +37,16 @@ void SetShaderUniformBlockBindings(GLuint shader) { } // namespace Impl void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) { - const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; + const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); + const auto& regs = gpu.regs; + const auto& state = gpu.state; // TODO(bunnei): Support more than one viewport viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; + + // We only assign the instance to the first component of the vector, the rest is just padding. + instance_id[0] = state.current_instance; } } // namespace GLShader diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 716933a0b..75fa73605 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h @@ -24,14 +24,15 @@ void SetShaderUniformBlockBindings(GLuint shader); } // namespace Impl /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned -// NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at +// NOTE: Always keep a vec4 at the end. The GL spec is not clear whether the alignment at // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. // Not following that rule will cause problems on some AMD drivers. struct MaxwellUniformData { void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); alignas(16) GLvec4 viewport_flip; + alignas(16) GLuvec4 instance_id; }; -static_assert(sizeof(MaxwellUniformData) == 16, "MaxwellUniformData structure size is incorrect"); +static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect"); static_assert(sizeof(MaxwellUniformData) < 16384, "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); |