disk_cache_format_hex_id(buf, device->cache_uuid, VK_UUID_SIZE * 2);
device->disk_cache = disk_cache_create(device->name, buf, shader_env_flags);
- if (device->rad_info.chip_class < GFX8 || !device->use_llvm)
+ if (device->rad_info.chip_class < GFX8)
fprintf(stderr, "WARNING: radv is not a conformant vulkan implementation, testing use only.\n");
radv_get_driver_uuid(&device->driver_uuid);
p->conformanceVersion = (VkConformanceVersion) {
.major = 1,
.minor = 2,
- .subminor = 0,
+ .subminor = 3,
.patch = 0,
};
goto fail;
}
+ if (getenv("RADV_TRAP_HANDLER")) {
+ /* TODO: Add support for more hardware. */
+ assert(device->physical_device->rad_info.chip_class == GFX8);
+
+ fprintf(stderr, "**********************************************************************\n");
+ fprintf(stderr, "* WARNING: RADV_TRAP_HANDLER is experimental and only for debugging! *\n");
+ fprintf(stderr, "**********************************************************************\n");
+
+ /* To get the disassembly of the faulty shaders, we have to
+ * keep some shader info around.
+ */
+ keep_shader_info = true;
+
+ if (!radv_trap_handler_init(device))
+ goto fail;
+ }
+
device->keep_shader_info = keep_shader_info;
result = radv_device_init_meta(device);
if (result != VK_SUCCESS)
radv_thread_trace_finish(device);
+ radv_trap_handler_finish(device);
+
if (device->trace_bo)
device->ws->buffer_destroy(device->trace_bo);
VkPipelineCache pc = radv_pipeline_cache_to_handle(device->mem_cache);
radv_DestroyPipelineCache(radv_device_to_handle(device), pc, NULL);
+ radv_trap_handler_finish(device);
+
radv_destroy_shader_slabs(device);
pthread_cond_destroy(&device->timeline_cond);
}
}
+static void
+radv_emit_trap_handler(struct radv_queue *queue,
+ struct radeon_cmdbuf *cs,
+ struct radeon_winsys_bo *tma_bo)
+{
+ struct radv_device *device = queue->device;
+ struct radeon_winsys_bo *tba_bo;
+ uint64_t tba_va, tma_va;
+
+ if (!device->trap_handler_shader || !tma_bo)
+ return;
+
+ tba_bo = device->trap_handler_shader->bo;
+
+ tba_va = radv_buffer_get_va(tba_bo) + device->trap_handler_shader->bo_offset;
+ tma_va = radv_buffer_get_va(tma_bo);
+
+ radv_cs_add_buffer(queue->device->ws, cs, tba_bo);
+ radv_cs_add_buffer(queue->device->ws, cs, tma_bo);
+
+ if (queue->queue_family_index == RADV_QUEUE_GENERAL) {
+ uint32_t regs[] = {R_00B000_SPI_SHADER_TBA_LO_PS,
+ R_00B100_SPI_SHADER_TBA_LO_VS,
+ R_00B200_SPI_SHADER_TBA_LO_GS,
+ R_00B300_SPI_SHADER_TBA_LO_ES,
+ R_00B400_SPI_SHADER_TBA_LO_HS,
+ R_00B500_SPI_SHADER_TBA_LO_LS};
+
+ for (int i = 0; i < ARRAY_SIZE(regs); ++i) {
+ radeon_set_sh_reg_seq(cs, regs[i], 4);
+ radeon_emit(cs, tba_va >> 8);
+ radeon_emit(cs, tba_va >> 40);
+ radeon_emit(cs, tma_va >> 8);
+ radeon_emit(cs, tma_va >> 40);
+ }
+ } else {
+ radeon_set_sh_reg_seq(cs, R_00B838_COMPUTE_TBA_LO, 4);
+ radeon_emit(cs, tba_va >> 8);
+ radeon_emit(cs, tba_va >> 40);
+ radeon_emit(cs, tma_va >> 8);
+ radeon_emit(cs, tma_va >> 40);
+ }
+}
+
static void
radv_init_graphics_state(struct radeon_cmdbuf *cs, struct radv_queue *queue)
{
compute_scratch_waves, compute_scratch_bo);
radv_emit_graphics_scratch(queue, cs, scratch_size_per_wave,
scratch_waves, scratch_bo);
+ radv_emit_trap_handler(queue, cs, queue->device->tma_bo);
if (gds_bo)
radv_cs_add_buffer(queue->device->ws, cs, gds_bo);
if (queue->device->trace_bo) {
radv_check_gpu_hangs(queue, cs_array[j]);
}
+
+ if (queue->device->tma_bo) {
+ radv_check_trap_handler(queue);
+ }
}
free(cs_array);