void
zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_object *obj)
{
+ assert(!obj->map_count);
if (obj->is_buffer)
vkDestroyBuffer(screen->dev, obj->buffer, NULL);
else
const struct pipe_box *box, struct zink_transfer *trans)
{
struct zink_screen *screen = zink_screen(ctx->base.screen);
- void *ptr;
+ void *ptr = NULL;
if (!(usage & PIPE_MAP_UNSYNCHRONIZED)) {
if (usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE) {
}
}
+ if (!trans->staging_res && res->obj->map)
+ ptr = res->obj->map;
- VkResult result = vkMapMemory(screen->dev, res->obj->mem, res->obj->offset, res->obj->size, 0, &ptr);
- if (result != VK_SUCCESS)
- return NULL;
+ if (!ptr) {
+ VkResult result = vkMapMemory(screen->dev, res->obj->mem, res->obj->offset, res->obj->size, 0, &ptr);
+ if (result != VK_SUCCESS)
+ return NULL;
+ }
#if defined(__APPLE__)
if (!(usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE)) {
}
#endif
- ptr = ((uint8_t *)ptr) + box->x;
if (usage & PIPE_MAP_WRITE)
util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width);
return ptr;
trans->base.usage = usage;
trans->base.box = *box;
- void *ptr;
+ void *ptr, *base;
if (pres->target == PIPE_BUFFER) {
- ptr = buffer_transfer_map(ctx, res, usage, box, trans);
+ base = buffer_transfer_map(ctx, res, usage, box, trans);
+ ptr = ((uint8_t *)base) + box->x;
} else {
if (usage & PIPE_MAP_WRITE && !(usage & PIPE_MAP_READ))
/* this is like a blit, so we can potentially dump some clears or maybe we have to */
VkResult result = vkMapMemory(screen->dev, staging_res->obj->mem,
staging_res->obj->offset,
- staging_res->obj->size, 0, &ptr);
+ staging_res->obj->size, 0, &base);
if (result != VK_SUCCESS)
return NULL;
+ ptr = base;
} else {
assert(!res->optimal_tiling);
+
/* special case compute reads since they aren't handled by zink_fence_wait() */
if (zink_resource_has_usage(res, ZINK_RESOURCE_ACCESS_READ, ZINK_QUEUE_COMPUTE))
resource_sync_reads_from_compute(ctx, res);
else
zink_fence_wait(pctx);
}
- VkResult result = vkMapMemory(screen->dev, res->obj->mem, res->obj->offset, res->obj->size, 0, &ptr);
- if (result != VK_SUCCESS)
- return NULL;
+ if (res->obj->map)
+ base = res->obj->map;
+ else {
+ VkResult result = vkMapMemory(screen->dev, res->obj->mem, res->obj->offset, res->obj->size, 0, &base);
+ if (result != VK_SUCCESS)
+ return NULL;
+ }
VkImageSubresource isr = {
res->aspect,
level,
box->z * srl.depthPitch +
(box->y / desc->block.height) * srl.rowPitch +
(box->x / desc->block.width) * (desc->block.bits / 8);
- ptr = ((uint8_t *)ptr) + offset;
+ ptr = ((uint8_t *)base) + offset;
}
}
if ((usage & PIPE_MAP_PERSISTENT) && !(usage & PIPE_MAP_COHERENT))
res->obj->persistent_maps++;
+ if (trans->staging_res) {
+ zink_resource(trans->staging_res)->obj->map = base;
+ p_atomic_inc(&zink_resource(trans->staging_res)->obj->map_count);
+ } else {
+ res->obj->map = base;
+ p_atomic_inc(&res->obj->map_count);
+ }
+
*transfer = &trans->base;
return ptr;
}
struct zink_transfer *trans = (struct zink_transfer *)ptrans;
if (trans->staging_res) {
struct zink_resource *staging_res = zink_resource(trans->staging_res);
- vkUnmapMemory(screen->dev, staging_res->obj->mem);
- } else
+ if (p_atomic_dec_zero(&staging_res->obj->map_count)) {
+ vkUnmapMemory(screen->dev, staging_res->obj->mem);
+ staging_res->obj->map = NULL;
+ }
+ } else if (p_atomic_dec_zero(&res->obj->map_count)) {
vkUnmapMemory(screen->dev, res->obj->mem);
+ res->obj->map = NULL;
+ }
if ((trans->base.usage & PIPE_MAP_PERSISTENT) && !(trans->base.usage & PIPE_MAP_COHERENT))
res->obj->persistent_maps--;
if (!(trans->base.usage & (PIPE_MAP_FLUSH_EXPLICIT | PIPE_MAP_COHERENT))) {