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 uint16_t clean_mask; 56 struct virgl_hw_res *hw_res; 57 struct virgl_resource_metadata metadata; 58 59 /* For PIPE_BUFFER only. Data outside of this range are uninitialized. */ 60 struct util_range valid_buffer_range; 61 62 /* This mask indicates where the resource has been bound to, excluding 63 * pipe_surface binds. 64 * 65 * This is more accurate than pipe_resource::bind. Besides, 66 * pipe_resource::bind can be 0 with direct state access, and is not 67 * usable. 68 */ 69 unsigned bind_history; 70 uint32_t blob_mem; 71}; 72 73struct virgl_transfer { 74 struct pipe_transfer base; 75 uint32_t offset, l_stride; 76 struct util_range range; 77 struct list_head queue_link; 78 struct pipe_transfer *resolve_transfer; 79 80 struct virgl_hw_res *hw_res; 81 void *hw_res_map; 82 /* If not NULL, denotes that this is a copy transfer, i.e., 83 * that the transfer source data should be taken from this 84 * resource instead of the original transfer resource. 85 */ 86 struct virgl_hw_res *copy_src_hw_res; 87 /* The offset in the copy source resource to copy data from. */ 88 uint32_t copy_src_offset; 89}; 90 91void virgl_resource_destroy(struct pipe_screen *screen, 92 struct pipe_resource *resource); 93 94void virgl_init_screen_resource_functions(struct pipe_screen *screen); 95 96void virgl_init_context_resource_functions(struct pipe_context *ctx); 97 98void virgl_texture_init(struct virgl_resource *res); 99 100static inline struct virgl_resource *virgl_resource(struct pipe_resource *r) 101{ 102 return (struct virgl_resource *)r; 103} 104 105static inline struct virgl_transfer *virgl_transfer(struct pipe_transfer *trans) 106{ 107 return (struct virgl_transfer *)trans; 108} 109 110void virgl_buffer_transfer_flush_region(struct pipe_context *ctx, 111 struct pipe_transfer *transfer, 112 const struct pipe_box *box); 113 114void virgl_buffer_transfer_unmap(struct pipe_context *ctx, 115 struct pipe_transfer *transfer); 116 117void virgl_buffer_init(struct virgl_resource *res); 118 119static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs, 120 unsigned pbind) 121{ 122 unsigned outbind = 0; 123 if (pbind & PIPE_BIND_DEPTH_STENCIL) 124 outbind |= VIRGL_BIND_DEPTH_STENCIL; 125 if (pbind & PIPE_BIND_RENDER_TARGET) 126 outbind |= VIRGL_BIND_RENDER_TARGET; 127 if (pbind & PIPE_BIND_SAMPLER_VIEW) 128 outbind |= VIRGL_BIND_SAMPLER_VIEW; 129 if (pbind & PIPE_BIND_VERTEX_BUFFER) 130 outbind |= VIRGL_BIND_VERTEX_BUFFER; 131 if (pbind & PIPE_BIND_INDEX_BUFFER) 132 outbind |= VIRGL_BIND_INDEX_BUFFER; 133 if (pbind & PIPE_BIND_CONSTANT_BUFFER) 134 outbind |= VIRGL_BIND_CONSTANT_BUFFER; 135 if (pbind & PIPE_BIND_DISPLAY_TARGET) 136 outbind |= VIRGL_BIND_DISPLAY_TARGET; 137 if (pbind & PIPE_BIND_STREAM_OUTPUT) 138 outbind |= VIRGL_BIND_STREAM_OUTPUT; 139 if (pbind & PIPE_BIND_CURSOR) 140 outbind |= VIRGL_BIND_CURSOR; 141 if (pbind & PIPE_BIND_CUSTOM) 142 outbind |= VIRGL_BIND_CUSTOM; 143 if (pbind & PIPE_BIND_SCANOUT) 144 outbind |= VIRGL_BIND_SCANOUT; 145 if (pbind & PIPE_BIND_SHARED) 146 outbind |= VIRGL_BIND_SHARED; 147 if (pbind & PIPE_BIND_SHADER_BUFFER) 148 outbind |= VIRGL_BIND_SHADER_BUFFER; 149 if (pbind & PIPE_BIND_QUERY_BUFFER) 150 outbind |= VIRGL_BIND_QUERY_BUFFER; 151 if (pbind & PIPE_BIND_COMMAND_ARGS_BUFFER) 152 if (vs->caps.caps.v2.capability_bits & VIRGL_CAP_BIND_COMMAND_ARGS) 153 outbind |= VIRGL_BIND_COMMAND_ARGS; 154 155 /* Staging resources should only be created directly through the winsys, 156 * not using pipe_resources. 157 */ 158 assert(!(outbind & VIRGL_BIND_STAGING)); 159 160 return outbind; 161} 162 163static inline unsigned pipe_to_virgl_flags(const struct virgl_screen *vs, 164 unsigned pflags) 165{ 166 unsigned out_flags = 0; 167 if (pflags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) 168 out_flags |= VIRGL_RESOURCE_FLAG_MAP_PERSISTENT; 169 170 if (pflags & PIPE_RESOURCE_FLAG_MAP_COHERENT) 171 out_flags |= VIRGL_RESOURCE_FLAG_MAP_COHERENT; 172 173 return out_flags; 174} 175 176void * 177virgl_resource_transfer_map(struct pipe_context *ctx, 178 struct pipe_resource *resource, 179 unsigned level, 180 unsigned usage, 181 const struct pipe_box *box, 182 struct pipe_transfer **transfer); 183 184struct virgl_transfer * 185virgl_resource_create_transfer(struct virgl_context *vctx, 186 struct pipe_resource *pres, 187 const struct virgl_resource_metadata *metadata, 188 unsigned level, unsigned usage, 189 const struct pipe_box *box); 190 191void virgl_resource_destroy_transfer(struct virgl_context *vctx, 192 struct virgl_transfer *trans); 193 194void virgl_resource_destroy(struct pipe_screen *screen, 195 struct pipe_resource *resource); 196 197bool virgl_resource_get_handle(struct pipe_screen *screen, 198 struct pipe_context *context, 199 struct pipe_resource *resource, 200 struct winsys_handle *whandle, 201 unsigned usage); 202 203void virgl_resource_dirty(struct virgl_resource *res, uint32_t level); 204 205void *virgl_texture_transfer_map(struct pipe_context *ctx, 206 struct pipe_resource *resource, 207 unsigned level, 208 unsigned usage, 209 const struct pipe_box *box, 210 struct pipe_transfer **transfer); 211 212void virgl_texture_transfer_unmap(struct pipe_context *ctx, 213 struct pipe_transfer *transfer); 214 215#endif 216