diff options
| author | 2021-03-26 18:45:38 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:24 -0400 | |
| commit | 17063d16a3cfe6542e74265739191e1d018fc456 (patch) | |
| tree | 3dc74c85c9be19183f4c889306458c9a6307b108 /src/video_core/renderer_vulkan | |
| parent | shader: Refactor PTP and other minor changes (diff) | |
| download | yuzu-17063d16a3cfe6542e74265739191e1d018fc456.tar.gz yuzu-17063d16a3cfe6542e74265739191e1d018fc456.tar.xz yuzu-17063d16a3cfe6542e74265739191e1d018fc456.zip | |
shader: Implement TXQ and fix FragDepth
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 504b8c9d6..30d424346 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include "video_core/memory_manager.h" | 25 | #include "video_core/memory_manager.h" |
| 26 | #include "video_core/renderer_vulkan/fixed_pipeline_state.h" | 26 | #include "video_core/renderer_vulkan/fixed_pipeline_state.h" |
| 27 | #include "video_core/renderer_vulkan/maxwell_to_vk.h" | 27 | #include "video_core/renderer_vulkan/maxwell_to_vk.h" |
| 28 | #include "video_core/renderer_vulkan/pipeline_helper.h" | ||
| 28 | #include "video_core/renderer_vulkan/vk_compute_pipeline.h" | 29 | #include "video_core/renderer_vulkan/vk_compute_pipeline.h" |
| 29 | #include "video_core/renderer_vulkan/vk_descriptor_pool.h" | 30 | #include "video_core/renderer_vulkan/vk_descriptor_pool.h" |
| 30 | #include "video_core/renderer_vulkan/vk_pipeline_cache.h" | 31 | #include "video_core/renderer_vulkan/vk_pipeline_cache.h" |
| @@ -45,6 +46,10 @@ auto MakeSpan(Container& container) { | |||
| 45 | return std::span(container.data(), container.size()); | 46 | return std::span(container.data(), container.size()); |
| 46 | } | 47 | } |
| 47 | 48 | ||
| 49 | u64 MakeCbufKey(u32 index, u32 offset) { | ||
| 50 | return (static_cast<u64>(index) << 32) | static_cast<u64>(offset); | ||
| 51 | } | ||
| 52 | |||
| 48 | class GenericEnvironment : public Shader::Environment { | 53 | class GenericEnvironment : public Shader::Environment { |
| 49 | public: | 54 | public: |
| 50 | explicit GenericEnvironment() = default; | 55 | explicit GenericEnvironment() = default; |
| @@ -101,15 +106,21 @@ public: | |||
| 101 | const auto data{std::make_unique<char[]>(code_size)}; | 106 | const auto data{std::make_unique<char[]>(code_size)}; |
| 102 | gpu_memory->ReadBlock(program_base + read_lowest, data.get(), code_size); | 107 | gpu_memory->ReadBlock(program_base + read_lowest, data.get(), code_size); |
| 103 | 108 | ||
| 109 | const u64 num_texture_types{static_cast<u64>(texture_types.size())}; | ||
| 104 | const u32 texture_bound{TextureBoundBuffer()}; | 110 | const u32 texture_bound{TextureBoundBuffer()}; |
| 105 | 111 | ||
| 106 | file.write(reinterpret_cast<const char*>(&code_size), sizeof(code_size)) | 112 | file.write(reinterpret_cast<const char*>(&code_size), sizeof(code_size)) |
| 113 | .write(reinterpret_cast<const char*>(&num_texture_types), sizeof(num_texture_types)) | ||
| 107 | .write(reinterpret_cast<const char*>(&texture_bound), sizeof(texture_bound)) | 114 | .write(reinterpret_cast<const char*>(&texture_bound), sizeof(texture_bound)) |
| 108 | .write(reinterpret_cast<const char*>(&start_address), sizeof(start_address)) | 115 | .write(reinterpret_cast<const char*>(&start_address), sizeof(start_address)) |
| 109 | .write(reinterpret_cast<const char*>(&read_lowest), sizeof(read_lowest)) | 116 | .write(reinterpret_cast<const char*>(&read_lowest), sizeof(read_lowest)) |
| 110 | .write(reinterpret_cast<const char*>(&read_highest), sizeof(read_highest)) | 117 | .write(reinterpret_cast<const char*>(&read_highest), sizeof(read_highest)) |
| 111 | .write(reinterpret_cast<const char*>(&stage), sizeof(stage)) | 118 | .write(reinterpret_cast<const char*>(&stage), sizeof(stage)) |
| 112 | .write(data.get(), code_size); | 119 | .write(data.get(), code_size); |
| 120 | for (const auto [key, type] : texture_types) { | ||
| 121 | file.write(reinterpret_cast<const char*>(&key), sizeof(key)) | ||
| 122 | .write(reinterpret_cast<const char*>(&type), sizeof(type)); | ||
| 123 | } | ||
| 113 | if (stage == Shader::Stage::Compute) { | 124 | if (stage == Shader::Stage::Compute) { |
| 114 | const std::array<u32, 3> workgroup_size{WorkgroupSize()}; | 125 | const std::array<u32, 3> workgroup_size{WorkgroupSize()}; |
| 115 | file.write(reinterpret_cast<const char*>(&workgroup_size), sizeof(workgroup_size)); | 126 | file.write(reinterpret_cast<const char*>(&workgroup_size), sizeof(workgroup_size)); |
| @@ -147,10 +158,47 @@ protected: | |||
| 147 | return std::nullopt; | 158 | return std::nullopt; |
| 148 | } | 159 | } |
| 149 | 160 | ||
| 161 | Shader::TextureType ReadTextureTypeImpl(GPUVAddr tic_addr, u32 tic_limit, bool via_header_index, | ||
| 162 | GPUVAddr cbuf_addr, u32 cbuf_size, u32 cbuf_index, | ||
| 163 | u32 cbuf_offset) { | ||
| 164 | const u32 raw{cbuf_offset < cbuf_size ? gpu_memory->Read<u32>(cbuf_addr + cbuf_offset) : 0}; | ||
| 165 | const TextureHandle handle{raw, via_header_index}; | ||
| 166 | const GPUVAddr descriptor_addr{tic_addr + handle.image * sizeof(Tegra::Texture::TICEntry)}; | ||
| 167 | Tegra::Texture::TICEntry entry; | ||
| 168 | gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry)); | ||
| 169 | |||
| 170 | const Shader::TextureType result{[&] { | ||
| 171 | switch (entry.texture_type) { | ||
| 172 | case Tegra::Texture::TextureType::Texture1D: | ||
| 173 | return Shader::TextureType::Color1D; | ||
| 174 | case Tegra::Texture::TextureType::Texture2D: | ||
| 175 | case Tegra::Texture::TextureType::Texture2DNoMipmap: | ||
| 176 | return Shader::TextureType::Color2D; | ||
| 177 | case Tegra::Texture::TextureType::Texture3D: | ||
| 178 | return Shader::TextureType::Color3D; | ||
| 179 | case Tegra::Texture::TextureType::TextureCubemap: | ||
| 180 | return Shader::TextureType::ColorCube; | ||
| 181 | case Tegra::Texture::TextureType::Texture1DArray: | ||
| 182 | return Shader::TextureType::ColorArray1D; | ||
| 183 | case Tegra::Texture::TextureType::Texture2DArray: | ||
| 184 | return Shader::TextureType::ColorArray2D; | ||
| 185 | case Tegra::Texture::TextureType::Texture1DBuffer: | ||
| 186 | throw Shader::NotImplementedException("Texture buffer"); | ||
| 187 | case Tegra::Texture::TextureType::TextureCubeArray: | ||
| 188 | return Shader::TextureType::ColorArrayCube; | ||
| 189 | default: | ||
| 190 | throw Shader::NotImplementedException("Unknown texture type"); | ||
| 191 | } | ||
| 192 | }()}; | ||
| 193 | texture_types.emplace(MakeCbufKey(cbuf_index, cbuf_offset), result); | ||
| 194 | return result; | ||
| 195 | } | ||
| 196 | |||
| 150 | Tegra::MemoryManager* gpu_memory{}; | 197 | Tegra::MemoryManager* gpu_memory{}; |
| 151 | GPUVAddr program_base{}; | 198 | GPUVAddr program_base{}; |
| 152 | 199 | ||
| 153 | std::vector<u64> code; | 200 | std::vector<u64> code; |
| 201 | std::unordered_map<u64, Shader::TextureType> texture_types; | ||
| 154 | 202 | ||
| 155 | u32 read_lowest = std::numeric_limits<u32>::max(); | 203 | u32 read_lowest = std::numeric_limits<u32>::max(); |
| 156 | u32 read_highest = 0; | 204 | u32 read_highest = 0; |
| @@ -176,29 +224,45 @@ public: | |||
| 176 | switch (program) { | 224 | switch (program) { |
| 177 | case Maxwell::ShaderProgram::VertexA: | 225 | case Maxwell::ShaderProgram::VertexA: |
| 178 | stage = Shader::Stage::VertexA; | 226 | stage = Shader::Stage::VertexA; |
| 227 | stage_index = 0; | ||
| 179 | break; | 228 | break; |
| 180 | case Maxwell::ShaderProgram::VertexB: | 229 | case Maxwell::ShaderProgram::VertexB: |
| 181 | stage = Shader::Stage::VertexB; | 230 | stage = Shader::Stage::VertexB; |
| 231 | stage_index = 0; | ||
| 182 | break; | 232 | break; |
| 183 | case Maxwell::ShaderProgram::TesselationControl: | 233 | case Maxwell::ShaderProgram::TesselationControl: |
| 184 | stage = Shader::Stage::TessellationControl; | 234 | stage = Shader::Stage::TessellationControl; |
| 235 | stage_index = 1; | ||
| 185 | break; | 236 | break; |
| 186 | case Maxwell::ShaderProgram::TesselationEval: | 237 | case Maxwell::ShaderProgram::TesselationEval: |
| 187 | stage = Shader::Stage::TessellationEval; | 238 | stage = Shader::Stage::TessellationEval; |
| 239 | stage_index = 2; | ||
| 188 | break; | 240 | break; |
| 189 | case Maxwell::ShaderProgram::Geometry: | 241 | case Maxwell::ShaderProgram::Geometry: |
| 190 | stage = Shader::Stage::Geometry; | 242 | stage = Shader::Stage::Geometry; |
| 243 | stage_index = 3; | ||
| 191 | break; | 244 | break; |
| 192 | case Maxwell::ShaderProgram::Fragment: | 245 | case Maxwell::ShaderProgram::Fragment: |
| 193 | stage = Shader::Stage::Fragment; | 246 | stage = Shader::Stage::Fragment; |
| 247 | stage_index = 4; | ||
| 194 | break; | 248 | break; |
| 195 | default: | 249 | default: |
| 196 | UNREACHABLE_MSG("Invalid program={}", program); | 250 | UNREACHABLE_MSG("Invalid program={}", program); |
| 251 | break; | ||
| 197 | } | 252 | } |
| 198 | } | 253 | } |
| 199 | 254 | ||
| 200 | ~GraphicsEnvironment() override = default; | 255 | ~GraphicsEnvironment() override = default; |
| 201 | 256 | ||
| 257 | Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { | ||
| 258 | const auto& regs{maxwell3d->regs}; | ||
| 259 | const auto& cbuf{maxwell3d->state.shader_stages[stage_index].const_buffers[cbuf_index]}; | ||
| 260 | ASSERT(cbuf.enabled); | ||
| 261 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; | ||
| 262 | return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, via_header_index, | ||
| 263 | cbuf.address, cbuf.size, cbuf_index, cbuf_offset); | ||
| 264 | } | ||
| 265 | |||
| 202 | u32 TextureBoundBuffer() const override { | 266 | u32 TextureBoundBuffer() const override { |
| 203 | return maxwell3d->regs.tex_cb_index; | 267 | return maxwell3d->regs.tex_cb_index; |
| 204 | } | 268 | } |
| @@ -209,6 +273,7 @@ public: | |||
| 209 | 273 | ||
| 210 | private: | 274 | private: |
| 211 | Tegra::Engines::Maxwell3D* maxwell3d{}; | 275 | Tegra::Engines::Maxwell3D* maxwell3d{}; |
| 276 | size_t stage_index{}; | ||
| 212 | }; | 277 | }; |
| 213 | 278 | ||
| 214 | class ComputeEnvironment final : public GenericEnvironment { | 279 | class ComputeEnvironment final : public GenericEnvironment { |
| @@ -224,6 +289,15 @@ public: | |||
| 224 | 289 | ||
| 225 | ~ComputeEnvironment() override = default; | 290 | ~ComputeEnvironment() override = default; |
| 226 | 291 | ||
| 292 | Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { | ||
| 293 | const auto& regs{kepler_compute->regs}; | ||
| 294 | const auto& qmd{kepler_compute->launch_description}; | ||
| 295 | ASSERT(((qmd.const_buffer_enable_mask.Value() >> cbuf_index) & 1) != 0); | ||
| 296 | const auto& cbuf{qmd.const_buffer_config[cbuf_index]}; | ||
| 297 | return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, | ||
| 298 | cbuf.Address(), cbuf.size, cbuf_index, cbuf_offset); | ||
| 299 | } | ||
| 300 | |||
| 227 | u32 TextureBoundBuffer() const override { | 301 | u32 TextureBoundBuffer() const override { |
| 228 | return kepler_compute->regs.tex_cb_index; | 302 | return kepler_compute->regs.tex_cb_index; |
| 229 | } | 303 | } |
| @@ -278,7 +352,9 @@ class FileEnvironment final : public Shader::Environment { | |||
| 278 | public: | 352 | public: |
| 279 | void Deserialize(std::ifstream& file) { | 353 | void Deserialize(std::ifstream& file) { |
| 280 | u64 code_size{}; | 354 | u64 code_size{}; |
| 355 | u64 num_texture_types{}; | ||
| 281 | file.read(reinterpret_cast<char*>(&code_size), sizeof(code_size)) | 356 | file.read(reinterpret_cast<char*>(&code_size), sizeof(code_size)) |
| 357 | .read(reinterpret_cast<char*>(&num_texture_types), sizeof(num_texture_types)) | ||
| 282 | .read(reinterpret_cast<char*>(&texture_bound), sizeof(texture_bound)) | 358 | .read(reinterpret_cast<char*>(&texture_bound), sizeof(texture_bound)) |
| 283 | .read(reinterpret_cast<char*>(&start_address), sizeof(start_address)) | 359 | .read(reinterpret_cast<char*>(&start_address), sizeof(start_address)) |
| 284 | .read(reinterpret_cast<char*>(&read_lowest), sizeof(read_lowest)) | 360 | .read(reinterpret_cast<char*>(&read_lowest), sizeof(read_lowest)) |
| @@ -286,6 +362,13 @@ public: | |||
| 286 | .read(reinterpret_cast<char*>(&stage), sizeof(stage)); | 362 | .read(reinterpret_cast<char*>(&stage), sizeof(stage)); |
| 287 | code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64))); | 363 | code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64))); |
| 288 | file.read(reinterpret_cast<char*>(code.get()), code_size); | 364 | file.read(reinterpret_cast<char*>(code.get()), code_size); |
| 365 | for (size_t i = 0; i < num_texture_types; ++i) { | ||
| 366 | u64 key; | ||
| 367 | Shader::TextureType type; | ||
| 368 | file.read(reinterpret_cast<char*>(&key), sizeof(key)) | ||
| 369 | .read(reinterpret_cast<char*>(&type), sizeof(type)); | ||
| 370 | texture_types.emplace(key, type); | ||
| 371 | } | ||
| 289 | if (stage == Shader::Stage::Compute) { | 372 | if (stage == Shader::Stage::Compute) { |
| 290 | file.read(reinterpret_cast<char*>(&workgroup_size), sizeof(workgroup_size)); | 373 | file.read(reinterpret_cast<char*>(&workgroup_size), sizeof(workgroup_size)); |
| 291 | } else { | 374 | } else { |
| @@ -300,6 +383,14 @@ public: | |||
| 300 | return code[(address - read_lowest) / sizeof(u64)]; | 383 | return code[(address - read_lowest) / sizeof(u64)]; |
| 301 | } | 384 | } |
| 302 | 385 | ||
| 386 | Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { | ||
| 387 | const auto it{texture_types.find(MakeCbufKey(cbuf_index, cbuf_offset))}; | ||
| 388 | if (it == texture_types.end()) { | ||
| 389 | throw Shader::LogicError("Uncached read texture type"); | ||
| 390 | } | ||
| 391 | return it->second; | ||
| 392 | } | ||
| 393 | |||
| 303 | u32 TextureBoundBuffer() const override { | 394 | u32 TextureBoundBuffer() const override { |
| 304 | return texture_bound; | 395 | return texture_bound; |
| 305 | } | 396 | } |
| @@ -310,6 +401,7 @@ public: | |||
| 310 | 401 | ||
| 311 | private: | 402 | private: |
| 312 | std::unique_ptr<u64[]> code; | 403 | std::unique_ptr<u64[]> code; |
| 404 | std::unordered_map<u64, Shader::TextureType> texture_types; | ||
| 313 | std::array<u32, 3> workgroup_size{}; | 405 | std::array<u32, 3> workgroup_size{}; |
| 314 | u32 texture_bound{}; | 406 | u32 texture_bound{}; |
| 315 | u32 read_lowest{}; | 407 | u32 read_lowest{}; |