From c11962e8e4b6b8c1424cfaebfd034e47c9fe122e Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Fri, 24 Dec 2021 22:05:58 +0530 Subject: [PATCH] Implement Maxwell3D Bindless Texture Constant Buffer Index The index of the constant buffer with bindless texture descriptors is now retrieved from Maxwell3D register state and passed to the shader compiler. --- .../cpp/skyline/gpu/interconnect/graphics_context.h | 11 ++++++++++- app/src/main/cpp/skyline/gpu/shader_manager.cpp | 11 ++++++----- app/src/main/cpp/skyline/gpu/shader_manager.h | 2 +- .../main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp | 4 ++++ .../main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h | 2 ++ 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h index 8936b2fa..63104fd3 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h @@ -743,7 +743,7 @@ namespace skyline::gpu::interconnect { return std::nullopt; })}; - shader.program = gpu.shader.ParseGraphicsShader(shader.data, shader.stage, shader.offset); + shader.program = gpu.shader.ParseGraphicsShader(shader.stage, shader.data, shader.offset, bindlessTextureConstantBufferIndex); if (shader.stage != ShaderCompiler::Stage::VertexA && shader.stage != ShaderCompiler::Stage::VertexB) { pipelineStage.program.emplace>(*shader.program); @@ -1547,6 +1547,15 @@ namespace skyline::gpu::interconnect { } } indexBuffer{}; + /* Textures */ + private: + u32 bindlessTextureConstantBufferIndex{}; + + public: + void SetBindlessTextureConstantBufferIndex(u32 index) { + bindlessTextureConstantBufferIndex = index; + } + public: void SetIndexBufferStartIovaHigh(u32 high) { indexBuffer.start.high = high; diff --git a/app/src/main/cpp/skyline/gpu/shader_manager.cpp b/app/src/main/cpp/skyline/gpu/shader_manager.cpp index 37ceba61..8aa29c61 100644 --- a/app/src/main/cpp/skyline/gpu/shader_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/shader_manager.cpp @@ -85,12 +85,13 @@ namespace skyline::gpu { private: span binary; u32 baseOffset; + u32 textureBufferIndex; public: - GraphicsEnvironment(span pBinary, u32 baseOffset, Shader::Stage pStage) : binary(pBinary), baseOffset(baseOffset) { + GraphicsEnvironment(Shader::Stage pStage, span pBinary, u32 baseOffset, u32 textureBufferIndex) : binary(pBinary), baseOffset(baseOffset), textureBufferIndex(textureBufferIndex) { + stage = pStage; sph = *reinterpret_cast(binary.data()); start_address = baseOffset; - stage = pStage; } [[nodiscard]] u64 ReadInstruction(u32 address) final { @@ -109,7 +110,7 @@ namespace skyline::gpu { } [[nodiscard]] u32 TextureBoundBuffer() const final { - throw exception("Not implemented"); + return textureBufferIndex; } [[nodiscard]] u32 LocalMemorySize() const final { @@ -164,8 +165,8 @@ namespace skyline::gpu { } }; - Shader::IR::Program ShaderManager::ParseGraphicsShader(span binary, Shader::Stage stage, u32 baseOffset) { - GraphicsEnvironment environment{binary, baseOffset, stage}; + Shader::IR::Program ShaderManager::ParseGraphicsShader(Shader::Stage stage, span binary, u32 baseOffset, u32 bindlessTextureConstantBufferIndex) { + GraphicsEnvironment environment{stage, binary, baseOffset, bindlessTextureConstantBufferIndex}; Shader::Maxwell::Flow::CFG cfg(environment, flowBlockPool, Shader::Maxwell::Location{static_cast(baseOffset + sizeof(Shader::ProgramHeader))}); return Shader::Maxwell::TranslateProgram(instPool, blockPool, environment, cfg, hostTranslateInfo); diff --git a/app/src/main/cpp/skyline/gpu/shader_manager.h b/app/src/main/cpp/skyline/gpu/shader_manager.h index 2a152fc8..475083e3 100644 --- a/app/src/main/cpp/skyline/gpu/shader_manager.h +++ b/app/src/main/cpp/skyline/gpu/shader_manager.h @@ -31,7 +31,7 @@ namespace skyline::gpu { public: ShaderManager(const DeviceState &state, GPU &gpu); - Shader::IR::Program ParseGraphicsShader(span binary, Shader::Stage stage, u32 baseOffset); + Shader::IR::Program ParseGraphicsShader(Shader::Stage stage, span binary, u32 baseOffset, u32 bindlessTextureConstantBufferIndex); /** * @brief Combines the VertexA and VertexB shader programs into a single program diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp index 7ee2b29d..2b84ac5a 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp @@ -463,6 +463,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d { context.SetIndexBufferFormat(format); }) + MAXWELL3D_CASE(bindlessTextureConstantBufferIndex, { + context.SetBindlessTextureConstantBufferIndex(bindlessTextureConstantBufferIndex); + }) + default: break; } diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h index c9ba0215..30eb723d 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h @@ -294,6 +294,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d { Register<0x8E0, ConstantBufferSelector> constantBufferSelector; Register<0x900, std::array> bind; //!< Binds constant buffers to pipeline stages + + Register<0x982, u32> bindlessTextureConstantBufferIndex; //!< The index of the constant buffer containing bindless texture descriptors }; static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32))); #pragma pack(pop)