17ec681f3Smrg/*
27ec681f3Smrg * Copyright 2018 Collabora Ltd.
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub
87ec681f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom
97ec681f3Smrg * the Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
197ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
207ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
217ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
227ec681f3Smrg */
237ec681f3Smrg
247ec681f3Smrg#ifndef ZINK_RESOURCE_H
257ec681f3Smrg#define ZINK_RESOURCE_H
267ec681f3Smrg
277ec681f3Smrgstruct pipe_screen;
287ec681f3Smrgstruct sw_displaytarget;
297ec681f3Smrgstruct zink_batch;
307ec681f3Smrgstruct zink_context;
317ec681f3Smrgstruct zink_bo;
327ec681f3Smrg
337ec681f3Smrg#include "util/hash_table.h"
347ec681f3Smrg#include "util/simple_mtx.h"
357ec681f3Smrg#include "util/u_transfer.h"
367ec681f3Smrg#include "util/u_range.h"
377ec681f3Smrg#include "util/u_dynarray.h"
387ec681f3Smrg#include "util/u_threaded_context.h"
397ec681f3Smrg
407ec681f3Smrg#include "zink_batch.h"
417ec681f3Smrg#include "zink_descriptors.h"
427ec681f3Smrg
437ec681f3Smrg#include <vulkan/vulkan.h>
447ec681f3Smrg
457ec681f3Smrg#define ZINK_MAP_TEMPORARY (PIPE_MAP_DRV_PRV << 0)
467ec681f3Smrg#define ZINK_BIND_TRANSIENT (1 << 30) //transient fb attachment
477ec681f3Smrg
487ec681f3Smrgstruct mem_key {
497ec681f3Smrg   unsigned seen_count;
507ec681f3Smrg   struct {
517ec681f3Smrg      unsigned heap_index;
527ec681f3Smrg      VkMemoryRequirements reqs;
537ec681f3Smrg   } key;
547ec681f3Smrg};
557ec681f3Smrg
567ec681f3Smrgstruct zink_resource_object {
577ec681f3Smrg   struct pipe_reference reference;
587ec681f3Smrg
597ec681f3Smrg   VkPipelineStageFlagBits access_stage;
607ec681f3Smrg   VkAccessFlags access;
617ec681f3Smrg   bool unordered_barrier;
627ec681f3Smrg
637ec681f3Smrg   unsigned persistent_maps; //if nonzero, requires vkFlushMappedMemoryRanges during batch use
647ec681f3Smrg   struct zink_descriptor_refs desc_set_refs;
657ec681f3Smrg
667ec681f3Smrg   struct util_dynarray tmp;
677ec681f3Smrg
687ec681f3Smrg   union {
697ec681f3Smrg      VkBuffer buffer;
707ec681f3Smrg      VkImage image;
717ec681f3Smrg   };
727ec681f3Smrg
737ec681f3Smrg   VkSampleLocationsInfoEXT zs_evaluate;
747ec681f3Smrg   bool needs_zs_evaluate;
757ec681f3Smrg
767ec681f3Smrg   bool storage_init; //layout was set for image
777ec681f3Smrg   bool transfer_dst;
787ec681f3Smrg   bool is_buffer;
797ec681f3Smrg   VkImageAspectFlags modifier_aspect;
807ec681f3Smrg
817ec681f3Smrg   struct zink_bo *bo;
827ec681f3Smrg   VkDeviceSize offset, size, alignment;
837ec681f3Smrg   VkImageCreateFlags vkflags;
847ec681f3Smrg   VkImageUsageFlags vkusage;
857ec681f3Smrg
867ec681f3Smrg   bool host_visible;
877ec681f3Smrg   bool coherent;
887ec681f3Smrg};
897ec681f3Smrg
907ec681f3Smrgstruct zink_resource {
917ec681f3Smrg   struct threaded_resource base;
927ec681f3Smrg
937ec681f3Smrg   enum pipe_format internal_format:16;
947ec681f3Smrg
957ec681f3Smrg   struct zink_resource_object *obj;
967ec681f3Smrg   struct zink_resource_object *scanout_obj; //TODO: remove for wsi
977ec681f3Smrg   bool scanout_obj_init;
987ec681f3Smrg   union {
997ec681f3Smrg      struct {
1007ec681f3Smrg         struct util_range valid_buffer_range;
1017ec681f3Smrg         uint32_t vbo_bind_mask : PIPE_MAX_ATTRIBS;
1027ec681f3Smrg         uint8_t ubo_bind_count[2];
1037ec681f3Smrg         uint8_t so_bind_count;
1047ec681f3Smrg         bool so_valid;
1057ec681f3Smrg         uint32_t ubo_bind_mask[PIPE_SHADER_TYPES];
1067ec681f3Smrg         uint32_t ssbo_bind_mask[PIPE_SHADER_TYPES];
1077ec681f3Smrg      };
1087ec681f3Smrg      struct {
1097ec681f3Smrg         VkFormat format;
1107ec681f3Smrg         VkImageLayout layout;
1117ec681f3Smrg         VkImageAspectFlags aspect;
1127ec681f3Smrg         bool optimal_tiling;
1137ec681f3Smrg         uint8_t fb_binds;
1147ec681f3Smrg      };
1157ec681f3Smrg   };
1167ec681f3Smrg   uint32_t sampler_binds[PIPE_SHADER_TYPES];
1177ec681f3Smrg   uint16_t image_bind_count[2]; //gfx, compute
1187ec681f3Smrg   uint16_t write_bind_count[2]; //gfx, compute
1197ec681f3Smrg   uint16_t bindless[2]; //tex, img
1207ec681f3Smrg   union {
1217ec681f3Smrg      uint16_t bind_count[2]; //gfx, compute
1227ec681f3Smrg      uint32_t all_binds;
1237ec681f3Smrg   };
1247ec681f3Smrg
1257ec681f3Smrg   union {
1267ec681f3Smrg      struct {
1277ec681f3Smrg         struct hash_table bufferview_cache;
1287ec681f3Smrg         simple_mtx_t bufferview_mtx;
1297ec681f3Smrg      };
1307ec681f3Smrg      struct {
1317ec681f3Smrg         struct hash_table surface_cache;
1327ec681f3Smrg         simple_mtx_t surface_mtx;
1337ec681f3Smrg      };
1347ec681f3Smrg   };
1357ec681f3Smrg
1367ec681f3Smrg   bool dmabuf_acquire;
1377ec681f3Smrg   struct sw_displaytarget *dt;
1387ec681f3Smrg   unsigned dt_stride;
1397ec681f3Smrg
1407ec681f3Smrg   uint8_t modifiers_count;
1417ec681f3Smrg   uint64_t *modifiers;
1427ec681f3Smrg};
1437ec681f3Smrg
1447ec681f3Smrgstruct zink_transfer {
1457ec681f3Smrg   struct threaded_transfer base;
1467ec681f3Smrg   struct pipe_resource *staging_res;
1477ec681f3Smrg   unsigned offset;
1487ec681f3Smrg   unsigned depthPitch;
1497ec681f3Smrg};
1507ec681f3Smrg
1517ec681f3Smrgstatic inline struct zink_resource *
1527ec681f3Smrgzink_resource(struct pipe_resource *r)
1537ec681f3Smrg{
1547ec681f3Smrg   return (struct zink_resource *)r;
1557ec681f3Smrg}
1567ec681f3Smrg
1577ec681f3Smrgbool
1587ec681f3Smrgzink_screen_resource_init(struct pipe_screen *pscreen);
1597ec681f3Smrg
1607ec681f3Smrgvoid
1617ec681f3Smrgzink_context_resource_init(struct pipe_context *pctx);
1627ec681f3Smrg
1637ec681f3Smrgvoid
1647ec681f3Smrgzink_get_depth_stencil_resources(struct pipe_resource *res,
1657ec681f3Smrg                                 struct zink_resource **out_z,
1667ec681f3Smrg                                 struct zink_resource **out_s);
1677ec681f3SmrgVkMappedMemoryRange
1687ec681f3Smrgzink_resource_init_mem_range(struct zink_screen *screen, struct zink_resource_object *obj, VkDeviceSize offset, VkDeviceSize size);
1697ec681f3Smrgvoid
1707ec681f3Smrgzink_resource_setup_transfer_layouts(struct zink_context *ctx, struct zink_resource *src, struct zink_resource *dst);
1717ec681f3Smrg
1727ec681f3Smrgvoid
1737ec681f3Smrgzink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_object *resource_object);
1747ec681f3Smrg
1757ec681f3Smrgvoid
1767ec681f3Smrgdebug_describe_zink_resource_object(char *buf, const struct zink_resource_object *ptr);
1777ec681f3Smrg
1787ec681f3Smrgstatic inline void
1797ec681f3Smrgzink_resource_object_reference(struct zink_screen *screen,
1807ec681f3Smrg                             struct zink_resource_object **dst,
1817ec681f3Smrg                             struct zink_resource_object *src)
1827ec681f3Smrg{
1837ec681f3Smrg   struct zink_resource_object *old_dst = dst ? *dst : NULL;
1847ec681f3Smrg
1857ec681f3Smrg   if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
1867ec681f3Smrg                                (debug_reference_descriptor)debug_describe_zink_resource_object))
1877ec681f3Smrg      zink_destroy_resource_object(screen, old_dst);
1887ec681f3Smrg   if (dst) *dst = src;
1897ec681f3Smrg}
1907ec681f3Smrg
1917ec681f3SmrgVkBuffer
1927ec681f3Smrgzink_resource_tmp_buffer(struct zink_screen *screen, struct zink_resource *res, unsigned offset_add, unsigned add_binds, unsigned *offset);
1937ec681f3Smrg
1947ec681f3Smrgbool
1957ec681f3Smrgzink_resource_object_init_storage(struct zink_context *ctx, struct zink_resource *res);
1967ec681f3Smrg
1977ec681f3Smrgstatic inline bool
1987ec681f3Smrgzink_resource_has_binds(const struct zink_resource *res)
1997ec681f3Smrg{
2007ec681f3Smrg   return res->all_binds > 0;
2017ec681f3Smrg}
2027ec681f3Smrg
2037ec681f3Smrg#ifndef __cplusplus
2047ec681f3Smrg#include "zink_bo.h"
2057ec681f3Smrg
2067ec681f3Smrgstatic inline bool
2077ec681f3Smrgzink_resource_usage_is_unflushed(const struct zink_resource *res)
2087ec681f3Smrg{
2097ec681f3Smrg   return zink_bo_has_unflushed_usage(res->obj->bo);
2107ec681f3Smrg}
2117ec681f3Smrg
2127ec681f3Smrgstatic inline bool
2137ec681f3Smrgzink_resource_usage_is_unflushed_write(const struct zink_resource *res)
2147ec681f3Smrg{
2157ec681f3Smrg   return zink_batch_usage_is_unflushed(res->obj->bo->writes);
2167ec681f3Smrg}
2177ec681f3Smrg
2187ec681f3Smrg
2197ec681f3Smrgstatic inline bool
2207ec681f3Smrgzink_resource_usage_matches(const struct zink_resource *res, const struct zink_batch_state *bs)
2217ec681f3Smrg{
2227ec681f3Smrg   return zink_bo_usage_matches(res->obj->bo, bs);
2237ec681f3Smrg}
2247ec681f3Smrg
2257ec681f3Smrgstatic inline bool
2267ec681f3Smrgzink_resource_has_usage(const struct zink_resource *res)
2277ec681f3Smrg{
2287ec681f3Smrg   return zink_bo_has_usage(res->obj->bo);
2297ec681f3Smrg}
2307ec681f3Smrg
2317ec681f3Smrgstatic inline bool
2327ec681f3Smrgzink_resource_has_unflushed_usage(const struct zink_resource *res)
2337ec681f3Smrg{
2347ec681f3Smrg   return zink_bo_has_unflushed_usage(res->obj->bo);
2357ec681f3Smrg}
2367ec681f3Smrg
2377ec681f3Smrgstatic inline bool
2387ec681f3Smrgzink_resource_usage_check_completion(struct zink_screen *screen, struct zink_resource *res, enum zink_resource_access access)
2397ec681f3Smrg{
2407ec681f3Smrg   return zink_bo_usage_check_completion(screen, res->obj->bo, access);
2417ec681f3Smrg}
2427ec681f3Smrg
2437ec681f3Smrgstatic inline void
2447ec681f3Smrgzink_resource_usage_wait(struct zink_context *ctx, struct zink_resource *res, enum zink_resource_access access)
2457ec681f3Smrg{
2467ec681f3Smrg   zink_bo_usage_wait(ctx, res->obj->bo, access);
2477ec681f3Smrg}
2487ec681f3Smrg
2497ec681f3Smrgstatic inline void
2507ec681f3Smrgzink_resource_usage_set(struct zink_resource *res, struct zink_batch_state *bs, bool write)
2517ec681f3Smrg{
2527ec681f3Smrg   zink_bo_usage_set(res->obj->bo, bs, write);
2537ec681f3Smrg}
2547ec681f3Smrg
2557ec681f3Smrgstatic inline bool
2567ec681f3Smrgzink_resource_object_usage_unset(struct zink_resource_object *obj, struct zink_batch_state *bs)
2577ec681f3Smrg{
2587ec681f3Smrg   return zink_bo_usage_unset(obj->bo, bs);
2597ec681f3Smrg}
2607ec681f3Smrg
2617ec681f3Smrg#endif
2627ec681f3Smrg#endif
263