summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-07-11 21:54:07 -0300
committerGravatar ReinUsesLisp2019-09-05 20:35:51 -0300
commit3a450c1395cdb8b4f73687f8c49648e9190fc3a0 (patch)
tree4be17483ce66e8631bea393f9ca557da3af61214 /src
parentgl_rasterizer: Split SetupTextures (diff)
downloadyuzu-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.cpp53
-rw-r--r--src/video_core/engines/kepler_compute.h23
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp22
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h2
-rw-r--r--src/video_core/shader/node.h4
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
53Tegra::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
67Texture::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
73u32 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
52void KeplerCompute::ProcessLaunch() { 80void 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
91Texture::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
108Texture::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
16namespace Core { 17namespace Core {
17class System; 18class 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
197private: 206private:
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);
218ASSERT_REG_POSITION(tsc, 0x557); 233ASSERT_REG_POSITION(tsc, 0x557);
219ASSERT_REG_POSITION(tic, 0x55D); 234ASSERT_REG_POSITION(tic, 0x55D);
220ASSERT_REG_POSITION(code_loc, 0x582); 235ASSERT_REG_POSITION(code_loc, 0x582);
221ASSERT_REG_POSITION(texture_const_buffer_index, 0x982); 236ASSERT_REG_POSITION(tex_cb_index, 0x982);
222ASSERT_LAUNCH_PARAM_POSITION(program_start, 0x8); 237ASSERT_LAUNCH_PARAM_POSITION(program_start, 0x8);
223ASSERT_LAUNCH_PARAM_POSITION(grid_dim_x, 0xC); 238ASSERT_LAUNCH_PARAM_POSITION(grid_dim_x, 0xC);
224ASSERT_LAUNCH_PARAM_POSITION(shared_alloc, 0x11); 239ASSERT_LAUNCH_PARAM_POSITION(shared_alloc, 0x11);
225ASSERT_LAUNCH_PARAM_POSITION(block_dim_x, 0x12); 240ASSERT_LAUNCH_PARAM_POSITION(block_dim_x, 0x12);
226ASSERT_LAUNCH_PARAM_POSITION(memory_config, 0x14); 241ASSERT_LAUNCH_PARAM_POSITION(const_buffer_enable_mask, 0x14);
227ASSERT_LAUNCH_PARAM_POSITION(const_buffer_config, 0x1D); 242ASSERT_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
1043void 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
1041void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { 1061void 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);