static void vmw_swc_destroy(struct svga_winsys_context *swc) { struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); unsigned i; for(i = 0; i < vswc->surface.used; ++i) { struct vmw_ctx_validate_item *isurf = &vswc->surface.items[i]; if (isurf->referenced) p_atomic_dec(&isurf->vsurf->validated); vmw_svga_winsys_surface_reference(&isurf->vsurf, NULL); } for(i = 0; i < vswc->shader.used; ++i) { struct vmw_ctx_validate_item *ishader = &vswc->shader.items[i]; if (ishader->referenced) p_atomic_dec(&ishader->vshader->validated); vmw_svga_winsys_shader_reference(&ishader->vshader, NULL); } util_hash_table_destroy(vswc->hash); pb_validate_destroy(vswc->validate); vmw_ioctl_context_destroy(vswc->vws, swc->cid); #ifdef DEBUG debug_flush_ctx_destroy(vswc->fctx); #endif FREE(vswc); }
void vmw_svga_winsys_shader_destroy(struct svga_winsys_screen *sws, struct svga_winsys_gb_shader *shader) { struct vmw_svga_winsys_shader *d_shader = vmw_svga_winsys_shader(shader); vmw_svga_winsys_shader_reference(&d_shader, NULL); }
static void vmw_swc_shader_relocation(struct svga_winsys_context *swc, uint32 *shid, uint32 *mobid, uint32 *offset, struct svga_winsys_gb_shader *shader, unsigned flags) { struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); struct vmw_winsys_screen *vws = vswc->vws; struct vmw_svga_winsys_shader *vshader; struct vmw_ctx_validate_item *ishader; if(!shader) { *shid = SVGA3D_INVALID_ID; return; } vshader = vmw_svga_winsys_shader(shader); if (!vws->base.have_vgpu10) { assert(vswc->shader.staged < vswc->shader.reserved); ishader = util_hash_table_get(vswc->hash, vshader); if (ishader == NULL) { ishader = &vswc->shader.items[vswc->shader.used + vswc->shader.staged]; vmw_svga_winsys_shader_reference(&ishader->vshader, vshader); ishader->referenced = FALSE; /* * Note that a failure here may just fall back to unhashed behavior * and potentially cause unnecessary flushing, so ignore the * return code. */ (void) util_hash_table_set(vswc->hash, vshader, ishader); ++vswc->shader.staged; } if (!ishader->referenced) { ishader->referenced = TRUE; p_atomic_inc(&vshader->validated); } } if (shid) *shid = vshader->shid; if (vshader->buf) vmw_swc_mob_relocation(swc, mobid, offset, vshader->buf, 0, SVGA_RELOC_READ); }
static enum pipe_error vmw_swc_flush(struct svga_winsys_context *swc, struct pipe_fence_handle **pfence) { struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); struct pipe_fence_handle *fence = NULL; unsigned i; enum pipe_error ret; ret = pb_validate_validate(vswc->validate); assert(ret == PIPE_OK); if(ret == PIPE_OK) { /* Apply relocations */ for(i = 0; i < vswc->region.used; ++i) { struct vmw_buffer_relocation *reloc = &vswc->region.relocs[i]; struct SVGAGuestPtr ptr; if(!vmw_gmr_bufmgr_region_ptr(reloc->buffer, &ptr)) assert(0); ptr.offset += reloc->offset; if (reloc->is_mob) { if (reloc->mob.id) *reloc->mob.id = ptr.gmrId; if (reloc->mob.offset_into_mob) *reloc->mob.offset_into_mob = ptr.offset; else { assert(ptr.offset == 0); } } else *reloc->region.where = ptr; } if (vswc->command.used || pfence != NULL) vmw_ioctl_command(vswc->vws, vswc->base.cid, 0, vswc->command.buffer, vswc->command.used, &fence); pb_validate_fence(vswc->validate, fence); } vswc->command.used = 0; vswc->command.reserved = 0; for(i = 0; i < vswc->surface.used + vswc->surface.staged; ++i) { struct vmw_ctx_validate_item *isurf = &vswc->surface.items[i]; if (isurf->referenced) p_atomic_dec(&isurf->vsurf->validated); vmw_svga_winsys_surface_reference(&isurf->vsurf, NULL); } util_hash_table_clear(vswc->hash); vswc->surface.used = 0; vswc->surface.reserved = 0; for(i = 0; i < vswc->shader.used + vswc->shader.staged; ++i) { struct vmw_ctx_validate_item *ishader = &vswc->shader.items[i]; if (ishader->referenced) p_atomic_dec(&ishader->vshader->validated); vmw_svga_winsys_shader_reference(&ishader->vshader, NULL); } vswc->shader.used = 0; vswc->shader.reserved = 0; vswc->region.used = 0; vswc->region.reserved = 0; #ifdef DEBUG vswc->must_flush = FALSE; debug_flush_flush(vswc->fctx); #endif vswc->preemptive_flush = FALSE; vswc->seen_surfaces = 0; vswc->seen_regions = 0; vswc->seen_mobs = 0; if(pfence) vmw_fence_reference(vswc->vws, pfence, fence); vmw_fence_reference(vswc->vws, &fence, NULL); return ret; }