Skip to content

Commit 4785d9e

Browse files
authored
Update tile_manager.cpp
1 parent d8aaf41 commit 4785d9e

File tree

1 file changed

+52
-14
lines changed

1 file changed

+52
-14
lines changed

src/video_core/texture_cache/tile_manager.cpp

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ struct DetilerParams {
7171
u32 num_levels;
7272
u32 pitch0;
7373
u32 height;
74-
u32 sizes[14];
74+
std::array<u32, 14> sizes{};
7575
};
7676

7777
TileManager::TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler)
@@ -264,33 +264,71 @@ std::pair<vk::Buffer, u32> TileManager::TryDetile(vk::Buffer in_buffer, u32 in_o
264264
cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, *detiler->pl_layout, 0,
265265
set_writes);
266266

267-
DetilerParams params;
267+
DetilerParams params{};
268268
params.num_levels = info.resources.levels;
269269
params.pitch0 = info.pitch >> (info.props.is_block ? 2u : 0u);
270270
params.height = info.size.height;
271-
if (info.tiling_mode == AmdGpu::TilingMode::Texture_Volume ||
272-
info.tiling_mode == AmdGpu::TilingMode::Display_MicroTiled) {
273-
ASSERT(info.resources.levels == 1);
271+
272+
const bool is_volume = info.tiling_mode == AmdGpu::TilingMode::Texture_Volume;
273+
const bool is_display = info.tiling_mode == AmdGpu::TilingMode::Display_MicroTiled;
274+
275+
if (is_volume || is_display) {
276+
// Display surfaces must not use mipmaps.
277+
if (is_display && info.resources.levels > 1) {
278+
LOG_ERROR(Lib_Videodec, "Display tiling with multiple mip levels is not supported.");
279+
return {}; // or handle error
280+
}
281+
282+
ASSERT(in_buffer != out_buffer.first);
283+
274284
const auto tiles_per_row = info.pitch / 8u;
275-
const auto tiles_per_slice = tiles_per_row * ((info.size.height + 7u) / 8u);
285+
const auto tiles_per_slice = tiles_per_row * (Common::AlignUp(info.size.height, 8u) / 8u);
286+
276287
params.sizes[0] = tiles_per_row;
277288
params.sizes[1] = tiles_per_slice;
289+
290+
for (size_t i = 2; i < params.sizes.size(); ++i)
291+
params.sizes[i] = 0;
278292
} else {
279-
ASSERT(info.resources.levels <= 14);
280-
std::memset(&params.sizes, 0, sizeof(params.sizes));
281-
for (int m = 0; m < info.resources.levels; ++m) {
282-
params.sizes[m] = info.mips_layout[m].size + (m > 0 ? params.sizes[m - 1] : 0);
293+
if (info.resources.levels > params.sizes.size()) {
294+
LOG_ERROR(Lib_Videodec, "Too many mip levels: {}, max supported is {}",
295+
info.resources.levels, params.sizes.size());
296+
return {};
283297
}
298+
299+
u32 accum = 0;
300+
for (uint32_t m = 0; m < info.resources.levels; ++m) {
301+
accum += info.mips_layout[m].size;
302+
params.sizes[m] = accum;
303+
}
304+
for (uint32_t m = info.resources.levels; m < params.sizes.size(); ++m)
305+
params.sizes[m] = 0;
284306
}
285307

308+
// Log DetilerParams for debug
309+
LOG_DEBUG(Lib_Videodec, "DetilerParams: levels={}, pitch0={}, height={}", params.num_levels,
310+
params.pitch0, params.height);
311+
for (size_t i = 0; i < params.sizes.size(); ++i)
312+
LOG_DEBUG(Lib_Videodec, " sizes[{}] = {}", i, params.sizes[i]);
313+
286314
cmdbuf.pushConstants(*detiler->pl_layout, vk::ShaderStageFlagBits::eCompute, 0u, sizeof(params),
287315
&params);
288316

289-
ASSERT((image_size % 64) == 0);
290-
const auto bpp = info.num_bits * (info.props.is_block ? 16u : 1u);
291-
const auto num_tiles = image_size / (64 * (bpp / 8));
317+
// Make sure size is aligned
318+
const auto aligned_image_size = Common::AlignUp(image_size, 64u);
319+
ASSERT((aligned_image_size % 64) == 0);
320+
321+
const auto bits_per_pixel = info.num_bits * (info.props.is_block ? 16u : 1u);
322+
ASSERT((bits_per_pixel % 8) == 0);
323+
324+
const auto bytes_per_pixel = bits_per_pixel / 8;
325+
const auto num_tiles = aligned_image_size / (64 * bytes_per_pixel);
326+
327+
LOG_DEBUG(Lib_Videodec, "Dispatch: image_size={}, aligned={}, bpp={}, num_tiles={}", image_size,
328+
aligned_image_size, bits_per_pixel, num_tiles);
329+
292330
cmdbuf.dispatch(num_tiles, 1, 1);
293-
return {out_buffer.first, 0};
331+
return std::make_pair(out_buffer.first, 0u);
294332
}
295333

296334
} // namespace VideoCore

0 commit comments

Comments
 (0)