mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	kepler_compute: Implement texture queries
This commit is contained in:
		
							parent
							
								
									2e5b5c2358
								
							
						
					
					
						commit
						3a450c1395
					
				@ -2,6 +2,7 @@
 | 
				
			|||||||
// Licensed under GPLv2 or any later version
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <bitset>
 | 
				
			||||||
#include "common/assert.h"
 | 
					#include "common/assert.h"
 | 
				
			||||||
#include "common/logging/log.h"
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
#include "core/core.h"
 | 
					#include "core/core.h"
 | 
				
			||||||
@ -49,6 +50,33 @@ void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tegra::Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) const {
 | 
				
			||||||
 | 
					    const std::bitset<8> cbuf_mask = launch_description.const_buffer_enable_mask.Value();
 | 
				
			||||||
 | 
					    ASSERT(cbuf_mask[regs.tex_cb_index]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto& texinfo = launch_description.const_buffer_config[regs.tex_cb_index];
 | 
				
			||||||
 | 
					    ASSERT(texinfo.Address() != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const GPUVAddr address = texinfo.Address() + offset * sizeof(Texture::TextureHandle);
 | 
				
			||||||
 | 
					    ASSERT(address < texinfo.Address() + texinfo.size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(address)};
 | 
				
			||||||
 | 
					    return GetTextureInfo(tex_handle, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Texture::FullTextureInfo KeplerCompute::GetTextureInfo(const Texture::TextureHandle tex_handle,
 | 
				
			||||||
 | 
					                                                       std::size_t offset) const {
 | 
				
			||||||
 | 
					    return Texture::FullTextureInfo{static_cast<u32>(offset), GetTICEntry(tex_handle.tic_id),
 | 
				
			||||||
 | 
					                                    GetTSCEntry(tex_handle.tsc_id)};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32 KeplerCompute::AccessConstBuffer32(u64 const_buffer, u64 offset) const {
 | 
				
			||||||
 | 
					    const auto& buffer = launch_description.const_buffer_config[const_buffer];
 | 
				
			||||||
 | 
					    u32 result;
 | 
				
			||||||
 | 
					    std::memcpy(&result, memory_manager.GetPointer(buffer.Address() + offset), sizeof(u32));
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void KeplerCompute::ProcessLaunch() {
 | 
					void KeplerCompute::ProcessLaunch() {
 | 
				
			||||||
    const GPUVAddr launch_desc_loc = regs.launch_desc_loc.Address();
 | 
					    const GPUVAddr launch_desc_loc = regs.launch_desc_loc.Address();
 | 
				
			||||||
    memory_manager.ReadBlockUnsafe(launch_desc_loc, &launch_description,
 | 
					    memory_manager.ReadBlockUnsafe(launch_desc_loc, &launch_description,
 | 
				
			||||||
@ -60,4 +88,29 @@ void KeplerCompute::ProcessLaunch() {
 | 
				
			|||||||
    rasterizer.DispatchCompute(code_addr);
 | 
					    rasterizer.DispatchCompute(code_addr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Texture::TICEntry KeplerCompute::GetTICEntry(u32 tic_index) const {
 | 
				
			||||||
 | 
					    const GPUVAddr tic_address_gpu{regs.tic.Address() + tic_index * sizeof(Texture::TICEntry)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Texture::TICEntry tic_entry;
 | 
				
			||||||
 | 
					    memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto r_type{tic_entry.r_type.Value()};
 | 
				
			||||||
 | 
					    const auto g_type{tic_entry.g_type.Value()};
 | 
				
			||||||
 | 
					    const auto b_type{tic_entry.b_type.Value()};
 | 
				
			||||||
 | 
					    const auto a_type{tic_entry.a_type.Value()};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO(Subv): Different data types for separate components are not supported
 | 
				
			||||||
 | 
					    DEBUG_ASSERT(r_type == g_type && r_type == b_type && r_type == a_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return tic_entry;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Texture::TSCEntry KeplerCompute::GetTSCEntry(u32 tsc_index) const {
 | 
				
			||||||
 | 
					    const GPUVAddr tsc_address_gpu{regs.tsc.Address() + tsc_index * sizeof(Texture::TSCEntry)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Texture::TSCEntry tsc_entry;
 | 
				
			||||||
 | 
					    memory_manager.ReadBlockUnsafe(tsc_address_gpu, &tsc_entry, sizeof(Texture::TSCEntry));
 | 
				
			||||||
 | 
					    return tsc_entry;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Tegra::Engines
 | 
					} // namespace Tegra::Engines
 | 
				
			||||||
 | 
				
			|||||||
@ -12,6 +12,7 @@
 | 
				
			|||||||
#include "common/common_types.h"
 | 
					#include "common/common_types.h"
 | 
				
			||||||
#include "video_core/engines/engine_upload.h"
 | 
					#include "video_core/engines/engine_upload.h"
 | 
				
			||||||
#include "video_core/gpu.h"
 | 
					#include "video_core/gpu.h"
 | 
				
			||||||
 | 
					#include "video_core/textures/texture.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Core {
 | 
					namespace Core {
 | 
				
			||||||
class System;
 | 
					class System;
 | 
				
			||||||
@ -111,7 +112,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                INSERT_PADDING_WORDS(0x3FE);
 | 
					                INSERT_PADDING_WORDS(0x3FE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                u32 texture_const_buffer_index;
 | 
					                u32 tex_cb_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                INSERT_PADDING_WORDS(0x374);
 | 
					                INSERT_PADDING_WORDS(0x374);
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@ -149,7 +150,7 @@ public:
 | 
				
			|||||||
        union {
 | 
					        union {
 | 
				
			||||||
            BitField<0, 8, u32> const_buffer_enable_mask;
 | 
					            BitField<0, 8, u32> const_buffer_enable_mask;
 | 
				
			||||||
            BitField<29, 2, u32> cache_layout;
 | 
					            BitField<29, 2, u32> cache_layout;
 | 
				
			||||||
        } memory_config;
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        INSERT_PADDING_WORDS(0x8);
 | 
					        INSERT_PADDING_WORDS(0x8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -194,6 +195,14 @@ public:
 | 
				
			|||||||
    /// Write the value to the register identified by method.
 | 
					    /// Write the value to the register identified by method.
 | 
				
			||||||
    void CallMethod(const GPU::MethodCall& method_call);
 | 
					    void CallMethod(const GPU::MethodCall& method_call);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Tegra::Texture::FullTextureInfo GetTexture(std::size_t offset) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Given a Texture Handle, returns the TSC and TIC entries.
 | 
				
			||||||
 | 
					    Texture::FullTextureInfo GetTextureInfo(const Texture::TextureHandle tex_handle,
 | 
				
			||||||
 | 
					                                            std::size_t offset) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u32 AccessConstBuffer32(u64 const_buffer, u64 offset) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    Core::System& system;
 | 
					    Core::System& system;
 | 
				
			||||||
    VideoCore::RasterizerInterface& rasterizer;
 | 
					    VideoCore::RasterizerInterface& rasterizer;
 | 
				
			||||||
@ -201,6 +210,12 @@ private:
 | 
				
			|||||||
    Upload::State upload_state;
 | 
					    Upload::State upload_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ProcessLaunch();
 | 
					    void ProcessLaunch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves information about a specific TIC entry from the TIC buffer.
 | 
				
			||||||
 | 
					    Texture::TICEntry GetTICEntry(u32 tic_index) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Retrieves information about a specific TSC entry from the TSC buffer.
 | 
				
			||||||
 | 
					    Texture::TSCEntry GetTSCEntry(u32 tsc_index) const;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ASSERT_REG_POSITION(field_name, position)                                                  \
 | 
					#define ASSERT_REG_POSITION(field_name, position)                                                  \
 | 
				
			||||||
@ -218,12 +233,12 @@ ASSERT_REG_POSITION(launch, 0xAF);
 | 
				
			|||||||
ASSERT_REG_POSITION(tsc, 0x557);
 | 
					ASSERT_REG_POSITION(tsc, 0x557);
 | 
				
			||||||
ASSERT_REG_POSITION(tic, 0x55D);
 | 
					ASSERT_REG_POSITION(tic, 0x55D);
 | 
				
			||||||
ASSERT_REG_POSITION(code_loc, 0x582);
 | 
					ASSERT_REG_POSITION(code_loc, 0x582);
 | 
				
			||||||
ASSERT_REG_POSITION(texture_const_buffer_index, 0x982);
 | 
					ASSERT_REG_POSITION(tex_cb_index, 0x982);
 | 
				
			||||||
ASSERT_LAUNCH_PARAM_POSITION(program_start, 0x8);
 | 
					ASSERT_LAUNCH_PARAM_POSITION(program_start, 0x8);
 | 
				
			||||||
ASSERT_LAUNCH_PARAM_POSITION(grid_dim_x, 0xC);
 | 
					ASSERT_LAUNCH_PARAM_POSITION(grid_dim_x, 0xC);
 | 
				
			||||||
ASSERT_LAUNCH_PARAM_POSITION(shared_alloc, 0x11);
 | 
					ASSERT_LAUNCH_PARAM_POSITION(shared_alloc, 0x11);
 | 
				
			||||||
ASSERT_LAUNCH_PARAM_POSITION(block_dim_x, 0x12);
 | 
					ASSERT_LAUNCH_PARAM_POSITION(block_dim_x, 0x12);
 | 
				
			||||||
ASSERT_LAUNCH_PARAM_POSITION(memory_config, 0x14);
 | 
					ASSERT_LAUNCH_PARAM_POSITION(const_buffer_enable_mask, 0x14);
 | 
				
			||||||
ASSERT_LAUNCH_PARAM_POSITION(const_buffer_config, 0x1D);
 | 
					ASSERT_LAUNCH_PARAM_POSITION(const_buffer_config, 0x1D);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef ASSERT_REG_POSITION
 | 
					#undef ASSERT_REG_POSITION
 | 
				
			||||||
 | 
				
			|||||||
@ -801,6 +801,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto kernel = shader_cache.GetComputeKernel(code_addr);
 | 
					    auto kernel = shader_cache.GetComputeKernel(code_addr);
 | 
				
			||||||
 | 
					    SetupComputeImages(kernel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const auto [program, next_bindings] = kernel->GetProgramHandle({});
 | 
					    const auto [program, next_bindings] = kernel->GetProgramHandle({});
 | 
				
			||||||
    state.draw.shader_program = program;
 | 
					    state.draw.shader_program = program;
 | 
				
			||||||
    state.draw.program_pipeline = 0;
 | 
					    state.draw.program_pipeline = 0;
 | 
				
			||||||
@ -922,7 +924,7 @@ void RasterizerOpenGL::SetupComputeConstBuffers(const Shader& kernel) {
 | 
				
			|||||||
    const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
 | 
					    const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
 | 
				
			||||||
    for (const auto& entry : kernel->GetShaderEntries().const_buffers) {
 | 
					    for (const auto& entry : kernel->GetShaderEntries().const_buffers) {
 | 
				
			||||||
        const auto& config = launch_desc.const_buffer_config[entry.GetIndex()];
 | 
					        const auto& config = launch_desc.const_buffer_config[entry.GetIndex()];
 | 
				
			||||||
        const std::bitset<8> mask = launch_desc.memory_config.const_buffer_enable_mask.Value();
 | 
					        const std::bitset<8> mask = launch_desc.const_buffer_enable_mask.Value();
 | 
				
			||||||
        Tegra::Engines::ConstBufferInfo buffer;
 | 
					        Tegra::Engines::ConstBufferInfo buffer;
 | 
				
			||||||
        buffer.address = config.Address();
 | 
					        buffer.address = config.Address();
 | 
				
			||||||
        buffer.size = config.size;
 | 
					        buffer.size = config.size;
 | 
				
			||||||
@ -1038,6 +1040,24 @@ bool RasterizerOpenGL::SetupTexture(const Shader& shader, u32 binding,
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
 | 
				
			||||||
 | 
					    const auto& compute = system.GPU().KeplerCompute();
 | 
				
			||||||
 | 
					    const auto& entries = shader->GetShaderEntries().images;
 | 
				
			||||||
 | 
					    for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
 | 
				
			||||||
 | 
					        const auto& entry = entries[bindpoint];
 | 
				
			||||||
 | 
					        const auto texture = [&]() {
 | 
				
			||||||
 | 
					            if (!entry.IsBindless()) {
 | 
				
			||||||
 | 
					                return compute.GetTexture(entry.GetOffset());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            const auto cbuf = entry.GetBindlessCBuf();
 | 
				
			||||||
 | 
					            Tegra::Texture::TextureHandle tex_handle;
 | 
				
			||||||
 | 
					            tex_handle.raw = compute.AccessConstBuffer32(cbuf.first, cbuf.second);
 | 
				
			||||||
 | 
					            return compute.GetTextureInfo(tex_handle, entry.GetOffset());
 | 
				
			||||||
 | 
					        }();
 | 
				
			||||||
 | 
					        UNIMPLEMENTED();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
 | 
					void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
 | 
				
			||||||
    const auto& regs = system.GPU().Maxwell3D().regs;
 | 
					    const auto& regs = system.GPU().Maxwell3D().regs;
 | 
				
			||||||
    const bool geometry_shaders_enabled =
 | 
					    const bool geometry_shaders_enabled =
 | 
				
			||||||
 | 
				
			|||||||
@ -146,6 +146,8 @@ private:
 | 
				
			|||||||
                      const Tegra::Texture::FullTextureInfo& texture,
 | 
					                      const Tegra::Texture::FullTextureInfo& texture,
 | 
				
			||||||
                      const GLShader::SamplerEntry& entry);
 | 
					                      const GLShader::SamplerEntry& entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void SetupComputeImages(const Shader& shader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Syncs the viewport and depth range to match the guest state
 | 
					    /// Syncs the viewport and depth range to match the guest state
 | 
				
			||||||
    void SyncViewport(OpenGLState& current_state);
 | 
					    void SyncViewport(OpenGLState& current_state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -303,6 +303,10 @@ public:
 | 
				
			|||||||
        return is_bindless;
 | 
					        return is_bindless;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::pair<u32, u32> GetBindlessCBuf() const {
 | 
				
			||||||
 | 
					        return {static_cast<u32>(offset >> 32), static_cast<u32>(offset)};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool operator<(const Image& rhs) const {
 | 
					    bool operator<(const Image& rhs) const {
 | 
				
			||||||
        return std::tie(offset, index, type, is_bindless) <
 | 
					        return std::tie(offset, index, type, is_bindless) <
 | 
				
			||||||
               std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_bindless);
 | 
					               std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_bindless);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user