diff options
| author | 2019-07-11 21:54:07 -0300 | |
|---|---|---|
| committer | 2019-09-05 20:35:51 -0300 | |
| commit | 3a450c1395cdb8b4f73687f8c49648e9190fc3a0 (patch) | |
| tree | 4be17483ce66e8631bea393f9ca557da3af61214 /src | |
| parent | gl_rasterizer: Split SetupTextures (diff) | |
| download | yuzu-3a450c1395cdb8b4f73687f8c49648e9190fc3a0.tar.gz yuzu-3a450c1395cdb8b4f73687f8c49648e9190fc3a0.tar.xz yuzu-3a450c1395cdb8b4f73687f8c49648e9190fc3a0.zip | |
kepler_compute: Implement texture queries
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 53 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.h | 23 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 2 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 4 |
5 files changed, 99 insertions, 5 deletions
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 08586d33c..63d449135 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.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 <bitset> | ||
| 5 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 6 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 8 | #include "core/core.h" |
| @@ -49,6 +50,33 @@ void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) { | |||
| 49 | } | 50 | } |
| 50 | } | 51 | } |
| 51 | 52 | ||
| 53 | Tegra::Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) const { | ||
| 54 | const std::bitset<8> cbuf_mask = launch_description.const_buffer_enable_mask.Value(); | ||
| 55 | ASSERT(cbuf_mask[regs.tex_cb_index]); | ||
| 56 | |||
| 57 | const auto& texinfo = launch_description.const_buffer_config[regs.tex_cb_index]; | ||
| 58 | ASSERT(texinfo.Address() != 0); | ||
| 59 | |||
| 60 | const GPUVAddr address = texinfo.Address() + offset * sizeof(Texture::TextureHandle); | ||
| 61 | ASSERT(address < texinfo.Address() + texinfo.size); | ||
| 62 | |||
| 63 | const Texture::TextureHandle tex_handle{memory_manager.Read<u32>(address)}; | ||
| 64 | return GetTextureInfo(tex_handle, offset); | ||
| 65 | } | ||
| 66 | |||
| 67 | Texture::FullTextureInfo KeplerCompute::GetTextureInfo(const Texture::TextureHandle tex_handle, | ||
| 68 | std::size_t offset) const { | ||
| 69 | return Texture::FullTextureInfo{static_cast<u32>(offset), GetTICEntry(tex_handle.tic_id), | ||
| 70 | GetTSCEntry(tex_handle.tsc_id)}; | ||
| 71 | } | ||
| 72 | |||
| 73 | u32 KeplerCompute::AccessConstBuffer32(u64 const_buffer, u64 offset) const { | ||
| 74 | const auto& buffer = launch_description.const_buffer_config[const_buffer]; | ||
| 75 | u32 result; | ||
| 76 | std::memcpy(&result, memory_manager.GetPointer(buffer.Address() + offset), sizeof(u32)); | ||
| 77 | return result; | ||
| 78 | } | ||
| 79 | |||
| 52 | void KeplerCompute::ProcessLaunch() { | 80 | void KeplerCompute::ProcessLaunch() { |
| 53 | const GPUVAddr launch_desc_loc = regs.launch_desc_loc.Address(); | 81 | const GPUVAddr launch_desc_loc = regs.launch_desc_loc.Address(); |
| 54 | memory_manager.ReadBlockUnsafe(launch_desc_loc, &launch_description, | 82 | memory_manager.ReadBlockUnsafe(launch_desc_loc, &launch_description, |
| @@ -60,4 +88,29 @@ void KeplerCompute::ProcessLaunch() { | |||
| 60 | rasterizer.DispatchCompute(code_addr); | 88 | rasterizer.DispatchCompute(code_addr); |
| 61 | } | 89 | } |
| 62 | 90 | ||
| 91 | Texture::TICEntry KeplerCompute::GetTICEntry(u32 tic_index) const { | ||
| 92 | const GPUVAddr tic_address_gpu{regs.tic.Address() + tic_index * sizeof(Texture::TICEntry)}; | ||
| 93 | |||
| 94 | Texture::TICEntry tic_entry; | ||
| 95 | memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry)); | ||
| 96 | |||
| 97 | const auto r_type{tic_entry.r_type.Value()}; | ||
| 98 | const auto g_type{tic_entry.g_type.Value()}; | ||
| 99 | const auto b_type{tic_entry.b_type.Value()}; | ||
| 100 | const auto a_type{tic_entry.a_type.Value()}; | ||
| 101 | |||
| 102 | // TODO(Subv): Different data types for separate components are not supported | ||
| 103 | DEBUG_ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); | ||
| 104 | |||
| 105 | return tic_entry; | ||
| 106 | } | ||
| 107 | |||
| 108 | Texture::TSCEntry KeplerCompute::GetTSCEntry(u32 tsc_index) const { | ||
| 109 | const GPUVAddr tsc_address_gpu{regs.tsc.Address() + tsc_index * sizeof(Texture::TSCEntry)}; | ||
| 110 | |||
| 111 | Texture::TSCEntry tsc_entry; | ||
| 112 | memory_manager.ReadBlockUnsafe(tsc_address_gpu, &tsc_entry, sizeof(Texture::TSCEntry)); | ||
| 113 | return tsc_entry; | ||
| 114 | } | ||
| 115 | |||
| 63 | } // namespace Tegra::Engines | 116 | } // namespace Tegra::Engines |
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h index 6a3309a2c..90cf650d2 100644 --- a/src/video_core/engines/kepler_compute.h +++ b/src/video_core/engines/kepler_compute.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "video_core/engines/engine_upload.h" | 13 | #include "video_core/engines/engine_upload.h" |
| 14 | #include "video_core/gpu.h" | 14 | #include "video_core/gpu.h" |
| 15 | #include "video_core/textures/texture.h" | ||
| 15 | 16 | ||
| 16 | namespace Core { | 17 | namespace Core { |
| 17 | class System; | 18 | class System; |
| @@ -111,7 +112,7 @@ public: | |||
| 111 | 112 | ||
| 112 | INSERT_PADDING_WORDS(0x3FE); | 113 | INSERT_PADDING_WORDS(0x3FE); |
| 113 | 114 | ||
| 114 | u32 texture_const_buffer_index; | 115 | u32 tex_cb_index; |
| 115 | 116 | ||
| 116 | INSERT_PADDING_WORDS(0x374); | 117 | INSERT_PADDING_WORDS(0x374); |
| 117 | }; | 118 | }; |
| @@ -149,7 +150,7 @@ public: | |||
| 149 | union { | 150 | union { |
| 150 | BitField<0, 8, u32> const_buffer_enable_mask; | 151 | BitField<0, 8, u32> const_buffer_enable_mask; |
| 151 | BitField<29, 2, u32> cache_layout; | 152 | BitField<29, 2, u32> cache_layout; |
| 152 | } memory_config; | 153 | }; |
| 153 | 154 | ||
| 154 | INSERT_PADDING_WORDS(0x8); | 155 | INSERT_PADDING_WORDS(0x8); |
| 155 | 156 | ||
| @@ -194,6 +195,14 @@ public: | |||
| 194 | /// Write the value to the register identified by method. | 195 | /// Write the value to the register identified by method. |
| 195 | void CallMethod(const GPU::MethodCall& method_call); | 196 | void CallMethod(const GPU::MethodCall& method_call); |
| 196 | 197 | ||
| 198 | Tegra::Texture::FullTextureInfo GetTexture(std::size_t offset) const; | ||
| 199 | |||
| 200 | /// Given a Texture Handle, returns the TSC and TIC entries. | ||
| 201 | Texture::FullTextureInfo GetTextureInfo(const Texture::TextureHandle tex_handle, | ||
| 202 | std::size_t offset) const; | ||
| 203 | |||
| 204 | u32 AccessConstBuffer32(u64 const_buffer, u64 offset) const; | ||
| 205 | |||
| 197 | private: | 206 | private: |
| 198 | Core::System& system; | 207 | Core::System& system; |
| 199 | VideoCore::RasterizerInterface& rasterizer; | 208 | VideoCore::RasterizerInterface& rasterizer; |
| @@ -201,6 +210,12 @@ private: | |||
| 201 | Upload::State upload_state; | 210 | Upload::State upload_state; |
| 202 | 211 | ||
| 203 | void ProcessLaunch(); | 212 | void ProcessLaunch(); |
| 213 | |||
| 214 | /// Retrieves information about a specific TIC entry from the TIC buffer. | ||
| 215 | Texture::TICEntry GetTICEntry(u32 tic_index) const; | ||
| 216 | |||
| 217 | /// Retrieves information about a specific TSC entry from the TSC buffer. | ||
| 218 | Texture::TSCEntry GetTSCEntry(u32 tsc_index) const; | ||
| 204 | }; | 219 | }; |
| 205 | 220 | ||
| 206 | #define ASSERT_REG_POSITION(field_name, position) \ | 221 | #define ASSERT_REG_POSITION(field_name, position) \ |
| @@ -218,12 +233,12 @@ ASSERT_REG_POSITION(launch, 0xAF); | |||
| 218 | ASSERT_REG_POSITION(tsc, 0x557); | 233 | ASSERT_REG_POSITION(tsc, 0x557); |
| 219 | ASSERT_REG_POSITION(tic, 0x55D); | 234 | ASSERT_REG_POSITION(tic, 0x55D); |
| 220 | ASSERT_REG_POSITION(code_loc, 0x582); | 235 | ASSERT_REG_POSITION(code_loc, 0x582); |
| 221 | ASSERT_REG_POSITION(texture_const_buffer_index, 0x982); | 236 | ASSERT_REG_POSITION(tex_cb_index, 0x982); |
| 222 | ASSERT_LAUNCH_PARAM_POSITION(program_start, 0x8); | 237 | ASSERT_LAUNCH_PARAM_POSITION(program_start, 0x8); |
| 223 | ASSERT_LAUNCH_PARAM_POSITION(grid_dim_x, 0xC); | 238 | ASSERT_LAUNCH_PARAM_POSITION(grid_dim_x, 0xC); |
| 224 | ASSERT_LAUNCH_PARAM_POSITION(shared_alloc, 0x11); | 239 | ASSERT_LAUNCH_PARAM_POSITION(shared_alloc, 0x11); |
| 225 | ASSERT_LAUNCH_PARAM_POSITION(block_dim_x, 0x12); | 240 | ASSERT_LAUNCH_PARAM_POSITION(block_dim_x, 0x12); |
| 226 | ASSERT_LAUNCH_PARAM_POSITION(memory_config, 0x14); | 241 | ASSERT_LAUNCH_PARAM_POSITION(const_buffer_enable_mask, 0x14); |
| 227 | ASSERT_LAUNCH_PARAM_POSITION(const_buffer_config, 0x1D); | 242 | ASSERT_LAUNCH_PARAM_POSITION(const_buffer_config, 0x1D); |
| 228 | 243 | ||
| 229 | #undef ASSERT_REG_POSITION | 244 | #undef ASSERT_REG_POSITION |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0f0902259..5375ab9e0 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -801,6 +801,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { | |||
| 801 | } | 801 | } |
| 802 | 802 | ||
| 803 | auto kernel = shader_cache.GetComputeKernel(code_addr); | 803 | auto kernel = shader_cache.GetComputeKernel(code_addr); |
| 804 | SetupComputeImages(kernel); | ||
| 805 | |||
| 804 | const auto [program, next_bindings] = kernel->GetProgramHandle({}); | 806 | const auto [program, next_bindings] = kernel->GetProgramHandle({}); |
| 805 | state.draw.shader_program = program; | 807 | state.draw.shader_program = program; |
| 806 | state.draw.program_pipeline = 0; | 808 | state.draw.program_pipeline = 0; |
| @@ -922,7 +924,7 @@ void RasterizerOpenGL::SetupComputeConstBuffers(const Shader& kernel) { | |||
| 922 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; | 924 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; |
| 923 | for (const auto& entry : kernel->GetShaderEntries().const_buffers) { | 925 | for (const auto& entry : kernel->GetShaderEntries().const_buffers) { |
| 924 | const auto& config = launch_desc.const_buffer_config[entry.GetIndex()]; | 926 | const auto& config = launch_desc.const_buffer_config[entry.GetIndex()]; |
| 925 | const std::bitset<8> mask = launch_desc.memory_config.const_buffer_enable_mask.Value(); | 927 | const std::bitset<8> mask = launch_desc.const_buffer_enable_mask.Value(); |
| 926 | Tegra::Engines::ConstBufferInfo buffer; | 928 | Tegra::Engines::ConstBufferInfo buffer; |
| 927 | buffer.address = config.Address(); | 929 | buffer.address = config.Address(); |
| 928 | buffer.size = config.size; | 930 | buffer.size = config.size; |
| @@ -1038,6 +1040,24 @@ bool RasterizerOpenGL::SetupTexture(const Shader& shader, u32 binding, | |||
| 1038 | return false; | 1040 | return false; |
| 1039 | } | 1041 | } |
| 1040 | 1042 | ||
| 1043 | void RasterizerOpenGL::SetupComputeImages(const Shader& shader) { | ||
| 1044 | const auto& compute = system.GPU().KeplerCompute(); | ||
| 1045 | const auto& entries = shader->GetShaderEntries().images; | ||
| 1046 | for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { | ||
| 1047 | const auto& entry = entries[bindpoint]; | ||
| 1048 | const auto texture = [&]() { | ||
| 1049 | if (!entry.IsBindless()) { | ||
| 1050 | return compute.GetTexture(entry.GetOffset()); | ||
| 1051 | } | ||
| 1052 | const auto cbuf = entry.GetBindlessCBuf(); | ||
| 1053 | Tegra::Texture::TextureHandle tex_handle; | ||
| 1054 | tex_handle.raw = compute.AccessConstBuffer32(cbuf.first, cbuf.second); | ||
| 1055 | return compute.GetTextureInfo(tex_handle, entry.GetOffset()); | ||
| 1056 | }(); | ||
| 1057 | UNIMPLEMENTED(); | ||
| 1058 | } | ||
| 1059 | } | ||
| 1060 | |||
| 1041 | void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { | 1061 | void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { |
| 1042 | const auto& regs = system.GPU().Maxwell3D().regs; | 1062 | const auto& regs = system.GPU().Maxwell3D().regs; |
| 1043 | const bool geometry_shaders_enabled = | 1063 | const bool geometry_shaders_enabled = |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 23ab7aff0..6fa1b7ec4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -146,6 +146,8 @@ private: | |||
| 146 | const Tegra::Texture::FullTextureInfo& texture, | 146 | const Tegra::Texture::FullTextureInfo& texture, |
| 147 | const GLShader::SamplerEntry& entry); | 147 | const GLShader::SamplerEntry& entry); |
| 148 | 148 | ||
| 149 | void SetupComputeImages(const Shader& shader); | ||
| 150 | |||
| 149 | /// Syncs the viewport and depth range to match the guest state | 151 | /// Syncs the viewport and depth range to match the guest state |
| 150 | void SyncViewport(OpenGLState& current_state); | 152 | void SyncViewport(OpenGLState& current_state); |
| 151 | 153 | ||
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 5db9313c4..0397f4c6e 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -303,6 +303,10 @@ public: | |||
| 303 | return is_bindless; | 303 | return is_bindless; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | std::pair<u32, u32> GetBindlessCBuf() const { | ||
| 307 | return {static_cast<u32>(offset >> 32), static_cast<u32>(offset)}; | ||
| 308 | } | ||
| 309 | |||
| 306 | bool operator<(const Image& rhs) const { | 310 | bool operator<(const Image& rhs) const { |
| 307 | return std::tie(offset, index, type, is_bindless) < | 311 | return std::tie(offset, index, type, is_bindless) < |
| 308 | std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_bindless); | 312 | std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_bindless); |