Compare commits
5 Commits
master
...
placed-ali
Author | SHA1 | Date |
---|---|---|
Hans-Kristian Arntzen | 3d1de5dc6a | |
Hans-Kristian Arntzen | 0be0369ede | |
Hans-Kristian Arntzen | 876447f254 | |
Hans-Kristian Arntzen | 2c42c0da93 | |
Hans-Kristian Arntzen | b1e735ee8f |
|
@ -89,6 +89,7 @@ extern "C" {
|
|||
#define VKD3D_CONFIG_FLAG_SHADER_CACHE_SYNC (1ull << 27)
|
||||
#define VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV (1ull << 28)
|
||||
#define VKD3D_CONFIG_FLAG_ZERO_MEMORY_WORKAROUNDS_COMMITTED_BUFFER_UAV (1ull << 29)
|
||||
#define VKD3D_CONFIG_FLAG_BREADCRUMBS_TRACE (1ull << 30)
|
||||
|
||||
typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event);
|
||||
|
||||
|
|
|
@ -82,6 +82,24 @@ static const char *vkd3d_breadcrumb_command_type_to_str(enum vkd3d_breadcrumb_co
|
|||
return "root_desc";
|
||||
case VKD3D_BREADCRUMB_COMMAND_ROOT_CONST:
|
||||
return "root_const";
|
||||
case VKD3D_BREADCRUMB_COMMAND_BIND_RTV:
|
||||
return "bind_rtv";
|
||||
case VKD3D_BREADCRUMB_COMMAND_BIND_DSV:
|
||||
return "bind_dsv";
|
||||
case VKD3D_BREADCRUMB_COMMAND_COOKIE:
|
||||
return "cookie";
|
||||
case VKD3D_BREADCRUMB_COMMAND_CLEAR_UAV_FLOAT:
|
||||
return "clear_uav_float";
|
||||
case VKD3D_BREADCRUMB_COMMAND_CLEAR_UAV_UINT:
|
||||
return "clear_uav_uint";
|
||||
case VKD3D_BREADCRUMB_COMMAND_CLEAR_UAV_FALLBACK:
|
||||
return "clear_uav_fallback";
|
||||
case VKD3D_BREADCRUMB_COMMAND_CLEAR_RTV:
|
||||
return "clear_rtv";
|
||||
case VKD3D_BREADCRUMB_COMMAND_CLEAR_DSV:
|
||||
return "clear_dsv";
|
||||
case VKD3D_BREADCRUMB_COMMAND_DISCARD:
|
||||
return "discard";
|
||||
|
||||
default:
|
||||
return "?";
|
||||
|
@ -273,8 +291,11 @@ static void vkd3d_breadcrumb_tracer_report_command_list(
|
|||
const struct vkd3d_breadcrumb_command *cmd;
|
||||
bool observed_begin_cmd = false;
|
||||
bool observed_end_cmd = false;
|
||||
bool ignore_markers;
|
||||
unsigned int i;
|
||||
|
||||
ignore_markers = begin_marker == UINT32_MAX && end_marker == UINT32_MAX;
|
||||
|
||||
if (end_marker == 0)
|
||||
{
|
||||
ERR(" ===== Potential crash region BEGIN (make sure RADV_DEBUG=syncshaders is used for maximum accuracy) =====\n");
|
||||
|
@ -287,6 +308,12 @@ static void vkd3d_breadcrumb_tracer_report_command_list(
|
|||
{
|
||||
cmd = &context->commands[i];
|
||||
|
||||
if (ignore_markers && (cmd->type == VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER ||
|
||||
cmd->type == VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If there is a command which sets TOP_OF_PIPE, but we haven't observed the marker yet,
|
||||
* the command processor hasn't gotten there yet (most likely ...), so that should be the
|
||||
* natural end-point. */
|
||||
|
@ -306,6 +333,10 @@ static void vkd3d_breadcrumb_tracer_report_command_list(
|
|||
{
|
||||
ERR(" Set arg: %"PRIu64" (#%"PRIx64")\n", cmd->word_64bit, cmd->word_64bit);
|
||||
}
|
||||
else if (cmd->type == VKD3D_BREADCRUMB_COMMAND_COOKIE)
|
||||
{
|
||||
ERR(" Set resource cookie: %"PRIu64"\n", cmd->word_64bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR(" Command: %s\n", vkd3d_breadcrumb_command_type_to_str(cmd->type));
|
||||
|
@ -338,6 +369,13 @@ static void vkd3d_breadcrumb_tracer_report_command_list(
|
|||
}
|
||||
}
|
||||
|
||||
void vkd3d_breadcrumb_tracer_dump_command_list(struct vkd3d_breadcrumb_tracer *tracer,
|
||||
unsigned int index)
|
||||
{
|
||||
vkd3d_breadcrumb_tracer_report_command_list(&tracer->trace_contexts[index],
|
||||
UINT32_MAX, UINT32_MAX);
|
||||
}
|
||||
|
||||
static void vkd3d_breadcrumb_tracer_report_command_list_amd(struct vkd3d_breadcrumb_tracer *tracer,
|
||||
unsigned int context_index)
|
||||
{
|
||||
|
@ -645,3 +683,116 @@ void vkd3d_breadcrumb_tracer_end_command_list(struct d3d12_command_list *list)
|
|||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER;
|
||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
||||
}
|
||||
|
||||
/* There is no obvious home for this code. It could be in heap.c, but this kind of
|
||||
* debug is only really useful when doing crash debugging, i.e. breadcrumbs,
|
||||
* so might as well have it here. */
|
||||
|
||||
static bool d3d12_resource_is_linear_placement(const struct d3d12_resource *resource)
|
||||
{
|
||||
return (resource->desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
|
||||
!(resource->flags & VKD3D_RESOURCE_ACCELERATION_STRUCTURE)) ||
|
||||
(resource->flags & VKD3D_RESOURCE_LINEAR_TILING);
|
||||
}
|
||||
|
||||
static void d3d12_resource_report_parameters(char *buf, size_t buf_size, const struct d3d12_resource *resource)
|
||||
{
|
||||
if (resource->desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
snprintf(buf, buf_size,
|
||||
"IMAGE: format = %s, width = %"PRIu64", height = %u, depth/layers = %u, levels = %u, flags = #%x",
|
||||
debug_dxgi_format(resource->desc.Format),
|
||||
resource->desc.Width,
|
||||
resource->desc.Height,
|
||||
resource->desc.DepthOrArraySize,
|
||||
resource->desc.MipLevels,
|
||||
resource->desc.Flags);
|
||||
}
|
||||
else if (resource->flags & VKD3D_RESOURCE_ACCELERATION_STRUCTURE)
|
||||
snprintf(buf, buf_size, "RTAS");
|
||||
else
|
||||
snprintf(buf, buf_size, "BUFFER");
|
||||
}
|
||||
|
||||
void vkd3d_breadcrumb_tracer_register_placed_resource(struct d3d12_heap *heap,
|
||||
struct d3d12_resource *resource,
|
||||
VkDeviceSize heap_offset, VkDeviceSize required_size)
|
||||
{
|
||||
const struct d3d12_heap_resource_placement *placement;
|
||||
bool candidate_resource_is_linear;
|
||||
bool placed_resource_is_linear;
|
||||
VkDeviceSize begin_overlap;
|
||||
VkDeviceSize end_overlap;
|
||||
char report_buffer[1024];
|
||||
bool has_alias = false;
|
||||
const char *msg;
|
||||
size_t i;
|
||||
|
||||
/* Linear aliasing with other linear resources is fine.
|
||||
* Image <-> Image, and Image <-> Buffer is far more dangerous however. */
|
||||
placed_resource_is_linear = d3d12_resource_is_linear_placement(resource);
|
||||
|
||||
pthread_mutex_lock(&heap->placement_lock);
|
||||
|
||||
for (i = 0; i < heap->placements_count; i++)
|
||||
{
|
||||
placement = &heap->placements[i];
|
||||
candidate_resource_is_linear = d3d12_resource_is_linear_placement(placement->resource);
|
||||
|
||||
begin_overlap = max(placement->heap_offset, heap_offset);
|
||||
end_overlap = min(placement->heap_offset + placement->size, heap_offset + required_size);
|
||||
|
||||
if (begin_overlap < end_overlap && candidate_resource_is_linear != placed_resource_is_linear)
|
||||
{
|
||||
/* Overlap. */
|
||||
/* Potentially problematic scenario, report this. */
|
||||
if (!has_alias)
|
||||
{
|
||||
if (resource->desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
msg = "Attempting to place linear buffer resource on heap, placement aliases with non-linear layout.";
|
||||
else
|
||||
msg = "Attempting to place opaque resource on heap, placement aliases with other resources.";
|
||||
|
||||
d3d12_resource_report_parameters(report_buffer, sizeof(report_buffer), resource);
|
||||
INFO("\n%s\n New placement: resource cookie = %"PRIu64", offset = %"PRIu64", size = %"PRIu64", VA = %"PRIx64"\n\t%s\n",
|
||||
msg,
|
||||
resource->res.cookie,
|
||||
heap_offset, required_size, resource->res.va,
|
||||
report_buffer);
|
||||
|
||||
has_alias = true;
|
||||
}
|
||||
|
||||
d3d12_resource_report_parameters(report_buffer, sizeof(report_buffer), placement->resource);
|
||||
INFO("\n Existing aliasing resource : cookie = %"PRIu64", offset = %"PRIu64", size = %"PRIu64".\n\t\t%s\n",
|
||||
placement->resource->res.cookie, placement->heap_offset, placement->size,
|
||||
report_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
vkd3d_array_reserve((void**)&heap->placements, &heap->placements_size,
|
||||
heap->placements_count + 1, sizeof(*heap->placements));
|
||||
|
||||
heap->placements[heap->placements_count].resource = resource;
|
||||
heap->placements[heap->placements_count].heap_offset = heap_offset;
|
||||
heap->placements[heap->placements_count].size = required_size;
|
||||
heap->placements_count++;
|
||||
|
||||
pthread_mutex_unlock(&heap->placement_lock);
|
||||
}
|
||||
|
||||
void vkd3d_breadcrumb_tracer_unregister_placed_resource(struct d3d12_heap *heap, struct d3d12_resource *resource)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
pthread_mutex_lock(&heap->placement_lock);
|
||||
for (i = 0; i < heap->placements_count; i++)
|
||||
{
|
||||
if (heap->placements[i].resource == resource)
|
||||
{
|
||||
heap->placements[i] = heap->placements[--heap->placements_count];
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&heap->placement_lock);
|
||||
}
|
|
@ -8173,6 +8173,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
|
|||
rtv_desc = d3d12_rtv_desc_from_cpu_handle(render_target_descriptors[i]);
|
||||
}
|
||||
|
||||
VKD3D_BREADCRUMB_COOKIE(rtv_desc && rtv_desc->resource ? rtv_desc->resource->res.cookie : 0);
|
||||
VKD3D_BREADCRUMB_AUX32(i);
|
||||
VKD3D_BREADCRUMB_COMMAND_STATE(BIND_RTV);
|
||||
|
||||
if (!rtv_desc || !rtv_desc->resource)
|
||||
{
|
||||
WARN("RTV descriptor %u is not initialized.\n", i);
|
||||
|
@ -8204,6 +8208,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
|
|||
{
|
||||
WARN("DSV descriptor is not initialized.\n");
|
||||
}
|
||||
|
||||
VKD3D_BREADCRUMB_COOKIE(rtv_desc && rtv_desc->resource ? rtv_desc->resource->res.cookie : 0);
|
||||
VKD3D_BREADCRUMB_COMMAND_STATE(BIND_DSV);
|
||||
}
|
||||
|
||||
if (d3d12_pipeline_state_is_graphics(list->state))
|
||||
|
@ -8301,6 +8308,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(d3d12_com
|
|||
|
||||
d3d12_command_list_clear_attachment(list, dsv_desc->resource, dsv_desc->view,
|
||||
clear_aspects, &clear_value, rect_count, rects);
|
||||
|
||||
VKD3D_BREADCRUMB_COOKIE(dsv_desc->resource->res.cookie);
|
||||
VKD3D_BREADCRUMB_COMMAND(CLEAR_DSV);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(d3d12_command_list_iface *iface,
|
||||
|
@ -8339,6 +8349,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(d3d12_com
|
|||
|
||||
d3d12_command_list_clear_attachment(list, rtv_desc->resource, rtv_desc->view,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT, &clear_value, rect_count, rects);
|
||||
|
||||
VKD3D_BREADCRUMB_COOKIE(rtv_desc->resource->res.cookie);
|
||||
VKD3D_BREADCRUMB_COMMAND(CLEAR_RTV);
|
||||
}
|
||||
|
||||
struct vkd3d_clear_uav_info
|
||||
|
@ -8931,6 +8944,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(d3
|
|||
{
|
||||
d3d12_command_list_clear_uav_with_copy(list, &d, resource_impl,
|
||||
&args, &color, uint_format, rect_count, rects);
|
||||
VKD3D_BREADCRUMB_COMMAND(CLEAR_UAV_FALLBACK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -8968,6 +8982,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(d3
|
|||
d3d12_command_allocator_add_view(list->allocator, inline_view);
|
||||
vkd3d_view_decref(inline_view, list->device);
|
||||
}
|
||||
|
||||
VKD3D_BREADCRUMB_COMMAND(CLEAR_UAV_UINT);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(d3d12_command_list_iface *iface,
|
||||
|
@ -8994,6 +9010,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(d
|
|||
color = vkd3d_fixup_clear_uav_swizzle(list->device, d.view->info.view->format->dxgi_format, color);
|
||||
|
||||
d3d12_command_list_clear_uav(list, &d, resource_impl, &args, &color, rect_count, rects);
|
||||
VKD3D_BREADCRUMB_COMMAND(CLEAR_UAV_FLOAT);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(d3d12_command_list_iface *iface,
|
||||
|
@ -9130,6 +9147,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(d3d12_command_l
|
|||
d3d12_command_list_discard_attachment_barrier(list, texture, &vk_subresource_range, is_bound);
|
||||
}
|
||||
}
|
||||
|
||||
VKD3D_BREADCRUMB_COOKIE(texture->res.cookie);
|
||||
VKD3D_BREADCRUMB_COMMAND(DISCARD);
|
||||
}
|
||||
|
||||
static inline bool d3d12_query_type_is_scoped(D3D12_QUERY_TYPE type)
|
||||
|
@ -9879,6 +9899,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(d3d12_command_l
|
|||
if (!max_command_count)
|
||||
return;
|
||||
|
||||
VKD3D_BREADCRUMB_COOKIE(arg_impl ? arg_impl->res.cookie : 0);
|
||||
VKD3D_BREADCRUMB_AUX64(arg_buffer_offset);
|
||||
VKD3D_BREADCRUMB_COOKIE(count_impl ? count_impl->res.cookie : 0);
|
||||
VKD3D_BREADCRUMB_AUX64(count_buffer_offset);
|
||||
|
||||
if ((count_buffer || list->predicate_va) && !list->device->vk_info.KHR_draw_indirect_count)
|
||||
{
|
||||
FIXME("Count buffers not supported by Vulkan implementation.\n");
|
||||
|
@ -11230,6 +11255,9 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
|
|||
size_t num_transitions, num_command_buffers;
|
||||
struct d3d12_command_queue_submission sub;
|
||||
struct d3d12_command_list *cmd_list;
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
unsigned int *breadcrumb_indices;
|
||||
#endif
|
||||
VkCommandBuffer *buffers;
|
||||
LONG **outstanding;
|
||||
unsigned int i, j;
|
||||
|
@ -11278,6 +11306,19 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS_TRACE)
|
||||
{
|
||||
if (!(breadcrumb_indices = vkd3d_malloc(sizeof(unsigned int) * command_list_count)))
|
||||
{
|
||||
vkd3d_free(outstanding);
|
||||
vkd3d_free(buffers);
|
||||
}
|
||||
}
|
||||
else
|
||||
breadcrumb_indices = NULL;
|
||||
#endif
|
||||
|
||||
sub.execute.debug_capture = false;
|
||||
|
||||
num_transitions = 0;
|
||||
|
@ -11292,6 +11333,9 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
|
|||
"Command list %p is in recording state.\n", command_lists[i]);
|
||||
vkd3d_free(outstanding);
|
||||
vkd3d_free(buffers);
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
vkd3d_free(breadcrumb_indices);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -11305,6 +11349,11 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
|
|||
buffers[j++] = cmd_list->vk_command_buffer;
|
||||
if (cmd_list->debug_capture)
|
||||
sub.execute.debug_capture = true;
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
if (breadcrumb_indices)
|
||||
breadcrumb_indices[i] = cmd_list->breadcrumb_context_index;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Append a full GPU barrier between submissions.
|
||||
|
@ -11345,6 +11394,10 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
|
|||
sub.execute.cmd_count = num_command_buffers;
|
||||
sub.execute.outstanding_submissions_counters = outstanding;
|
||||
sub.execute.outstanding_submissions_counter_count = command_list_count;
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
sub.execute.breadcrumb_indices = breadcrumb_indices;
|
||||
sub.execute.breadcrumb_indices_count = breadcrumb_indices ? command_list_count : 0;
|
||||
#endif
|
||||
d3d12_command_queue_add_submission(command_queue, &sub);
|
||||
}
|
||||
|
||||
|
@ -12448,6 +12501,18 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)
|
|||
for (i = 0; i < submission.execute.outstanding_submissions_counter_count; i++)
|
||||
InterlockedDecrement(submission.execute.outstanding_submissions_counters[i]);
|
||||
vkd3d_free(submission.execute.outstanding_submissions_counters);
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
for (i = 0; i < submission.execute.breadcrumb_indices_count; i++)
|
||||
{
|
||||
INFO("=== Executing command list context %u on VkQueue %p, queue family %u ===\n",
|
||||
submission.execute.breadcrumb_indices[i],
|
||||
(void*)queue->vkd3d_queue->vk_queue, queue->vkd3d_queue->vk_family_index);
|
||||
vkd3d_breadcrumb_tracer_dump_command_list(&queue->device->breadcrumb_tracer,
|
||||
submission.execute.breadcrumb_indices[i]);
|
||||
INFO("============================\n");
|
||||
}
|
||||
vkd3d_free(submission.execute.breadcrumb_indices);
|
||||
#endif
|
||||
VKD3D_REGION_END(queue_execute);
|
||||
break;
|
||||
|
||||
|
|
|
@ -664,6 +664,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] =
|
|||
{"pipeline_library_app_cache", VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_APP_CACHE_ONLY},
|
||||
{"shader_cache_sync", VKD3D_CONFIG_FLAG_SHADER_CACHE_SYNC},
|
||||
{"force_raw_va_cbv", VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV},
|
||||
{"breadcrumbs_trace", VKD3D_CONFIG_FLAG_BREADCRUMBS | VKD3D_CONFIG_FLAG_BREADCRUMBS_TRACE},
|
||||
};
|
||||
|
||||
static void vkd3d_config_flags_init_once(void)
|
||||
|
|
|
@ -59,9 +59,13 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap)
|
|||
{
|
||||
TRACE("Destroying heap %p.\n", heap);
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
vkd3d_free(heap->placements);
|
||||
pthread_mutex_destroy(&heap->placement_lock);
|
||||
#endif
|
||||
|
||||
vkd3d_free_memory(heap->device, &heap->device->memory_allocator, &heap->allocation);
|
||||
vkd3d_private_store_destroy(&heap->private_store);
|
||||
d3d12_device_release(heap->device);
|
||||
vkd3d_free(heap);
|
||||
}
|
||||
|
||||
|
@ -72,6 +76,18 @@ static void d3d12_heap_set_name(struct d3d12_heap *heap, const char *name)
|
|||
VK_OBJECT_TYPE_DEVICE_MEMORY, name);
|
||||
}
|
||||
|
||||
void d3d12_heap_dec_ref(struct d3d12_heap *heap)
|
||||
{
|
||||
ULONG refcount = InterlockedDecrement(&heap->internal_refcount);
|
||||
if (!refcount)
|
||||
d3d12_heap_destroy(heap);
|
||||
}
|
||||
|
||||
void d3d12_heap_inc_ref(struct d3d12_heap *heap)
|
||||
{
|
||||
InterlockedIncrement(&heap->internal_refcount);
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE d3d12_heap_Release(d3d12_heap_iface *iface)
|
||||
{
|
||||
struct d3d12_heap *heap = impl_from_ID3D12Heap1(iface);
|
||||
|
@ -80,7 +96,11 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(d3d12_heap_iface *iface)
|
|||
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
|
||||
|
||||
if (!refcount)
|
||||
d3d12_heap_destroy(heap);
|
||||
{
|
||||
struct d3d12_device *device = heap->device;
|
||||
d3d12_heap_dec_ref(heap);
|
||||
d3d12_device_release(device);
|
||||
}
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
@ -225,6 +245,7 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, struct d3d12_device *dev
|
|||
memset(heap, 0, sizeof(*heap));
|
||||
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
|
||||
heap->refcount = 1;
|
||||
heap->internal_refcount = 1;
|
||||
heap->desc = *desc;
|
||||
heap->device = device;
|
||||
|
||||
|
@ -252,6 +273,10 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, struct d3d12_device *dev
|
|||
return hr;
|
||||
}
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
pthread_mutex_init(&heap->placement_lock, NULL);
|
||||
#endif
|
||||
|
||||
d3d12_device_add_ref(heap->device);
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -1419,7 +1419,14 @@ static ULONG d3d12_resource_decref(struct d3d12_resource *resource)
|
|||
TRACE("%p decreasing refcount to %u.\n", resource, refcount);
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
VKD3D_UNUSED struct d3d12_heap *heap = resource->heap;
|
||||
d3d12_resource_destroy(resource, resource->device);
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
if (heap && (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS))
|
||||
d3d12_heap_dec_ref(heap);
|
||||
#endif
|
||||
}
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
@ -1511,7 +1518,6 @@ static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(d3d12_resource_iface *iface
|
|||
if (refcount == 1)
|
||||
{
|
||||
struct d3d12_device *device = resource->device;
|
||||
|
||||
d3d12_device_add_ref(device);
|
||||
d3d12_resource_incref(resource);
|
||||
}
|
||||
|
@ -2605,6 +2611,11 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12
|
|||
if (resource->vrs_view)
|
||||
VK_CALL(vkDestroyImageView(device->vk_device, resource->vrs_view, NULL));
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS) && resource->heap)
|
||||
vkd3d_breadcrumb_tracer_unregister_placed_resource(resource->heap, resource);
|
||||
#endif
|
||||
|
||||
vkd3d_private_store_destroy(&resource->private_store);
|
||||
d3d12_device_release(resource->device);
|
||||
vkd3d_free(resource);
|
||||
|
@ -2861,6 +2872,7 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE
|
|||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
VkMemoryRequirements memory_requirements;
|
||||
VKD3D_UNUSED VkDeviceSize required_size;
|
||||
VkBindImageMemoryInfo bind_info;
|
||||
struct d3d12_resource *object;
|
||||
VkResult vr;
|
||||
|
@ -2900,11 +2912,13 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE
|
|||
|
||||
if (heap_offset + memory_requirements.size > heap->allocation.resource.size)
|
||||
{
|
||||
ERR("Heap too small for the texture (heap=%"PRIu64", res=%"PRIu64".\n",
|
||||
ERR("Heap too small for the texture (heap=%"PRIu64", res=%"PRIu64").\n",
|
||||
heap->allocation.resource.size, heap_offset + memory_requirements.size);
|
||||
hr = E_INVALIDARG;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
required_size = memory_requirements.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2915,6 +2929,8 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE
|
|||
hr = E_INVALIDARG;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
required_size = desc->Width;
|
||||
}
|
||||
|
||||
vkd3d_memory_allocation_slice(&object->mem, &heap->allocation, heap_offset, 0);
|
||||
|
@ -2947,6 +2963,23 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE
|
|||
goto fail;
|
||||
}
|
||||
|
||||
/* Placed RTV and DSV *must* be explicitly initialized after alias barriers and first use,
|
||||
* so there is no need to do initial layout transition ourselves.
|
||||
* It is extremely dangerous to do so since the initialization will clobber other
|
||||
* aliased buffers when clearing DCC/HTILE state.
|
||||
* For details, see:
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-createplacedresource#notes-on-the-required-resource-initialization. */
|
||||
if (desc->Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL))
|
||||
object->initial_layout_transition = 0;
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS)
|
||||
{
|
||||
vkd3d_breadcrumb_tracer_register_placed_resource(heap, object, heap_offset, required_size);
|
||||
d3d12_heap_inc_ref(heap);
|
||||
}
|
||||
#endif
|
||||
|
||||
*resource = object;
|
||||
return S_OK;
|
||||
|
||||
|
|
|
@ -740,18 +740,38 @@ HRESULT vkd3d_memory_allocator_flush_clears(struct vkd3d_memory_allocator *alloc
|
|||
/* ID3D12Heap */
|
||||
typedef ID3D12Heap1 d3d12_heap_iface;
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
struct d3d12_heap_resource_placement
|
||||
{
|
||||
struct d3d12_resource *resource;
|
||||
VkDeviceSize heap_offset;
|
||||
VkDeviceSize size;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct d3d12_heap
|
||||
{
|
||||
d3d12_heap_iface ID3D12Heap_iface;
|
||||
LONG refcount;
|
||||
LONG internal_refcount;
|
||||
|
||||
D3D12_HEAP_DESC desc;
|
||||
struct vkd3d_memory_allocation allocation;
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
struct d3d12_heap_resource_placement *placements;
|
||||
size_t placements_count;
|
||||
size_t placements_size;
|
||||
pthread_mutex_t placement_lock;
|
||||
#endif
|
||||
|
||||
struct d3d12_device *device;
|
||||
struct vkd3d_private_store private_store;
|
||||
};
|
||||
|
||||
void d3d12_heap_inc_ref(struct d3d12_heap *heap);
|
||||
void d3d12_heap_dec_ref(struct d3d12_heap *heap);
|
||||
|
||||
HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc,
|
||||
void *host_address, struct d3d12_heap **heap);
|
||||
HRESULT d3d12_device_validate_custom_heap_type(struct d3d12_device *device,
|
||||
|
@ -2353,6 +2373,12 @@ struct d3d12_command_queue_submission_execute
|
|||
struct vkd3d_initial_transition *transitions;
|
||||
size_t transition_count;
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
/* Replays commands in submission order for heavy debug. */
|
||||
unsigned int *breadcrumb_indices;
|
||||
size_t breadcrumb_indices_count;
|
||||
#endif
|
||||
|
||||
bool debug_capture;
|
||||
};
|
||||
|
||||
|
@ -2552,6 +2578,15 @@ enum vkd3d_breadcrumb_command_type
|
|||
VKD3D_BREADCRUMB_COMMAND_IBO,
|
||||
VKD3D_BREADCRUMB_COMMAND_ROOT_DESC,
|
||||
VKD3D_BREADCRUMB_COMMAND_ROOT_CONST,
|
||||
VKD3D_BREADCRUMB_COMMAND_BIND_RTV,
|
||||
VKD3D_BREADCRUMB_COMMAND_BIND_DSV,
|
||||
VKD3D_BREADCRUMB_COMMAND_COOKIE,
|
||||
VKD3D_BREADCRUMB_COMMAND_CLEAR_UAV_FLOAT,
|
||||
VKD3D_BREADCRUMB_COMMAND_CLEAR_UAV_UINT,
|
||||
VKD3D_BREADCRUMB_COMMAND_CLEAR_UAV_FALLBACK,
|
||||
VKD3D_BREADCRUMB_COMMAND_CLEAR_RTV,
|
||||
VKD3D_BREADCRUMB_COMMAND_CLEAR_DSV,
|
||||
VKD3D_BREADCRUMB_COMMAND_DISCARD,
|
||||
};
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
|
@ -2622,6 +2657,14 @@ void vkd3d_breadcrumb_tracer_add_command(struct d3d12_command_list *list,
|
|||
void vkd3d_breadcrumb_tracer_signal(struct d3d12_command_list *list);
|
||||
void vkd3d_breadcrumb_tracer_end_command_list(struct d3d12_command_list *list);
|
||||
|
||||
void vkd3d_breadcrumb_tracer_register_placed_resource(struct d3d12_heap *heap, struct d3d12_resource *resource,
|
||||
VkDeviceSize heap_offset, VkDeviceSize required_size);
|
||||
void vkd3d_breadcrumb_tracer_unregister_placed_resource(struct d3d12_heap *heap, struct d3d12_resource *resource);
|
||||
|
||||
/* For heavy debug, replays the trace stream in submission order. */
|
||||
void vkd3d_breadcrumb_tracer_dump_command_list(struct vkd3d_breadcrumb_tracer *tracer,
|
||||
unsigned int index);
|
||||
|
||||
#define VKD3D_BREADCRUMB_COMMAND(cmd_type) do { \
|
||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS) { \
|
||||
struct vkd3d_breadcrumb_command breadcrumb_cmd; \
|
||||
|
@ -2658,6 +2701,15 @@ void vkd3d_breadcrumb_tracer_end_command_list(struct d3d12_command_list *list);
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
#define VKD3D_BREADCRUMB_COOKIE(v) do { \
|
||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS) { \
|
||||
struct vkd3d_breadcrumb_command breadcrumb_cmd; \
|
||||
breadcrumb_cmd.type = VKD3D_BREADCRUMB_COMMAND_COOKIE; \
|
||||
breadcrumb_cmd.word_64bit = v; \
|
||||
vkd3d_breadcrumb_tracer_add_command(list, &breadcrumb_cmd); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Remember to kick debug ring as well. */
|
||||
#define VKD3D_DEVICE_REPORT_BREADCRUMB_IF(device, cond) do { \
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS) && (cond)) { \
|
||||
|
@ -2670,6 +2722,7 @@ void vkd3d_breadcrumb_tracer_end_command_list(struct d3d12_command_list *list);
|
|||
#define VKD3D_BREADCRUMB_COMMAND_STATE(type) ((void)(VKD3D_BREADCRUMB_COMMAND_##type))
|
||||
#define VKD3D_BREADCRUMB_AUX32(v) ((void)(v))
|
||||
#define VKD3D_BREADCRUMB_AUX64(v) ((void)(v))
|
||||
#define VKD3D_BREADCRUMB_COOKIE(v) ((void)(v))
|
||||
#define VKD3D_DEVICE_REPORT_BREADCRUMB_IF(device, cond) ((void)(device), (void)(cond))
|
||||
#endif /* VKD3D_ENABLE_BREADCRUMBS */
|
||||
|
||||
|
|
Loading…
Reference in New Issue