Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 90 additions & 2 deletions src/vulkan/wrapper/wrapper_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "vk_util.h"
#include "util/list.h"
#include "util/simple_mtx.h"
#include "util/u_atomic.h"
#include "wrapper_texture_diag.h"

const struct vk_device_extension_table wrapper_device_extensions =
{
Expand Down Expand Up @@ -595,6 +597,43 @@ wrapper_create_device_queue(struct wrapper_device *device,
return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL
wrapper_CreateSampler(VkDevice _device, const VkSamplerCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSampler *pSampler)
{
VK_FROM_HANDLE(wrapper_device, device, _device);
VkResult result = device->dispatch_table.CreateSampler(device->dispatch_handle,
pCreateInfo, pAllocator, pSampler);
static unsigned count;
if (texture_diag_budget(device, &count, 256, "sampler")) {
const VkSamplerCreateInfo *s = pCreateInfo;
fprintf(stderr, "[WRAPPER_SAMPLE] sampler dev=%p result=%d handle=%llx flags=%x filter=%d,%d mip=%d address=%d,%d,%d lod=%g,%g bias=%g anisotropy=%u,%g compare=%u,%d border=%d unnormalized=%u\n",
(void *)device, result, result == VK_SUCCESS ? (unsigned long long)*pSampler : 0,
s->flags, s->minFilter, s->magFilter, s->mipmapMode,
s->addressModeU, s->addressModeV, s->addressModeW,
s->minLod, s->maxLod, s->mipLodBias, s->anisotropyEnable, s->maxAnisotropy,
s->compareEnable, s->compareOp, s->borderColor, s->unnormalizedCoordinates);
const VkBaseInStructure *ext = s->pNext;
for (unsigned i = 0; ext && i < 8; i++, ext = ext->pNext)
fprintf(stderr, "[WRAPPER_SAMPLE] sampler=%llx pnext=%d\n",
result == VK_SUCCESS ? (unsigned long long)*pSampler : 0, ext->sType);
}
return result;
}

VKAPI_ATTR void VKAPI_CALL
wrapper_UpdateDescriptorSetWithTemplate(VkDevice _device, VkDescriptorSet descriptorSet,
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
const void *pData)
{
VK_FROM_HANDLE(wrapper_device, device, _device);
texture_diag_template_update(device, descriptorUpdateTemplate, (uint64_t)descriptorSet, pData);
PFN_vkUpdateDescriptorSetWithTemplate update = device->dispatch_table.UpdateDescriptorSetWithTemplate
? device->dispatch_table.UpdateDescriptorSetWithTemplate
: device->dispatch_table.UpdateDescriptorSetWithTemplateKHR;
update(device->dispatch_handle, descriptorSet, descriptorUpdateTemplate, pData);
}

static void
wrapper_create_null_resources(struct wrapper_device *device)
{
Expand Down Expand Up @@ -674,6 +713,18 @@ wrapper_UpdateDescriptorSets(VkDevice _device, uint32_t descriptorWriteCount,
{
VK_FROM_HANDLE(wrapper_device, device, _device);
VkWriteDescriptorSet *fold_writes = (VkWriteDescriptorSet *)pDescriptorWrites;
texture_diag_writes(device, "write", descriptorWriteCount, pDescriptorWrites);
static unsigned copy_count;
if (descriptorCopyCount && texture_diag_budget(device, &copy_count, 128, "descriptor-copy")) {
for (uint32_t i = 0; i < MIN2(descriptorCopyCount, 32); i++) {
const VkCopyDescriptorSet *c = &pDescriptorCopies[i];
fprintf(stderr, "[WRAPPER_SAMPLE] copy dev=%p src=%llx:%u:%u dst=%llx:%u:%u count=%u\n",
(void *)device, (unsigned long long)c->srcSet, c->srcBinding, c->srcArrayElement,
(unsigned long long)c->dstSet, c->dstBinding, c->dstArrayElement, c->descriptorCount);
}
if (descriptorCopyCount > 32)
fprintf(stderr, "[WRAPPER_SAMPLE] copies truncated to 32 of %u\n", descriptorCopyCount);
}
VkCopyDescriptorSet *fold_copies = (VkCopyDescriptorSet *)pDescriptorCopies;
if (device->fold_sets &&
wrapper_fold_remap_updates(device, &descriptorWriteCount, &fold_writes,
Expand Down Expand Up @@ -741,6 +792,7 @@ wrapper_UpdateDescriptorSets(VkDevice _device, uint32_t descriptorWriteCount,

device->dispatch_table.UpdateDescriptorSets(device->dispatch_handle,
descriptorWriteCount, writes, descriptorCopyCount, pDescriptorCopies);
texture_diag_writes(device, "native-write", descriptorWriteCount, writes);

for (uint32_t i = 0; i < descriptorWriteCount; i++) {
if (writes[i].pBufferInfo != pDescriptorWrites[i].pBufferInfo)
Expand Down Expand Up @@ -2227,6 +2279,20 @@ wrapper_CreateImageView(VkDevice _device,
result = device->dispatch_table.CreateImageView(device->dispatch_handle,
&create_info, pAllocator, pView);

static unsigned view_count;
if (texture_diag_budget(device, &view_count, 1024, "image-view")) {
const VkImageSubresourceRange *r = &create_info.subresourceRange;
fprintf(stderr, "[WRAPPER_SAMPLE] view dev=%p result=%d handle=%llx image=%llx type=%d fmt=%d->%d swizzle=%d,%d,%d,%d aspect=%x mip=%u+%u->%u+%u layer=%u+%u pnext=%d\n",
(void *)device, result, result == VK_SUCCESS ? (unsigned long long)*pView : 0,
(unsigned long long)create_info.image, create_info.viewType,
pCreateInfo->format, create_info.format,
create_info.components.r, create_info.components.g,
create_info.components.b, create_info.components.a, r->aspectMask,
pCreateInfo->subresourceRange.baseMipLevel, pCreateInfo->subresourceRange.levelCount,
r->baseMipLevel, r->levelCount, r->baseArrayLayer, r->layerCount,
create_info.pNext ? ((const VkBaseInStructure *)create_info.pNext)->sType : 0);
}

if (result != VK_SUCCESS)
WRAPPER_LOG(error, "Failed to create image view, res %d", result);
/* Only the lowering paths read this table, and populating it costs an
Expand Down Expand Up @@ -2804,6 +2870,7 @@ wrapper_CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
const VkWriteDescriptorSet *pDescriptorWrites)
{
VK_FROM_HANDLE(wrapper_command_buffer, wcb, commandBuffer);
texture_diag_writes(wcb->device, "push-write", descriptorWriteCount, pDescriptorWrites);
if (!wcb->device->emulate_push_descriptor) {
wcb->device->dispatch_table.CmdPushDescriptorSetKHR(wcb->dispatch_handle,
pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites);
Expand Down Expand Up @@ -2861,6 +2928,7 @@ wrapper_CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
const void *pData)
{
VK_FROM_HANDLE(wrapper_command_buffer, wcb, commandBuffer);
texture_diag_template_update(wcb->device, descriptorUpdateTemplate, (uint64_t)layout, pData);
if (!wcb->device->emulate_push_descriptor) {
wcb->device->dispatch_table.CmdPushDescriptorSetWithTemplateKHR(
wcb->dispatch_handle, descriptorUpdateTemplate, layout, set, pData);
Expand Down Expand Up @@ -3110,6 +3178,16 @@ wrapper_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint
uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets)
{
VK_FROM_HANDLE(wrapper_command_buffer, wcb, commandBuffer);
static unsigned bind_count;
if (texture_diag_budget(wcb->device, &bind_count, 512, "bind")) {
for (uint32_t i = 0; i < MIN2(descriptorSetCount, 16); i++)
fprintf(stderr, "[WRAPPER_SAMPLE] bind dev=%p cmd=%p point=%d layout=%llx set=%u handle=%llx dynamicOffsets=%u folded=%d\n",
(void *)wcb->device, (void *)wcb, pipelineBindPoint,
(unsigned long long)layout, firstSet + i,
(unsigned long long)pDescriptorSets[i], dynamicOffsetCount, wcb->device->fold_sets);
if (descriptorSetCount > 16)
fprintf(stderr, "[WRAPPER_SAMPLE] bind truncated to 16 of %u\n", descriptorSetCount);
}
if (wcb->device->fold_sets &&
wrapper_fold_bind(wcb, pipelineBindPoint, layout, firstSet, descriptorSetCount,
pDescriptorSets, dynamicOffsetCount, pDynamicOffsets))
Expand Down Expand Up @@ -3169,8 +3247,11 @@ wrapper_CreateDescriptorUpdateTemplate(VkDevice _device,
VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
{
VK_FROM_HANDLE(wrapper_device, device, _device);
return wrapper_create_update_template(device, pCreateInfo, pAllocator,
pDescriptorUpdateTemplate);
VkResult result = wrapper_create_update_template(device, pCreateInfo, pAllocator,
pDescriptorUpdateTemplate);
if (result == VK_SUCCESS)
texture_diag_template_create(device, *pDescriptorUpdateTemplate, pCreateInfo);
return result;
}

static void
Expand All @@ -3179,6 +3260,7 @@ wrapper_destroy_update_template(struct wrapper_device *device,
const VkAllocationCallbacks *pAllocator)
{
const struct vk_device_dispatch_table *dt = &device->dispatch_table;
texture_diag_template_destroy(device, descriptorUpdateTemplate);
if (device->emulate_push_descriptor && descriptorUpdateTemplate) {
simple_mtx_lock(&device->push_mutex);
struct wrapper_push_template *rec = _mesa_hash_table_u64_search(
Expand Down Expand Up @@ -6284,6 +6366,12 @@ wrapper_DestroyDevice(VkDevice _device, const VkAllocationCallbacks* pAllocator)
{
VK_FROM_HANDLE(wrapper_device, device, _device);

while (device->texture_diag_templates) {
struct wrapper_texture_template *r = device->texture_diag_templates;
device->texture_diag_templates = r->next;
free(r);
}

wrapper_query_reset_finish(device);

simple_mtx_lock(&device->resource_mutex);
Expand Down
1 change: 1 addition & 0 deletions src/vulkan/wrapper/wrapper_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct wrapper_device {
struct hash_table_u64 *device_only_memory; /* allocations the host cannot map */
struct hash_table_u64 *image_table;
struct hash_table_u64 *image_view_table;
struct wrapper_texture_template *texture_diag_templates;
struct hash_table_u64 *imageless_fb_table;
struct hash_table_u64 *dynamic_pipeline_table;
struct hash_table_u64 *stride_pipeline_table;
Expand Down
140 changes: 140 additions & 0 deletions src/vulkan/wrapper/wrapper_texture_diag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/* Temporary, bounded Zink diagnostic; never changes rendering state.
* Metadata is device-owned and protected by resource_mutex. Unlogged state
* after a limit is unknown, not evidence that an operation was unused. */
struct wrapper_texture_template {
struct wrapper_texture_template *next;
VkDescriptorUpdateTemplate handle;
uint32_t count;
VkDescriptorUpdateTemplateEntry entries[];
};

static bool
texture_diag_enabled(struct wrapper_device *d)
{
const char *e = d->physical->instance->vk.app_info.engine_name;
return e && !strcmp(e, "mesa zink");
}

static bool
texture_diag_budget(struct wrapper_device *d, unsigned *counter,
unsigned limit, const char *kind)
{
if (!texture_diag_enabled(d)) return false;
unsigned n = p_atomic_inc_return(counter);
if (n == limit + 1)
fprintf(stderr, "[WRAPPER_SAMPLE] %s initial limit=%u; then every 4096th call up to call 262144; gaps are unknown\n", kind, limit);
return n <= limit || (n <= 262144 && n % 4096 == 0);
}

static bool
texture_diag_image_type(VkDescriptorType t)
{
return t == VK_DESCRIPTOR_TYPE_SAMPLER ||
t == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
t == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
t == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
t == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
}

static void
texture_diag_image(struct wrapper_device *d, const char *path, uint64_t owner,
uint32_t binding, uint32_t element, VkDescriptorType t,
const VkDescriptorImageInfo *i)
{
static unsigned count;
if (!texture_diag_budget(d, &count, 2048, "descriptor-image")) return;
/* Ignore fields not used by this descriptor type. */
bool s = t == VK_DESCRIPTOR_TYPE_SAMPLER || t == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bool v = t != VK_DESCRIPTOR_TYPE_SAMPLER;
fprintf(stderr, "[WRAPPER_SAMPLE] %s dev=%p owner=%llx binding=%u element=%u type=%d sampler=%llx view=%llx layout=%d\n",
path, (void *)d, (unsigned long long)owner, binding, element, t,
s ? (unsigned long long)i->sampler : 0,
v ? (unsigned long long)i->imageView : 0, v ? i->imageLayout : 0);
}

static void
texture_diag_writes(struct wrapper_device *d, const char *path,
uint32_t count, const VkWriteDescriptorSet *writes)
{
static unsigned batches;
if (!texture_diag_budget(d, &batches, 512, "write-batch")) return;
for (uint32_t k = 0; k < MIN2(count, 64); k++) {
const VkWriteDescriptorSet *w = &writes[k];
if (!texture_diag_image_type(w->descriptorType) || !w->pImageInfo) continue;
for (uint32_t j = 0; j < MIN2(w->descriptorCount, 32); j++)
texture_diag_image(d, path, !strcmp(path, "push-write") ? 0 : (uint64_t)w->dstSet, w->dstBinding,
w->dstArrayElement + j, w->descriptorType, &w->pImageInfo[j]);
if (w->descriptorCount > 32)
fprintf(stderr, "[WRAPPER_SAMPLE] array truncated to 32 of %u\n", w->descriptorCount);
}
if (count > 64) fprintf(stderr, "[WRAPPER_SAMPLE] writes truncated to 64 of %u\n", count);
}

static void
texture_diag_template_create(struct wrapper_device *d, VkDescriptorUpdateTemplate h,
const VkDescriptorUpdateTemplateCreateInfo *i)
{
static unsigned count;
if (!texture_diag_budget(d, &count, 128, "template-create")) return;
uint32_t n = MIN2(i->descriptorUpdateEntryCount, 64);
struct wrapper_texture_template *r = calloc(1, sizeof(*r) + n * sizeof(r->entries[0]));
if (!r) {
fprintf(stderr, "[WRAPPER_SAMPLE] metadata allocation failed; template unknown\n");
return;
}
r->handle = h; r->count = n;
if (n) memcpy(r->entries, i->pDescriptorUpdateEntries, n * sizeof(r->entries[0]));
simple_mtx_lock(&d->resource_mutex);
r->next = d->texture_diag_templates; d->texture_diag_templates = r;
simple_mtx_unlock(&d->resource_mutex);
fprintf(stderr, "[WRAPPER_SAMPLE] template dev=%p handle=%llx type=%d entries=%u captured=%u\n",
(void *)d, (unsigned long long)h, i->templateType, i->descriptorUpdateEntryCount, n);
}

static void
texture_diag_template_destroy(struct wrapper_device *d, VkDescriptorUpdateTemplate h)
{
simple_mtx_lock(&d->resource_mutex);
struct wrapper_texture_template **p = &d->texture_diag_templates;
while (*p) {
if ((*p)->handle == h) {
struct wrapper_texture_template *r = *p; *p = r->next; free(r); break;
}
p = &(*p)->next;
}
simple_mtx_unlock(&d->resource_mutex);
}

static void
texture_diag_template_update(struct wrapper_device *d, VkDescriptorUpdateTemplate h,
uint64_t owner, const void *data)
{
static unsigned count;
if (!texture_diag_budget(d, &count, 512, "template-update")) return;
simple_mtx_lock(&d->resource_mutex);
struct wrapper_texture_template *r = d->texture_diag_templates;
while (r && r->handle != h) r = r->next;
fprintf(stderr, "[WRAPPER_SAMPLE] template-update dev=%p template=%llx owner=%llx tracked=%d\n",
(void *)d, (unsigned long long)h, (unsigned long long)owner, r != NULL);
if (r) for (uint32_t k = 0; k < r->count; k++) {
const VkDescriptorUpdateTemplateEntry *e = &r->entries[k];
if (!texture_diag_image_type(e->descriptorType)) continue;
for (uint32_t j = 0; j < MIN2(e->descriptorCount, 32); j++) {
VkDescriptorImageInfo image = {0};
const char *src = (const char *)data + e->offset + j * e->stride;
/* The caller need only provide the members used by the type. */
if (e->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
e->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
memcpy(&image.sampler, src + offsetof(VkDescriptorImageInfo, sampler), sizeof(image.sampler));
if (e->descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER) {
memcpy(&image.imageView, src + offsetof(VkDescriptorImageInfo, imageView), sizeof(image.imageView));
memcpy(&image.imageLayout, src + offsetof(VkDescriptorImageInfo, imageLayout), sizeof(image.imageLayout));
}
texture_diag_image(d, "template-image", owner, e->dstBinding,
e->dstArrayElement + j, e->descriptorType, &image);
}
if (e->descriptorCount > 32)
fprintf(stderr, "[WRAPPER_SAMPLE] template array truncated to 32 of %u\n", e->descriptorCount);
}
simple_mtx_unlock(&d->resource_mutex);
}
Loading