1/* 2 * Copyright 2014, 2015 Red Hat. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24#ifndef VIRGL_RESOURCE_H 25#define VIRGL_RESOURCE_H 26 27#include "util/u_resource.h" 28#include "util/u_range.h" 29#include "util/list.h" 30#include "util/u_transfer.h" 31 32#include "virtio-gpu/virgl_hw.h" 33#include "virgl_screen.h" 34#define VR_MAX_TEXTURE_2D_LEVELS 15 35 36#define VIRGL_BLOB_MEM_GUEST 1 37#define VIRGL_BLOB_MEM_HOST3D 2 38#define VIRGL_BLOB_MEM_HOST3D_GUEST 3 39 40struct winsys_handle; 41struct virgl_screen; 42struct virgl_context; 43 44struct virgl_resource_metadata 45{ 46 unsigned long level_offset[VR_MAX_TEXTURE_2D_LEVELS]; 47 unsigned stride[VR_MAX_TEXTURE_2D_LEVELS]; 48 unsigned layer_stride[VR_MAX_TEXTURE_2D_LEVELS]; 49 uint32_t plane, plane_offset, total_size; 50 uint64_t modifier; 51}; 52 53struct virgl_resource { 54 struct pipe_resource b; 55 struct virgl_hw_res *hw_res; 56 struct virgl_resource_metadata metadata; 57 58 /* For PIPE_BUFFER only. Data outside of this range are uninitialized. */ 59 struct util_range valid_buffer_range; 60 61 /* This mask indicates where the resource has been bound to, excluding 62 * pipe_surface binds. 63 * 64 * This is more accurate than pipe_resource::bind. Besides, 65 * pipe_resource::bind can be 0 with direct state access, and is not 66 * usable. 67 */ 68 unsigned bind_history; 69 uint32_t blob_mem; 70 71 uint16_t clean_mask; 72 uint16_t use_staging : 1; 73 uint16_t reserved : 15; 74}; 75 76struct virgl_transfer { 77 struct pipe_transfer base; 78 uint32_t offset, l_stride; 79 struct util_range range; 80 struct list_head queue_link; 81 struct pipe_transfer *resolve_transfer; 82 83 struct virgl_hw_res *hw_res; 84 void *hw_res_map; 85 /* If not NULL, denotes that this is a copy transfer, i.e., 86 * that the transfer source data should be taken from this 87 * resource instead of the original transfer resource. 88 */ 89 struct virgl_hw_res *copy_src_hw_res; 90 /* The offset in the copy source resource to copy data from. */ 91 uint32_t copy_src_offset; 92 /* copy transfers can be performed to and from host */ 93 uint32_t direction; 94}; 95 96void virgl_resource_destroy(struct pipe_screen *screen, 97 struct pipe_resource *resource); 98 99void virgl_init_screen_resource_functions(struct pipe_screen *screen); 100 101void virgl_init_context_resource_functions(struct pipe_context *ctx); 102 103void virgl_texture_init(struct virgl_resource *res); 104 105static inline struct virgl_resource *virgl_resource(struct pipe_resource *r) 106{ 107 return (struct virgl_resource *)r; 108} 109 110static inline struct virgl_transfer *virgl_transfer(struct pipe_transfer *trans) 111{ 112 return (struct virgl_transfer *)trans; 113} 114 115void virgl_buffer_transfer_flush_region(struct pipe_context *ctx, 116 struct pipe_transfer *transfer, 117 const struct pipe_box *box); 118 119void virgl_buffer_transfer_unmap(struct pipe_context *ctx, 120 struct pipe_transfer *transfer); 121 122void virgl_buffer_init(struct virgl_resource *res); 123 124static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs, 125 unsigned pbind) 126{ 127 unsigned outbind = 0; 128 if (pbind & PIPE_BIND_DEPTH_STENCIL) 129 outbind |= VIRGL_BIND_DEPTH_STENCIL; 130 if (pbind & PIPE_BIND_RENDER_TARGET) 131 outbind |= VIRGL_BIND_RENDER_TARGET; 132 if (pbind & PIPE_BIND_SAMPLER_VIEW) 133 outbind |= VIRGL_BIND_SAMPLER_VIEW; 134 if (pbind & PIPE_BIND_VERTEX_BUFFER) 135 outbind |= VIRGL_BIND_VERTEX_BUFFER; 136 if (pbind & PIPE_BIND_INDEX_BUFFER) 137 outbind |= VIRGL_BIND_INDEX_BUFFER; 138 if (pbind & PIPE_BIND_CONSTANT_BUFFER) 139 outbind |= VIRGL_BIND_CONSTANT_BUFFER; 140 if (pbind & PIPE_BIND_DISPLAY_TARGET) 141 outbind |= VIRGL_BIND_DISPLAY_TARGET; 142 if (pbind & PIPE_BIND_STREAM_OUTPUT) 143 outbind |= VIRGL_BIND_STREAM_OUTPUT; 144 if (pbind & PIPE_BIND_CURSOR) 145 outbind |= VIRGL_BIND_CURSOR; 146 if (pbind & PIPE_BIND_CUSTOM) 147 outbind |= VIRGL_BIND_CUSTOM; 148 if (pbind & PIPE_BIND_SCANOUT) 149 outbind |= VIRGL_BIND_SCANOUT; 150 if (pbind & PIPE_BIND_SHARED) 151 outbind |= VIRGL_BIND_SHARED; 152 if (pbind & PIPE_BIND_SHADER_BUFFER) 153 outbind |= VIRGL_BIND_SHADER_BUFFER; 154 if (pbind & PIPE_BIND_QUERY_BUFFER) 155 outbind |= VIRGL_BIND_QUERY_BUFFER; 156 if (pbind & PIPE_BIND_COMMAND_ARGS_BUFFER) 157 if (vs->caps.caps.v2.capability_bits & VIRGL_CAP_BIND_COMMAND_ARGS) 158 outbind |= VIRGL_BIND_COMMAND_ARGS; 159 160 /* Staging resources should only be created directly through the winsys, 161 * not using pipe_resources. 162 */ 163 assert(!(outbind & VIRGL_BIND_STAGING)); 164 165 return outbind; 166} 167 168static inline unsigned pipe_to_virgl_flags(const struct virgl_screen *vs, 169 unsigned pflags) 170{ 171 unsigned out_flags = 0; 172 if (pflags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) 173 out_flags |= VIRGL_RESOURCE_FLAG_MAP_PERSISTENT; 174 175 if (pflags & PIPE_RESOURCE_FLAG_MAP_COHERENT) 176 out_flags |= VIRGL_RESOURCE_FLAG_MAP_COHERENT; 177 178 return out_flags; 179} 180 181void * 182virgl_resource_transfer_map(struct pipe_context *ctx, 183 struct pipe_resource *resource, 184 unsigned level, 185 unsigned usage, 186 const struct pipe_box *box, 187 struct pipe_transfer **transfer); 188 189struct virgl_transfer * 190virgl_resource_create_transfer(struct virgl_context *vctx, 191 struct pipe_resource *pres, 192 const struct virgl_resource_metadata *metadata, 193 unsigned level, unsigned usage, 194 const struct pipe_box *box); 195 196void virgl_resource_destroy_transfer(struct virgl_context *vctx, 197 struct virgl_transfer *trans); 198 199void virgl_resource_destroy(struct pipe_screen *screen, 200 struct pipe_resource *resource); 201 202bool virgl_resource_get_handle(struct pipe_screen *screen, 203 struct pipe_context *context, 204 struct pipe_resource *resource, 205 struct winsys_handle *whandle, 206 unsigned usage); 207 208void virgl_resource_dirty(struct virgl_resource *res, uint32_t level); 209 210void *virgl_texture_transfer_map(struct pipe_context *ctx, 211 struct pipe_resource *resource, 212 unsigned level, 213 unsigned usage, 214 const struct pipe_box *box, 215 struct pipe_transfer **transfer); 216 217void virgl_texture_transfer_unmap(struct pipe_context *ctx, 218 struct pipe_transfer *transfer); 219 220#endif 221