@@ -71,7 +71,7 @@ struct DetilerParams {
71
71
u32 num_levels;
72
72
u32 pitch0;
73
73
u32 height;
74
- u32 sizes[ 14 ] ;
74
+ std::array< u32 , 14 > sizes{} ;
75
75
};
76
76
77
77
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
264
264
cmdbuf.pushDescriptorSetKHR (vk::PipelineBindPoint::eCompute, *detiler->pl_layout , 0 ,
265
265
set_writes);
266
266
267
- DetilerParams params;
267
+ DetilerParams params{} ;
268
268
params.num_levels = info.resources .levels ;
269
269
params.pitch0 = info.pitch >> (info.props .is_block ? 2u : 0u );
270
270
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
+
274
284
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
+
276
287
params.sizes [0 ] = tiles_per_row;
277
288
params.sizes [1 ] = tiles_per_slice;
289
+
290
+ for (size_t i = 2 ; i < params.sizes .size (); ++i)
291
+ params.sizes [i] = 0 ;
278
292
} else {
279
- ASSERT (info.resources .levels <= 14 );
280
- std::memset (¶ms. 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 {} ;
283
297
}
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 ;
284
306
}
285
307
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
+
286
314
cmdbuf.pushConstants (*detiler->pl_layout , vk::ShaderStageFlagBits::eCompute, 0u , sizeof (params),
287
315
¶ms);
288
316
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
+
292
330
cmdbuf.dispatch (num_tiles, 1 , 1 );
293
- return { out_buffer.first , 0 } ;
331
+ return std::make_pair ( out_buffer.first , 0u ) ;
294
332
}
295
333
296
334
} // namespace VideoCore
0 commit comments