101e04c3fSmrg/*
201e04c3fSmrg * Copyright 2014, 2015 Red Hat.
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * on the rights to use, copy, modify, merge, publish, distribute, sub
801e04c3fSmrg * license, and/or sell copies of the Software, and to permit persons to whom
901e04c3fSmrg * the Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
1901e04c3fSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2001e04c3fSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2101e04c3fSmrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#ifndef VIRGL_RESOURCE_H
2501e04c3fSmrg#define VIRGL_RESOURCE_H
2601e04c3fSmrg
2701e04c3fSmrg#include "util/u_resource.h"
2801e04c3fSmrg#include "util/u_range.h"
2901e04c3fSmrg#include "util/list.h"
3001e04c3fSmrg#include "util/u_transfer.h"
3101e04c3fSmrg
327ec681f3Smrg#include "virtio-gpu/virgl_hw.h"
339f464c52Smaya#include "virgl_screen.h"
3401e04c3fSmrg#define VR_MAX_TEXTURE_2D_LEVELS 15
3501e04c3fSmrg
367ec681f3Smrg#define VIRGL_BLOB_MEM_GUEST 1
377ec681f3Smrg#define VIRGL_BLOB_MEM_HOST3D 2
387ec681f3Smrg#define VIRGL_BLOB_MEM_HOST3D_GUEST 3
397ec681f3Smrg
4001e04c3fSmrgstruct winsys_handle;
4101e04c3fSmrgstruct virgl_screen;
4201e04c3fSmrgstruct virgl_context;
4301e04c3fSmrg
449f464c52Smayastruct virgl_resource_metadata
459f464c52Smaya{
469f464c52Smaya   unsigned long level_offset[VR_MAX_TEXTURE_2D_LEVELS];
479f464c52Smaya   unsigned stride[VR_MAX_TEXTURE_2D_LEVELS];
489f464c52Smaya   unsigned layer_stride[VR_MAX_TEXTURE_2D_LEVELS];
497ec681f3Smrg   uint32_t plane, plane_offset, total_size;
507ec681f3Smrg   uint64_t modifier;
519f464c52Smaya};
529f464c52Smaya
5301e04c3fSmrgstruct virgl_resource {
547ec681f3Smrg   struct pipe_resource b;
559f464c52Smaya   uint16_t clean_mask;
5601e04c3fSmrg   struct virgl_hw_res *hw_res;
579f464c52Smaya   struct virgl_resource_metadata metadata;
587ec681f3Smrg
597ec681f3Smrg   /* For PIPE_BUFFER only.  Data outside of this range are uninitialized. */
607ec681f3Smrg   struct util_range valid_buffer_range;
617ec681f3Smrg
627ec681f3Smrg   /* This mask indicates where the resource has been bound to, excluding
637ec681f3Smrg    * pipe_surface binds.
647ec681f3Smrg    *
657ec681f3Smrg    * This is more accurate than pipe_resource::bind.  Besides,
667ec681f3Smrg    * pipe_resource::bind can be 0 with direct state access, and is not
677ec681f3Smrg    * usable.
687ec681f3Smrg    */
697ec681f3Smrg   unsigned bind_history;
707ec681f3Smrg   uint32_t blob_mem;
7101e04c3fSmrg};
7201e04c3fSmrg
7301e04c3fSmrgstruct virgl_transfer {
7401e04c3fSmrg   struct pipe_transfer base;
759f464c52Smaya   uint32_t offset, l_stride;
769f464c52Smaya   struct util_range range;
779f464c52Smaya   struct list_head queue_link;
789f464c52Smaya   struct pipe_transfer *resolve_transfer;
797ec681f3Smrg
807ec681f3Smrg   struct virgl_hw_res *hw_res;
819f464c52Smaya   void *hw_res_map;
827ec681f3Smrg   /* If not NULL, denotes that this is a copy transfer, i.e.,
837ec681f3Smrg    * that the transfer source data should be taken from this
847ec681f3Smrg    * resource instead of the original transfer resource.
857ec681f3Smrg    */
867ec681f3Smrg   struct virgl_hw_res *copy_src_hw_res;
877ec681f3Smrg   /* The offset in the copy source resource to copy data from. */
887ec681f3Smrg   uint32_t copy_src_offset;
8901e04c3fSmrg};
9001e04c3fSmrg
9101e04c3fSmrgvoid virgl_resource_destroy(struct pipe_screen *screen,
9201e04c3fSmrg                            struct pipe_resource *resource);
9301e04c3fSmrg
9401e04c3fSmrgvoid virgl_init_screen_resource_functions(struct pipe_screen *screen);
9501e04c3fSmrg
9601e04c3fSmrgvoid virgl_init_context_resource_functions(struct pipe_context *ctx);
9701e04c3fSmrg
989f464c52Smayavoid virgl_texture_init(struct virgl_resource *res);
9901e04c3fSmrg
10001e04c3fSmrgstatic inline struct virgl_resource *virgl_resource(struct pipe_resource *r)
10101e04c3fSmrg{
10201e04c3fSmrg   return (struct virgl_resource *)r;
10301e04c3fSmrg}
10401e04c3fSmrg
10501e04c3fSmrgstatic inline struct virgl_transfer *virgl_transfer(struct pipe_transfer *trans)
10601e04c3fSmrg{
10701e04c3fSmrg   return (struct virgl_transfer *)trans;
10801e04c3fSmrg}
10901e04c3fSmrg
1107ec681f3Smrgvoid virgl_buffer_transfer_flush_region(struct pipe_context *ctx,
1117ec681f3Smrg                                        struct pipe_transfer *transfer,
1127ec681f3Smrg                                        const struct pipe_box *box);
1137ec681f3Smrg
1147ec681f3Smrgvoid virgl_buffer_transfer_unmap(struct pipe_context *ctx,
1157ec681f3Smrg                                 struct pipe_transfer *transfer);
1167ec681f3Smrg
1179f464c52Smayavoid virgl_buffer_init(struct virgl_resource *res);
11801e04c3fSmrg
1197ec681f3Smrgstatic inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs,
1207ec681f3Smrg                                          unsigned pbind)
12101e04c3fSmrg{
12201e04c3fSmrg   unsigned outbind = 0;
12301e04c3fSmrg   if (pbind & PIPE_BIND_DEPTH_STENCIL)
12401e04c3fSmrg      outbind |= VIRGL_BIND_DEPTH_STENCIL;
12501e04c3fSmrg   if (pbind & PIPE_BIND_RENDER_TARGET)
12601e04c3fSmrg      outbind |= VIRGL_BIND_RENDER_TARGET;
12701e04c3fSmrg   if (pbind & PIPE_BIND_SAMPLER_VIEW)
12801e04c3fSmrg      outbind |= VIRGL_BIND_SAMPLER_VIEW;
12901e04c3fSmrg   if (pbind & PIPE_BIND_VERTEX_BUFFER)
13001e04c3fSmrg      outbind |= VIRGL_BIND_VERTEX_BUFFER;
13101e04c3fSmrg   if (pbind & PIPE_BIND_INDEX_BUFFER)
13201e04c3fSmrg      outbind |= VIRGL_BIND_INDEX_BUFFER;
13301e04c3fSmrg   if (pbind & PIPE_BIND_CONSTANT_BUFFER)
13401e04c3fSmrg      outbind |= VIRGL_BIND_CONSTANT_BUFFER;
13501e04c3fSmrg   if (pbind & PIPE_BIND_DISPLAY_TARGET)
13601e04c3fSmrg      outbind |= VIRGL_BIND_DISPLAY_TARGET;
13701e04c3fSmrg   if (pbind & PIPE_BIND_STREAM_OUTPUT)
13801e04c3fSmrg      outbind |= VIRGL_BIND_STREAM_OUTPUT;
13901e04c3fSmrg   if (pbind & PIPE_BIND_CURSOR)
14001e04c3fSmrg      outbind |= VIRGL_BIND_CURSOR;
14101e04c3fSmrg   if (pbind & PIPE_BIND_CUSTOM)
14201e04c3fSmrg      outbind |= VIRGL_BIND_CUSTOM;
14301e04c3fSmrg   if (pbind & PIPE_BIND_SCANOUT)
14401e04c3fSmrg      outbind |= VIRGL_BIND_SCANOUT;
1457ec681f3Smrg   if (pbind & PIPE_BIND_SHARED)
1467ec681f3Smrg      outbind |= VIRGL_BIND_SHARED;
14701e04c3fSmrg   if (pbind & PIPE_BIND_SHADER_BUFFER)
14801e04c3fSmrg      outbind |= VIRGL_BIND_SHADER_BUFFER;
1499f464c52Smaya   if (pbind & PIPE_BIND_QUERY_BUFFER)
1509f464c52Smaya      outbind |= VIRGL_BIND_QUERY_BUFFER;
1519f464c52Smaya   if (pbind & PIPE_BIND_COMMAND_ARGS_BUFFER)
1529f464c52Smaya      if (vs->caps.caps.v2.capability_bits & VIRGL_CAP_BIND_COMMAND_ARGS)
1539f464c52Smaya         outbind |= VIRGL_BIND_COMMAND_ARGS;
1547ec681f3Smrg
1557ec681f3Smrg   /* Staging resources should only be created directly through the winsys,
1567ec681f3Smrg    * not using pipe_resources.
1577ec681f3Smrg    */
1587ec681f3Smrg   assert(!(outbind & VIRGL_BIND_STAGING));
1597ec681f3Smrg
16001e04c3fSmrg   return outbind;
16101e04c3fSmrg}
16201e04c3fSmrg
1637ec681f3Smrgstatic inline unsigned pipe_to_virgl_flags(const struct virgl_screen *vs,
1647ec681f3Smrg                                           unsigned pflags)
1657ec681f3Smrg{
1667ec681f3Smrg   unsigned out_flags = 0;
1677ec681f3Smrg   if (pflags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
1687ec681f3Smrg      out_flags |= VIRGL_RESOURCE_FLAG_MAP_PERSISTENT;
1697ec681f3Smrg
1707ec681f3Smrg   if (pflags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
1717ec681f3Smrg      out_flags |= VIRGL_RESOURCE_FLAG_MAP_COHERENT;
1729f464c52Smaya
1737ec681f3Smrg   return out_flags;
1747ec681f3Smrg}
1757ec681f3Smrg
1767ec681f3Smrgvoid *
1777ec681f3Smrgvirgl_resource_transfer_map(struct pipe_context *ctx,
1787ec681f3Smrg                            struct pipe_resource *resource,
1797ec681f3Smrg                            unsigned level,
1807ec681f3Smrg                            unsigned usage,
1817ec681f3Smrg                            const struct pipe_box *box,
1827ec681f3Smrg                            struct pipe_transfer **transfer);
1839f464c52Smaya
1849f464c52Smayastruct virgl_transfer *
1857ec681f3Smrgvirgl_resource_create_transfer(struct virgl_context *vctx,
1869f464c52Smaya                               struct pipe_resource *pres,
1879f464c52Smaya                               const struct virgl_resource_metadata *metadata,
1889f464c52Smaya                               unsigned level, unsigned usage,
1899f464c52Smaya                               const struct pipe_box *box);
1909f464c52Smaya
1917ec681f3Smrgvoid virgl_resource_destroy_transfer(struct virgl_context *vctx,
1929f464c52Smaya                                     struct virgl_transfer *trans);
1939f464c52Smaya
1949f464c52Smayavoid virgl_resource_destroy(struct pipe_screen *screen,
1959f464c52Smaya                            struct pipe_resource *resource);
1969f464c52Smaya
1977ec681f3Smrgbool virgl_resource_get_handle(struct pipe_screen *screen,
1987ec681f3Smrg                               struct pipe_context *context,
1997ec681f3Smrg                               struct pipe_resource *resource,
2007ec681f3Smrg                               struct winsys_handle *whandle,
2017ec681f3Smrg                               unsigned usage);
2029f464c52Smaya
2039f464c52Smayavoid virgl_resource_dirty(struct virgl_resource *res, uint32_t level);
2049f464c52Smaya
2057ec681f3Smrgvoid *virgl_texture_transfer_map(struct pipe_context *ctx,
2067ec681f3Smrg                                 struct pipe_resource *resource,
2077ec681f3Smrg                                 unsigned level,
2087ec681f3Smrg                                 unsigned usage,
2097ec681f3Smrg                                 const struct pipe_box *box,
2107ec681f3Smrg                                 struct pipe_transfer **transfer);
2117ec681f3Smrg
2127ec681f3Smrgvoid virgl_texture_transfer_unmap(struct pipe_context *ctx,
2137ec681f3Smrg                                  struct pipe_transfer *transfer);
2147ec681f3Smrg
21501e04c3fSmrg#endif
216