1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2009-2015 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "svga_cmd.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "util/u_debug.h" 30bf215546Sopenharmony_ci#include "util/u_memory.h" 31bf215546Sopenharmony_ci#include "util/u_debug_stack.h" 32bf215546Sopenharmony_ci#include "util/u_debug_flush.h" 33bf215546Sopenharmony_ci#include "util/u_hash_table.h" 34bf215546Sopenharmony_ci#include "pipebuffer/pb_buffer.h" 35bf215546Sopenharmony_ci#include "pipebuffer/pb_validate.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "svga_winsys.h" 38bf215546Sopenharmony_ci#include "vmw_context.h" 39bf215546Sopenharmony_ci#include "vmw_screen.h" 40bf215546Sopenharmony_ci#include "vmw_buffer.h" 41bf215546Sopenharmony_ci#include "vmw_surface.h" 42bf215546Sopenharmony_ci#include "vmw_fence.h" 43bf215546Sopenharmony_ci#include "vmw_shader.h" 44bf215546Sopenharmony_ci#include "vmw_query.h" 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci#define VMW_COMMAND_SIZE (64*1024) 47bf215546Sopenharmony_ci#define VMW_SURFACE_RELOCS (1024) 48bf215546Sopenharmony_ci#define VMW_SHADER_RELOCS (1024) 49bf215546Sopenharmony_ci#define VMW_REGION_RELOCS (512) 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci#define VMW_MUST_FLUSH_STACK 8 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci/* 54bf215546Sopenharmony_ci * A factor applied to the maximum mob memory size to determine 55bf215546Sopenharmony_ci * the optimial time to preemptively flush the command buffer. 56bf215546Sopenharmony_ci * The constant is based on some performance trials with SpecViewperf. 57bf215546Sopenharmony_ci */ 58bf215546Sopenharmony_ci#define VMW_MAX_MOB_MEM_FACTOR 2 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci/* 61bf215546Sopenharmony_ci * A factor applied to the maximum surface memory size to determine 62bf215546Sopenharmony_ci * the optimial time to preemptively flush the command buffer. 63bf215546Sopenharmony_ci * The constant is based on some performance trials with SpecViewperf. 64bf215546Sopenharmony_ci */ 65bf215546Sopenharmony_ci#define VMW_MAX_SURF_MEM_FACTOR 2 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_cistruct vmw_buffer_relocation 70bf215546Sopenharmony_ci{ 71bf215546Sopenharmony_ci struct pb_buffer *buffer; 72bf215546Sopenharmony_ci boolean is_mob; 73bf215546Sopenharmony_ci uint32 offset; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci union { 76bf215546Sopenharmony_ci struct { 77bf215546Sopenharmony_ci struct SVGAGuestPtr *where; 78bf215546Sopenharmony_ci } region; 79bf215546Sopenharmony_ci struct { 80bf215546Sopenharmony_ci SVGAMobId *id; 81bf215546Sopenharmony_ci uint32 *offset_into_mob; 82bf215546Sopenharmony_ci } mob; 83bf215546Sopenharmony_ci }; 84bf215546Sopenharmony_ci}; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_cistruct vmw_ctx_validate_item { 87bf215546Sopenharmony_ci union { 88bf215546Sopenharmony_ci struct vmw_svga_winsys_surface *vsurf; 89bf215546Sopenharmony_ci struct vmw_svga_winsys_shader *vshader; 90bf215546Sopenharmony_ci }; 91bf215546Sopenharmony_ci boolean referenced; 92bf215546Sopenharmony_ci}; 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_cistruct vmw_svga_winsys_context 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci struct svga_winsys_context base; 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci struct vmw_winsys_screen *vws; 99bf215546Sopenharmony_ci struct hash_table *hash; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci#ifdef DEBUG 102bf215546Sopenharmony_ci boolean must_flush; 103bf215546Sopenharmony_ci struct debug_stack_frame must_flush_stack[VMW_MUST_FLUSH_STACK]; 104bf215546Sopenharmony_ci struct debug_flush_ctx *fctx; 105bf215546Sopenharmony_ci#endif 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci struct { 108bf215546Sopenharmony_ci uint8_t buffer[VMW_COMMAND_SIZE]; 109bf215546Sopenharmony_ci uint32_t size; 110bf215546Sopenharmony_ci uint32_t used; 111bf215546Sopenharmony_ci uint32_t reserved; 112bf215546Sopenharmony_ci } command; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci struct { 115bf215546Sopenharmony_ci struct vmw_ctx_validate_item items[VMW_SURFACE_RELOCS]; 116bf215546Sopenharmony_ci uint32_t size; 117bf215546Sopenharmony_ci uint32_t used; 118bf215546Sopenharmony_ci uint32_t staged; 119bf215546Sopenharmony_ci uint32_t reserved; 120bf215546Sopenharmony_ci } surface; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci struct { 123bf215546Sopenharmony_ci struct vmw_buffer_relocation relocs[VMW_REGION_RELOCS]; 124bf215546Sopenharmony_ci uint32_t size; 125bf215546Sopenharmony_ci uint32_t used; 126bf215546Sopenharmony_ci uint32_t staged; 127bf215546Sopenharmony_ci uint32_t reserved; 128bf215546Sopenharmony_ci } region; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci struct { 131bf215546Sopenharmony_ci struct vmw_ctx_validate_item items[VMW_SHADER_RELOCS]; 132bf215546Sopenharmony_ci uint32_t size; 133bf215546Sopenharmony_ci uint32_t used; 134bf215546Sopenharmony_ci uint32_t staged; 135bf215546Sopenharmony_ci uint32_t reserved; 136bf215546Sopenharmony_ci } shader; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci struct pb_validate *validate; 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci /** 141bf215546Sopenharmony_ci * The amount of surface, GMR or MOB memory that is referred by the commands 142bf215546Sopenharmony_ci * currently batched in the context command buffer. 143bf215546Sopenharmony_ci */ 144bf215546Sopenharmony_ci uint64_t seen_surfaces; 145bf215546Sopenharmony_ci uint64_t seen_regions; 146bf215546Sopenharmony_ci uint64_t seen_mobs; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci /** 149bf215546Sopenharmony_ci * Whether this context should fail to reserve more commands, not because it 150bf215546Sopenharmony_ci * ran out of command space, but because a substantial ammount of GMR was 151bf215546Sopenharmony_ci * referred. 152bf215546Sopenharmony_ci */ 153bf215546Sopenharmony_ci boolean preemptive_flush; 154bf215546Sopenharmony_ci}; 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_cistatic inline struct vmw_svga_winsys_context * 158bf215546Sopenharmony_civmw_svga_winsys_context(struct svga_winsys_context *swc) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci assert(swc); 161bf215546Sopenharmony_ci return (struct vmw_svga_winsys_context *)swc; 162bf215546Sopenharmony_ci} 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_cistatic inline enum pb_usage_flags 166bf215546Sopenharmony_civmw_translate_to_pb_flags(unsigned flags) 167bf215546Sopenharmony_ci{ 168bf215546Sopenharmony_ci enum pb_usage_flags f = 0; 169bf215546Sopenharmony_ci if (flags & SVGA_RELOC_READ) 170bf215546Sopenharmony_ci f |= PB_USAGE_GPU_READ; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci if (flags & SVGA_RELOC_WRITE) 173bf215546Sopenharmony_ci f |= PB_USAGE_GPU_WRITE; 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci return f; 176bf215546Sopenharmony_ci} 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_cistatic enum pipe_error 179bf215546Sopenharmony_civmw_swc_flush(struct svga_winsys_context *swc, 180bf215546Sopenharmony_ci struct pipe_fence_handle **pfence) 181bf215546Sopenharmony_ci{ 182bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 183bf215546Sopenharmony_ci struct vmw_winsys_screen *vws = vswc->vws; 184bf215546Sopenharmony_ci struct pipe_fence_handle *fence = NULL; 185bf215546Sopenharmony_ci unsigned i; 186bf215546Sopenharmony_ci enum pipe_error ret; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci /* 189bf215546Sopenharmony_ci * If we hit a retry, lock the mutex and retry immediately. 190bf215546Sopenharmony_ci * If we then still hit a retry, sleep until another thread 191bf215546Sopenharmony_ci * wakes us up after it has released its buffers from the 192bf215546Sopenharmony_ci * validate list. 193bf215546Sopenharmony_ci * 194bf215546Sopenharmony_ci * If we hit another error condition, we still need to broadcast since 195bf215546Sopenharmony_ci * pb_validate_validate releases validated buffers in its error path. 196bf215546Sopenharmony_ci */ 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci ret = pb_validate_validate(vswc->validate); 199bf215546Sopenharmony_ci if (ret != PIPE_OK) { 200bf215546Sopenharmony_ci mtx_lock(&vws->cs_mutex); 201bf215546Sopenharmony_ci while (ret == PIPE_ERROR_RETRY) { 202bf215546Sopenharmony_ci ret = pb_validate_validate(vswc->validate); 203bf215546Sopenharmony_ci if (ret == PIPE_ERROR_RETRY) { 204bf215546Sopenharmony_ci cnd_wait(&vws->cs_cond, &vws->cs_mutex); 205bf215546Sopenharmony_ci } 206bf215546Sopenharmony_ci } 207bf215546Sopenharmony_ci if (ret != PIPE_OK) { 208bf215546Sopenharmony_ci cnd_broadcast(&vws->cs_cond); 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci mtx_unlock(&vws->cs_mutex); 211bf215546Sopenharmony_ci } 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci assert(ret == PIPE_OK); 214bf215546Sopenharmony_ci if(ret == PIPE_OK) { 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci /* Apply relocations */ 217bf215546Sopenharmony_ci for(i = 0; i < vswc->region.used; ++i) { 218bf215546Sopenharmony_ci struct vmw_buffer_relocation *reloc = &vswc->region.relocs[i]; 219bf215546Sopenharmony_ci struct SVGAGuestPtr ptr; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci if(!vmw_gmr_bufmgr_region_ptr(reloc->buffer, &ptr)) 222bf215546Sopenharmony_ci assert(0); 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci ptr.offset += reloc->offset; 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci if (reloc->is_mob) { 227bf215546Sopenharmony_ci if (reloc->mob.id) 228bf215546Sopenharmony_ci *reloc->mob.id = ptr.gmrId; 229bf215546Sopenharmony_ci if (reloc->mob.offset_into_mob) 230bf215546Sopenharmony_ci *reloc->mob.offset_into_mob = ptr.offset; 231bf215546Sopenharmony_ci else { 232bf215546Sopenharmony_ci assert(ptr.offset == 0); 233bf215546Sopenharmony_ci } 234bf215546Sopenharmony_ci } else 235bf215546Sopenharmony_ci *reloc->region.where = ptr; 236bf215546Sopenharmony_ci } 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci if (vswc->command.used || pfence != NULL) 239bf215546Sopenharmony_ci vmw_ioctl_command(vws, 240bf215546Sopenharmony_ci vswc->base.cid, 241bf215546Sopenharmony_ci 0, 242bf215546Sopenharmony_ci vswc->command.buffer, 243bf215546Sopenharmony_ci vswc->command.used, 244bf215546Sopenharmony_ci &fence, 245bf215546Sopenharmony_ci vswc->base.imported_fence_fd, 246bf215546Sopenharmony_ci vswc->base.hints); 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci pb_validate_fence(vswc->validate, fence); 249bf215546Sopenharmony_ci mtx_lock(&vws->cs_mutex); 250bf215546Sopenharmony_ci cnd_broadcast(&vws->cs_cond); 251bf215546Sopenharmony_ci mtx_unlock(&vws->cs_mutex); 252bf215546Sopenharmony_ci } 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci vswc->command.used = 0; 255bf215546Sopenharmony_ci vswc->command.reserved = 0; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci for(i = 0; i < vswc->surface.used + vswc->surface.staged; ++i) { 258bf215546Sopenharmony_ci struct vmw_ctx_validate_item *isurf = &vswc->surface.items[i]; 259bf215546Sopenharmony_ci if (isurf->referenced) 260bf215546Sopenharmony_ci p_atomic_dec(&isurf->vsurf->validated); 261bf215546Sopenharmony_ci vmw_svga_winsys_surface_reference(&isurf->vsurf, NULL); 262bf215546Sopenharmony_ci } 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci _mesa_hash_table_clear(vswc->hash, NULL); 265bf215546Sopenharmony_ci vswc->surface.used = 0; 266bf215546Sopenharmony_ci vswc->surface.reserved = 0; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci for(i = 0; i < vswc->shader.used + vswc->shader.staged; ++i) { 269bf215546Sopenharmony_ci struct vmw_ctx_validate_item *ishader = &vswc->shader.items[i]; 270bf215546Sopenharmony_ci if (ishader->referenced) 271bf215546Sopenharmony_ci p_atomic_dec(&ishader->vshader->validated); 272bf215546Sopenharmony_ci vmw_svga_winsys_shader_reference(&ishader->vshader, NULL); 273bf215546Sopenharmony_ci } 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci vswc->shader.used = 0; 276bf215546Sopenharmony_ci vswc->shader.reserved = 0; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci vswc->region.used = 0; 279bf215546Sopenharmony_ci vswc->region.reserved = 0; 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci#ifdef DEBUG 282bf215546Sopenharmony_ci vswc->must_flush = FALSE; 283bf215546Sopenharmony_ci debug_flush_flush(vswc->fctx); 284bf215546Sopenharmony_ci#endif 285bf215546Sopenharmony_ci swc->hints &= ~SVGA_HINT_FLAG_CAN_PRE_FLUSH; 286bf215546Sopenharmony_ci swc->hints &= ~SVGA_HINT_FLAG_EXPORT_FENCE_FD; 287bf215546Sopenharmony_ci vswc->preemptive_flush = FALSE; 288bf215546Sopenharmony_ci vswc->seen_surfaces = 0; 289bf215546Sopenharmony_ci vswc->seen_regions = 0; 290bf215546Sopenharmony_ci vswc->seen_mobs = 0; 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci if (vswc->base.imported_fence_fd != -1) { 293bf215546Sopenharmony_ci close(vswc->base.imported_fence_fd); 294bf215546Sopenharmony_ci vswc->base.imported_fence_fd = -1; 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci if(pfence) 298bf215546Sopenharmony_ci vmw_fence_reference(vswc->vws, pfence, fence); 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci vmw_fence_reference(vswc->vws, &fence, NULL); 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci return ret; 303bf215546Sopenharmony_ci} 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_cistatic void * 307bf215546Sopenharmony_civmw_swc_reserve(struct svga_winsys_context *swc, 308bf215546Sopenharmony_ci uint32_t nr_bytes, uint32_t nr_relocs ) 309bf215546Sopenharmony_ci{ 310bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci#ifdef DEBUG 313bf215546Sopenharmony_ci /* Check if somebody forgot to check the previous failure */ 314bf215546Sopenharmony_ci if(vswc->must_flush) { 315bf215546Sopenharmony_ci debug_printf("Forgot to flush:\n"); 316bf215546Sopenharmony_ci debug_backtrace_dump(vswc->must_flush_stack, VMW_MUST_FLUSH_STACK); 317bf215546Sopenharmony_ci assert(!vswc->must_flush); 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci debug_flush_might_flush(vswc->fctx); 320bf215546Sopenharmony_ci#endif 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci assert(nr_bytes <= vswc->command.size); 323bf215546Sopenharmony_ci if(nr_bytes > vswc->command.size) 324bf215546Sopenharmony_ci return NULL; 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci if(vswc->preemptive_flush || 327bf215546Sopenharmony_ci vswc->command.used + nr_bytes > vswc->command.size || 328bf215546Sopenharmony_ci vswc->surface.used + nr_relocs > vswc->surface.size || 329bf215546Sopenharmony_ci vswc->shader.used + nr_relocs > vswc->shader.size || 330bf215546Sopenharmony_ci vswc->region.used + nr_relocs > vswc->region.size) { 331bf215546Sopenharmony_ci#ifdef DEBUG 332bf215546Sopenharmony_ci vswc->must_flush = TRUE; 333bf215546Sopenharmony_ci debug_backtrace_capture(vswc->must_flush_stack, 1, 334bf215546Sopenharmony_ci VMW_MUST_FLUSH_STACK); 335bf215546Sopenharmony_ci#endif 336bf215546Sopenharmony_ci return NULL; 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci assert(vswc->command.used + nr_bytes <= vswc->command.size); 340bf215546Sopenharmony_ci assert(vswc->surface.used + nr_relocs <= vswc->surface.size); 341bf215546Sopenharmony_ci assert(vswc->shader.used + nr_relocs <= vswc->shader.size); 342bf215546Sopenharmony_ci assert(vswc->region.used + nr_relocs <= vswc->region.size); 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci vswc->command.reserved = nr_bytes; 345bf215546Sopenharmony_ci vswc->surface.reserved = nr_relocs; 346bf215546Sopenharmony_ci vswc->surface.staged = 0; 347bf215546Sopenharmony_ci vswc->shader.reserved = nr_relocs; 348bf215546Sopenharmony_ci vswc->shader.staged = 0; 349bf215546Sopenharmony_ci vswc->region.reserved = nr_relocs; 350bf215546Sopenharmony_ci vswc->region.staged = 0; 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci return vswc->command.buffer + vswc->command.used; 353bf215546Sopenharmony_ci} 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_cistatic unsigned 356bf215546Sopenharmony_civmw_swc_get_command_buffer_size(struct svga_winsys_context *swc) 357bf215546Sopenharmony_ci{ 358bf215546Sopenharmony_ci const struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 359bf215546Sopenharmony_ci return vswc->command.used; 360bf215546Sopenharmony_ci} 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_cistatic void 363bf215546Sopenharmony_civmw_swc_context_relocation(struct svga_winsys_context *swc, 364bf215546Sopenharmony_ci uint32 *cid) 365bf215546Sopenharmony_ci{ 366bf215546Sopenharmony_ci *cid = swc->cid; 367bf215546Sopenharmony_ci} 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_cistatic boolean 370bf215546Sopenharmony_civmw_swc_add_validate_buffer(struct vmw_svga_winsys_context *vswc, 371bf215546Sopenharmony_ci struct pb_buffer *pb_buf, 372bf215546Sopenharmony_ci unsigned flags) 373bf215546Sopenharmony_ci{ 374bf215546Sopenharmony_ci ASSERTED enum pipe_error ret; 375bf215546Sopenharmony_ci unsigned translated_flags; 376bf215546Sopenharmony_ci boolean already_present; 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci translated_flags = vmw_translate_to_pb_flags(flags); 379bf215546Sopenharmony_ci ret = pb_validate_add_buffer(vswc->validate, pb_buf, translated_flags, 380bf215546Sopenharmony_ci vswc->hash, &already_present); 381bf215546Sopenharmony_ci assert(ret == PIPE_OK); 382bf215546Sopenharmony_ci return !already_present; 383bf215546Sopenharmony_ci} 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_cistatic void 386bf215546Sopenharmony_civmw_swc_region_relocation(struct svga_winsys_context *swc, 387bf215546Sopenharmony_ci struct SVGAGuestPtr *where, 388bf215546Sopenharmony_ci struct svga_winsys_buffer *buffer, 389bf215546Sopenharmony_ci uint32 offset, 390bf215546Sopenharmony_ci unsigned flags) 391bf215546Sopenharmony_ci{ 392bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 393bf215546Sopenharmony_ci struct vmw_buffer_relocation *reloc; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci assert(vswc->region.staged < vswc->region.reserved); 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci reloc = &vswc->region.relocs[vswc->region.used + vswc->region.staged]; 398bf215546Sopenharmony_ci reloc->region.where = where; 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci /* 401bf215546Sopenharmony_ci * pb_validate holds a refcount to the buffer, so no need to 402bf215546Sopenharmony_ci * refcount it again in the relocation. 403bf215546Sopenharmony_ci */ 404bf215546Sopenharmony_ci reloc->buffer = vmw_pb_buffer(buffer); 405bf215546Sopenharmony_ci reloc->offset = offset; 406bf215546Sopenharmony_ci reloc->is_mob = FALSE; 407bf215546Sopenharmony_ci ++vswc->region.staged; 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci if (vmw_swc_add_validate_buffer(vswc, reloc->buffer, flags)) { 410bf215546Sopenharmony_ci vswc->seen_regions += reloc->buffer->size; 411bf215546Sopenharmony_ci if ((swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) && 412bf215546Sopenharmony_ci vswc->seen_regions >= VMW_GMR_POOL_SIZE/5) 413bf215546Sopenharmony_ci vswc->preemptive_flush = TRUE; 414bf215546Sopenharmony_ci } 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci#ifdef DEBUG 417bf215546Sopenharmony_ci if (!(flags & SVGA_RELOC_INTERNAL)) 418bf215546Sopenharmony_ci debug_flush_cb_reference(vswc->fctx, vmw_debug_flush_buf(buffer)); 419bf215546Sopenharmony_ci#endif 420bf215546Sopenharmony_ci} 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_cistatic void 423bf215546Sopenharmony_civmw_swc_mob_relocation(struct svga_winsys_context *swc, 424bf215546Sopenharmony_ci SVGAMobId *id, 425bf215546Sopenharmony_ci uint32 *offset_into_mob, 426bf215546Sopenharmony_ci struct svga_winsys_buffer *buffer, 427bf215546Sopenharmony_ci uint32 offset, 428bf215546Sopenharmony_ci unsigned flags) 429bf215546Sopenharmony_ci{ 430bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 431bf215546Sopenharmony_ci struct vmw_buffer_relocation *reloc; 432bf215546Sopenharmony_ci struct pb_buffer *pb_buffer = vmw_pb_buffer(buffer); 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci if (id) { 435bf215546Sopenharmony_ci assert(vswc->region.staged < vswc->region.reserved); 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci reloc = &vswc->region.relocs[vswc->region.used + vswc->region.staged]; 438bf215546Sopenharmony_ci reloc->mob.id = id; 439bf215546Sopenharmony_ci reloc->mob.offset_into_mob = offset_into_mob; 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci /* 442bf215546Sopenharmony_ci * pb_validate holds a refcount to the buffer, so no need to 443bf215546Sopenharmony_ci * refcount it again in the relocation. 444bf215546Sopenharmony_ci */ 445bf215546Sopenharmony_ci reloc->buffer = pb_buffer; 446bf215546Sopenharmony_ci reloc->offset = offset; 447bf215546Sopenharmony_ci reloc->is_mob = TRUE; 448bf215546Sopenharmony_ci ++vswc->region.staged; 449bf215546Sopenharmony_ci } 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci if (vmw_swc_add_validate_buffer(vswc, pb_buffer, flags)) { 452bf215546Sopenharmony_ci vswc->seen_mobs += pb_buffer->size; 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci if ((swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) && 455bf215546Sopenharmony_ci vswc->seen_mobs >= 456bf215546Sopenharmony_ci vswc->vws->ioctl.max_mob_memory / VMW_MAX_MOB_MEM_FACTOR) 457bf215546Sopenharmony_ci vswc->preemptive_flush = TRUE; 458bf215546Sopenharmony_ci } 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci#ifdef DEBUG 461bf215546Sopenharmony_ci if (!(flags & SVGA_RELOC_INTERNAL)) 462bf215546Sopenharmony_ci debug_flush_cb_reference(vswc->fctx, vmw_debug_flush_buf(buffer)); 463bf215546Sopenharmony_ci#endif 464bf215546Sopenharmony_ci} 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci/** 468bf215546Sopenharmony_ci * vmw_swc_surface_clear_reference - Clear referenced info for a surface 469bf215546Sopenharmony_ci * 470bf215546Sopenharmony_ci * @swc: Pointer to an svga_winsys_context 471bf215546Sopenharmony_ci * @vsurf: Pointer to a vmw_svga_winsys_surface, the referenced info of which 472bf215546Sopenharmony_ci * we want to clear 473bf215546Sopenharmony_ci * 474bf215546Sopenharmony_ci * This is primarily used by a discard surface map to indicate that the 475bf215546Sopenharmony_ci * surface data is no longer referenced by a draw call, and mapping it 476bf215546Sopenharmony_ci * should therefore no longer cause a flush. 477bf215546Sopenharmony_ci */ 478bf215546Sopenharmony_civoid 479bf215546Sopenharmony_civmw_swc_surface_clear_reference(struct svga_winsys_context *swc, 480bf215546Sopenharmony_ci struct vmw_svga_winsys_surface *vsurf) 481bf215546Sopenharmony_ci{ 482bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 483bf215546Sopenharmony_ci struct vmw_ctx_validate_item *isrf = 484bf215546Sopenharmony_ci util_hash_table_get(vswc->hash, vsurf); 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci if (isrf && isrf->referenced) { 487bf215546Sopenharmony_ci isrf->referenced = FALSE; 488bf215546Sopenharmony_ci p_atomic_dec(&vsurf->validated); 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci} 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_cistatic void 493bf215546Sopenharmony_civmw_swc_surface_only_relocation(struct svga_winsys_context *swc, 494bf215546Sopenharmony_ci uint32 *where, 495bf215546Sopenharmony_ci struct vmw_svga_winsys_surface *vsurf, 496bf215546Sopenharmony_ci unsigned flags) 497bf215546Sopenharmony_ci{ 498bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 499bf215546Sopenharmony_ci struct vmw_ctx_validate_item *isrf; 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci assert(vswc->surface.staged < vswc->surface.reserved); 502bf215546Sopenharmony_ci isrf = util_hash_table_get(vswc->hash, vsurf); 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci if (isrf == NULL) { 505bf215546Sopenharmony_ci isrf = &vswc->surface.items[vswc->surface.used + vswc->surface.staged]; 506bf215546Sopenharmony_ci vmw_svga_winsys_surface_reference(&isrf->vsurf, vsurf); 507bf215546Sopenharmony_ci isrf->referenced = FALSE; 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_ci _mesa_hash_table_insert(vswc->hash, vsurf, isrf); 510bf215546Sopenharmony_ci ++vswc->surface.staged; 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci vswc->seen_surfaces += vsurf->size; 513bf215546Sopenharmony_ci if ((swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) && 514bf215546Sopenharmony_ci vswc->seen_surfaces >= 515bf215546Sopenharmony_ci vswc->vws->ioctl.max_surface_memory / VMW_MAX_SURF_MEM_FACTOR) 516bf215546Sopenharmony_ci vswc->preemptive_flush = TRUE; 517bf215546Sopenharmony_ci } 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_ci if (!(flags & SVGA_RELOC_INTERNAL) && !isrf->referenced) { 520bf215546Sopenharmony_ci isrf->referenced = TRUE; 521bf215546Sopenharmony_ci p_atomic_inc(&vsurf->validated); 522bf215546Sopenharmony_ci } 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci if (where) 525bf215546Sopenharmony_ci *where = vsurf->sid; 526bf215546Sopenharmony_ci} 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_cistatic void 529bf215546Sopenharmony_civmw_swc_surface_relocation(struct svga_winsys_context *swc, 530bf215546Sopenharmony_ci uint32 *where, 531bf215546Sopenharmony_ci uint32 *mobid, 532bf215546Sopenharmony_ci struct svga_winsys_surface *surface, 533bf215546Sopenharmony_ci unsigned flags) 534bf215546Sopenharmony_ci{ 535bf215546Sopenharmony_ci struct vmw_svga_winsys_surface *vsurf; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci assert(swc->have_gb_objects || mobid == NULL); 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci if (!surface) { 540bf215546Sopenharmony_ci *where = SVGA3D_INVALID_ID; 541bf215546Sopenharmony_ci if (mobid) 542bf215546Sopenharmony_ci *mobid = SVGA3D_INVALID_ID; 543bf215546Sopenharmony_ci return; 544bf215546Sopenharmony_ci } 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci vsurf = vmw_svga_winsys_surface(surface); 547bf215546Sopenharmony_ci vmw_swc_surface_only_relocation(swc, where, vsurf, flags); 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci if (swc->have_gb_objects && vsurf->buf != NULL) { 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci /* 552bf215546Sopenharmony_ci * Make sure backup buffer ends up fenced. 553bf215546Sopenharmony_ci */ 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci mtx_lock(&vsurf->mutex); 556bf215546Sopenharmony_ci assert(vsurf->buf != NULL); 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci /* 559bf215546Sopenharmony_ci * An internal reloc means that the surface transfer direction 560bf215546Sopenharmony_ci * is opposite to the MOB transfer direction... 561bf215546Sopenharmony_ci */ 562bf215546Sopenharmony_ci if ((flags & SVGA_RELOC_INTERNAL) && 563bf215546Sopenharmony_ci (flags & (SVGA_RELOC_READ | SVGA_RELOC_WRITE)) != 564bf215546Sopenharmony_ci (SVGA_RELOC_READ | SVGA_RELOC_WRITE)) 565bf215546Sopenharmony_ci flags ^= (SVGA_RELOC_READ | SVGA_RELOC_WRITE); 566bf215546Sopenharmony_ci vmw_swc_mob_relocation(swc, mobid, NULL, (struct svga_winsys_buffer *) 567bf215546Sopenharmony_ci vsurf->buf, 0, flags); 568bf215546Sopenharmony_ci mtx_unlock(&vsurf->mutex); 569bf215546Sopenharmony_ci } 570bf215546Sopenharmony_ci} 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_cistatic void 573bf215546Sopenharmony_civmw_swc_shader_relocation(struct svga_winsys_context *swc, 574bf215546Sopenharmony_ci uint32 *shid, 575bf215546Sopenharmony_ci uint32 *mobid, 576bf215546Sopenharmony_ci uint32 *offset, 577bf215546Sopenharmony_ci struct svga_winsys_gb_shader *shader, 578bf215546Sopenharmony_ci unsigned flags) 579bf215546Sopenharmony_ci{ 580bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 581bf215546Sopenharmony_ci struct vmw_winsys_screen *vws = vswc->vws; 582bf215546Sopenharmony_ci struct vmw_svga_winsys_shader *vshader; 583bf215546Sopenharmony_ci struct vmw_ctx_validate_item *ishader; 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci if(!shader) { 586bf215546Sopenharmony_ci *shid = SVGA3D_INVALID_ID; 587bf215546Sopenharmony_ci return; 588bf215546Sopenharmony_ci } 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci vshader = vmw_svga_winsys_shader(shader); 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci if (!vws->base.have_vgpu10) { 593bf215546Sopenharmony_ci assert(vswc->shader.staged < vswc->shader.reserved); 594bf215546Sopenharmony_ci ishader = util_hash_table_get(vswc->hash, vshader); 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci if (ishader == NULL) { 597bf215546Sopenharmony_ci ishader = &vswc->shader.items[vswc->shader.used + vswc->shader.staged]; 598bf215546Sopenharmony_ci vmw_svga_winsys_shader_reference(&ishader->vshader, vshader); 599bf215546Sopenharmony_ci ishader->referenced = FALSE; 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci _mesa_hash_table_insert(vswc->hash, vshader, ishader); 602bf215546Sopenharmony_ci ++vswc->shader.staged; 603bf215546Sopenharmony_ci } 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci if (!ishader->referenced) { 606bf215546Sopenharmony_ci ishader->referenced = TRUE; 607bf215546Sopenharmony_ci p_atomic_inc(&vshader->validated); 608bf215546Sopenharmony_ci } 609bf215546Sopenharmony_ci } 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci if (shid) 612bf215546Sopenharmony_ci *shid = vshader->shid; 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci if (vshader->buf) 615bf215546Sopenharmony_ci vmw_swc_mob_relocation(swc, mobid, offset, vshader->buf, 616bf215546Sopenharmony_ci 0, SVGA_RELOC_READ); 617bf215546Sopenharmony_ci} 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_cistatic void 620bf215546Sopenharmony_civmw_swc_query_relocation(struct svga_winsys_context *swc, 621bf215546Sopenharmony_ci SVGAMobId *id, 622bf215546Sopenharmony_ci struct svga_winsys_gb_query *query) 623bf215546Sopenharmony_ci{ 624bf215546Sopenharmony_ci /* Queries are backed by one big MOB */ 625bf215546Sopenharmony_ci vmw_swc_mob_relocation(swc, id, NULL, query->buf, 0, 626bf215546Sopenharmony_ci SVGA_RELOC_READ | SVGA_RELOC_WRITE); 627bf215546Sopenharmony_ci} 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_cistatic void 630bf215546Sopenharmony_civmw_swc_commit(struct svga_winsys_context *swc) 631bf215546Sopenharmony_ci{ 632bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci assert(vswc->command.used + vswc->command.reserved <= vswc->command.size); 635bf215546Sopenharmony_ci vswc->command.used += vswc->command.reserved; 636bf215546Sopenharmony_ci vswc->command.reserved = 0; 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci assert(vswc->surface.staged <= vswc->surface.reserved); 639bf215546Sopenharmony_ci assert(vswc->surface.used + vswc->surface.staged <= vswc->surface.size); 640bf215546Sopenharmony_ci vswc->surface.used += vswc->surface.staged; 641bf215546Sopenharmony_ci vswc->surface.staged = 0; 642bf215546Sopenharmony_ci vswc->surface.reserved = 0; 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci assert(vswc->shader.staged <= vswc->shader.reserved); 645bf215546Sopenharmony_ci assert(vswc->shader.used + vswc->shader.staged <= vswc->shader.size); 646bf215546Sopenharmony_ci vswc->shader.used += vswc->shader.staged; 647bf215546Sopenharmony_ci vswc->shader.staged = 0; 648bf215546Sopenharmony_ci vswc->shader.reserved = 0; 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ci assert(vswc->region.staged <= vswc->region.reserved); 651bf215546Sopenharmony_ci assert(vswc->region.used + vswc->region.staged <= vswc->region.size); 652bf215546Sopenharmony_ci vswc->region.used += vswc->region.staged; 653bf215546Sopenharmony_ci vswc->region.staged = 0; 654bf215546Sopenharmony_ci vswc->region.reserved = 0; 655bf215546Sopenharmony_ci} 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_cistatic void 659bf215546Sopenharmony_civmw_swc_destroy(struct svga_winsys_context *swc) 660bf215546Sopenharmony_ci{ 661bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 662bf215546Sopenharmony_ci unsigned i; 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_ci for(i = 0; i < vswc->surface.used; ++i) { 665bf215546Sopenharmony_ci struct vmw_ctx_validate_item *isurf = &vswc->surface.items[i]; 666bf215546Sopenharmony_ci if (isurf->referenced) 667bf215546Sopenharmony_ci p_atomic_dec(&isurf->vsurf->validated); 668bf215546Sopenharmony_ci vmw_svga_winsys_surface_reference(&isurf->vsurf, NULL); 669bf215546Sopenharmony_ci } 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_ci for(i = 0; i < vswc->shader.used; ++i) { 672bf215546Sopenharmony_ci struct vmw_ctx_validate_item *ishader = &vswc->shader.items[i]; 673bf215546Sopenharmony_ci if (ishader->referenced) 674bf215546Sopenharmony_ci p_atomic_dec(&ishader->vshader->validated); 675bf215546Sopenharmony_ci vmw_svga_winsys_shader_reference(&ishader->vshader, NULL); 676bf215546Sopenharmony_ci } 677bf215546Sopenharmony_ci 678bf215546Sopenharmony_ci _mesa_hash_table_destroy(vswc->hash, NULL); 679bf215546Sopenharmony_ci pb_validate_destroy(vswc->validate); 680bf215546Sopenharmony_ci vmw_ioctl_context_destroy(vswc->vws, swc->cid); 681bf215546Sopenharmony_ci#ifdef DEBUG 682bf215546Sopenharmony_ci debug_flush_ctx_destroy(vswc->fctx); 683bf215546Sopenharmony_ci#endif 684bf215546Sopenharmony_ci FREE(vswc); 685bf215546Sopenharmony_ci} 686bf215546Sopenharmony_ci 687bf215546Sopenharmony_ci/** 688bf215546Sopenharmony_ci * vmw_svga_winsys_vgpu10_shader_screate - The winsys shader_crate callback 689bf215546Sopenharmony_ci * 690bf215546Sopenharmony_ci * @swc: The winsys context. 691bf215546Sopenharmony_ci * @shaderId: Previously allocated shader id. 692bf215546Sopenharmony_ci * @shaderType: The shader type. 693bf215546Sopenharmony_ci * @bytecode: The shader bytecode 694bf215546Sopenharmony_ci * @bytecodelen: The length of the bytecode. 695bf215546Sopenharmony_ci * 696bf215546Sopenharmony_ci * Creates an svga_winsys_gb_shader structure and allocates a buffer for the 697bf215546Sopenharmony_ci * shader code and copies the shader code into the buffer. Shader 698bf215546Sopenharmony_ci * resource creation is not done. 699bf215546Sopenharmony_ci */ 700bf215546Sopenharmony_cistatic struct svga_winsys_gb_shader * 701bf215546Sopenharmony_civmw_svga_winsys_vgpu10_shader_create(struct svga_winsys_context *swc, 702bf215546Sopenharmony_ci uint32 shaderId, 703bf215546Sopenharmony_ci SVGA3dShaderType shaderType, 704bf215546Sopenharmony_ci const uint32 *bytecode, 705bf215546Sopenharmony_ci uint32 bytecodeLen, 706bf215546Sopenharmony_ci const SVGA3dDXShaderSignatureHeader *sgnInfo, 707bf215546Sopenharmony_ci uint32 sgnLen) 708bf215546Sopenharmony_ci{ 709bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 710bf215546Sopenharmony_ci struct vmw_svga_winsys_shader *shader; 711bf215546Sopenharmony_ci shader = vmw_svga_shader_create(&vswc->vws->base, shaderType, bytecode, 712bf215546Sopenharmony_ci bytecodeLen, sgnInfo, sgnLen); 713bf215546Sopenharmony_ci if (!shader) 714bf215546Sopenharmony_ci return NULL; 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci shader->shid = shaderId; 717bf215546Sopenharmony_ci return svga_winsys_shader(shader); 718bf215546Sopenharmony_ci} 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci/** 721bf215546Sopenharmony_ci * vmw_svga_winsys_vgpu10_shader_destroy - The winsys shader_destroy callback. 722bf215546Sopenharmony_ci * 723bf215546Sopenharmony_ci * @swc: The winsys context. 724bf215546Sopenharmony_ci * @shader: A shader structure previously allocated by shader_create. 725bf215546Sopenharmony_ci * 726bf215546Sopenharmony_ci * Frees the shader structure and the buffer holding the shader code. 727bf215546Sopenharmony_ci */ 728bf215546Sopenharmony_cistatic void 729bf215546Sopenharmony_civmw_svga_winsys_vgpu10_shader_destroy(struct svga_winsys_context *swc, 730bf215546Sopenharmony_ci struct svga_winsys_gb_shader *shader) 731bf215546Sopenharmony_ci{ 732bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci vmw_svga_winsys_shader_destroy(&vswc->vws->base, shader); 735bf215546Sopenharmony_ci} 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci/** 738bf215546Sopenharmony_ci * vmw_svga_winsys_resource_rebind - The winsys resource_rebind callback 739bf215546Sopenharmony_ci * 740bf215546Sopenharmony_ci * @swc: The winsys context. 741bf215546Sopenharmony_ci * @surface: The surface to be referenced. 742bf215546Sopenharmony_ci * @shader: The shader to be referenced. 743bf215546Sopenharmony_ci * @flags: Relocation flags. 744bf215546Sopenharmony_ci * 745bf215546Sopenharmony_ci * This callback is needed because shader backing buffers are sub-allocated, and 746bf215546Sopenharmony_ci * hence the kernel fencing is not sufficient. The buffers need to be put on 747bf215546Sopenharmony_ci * the context's validation list and fenced after command submission to avoid 748bf215546Sopenharmony_ci * reuse of busy shader buffers. In addition, surfaces need to be put on the 749bf215546Sopenharmony_ci * validation list in order for the driver to regard them as referenced 750bf215546Sopenharmony_ci * by the command stream. 751bf215546Sopenharmony_ci */ 752bf215546Sopenharmony_cistatic enum pipe_error 753bf215546Sopenharmony_civmw_svga_winsys_resource_rebind(struct svga_winsys_context *swc, 754bf215546Sopenharmony_ci struct svga_winsys_surface *surface, 755bf215546Sopenharmony_ci struct svga_winsys_gb_shader *shader, 756bf215546Sopenharmony_ci unsigned flags) 757bf215546Sopenharmony_ci{ 758bf215546Sopenharmony_ci /** 759bf215546Sopenharmony_ci * Need to reserve one validation item for either the surface or 760bf215546Sopenharmony_ci * the shader. 761bf215546Sopenharmony_ci */ 762bf215546Sopenharmony_ci if (!vmw_swc_reserve(swc, 0, 1)) 763bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci if (surface) 766bf215546Sopenharmony_ci vmw_swc_surface_relocation(swc, NULL, NULL, surface, flags); 767bf215546Sopenharmony_ci else if (shader) 768bf215546Sopenharmony_ci vmw_swc_shader_relocation(swc, NULL, NULL, NULL, shader, flags); 769bf215546Sopenharmony_ci 770bf215546Sopenharmony_ci vmw_swc_commit(swc); 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_ci return PIPE_OK; 773bf215546Sopenharmony_ci} 774bf215546Sopenharmony_ci 775bf215546Sopenharmony_cistruct svga_winsys_context * 776bf215546Sopenharmony_civmw_svga_winsys_context_create(struct svga_winsys_screen *sws) 777bf215546Sopenharmony_ci{ 778bf215546Sopenharmony_ci struct vmw_winsys_screen *vws = vmw_winsys_screen(sws); 779bf215546Sopenharmony_ci struct vmw_svga_winsys_context *vswc; 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci vswc = CALLOC_STRUCT(vmw_svga_winsys_context); 782bf215546Sopenharmony_ci if(!vswc) 783bf215546Sopenharmony_ci return NULL; 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci vswc->base.destroy = vmw_swc_destroy; 786bf215546Sopenharmony_ci vswc->base.reserve = vmw_swc_reserve; 787bf215546Sopenharmony_ci vswc->base.get_command_buffer_size = vmw_swc_get_command_buffer_size; 788bf215546Sopenharmony_ci vswc->base.surface_relocation = vmw_swc_surface_relocation; 789bf215546Sopenharmony_ci vswc->base.region_relocation = vmw_swc_region_relocation; 790bf215546Sopenharmony_ci vswc->base.mob_relocation = vmw_swc_mob_relocation; 791bf215546Sopenharmony_ci vswc->base.query_relocation = vmw_swc_query_relocation; 792bf215546Sopenharmony_ci vswc->base.query_bind = vmw_swc_query_bind; 793bf215546Sopenharmony_ci vswc->base.context_relocation = vmw_swc_context_relocation; 794bf215546Sopenharmony_ci vswc->base.shader_relocation = vmw_swc_shader_relocation; 795bf215546Sopenharmony_ci vswc->base.commit = vmw_swc_commit; 796bf215546Sopenharmony_ci vswc->base.flush = vmw_swc_flush; 797bf215546Sopenharmony_ci vswc->base.surface_map = vmw_svga_winsys_surface_map; 798bf215546Sopenharmony_ci vswc->base.surface_unmap = vmw_svga_winsys_surface_unmap; 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_ci vswc->base.shader_create = vmw_svga_winsys_vgpu10_shader_create; 801bf215546Sopenharmony_ci vswc->base.shader_destroy = vmw_svga_winsys_vgpu10_shader_destroy; 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_ci vswc->base.resource_rebind = vmw_svga_winsys_resource_rebind; 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci if (sws->have_vgpu10) 806bf215546Sopenharmony_ci vswc->base.cid = vmw_ioctl_extended_context_create(vws, sws->have_vgpu10); 807bf215546Sopenharmony_ci else 808bf215546Sopenharmony_ci vswc->base.cid = vmw_ioctl_context_create(vws); 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci if (vswc->base.cid == -1) 811bf215546Sopenharmony_ci goto out_no_context; 812bf215546Sopenharmony_ci 813bf215546Sopenharmony_ci vswc->base.imported_fence_fd = -1; 814bf215546Sopenharmony_ci 815bf215546Sopenharmony_ci vswc->base.have_gb_objects = sws->have_gb_objects; 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_ci vswc->vws = vws; 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci vswc->command.size = VMW_COMMAND_SIZE; 820bf215546Sopenharmony_ci vswc->surface.size = VMW_SURFACE_RELOCS; 821bf215546Sopenharmony_ci vswc->shader.size = VMW_SHADER_RELOCS; 822bf215546Sopenharmony_ci vswc->region.size = VMW_REGION_RELOCS; 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci vswc->validate = pb_validate_create(); 825bf215546Sopenharmony_ci if(!vswc->validate) 826bf215546Sopenharmony_ci goto out_no_validate; 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci vswc->hash = util_hash_table_create_ptr_keys(); 829bf215546Sopenharmony_ci if (!vswc->hash) 830bf215546Sopenharmony_ci goto out_no_hash; 831bf215546Sopenharmony_ci 832bf215546Sopenharmony_ci#ifdef DEBUG 833bf215546Sopenharmony_ci vswc->fctx = debug_flush_ctx_create(TRUE, VMW_DEBUG_FLUSH_STACK); 834bf215546Sopenharmony_ci#endif 835bf215546Sopenharmony_ci 836bf215546Sopenharmony_ci vswc->base.force_coherent = vws->force_coherent; 837bf215546Sopenharmony_ci return &vswc->base; 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ciout_no_hash: 840bf215546Sopenharmony_ci pb_validate_destroy(vswc->validate); 841bf215546Sopenharmony_ciout_no_validate: 842bf215546Sopenharmony_ci vmw_ioctl_context_destroy(vws, vswc->base.cid); 843bf215546Sopenharmony_ciout_no_context: 844bf215546Sopenharmony_ci FREE(vswc); 845bf215546Sopenharmony_ci return NULL; 846bf215546Sopenharmony_ci} 847