diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/environment.h | 2 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/texture_pass.cpp | 80 | ||||
| -rw-r--r-- | src/shader_recompiler/shader_info.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 32 |
6 files changed, 127 insertions, 49 deletions
diff --git a/src/shader_recompiler/environment.h b/src/shader_recompiler/environment.h index 1c50ae51e..090bc1c08 100644 --- a/src/shader_recompiler/environment.h +++ b/src/shader_recompiler/environment.h | |||
| @@ -17,7 +17,7 @@ public: | |||
| 17 | 17 | ||
| 18 | [[nodiscard]] virtual u32 ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) = 0; | 18 | [[nodiscard]] virtual u32 ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) = 0; |
| 19 | 19 | ||
| 20 | [[nodiscard]] virtual TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) = 0; | 20 | [[nodiscard]] virtual TextureType ReadTextureType(u32 raw_handle) = 0; |
| 21 | 21 | ||
| 22 | [[nodiscard]] virtual u32 TextureBoundBuffer() const = 0; | 22 | [[nodiscard]] virtual u32 TextureBoundBuffer() const = 0; |
| 23 | 23 | ||
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index e1d5a2ce1..5ac485522 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp | |||
| @@ -19,6 +19,9 @@ namespace { | |||
| 19 | struct ConstBufferAddr { | 19 | struct ConstBufferAddr { |
| 20 | u32 index; | 20 | u32 index; |
| 21 | u32 offset; | 21 | u32 offset; |
| 22 | u32 secondary_index; | ||
| 23 | u32 secondary_offset; | ||
| 24 | bool has_secondary; | ||
| 22 | }; | 25 | }; |
| 23 | 26 | ||
| 24 | struct TextureInst { | 27 | struct TextureInst { |
| @@ -109,9 +112,38 @@ bool IsTextureInstruction(const IR::Inst& inst) { | |||
| 109 | return IndexedInstruction(inst) != IR::Opcode::Void; | 112 | return IndexedInstruction(inst) != IR::Opcode::Void; |
| 110 | } | 113 | } |
| 111 | 114 | ||
| 115 | std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst); | ||
| 116 | |||
| 117 | std::optional<ConstBufferAddr> Track(const IR::Value& value) { | ||
| 118 | return IR::BreadthFirstSearch(value, TryGetConstBuffer); | ||
| 119 | } | ||
| 120 | |||
| 112 | std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) { | 121 | std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) { |
| 113 | if (inst->GetOpcode() != IR::Opcode::GetCbufU32) { | 122 | switch (inst->GetOpcode()) { |
| 123 | default: | ||
| 114 | return std::nullopt; | 124 | return std::nullopt; |
| 125 | case IR::Opcode::BitwiseOr32: { | ||
| 126 | std::optional lhs{Track(inst->Arg(0))}; | ||
| 127 | std::optional rhs{Track(inst->Arg(1))}; | ||
| 128 | if (!lhs || !rhs) { | ||
| 129 | return std::nullopt; | ||
| 130 | } | ||
| 131 | if (lhs->has_secondary || rhs->has_secondary) { | ||
| 132 | return std::nullopt; | ||
| 133 | } | ||
| 134 | if (lhs->index > rhs->index || lhs->offset > rhs->offset) { | ||
| 135 | std::swap(lhs, rhs); | ||
| 136 | } | ||
| 137 | return ConstBufferAddr{ | ||
| 138 | .index = lhs->index, | ||
| 139 | .offset = lhs->offset, | ||
| 140 | .secondary_index = rhs->index, | ||
| 141 | .secondary_offset = rhs->offset, | ||
| 142 | .has_secondary = true, | ||
| 143 | }; | ||
| 144 | } | ||
| 145 | case IR::Opcode::GetCbufU32: | ||
| 146 | break; | ||
| 115 | } | 147 | } |
| 116 | const IR::Value index{inst->Arg(0)}; | 148 | const IR::Value index{inst->Arg(0)}; |
| 117 | const IR::Value offset{inst->Arg(1)}; | 149 | const IR::Value offset{inst->Arg(1)}; |
| @@ -127,13 +159,12 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) { | |||
| 127 | return ConstBufferAddr{ | 159 | return ConstBufferAddr{ |
| 128 | .index{index.U32()}, | 160 | .index{index.U32()}, |
| 129 | .offset{offset.U32()}, | 161 | .offset{offset.U32()}, |
| 162 | .secondary_index = 0, | ||
| 163 | .secondary_offset = 0, | ||
| 164 | .has_secondary = false, | ||
| 130 | }; | 165 | }; |
| 131 | } | 166 | } |
| 132 | 167 | ||
| 133 | std::optional<ConstBufferAddr> Track(const IR::Value& value) { | ||
| 134 | return IR::BreadthFirstSearch(value, TryGetConstBuffer); | ||
| 135 | } | ||
| 136 | |||
| 137 | TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { | 168 | TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { |
| 138 | ConstBufferAddr addr; | 169 | ConstBufferAddr addr; |
| 139 | if (IsBindless(inst)) { | 170 | if (IsBindless(inst)) { |
| @@ -146,6 +177,9 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { | |||
| 146 | addr = ConstBufferAddr{ | 177 | addr = ConstBufferAddr{ |
| 147 | .index = env.TextureBoundBuffer(), | 178 | .index = env.TextureBoundBuffer(), |
| 148 | .offset = inst.Arg(0).U32(), | 179 | .offset = inst.Arg(0).U32(), |
| 180 | .secondary_index = 0, | ||
| 181 | .secondary_offset = 0, | ||
| 182 | .has_secondary = false, | ||
| 149 | }; | 183 | }; |
| 150 | } | 184 | } |
| 151 | return TextureInst{ | 185 | return TextureInst{ |
| @@ -155,6 +189,14 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { | |||
| 155 | }; | 189 | }; |
| 156 | } | 190 | } |
| 157 | 191 | ||
| 192 | TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) { | ||
| 193 | const u32 secondary_index{cbuf.has_secondary ? cbuf.index : cbuf.secondary_index}; | ||
| 194 | const u32 secondary_offset{cbuf.has_secondary ? cbuf.offset : cbuf.secondary_offset}; | ||
| 195 | const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset)}; | ||
| 196 | const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)}; | ||
| 197 | return env.ReadTextureType(lhs_raw | rhs_raw); | ||
| 198 | } | ||
| 199 | |||
| 158 | class Descriptors { | 200 | class Descriptors { |
| 159 | public: | 201 | public: |
| 160 | explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_, | 202 | explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_, |
| @@ -167,8 +209,11 @@ public: | |||
| 167 | 209 | ||
| 168 | u32 Add(const TextureBufferDescriptor& desc) { | 210 | u32 Add(const TextureBufferDescriptor& desc) { |
| 169 | return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) { | 211 | return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) { |
| 170 | return desc.cbuf_index == existing.cbuf_index && | 212 | return desc.has_secondary == existing.has_secondary && |
| 171 | desc.cbuf_offset == existing.cbuf_offset; | 213 | desc.cbuf_index == existing.cbuf_index && |
| 214 | desc.cbuf_offset == existing.cbuf_offset && | ||
| 215 | desc.secondary_cbuf_index == existing.secondary_cbuf_index && | ||
| 216 | desc.secondary_cbuf_offset == existing.secondary_cbuf_offset; | ||
| 172 | }); | 217 | }); |
| 173 | } | 218 | } |
| 174 | 219 | ||
| @@ -181,8 +226,12 @@ public: | |||
| 181 | 226 | ||
| 182 | u32 Add(const TextureDescriptor& desc) { | 227 | u32 Add(const TextureDescriptor& desc) { |
| 183 | return Add(texture_descriptors, desc, [&desc](const auto& existing) { | 228 | return Add(texture_descriptors, desc, [&desc](const auto& existing) { |
| 184 | return desc.cbuf_index == existing.cbuf_index && | 229 | return desc.type == existing.type && desc.is_depth == existing.is_depth && |
| 185 | desc.cbuf_offset == existing.cbuf_offset && desc.type == existing.type; | 230 | desc.has_secondary == existing.has_secondary && |
| 231 | desc.cbuf_index == existing.cbuf_index && | ||
| 232 | desc.cbuf_offset == existing.cbuf_offset && | ||
| 233 | desc.secondary_cbuf_index == existing.secondary_cbuf_index && | ||
| 234 | desc.secondary_cbuf_offset == existing.secondary_cbuf_offset; | ||
| 186 | }); | 235 | }); |
| 187 | } | 236 | } |
| 188 | 237 | ||
| @@ -247,14 +296,14 @@ void TexturePass(Environment& env, IR::Program& program) { | |||
| 247 | auto flags{inst->Flags<IR::TextureInstInfo>()}; | 296 | auto flags{inst->Flags<IR::TextureInstInfo>()}; |
| 248 | switch (inst->GetOpcode()) { | 297 | switch (inst->GetOpcode()) { |
| 249 | case IR::Opcode::ImageQueryDimensions: | 298 | case IR::Opcode::ImageQueryDimensions: |
| 250 | flags.type.Assign(env.ReadTextureType(cbuf.index, cbuf.offset)); | 299 | flags.type.Assign(ReadTextureType(env, cbuf)); |
| 251 | inst->SetFlags(flags); | 300 | inst->SetFlags(flags); |
| 252 | break; | 301 | break; |
| 253 | case IR::Opcode::ImageFetch: | 302 | case IR::Opcode::ImageFetch: |
| 254 | if (flags.type != TextureType::Color1D) { | 303 | if (flags.type != TextureType::Color1D) { |
| 255 | break; | 304 | break; |
| 256 | } | 305 | } |
| 257 | if (env.ReadTextureType(cbuf.index, cbuf.offset) == TextureType::Buffer) { | 306 | if (ReadTextureType(env, cbuf) == TextureType::Buffer) { |
| 258 | // Replace with the bound texture type only when it's a texture buffer | 307 | // Replace with the bound texture type only when it's a texture buffer |
| 259 | // If the instruction is 1D and the bound type is 2D, don't change the code and let | 308 | // If the instruction is 1D and the bound type is 2D, don't change the code and let |
| 260 | // the rasterizer robustness handle it | 309 | // the rasterizer robustness handle it |
| @@ -270,6 +319,9 @@ void TexturePass(Environment& env, IR::Program& program) { | |||
| 270 | switch (inst->GetOpcode()) { | 319 | switch (inst->GetOpcode()) { |
| 271 | case IR::Opcode::ImageRead: | 320 | case IR::Opcode::ImageRead: |
| 272 | case IR::Opcode::ImageWrite: { | 321 | case IR::Opcode::ImageWrite: { |
| 322 | if (cbuf.has_secondary) { | ||
| 323 | throw NotImplementedException("Unexpected separate sampler"); | ||
| 324 | } | ||
| 273 | const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite}; | 325 | const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite}; |
| 274 | if (flags.type == TextureType::Buffer) { | 326 | if (flags.type == TextureType::Buffer) { |
| 275 | index = descriptors.Add(ImageBufferDescriptor{ | 327 | index = descriptors.Add(ImageBufferDescriptor{ |
| @@ -294,16 +346,22 @@ void TexturePass(Environment& env, IR::Program& program) { | |||
| 294 | default: | 346 | default: |
| 295 | if (flags.type == TextureType::Buffer) { | 347 | if (flags.type == TextureType::Buffer) { |
| 296 | index = descriptors.Add(TextureBufferDescriptor{ | 348 | index = descriptors.Add(TextureBufferDescriptor{ |
| 349 | .has_secondary = cbuf.has_secondary, | ||
| 297 | .cbuf_index = cbuf.index, | 350 | .cbuf_index = cbuf.index, |
| 298 | .cbuf_offset = cbuf.offset, | 351 | .cbuf_offset = cbuf.offset, |
| 352 | .secondary_cbuf_index = cbuf.secondary_index, | ||
| 353 | .secondary_cbuf_offset = cbuf.secondary_offset, | ||
| 299 | .count = 1, | 354 | .count = 1, |
| 300 | }); | 355 | }); |
| 301 | } else { | 356 | } else { |
| 302 | index = descriptors.Add(TextureDescriptor{ | 357 | index = descriptors.Add(TextureDescriptor{ |
| 303 | .type = flags.type, | 358 | .type = flags.type, |
| 304 | .is_depth = flags.is_depth != 0, | 359 | .is_depth = flags.is_depth != 0, |
| 360 | .has_secondary = cbuf.has_secondary, | ||
| 305 | .cbuf_index = cbuf.index, | 361 | .cbuf_index = cbuf.index, |
| 306 | .cbuf_offset = cbuf.offset, | 362 | .cbuf_offset = cbuf.offset, |
| 363 | .secondary_cbuf_index = cbuf.secondary_index, | ||
| 364 | .secondary_cbuf_offset = cbuf.secondary_offset, | ||
| 307 | .count = 1, | 365 | .count = 1, |
| 308 | }); | 366 | }); |
| 309 | } | 367 | } |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index 50b4d1c05..0f45bdfb6 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -61,8 +61,11 @@ struct StorageBufferDescriptor { | |||
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | struct TextureBufferDescriptor { | 63 | struct TextureBufferDescriptor { |
| 64 | bool has_secondary; | ||
| 64 | u32 cbuf_index; | 65 | u32 cbuf_index; |
| 65 | u32 cbuf_offset; | 66 | u32 cbuf_offset; |
| 67 | u32 secondary_cbuf_index; | ||
| 68 | u32 secondary_cbuf_offset; | ||
| 66 | u32 count; | 69 | u32 count; |
| 67 | }; | 70 | }; |
| 68 | using TextureBufferDescriptors = boost::container::small_vector<TextureBufferDescriptor, 6>; | 71 | using TextureBufferDescriptors = boost::container::small_vector<TextureBufferDescriptor, 6>; |
| @@ -79,8 +82,11 @@ using ImageBufferDescriptors = boost::container::small_vector<ImageBufferDescrip | |||
| 79 | struct TextureDescriptor { | 82 | struct TextureDescriptor { |
| 80 | TextureType type; | 83 | TextureType type; |
| 81 | bool is_depth; | 84 | bool is_depth; |
| 85 | bool has_secondary; | ||
| 82 | u32 cbuf_index; | 86 | u32 cbuf_index; |
| 83 | u32 cbuf_offset; | 87 | u32 cbuf_offset; |
| 88 | u32 secondary_cbuf_index; | ||
| 89 | u32 secondary_cbuf_offset; | ||
| 84 | u32 count; | 90 | u32 count; |
| 85 | }; | 91 | }; |
| 86 | using TextureDescriptors = boost::container::small_vector<TextureDescriptor, 12>; | 92 | using TextureDescriptors = boost::container::small_vector<TextureDescriptor, 12>; |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 3c907ec5a..45d837ca4 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | |||
| @@ -88,23 +88,34 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 88 | boost::container::static_vector<u32, max_elements> image_view_indices; | 88 | boost::container::static_vector<u32, max_elements> image_view_indices; |
| 89 | boost::container::static_vector<VkSampler, max_elements> samplers; | 89 | boost::container::static_vector<VkSampler, max_elements> samplers; |
| 90 | 90 | ||
| 91 | const auto& launch_desc{kepler_compute.launch_description}; | 91 | const auto& qmd{kepler_compute.launch_description}; |
| 92 | const auto& cbufs{launch_desc.const_buffer_config}; | 92 | const auto& cbufs{qmd.const_buffer_config}; |
| 93 | const bool via_header_index{launch_desc.linked_tsc}; | 93 | const bool via_header_index{qmd.linked_tsc != 0}; |
| 94 | const auto read_handle{[&](u32 cbuf_index, u32 cbuf_offset) { | 94 | const auto read_handle{[&](const auto& desc) { |
| 95 | ASSERT(((launch_desc.const_buffer_enable_mask >> cbuf_index) & 1) != 0); | 95 | ASSERT(((qmd.const_buffer_enable_mask >> desc.cbuf_index) & 1) != 0); |
| 96 | const GPUVAddr addr{cbufs[cbuf_index].Address() + cbuf_offset}; | 96 | const GPUVAddr addr{cbufs[desc.cbuf_index].Address() + desc.cbuf_offset}; |
| 97 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; | 97 | if constexpr (std::is_same_v<decltype(desc), const Shader::TextureDescriptor&> || |
| 98 | return TextureHandle(raw_handle, via_header_index); | 98 | std::is_same_v<decltype(desc), const Shader::TextureBufferDescriptor&>) { |
| 99 | if (desc.has_secondary) { | ||
| 100 | ASSERT(((qmd.const_buffer_enable_mask >> desc.secondary_cbuf_index) & 1) != 0); | ||
| 101 | const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() + | ||
| 102 | desc.secondary_cbuf_offset}; | ||
| 103 | const u32 lhs_raw{gpu_memory.Read<u32>(addr)}; | ||
| 104 | const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)}; | ||
| 105 | const u32 raw{lhs_raw | rhs_raw}; | ||
| 106 | return TextureHandle{raw, via_header_index}; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | return TextureHandle{gpu_memory.Read<u32>(addr), via_header_index}; | ||
| 99 | }}; | 110 | }}; |
| 100 | const auto add_image{[&](const auto& desc) { | 111 | const auto add_image{[&](const auto& desc) { |
| 101 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 112 | const TextureHandle handle{read_handle(desc)}; |
| 102 | image_view_indices.push_back(handle.image); | 113 | image_view_indices.push_back(handle.image); |
| 103 | }}; | 114 | }}; |
| 104 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); | 115 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); |
| 105 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | 116 | std::ranges::for_each(info.image_buffer_descriptors, add_image); |
| 106 | for (const auto& desc : info.texture_descriptors) { | 117 | for (const auto& desc : info.texture_descriptors) { |
| 107 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 118 | const TextureHandle handle{read_handle(desc)}; |
| 108 | image_view_indices.push_back(handle.image); | 119 | image_view_indices.push_back(handle.image); |
| 109 | 120 | ||
| 110 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler); | 121 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler); |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index d5e9dae0f..08f00b9ce 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -169,20 +169,31 @@ void GraphicsPipeline::Configure(bool is_indexed) { | |||
| 169 | ++index; | 169 | ++index; |
| 170 | } | 170 | } |
| 171 | const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers}; | 171 | const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers}; |
| 172 | const auto read_handle{[&](u32 cbuf_index, u32 cbuf_offset) { | 172 | const auto read_handle{[&](const auto& desc) { |
| 173 | ASSERT(cbufs[cbuf_index].enabled); | 173 | ASSERT(cbufs[desc.cbuf_index].enabled); |
| 174 | const GPUVAddr addr{cbufs[cbuf_index].address + cbuf_offset}; | 174 | const GPUVAddr addr{cbufs[desc.cbuf_index].address + desc.cbuf_offset}; |
| 175 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; | 175 | if constexpr (std::is_same_v<decltype(desc), const Shader::TextureDescriptor&> || |
| 176 | return TextureHandle(raw_handle, via_header_index); | 176 | std::is_same_v<decltype(desc), const Shader::TextureBufferDescriptor&>) { |
| 177 | if (desc.has_secondary) { | ||
| 178 | ASSERT(cbufs[desc.secondary_cbuf_index].enabled); | ||
| 179 | const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address + | ||
| 180 | desc.secondary_cbuf_offset}; | ||
| 181 | const u32 lhs_raw{gpu_memory.Read<u32>(addr)}; | ||
| 182 | const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)}; | ||
| 183 | const u32 raw{lhs_raw | rhs_raw}; | ||
| 184 | return TextureHandle{raw, via_header_index}; | ||
| 185 | } | ||
| 186 | } | ||
| 187 | return TextureHandle{gpu_memory.Read<u32>(addr), via_header_index}; | ||
| 177 | }}; | 188 | }}; |
| 178 | const auto add_image{[&](const auto& desc) { | 189 | const auto add_image{[&](const auto& desc) { |
| 179 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 190 | const TextureHandle handle{read_handle(desc)}; |
| 180 | image_view_indices.push_back(handle.image); | 191 | image_view_indices.push_back(handle.image); |
| 181 | }}; | 192 | }}; |
| 182 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); | 193 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); |
| 183 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | 194 | std::ranges::for_each(info.image_buffer_descriptors, add_image); |
| 184 | for (const auto& desc : info.texture_descriptors) { | 195 | for (const auto& desc : info.texture_descriptors) { |
| 185 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 196 | const TextureHandle handle{read_handle(desc)}; |
| 186 | image_view_indices.push_back(handle.image); | 197 | image_view_indices.push_back(handle.image); |
| 187 | 198 | ||
| 188 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; | 199 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index e9b93336b..4317b2ac7 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -188,9 +188,7 @@ protected: | |||
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | Shader::TextureType ReadTextureTypeImpl(GPUVAddr tic_addr, u32 tic_limit, bool via_header_index, | 190 | Shader::TextureType ReadTextureTypeImpl(GPUVAddr tic_addr, u32 tic_limit, bool via_header_index, |
| 191 | GPUVAddr cbuf_addr, u32 cbuf_size, u32 cbuf_index, | 191 | u32 raw) { |
| 192 | u32 cbuf_offset) { | ||
| 193 | const u32 raw{cbuf_offset < cbuf_size ? gpu_memory->Read<u32>(cbuf_addr + cbuf_offset) : 0}; | ||
| 194 | const TextureHandle handle{raw, via_header_index}; | 192 | const TextureHandle handle{raw, via_header_index}; |
| 195 | const GPUVAddr descriptor_addr{tic_addr + handle.image * sizeof(Tegra::Texture::TICEntry)}; | 193 | const GPUVAddr descriptor_addr{tic_addr + handle.image * sizeof(Tegra::Texture::TICEntry)}; |
| 196 | Tegra::Texture::TICEntry entry; | 194 | Tegra::Texture::TICEntry entry; |
| @@ -219,7 +217,7 @@ protected: | |||
| 219 | throw Shader::NotImplementedException("Unknown texture type"); | 217 | throw Shader::NotImplementedException("Unknown texture type"); |
| 220 | } | 218 | } |
| 221 | }()}; | 219 | }()}; |
| 222 | texture_types.emplace(MakeCbufKey(cbuf_index, cbuf_offset), result); | 220 | texture_types.emplace(raw, result); |
| 223 | return result; | 221 | return result; |
| 224 | } | 222 | } |
| 225 | 223 | ||
| @@ -227,7 +225,7 @@ protected: | |||
| 227 | GPUVAddr program_base{}; | 225 | GPUVAddr program_base{}; |
| 228 | 226 | ||
| 229 | std::vector<u64> code; | 227 | std::vector<u64> code; |
| 230 | std::unordered_map<u64, Shader::TextureType> texture_types; | 228 | std::unordered_map<u32, Shader::TextureType> texture_types; |
| 231 | std::unordered_map<u64, u32> cbuf_values; | 229 | std::unordered_map<u64, u32> cbuf_values; |
| 232 | 230 | ||
| 233 | u32 local_memory_size{}; | 231 | u32 local_memory_size{}; |
| @@ -250,7 +248,7 @@ using Shader::Maxwell::TranslateProgram; | |||
| 250 | 248 | ||
| 251 | // TODO: Move this to a separate file | 249 | // TODO: Move this to a separate file |
| 252 | constexpr std::array<char, 8> MAGIC_NUMBER{'y', 'u', 'z', 'u', 'c', 'a', 'c', 'h'}; | 250 | constexpr std::array<char, 8> MAGIC_NUMBER{'y', 'u', 'z', 'u', 'c', 'a', 'c', 'h'}; |
| 253 | constexpr u32 CACHE_VERSION{1}; | 251 | constexpr u32 CACHE_VERSION{2}; |
| 254 | 252 | ||
| 255 | class GraphicsEnvironment final : public GenericEnvironment { | 253 | class GraphicsEnvironment final : public GenericEnvironment { |
| 256 | public: | 254 | public: |
| @@ -308,13 +306,10 @@ public: | |||
| 308 | return value; | 306 | return value; |
| 309 | } | 307 | } |
| 310 | 308 | ||
| 311 | Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { | 309 | Shader::TextureType ReadTextureType(u32 handle) override { |
| 312 | const auto& regs{maxwell3d->regs}; | 310 | const auto& regs{maxwell3d->regs}; |
| 313 | const auto& cbuf{maxwell3d->state.shader_stages[stage_index].const_buffers[cbuf_index]}; | ||
| 314 | ASSERT(cbuf.enabled); | ||
| 315 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; | 311 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; |
| 316 | return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, via_header_index, | 312 | return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, via_header_index, handle); |
| 317 | cbuf.address, cbuf.size, cbuf_index, cbuf_offset); | ||
| 318 | } | 313 | } |
| 319 | 314 | ||
| 320 | private: | 315 | private: |
| @@ -352,13 +347,10 @@ public: | |||
| 352 | return value; | 347 | return value; |
| 353 | } | 348 | } |
| 354 | 349 | ||
| 355 | Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { | 350 | Shader::TextureType ReadTextureType(u32 handle) override { |
| 356 | const auto& regs{kepler_compute->regs}; | 351 | const auto& regs{kepler_compute->regs}; |
| 357 | const auto& qmd{kepler_compute->launch_description}; | 352 | const auto& qmd{kepler_compute->launch_description}; |
| 358 | ASSERT(((qmd.const_buffer_enable_mask.Value() >> cbuf_index) & 1) != 0); | 353 | return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, handle); |
| 359 | const auto& cbuf{qmd.const_buffer_config[cbuf_index]}; | ||
| 360 | return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, | ||
| 361 | cbuf.Address(), cbuf.size, cbuf_index, cbuf_offset); | ||
| 362 | } | 354 | } |
| 363 | 355 | ||
| 364 | private: | 356 | private: |
| @@ -421,7 +413,7 @@ public: | |||
| 421 | code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64))); | 413 | code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64))); |
| 422 | file.read(reinterpret_cast<char*>(code.get()), code_size); | 414 | file.read(reinterpret_cast<char*>(code.get()), code_size); |
| 423 | for (size_t i = 0; i < num_texture_types; ++i) { | 415 | for (size_t i = 0; i < num_texture_types; ++i) { |
| 424 | u64 key; | 416 | u32 key; |
| 425 | Shader::TextureType type; | 417 | Shader::TextureType type; |
| 426 | file.read(reinterpret_cast<char*>(&key), sizeof(key)) | 418 | file.read(reinterpret_cast<char*>(&key), sizeof(key)) |
| 427 | .read(reinterpret_cast<char*>(&type), sizeof(type)); | 419 | .read(reinterpret_cast<char*>(&type), sizeof(type)); |
| @@ -457,8 +449,8 @@ public: | |||
| 457 | return it->second; | 449 | return it->second; |
| 458 | } | 450 | } |
| 459 | 451 | ||
| 460 | Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { | 452 | Shader::TextureType ReadTextureType(u32 handle) override { |
| 461 | const auto it{texture_types.find(MakeCbufKey(cbuf_index, cbuf_offset))}; | 453 | const auto it{texture_types.find(handle)}; |
| 462 | if (it == texture_types.end()) { | 454 | if (it == texture_types.end()) { |
| 463 | throw Shader::LogicError("Uncached read texture type"); | 455 | throw Shader::LogicError("Uncached read texture type"); |
| 464 | } | 456 | } |
| @@ -483,7 +475,7 @@ public: | |||
| 483 | 475 | ||
| 484 | private: | 476 | private: |
| 485 | std::unique_ptr<u64[]> code; | 477 | std::unique_ptr<u64[]> code; |
| 486 | std::unordered_map<u64, Shader::TextureType> texture_types; | 478 | std::unordered_map<u32, Shader::TextureType> texture_types; |
| 487 | std::unordered_map<u64, u32> cbuf_values; | 479 | std::unordered_map<u64, u32> cbuf_values; |
| 488 | std::array<u32, 3> workgroup_size{}; | 480 | std::array<u32, 3> workgroup_size{}; |
| 489 | u32 local_memory_size{}; | 481 | u32 local_memory_size{}; |