13192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/********************************************************** 23192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Copyright 2009 VMware, Inc. All rights reserved. 33192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 43192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Permission is hereby granted, free of charge, to any person 53192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * obtaining a copy of this software and associated documentation 63192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * files (the "Software"), to deal in the Software without 73192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * restriction, including without limitation the rights to use, copy, 83192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * modify, merge, publish, distribute, sublicense, and/or sell copies 93192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * of the Software, and to permit persons to whom the Software is 103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * furnished to do so, subject to the following conditions: 113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The above copyright notice and this permission notice shall be 133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * included in all copies or substantial portions of the Software. 143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SOFTWARE. 233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz **********************************************************/ 253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_cmd.h" 283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_debug.h" 303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_memory.h" 313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_debug_stack.h" 323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipebuffer/pb_buffer.h" 333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipebuffer/pb_validate.h" 343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_winsys.h" 363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_context.h" 373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_screen.h" 383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_buffer.h" 393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_surface.h" 403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_fence.h" 413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#define VMW_COMMAND_SIZE (64*1024) 433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#define VMW_SURFACE_RELOCS (1024) 44383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca#define VMW_REGION_RELOCS (512) 453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#define VMW_MUST_FLUSH_STACK 8 473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 48383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonsecastruct vmw_region_relocation 49383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca{ 50383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca struct SVGAGuestPtr *where; 51383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca struct pb_buffer *buffer; 52383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca /* TODO: put offset info inside where */ 53383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca uint32 offset; 54383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca}; 55383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct vmw_svga_winsys_context 573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_winsys_context base; 593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_winsys_screen *vws; 613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG 633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz boolean must_flush; 643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct debug_stack_frame must_flush_stack[VMW_MUST_FLUSH_STACK]; 653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif 663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct { 683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint8_t buffer[VMW_COMMAND_SIZE]; 693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32_t size; 703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32_t used; 713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32_t reserved; 723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } command; 733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct { 753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_surface *handles[VMW_SURFACE_RELOCS]; 763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32_t size; 773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32_t used; 783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32_t staged; 793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32_t reserved; 803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } surface; 81383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 82383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca struct { 83383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca struct vmw_region_relocation relocs[VMW_REGION_RELOCS]; 84383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca uint32_t size; 85383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca uint32_t used; 86383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca uint32_t staged; 87383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca uint32_t reserved; 88383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca } region; 893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pb_validate *validate; 913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 92a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca /** 93a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * The amount of GMR that is referred by the commands currently batched 94a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * in the context. 95a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca */ 96a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca uint32_t seen_regions; 97a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca 98a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca /** 99a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * Whether this context should fail to reserve more commands, not because it 100a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * ran out of command space, but because a substantial ammount of GMR was 101a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * referred. 102a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca */ 103a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca boolean preemptive_flush; 1043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}; 1053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct vmw_svga_winsys_context * 1083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_svga_winsys_context(struct svga_winsys_context *swc) 1093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 1103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(swc); 1113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return (struct vmw_svga_winsys_context *)swc; 1123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 1133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 115aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantzstatic INLINE unsigned 116aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantzvmw_translate_to_pb_flags(unsigned flags) 117aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz{ 118aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz unsigned f = 0; 119aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz if (flags & SVGA_RELOC_READ) 120aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz f |= PB_USAGE_GPU_READ; 121aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz 122aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz if (flags & SVGA_RELOC_WRITE) 123aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz f |= PB_USAGE_GPU_WRITE; 124aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz 125aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz return f; 126aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz} 127aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz 1283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic enum pipe_error 1293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_flush(struct svga_winsys_context *swc, 1303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pipe_fence_handle **pfence) 1313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 1323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 1333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pipe_fence_handle *fence = NULL; 1343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned i; 1353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz enum pipe_error ret; 1363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ret = pb_validate_validate(vswc->validate); 1383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(ret == PIPE_OK); 1393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(ret == PIPE_OK) { 140383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 141383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca /* Apply relocations */ 142383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca for(i = 0; i < vswc->region.used; ++i) { 143383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca struct vmw_region_relocation *reloc = &vswc->region.relocs[i]; 144383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca struct SVGAGuestPtr ptr; 145383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 146383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca if(!vmw_gmr_bufmgr_region_ptr(reloc->buffer, &ptr)) 147383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca assert(0); 148383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 149383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca ptr.offset += reloc->offset; 150383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 151383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca *reloc->where = ptr; 152383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca } 1533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1545a6ca7e9f24939cfacf2e8cd163a4efa9550ce1fThomas Hellstrom if (vswc->command.used || pfence != NULL) 1553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vmw_ioctl_command(vswc->vws, 156d12f2bb9c03a9e8a08824c849200f5b23c05914cThomas Hellstrom vswc->base.cid, 157ca21c85ab062f18649445fdbc4e494e31e5ca535Jakob Bornecrantz 0, 1583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->command.buffer, 1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->command.used, 160e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom &fence); 1613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz pb_validate_fence(vswc->validate, fence); 1633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 1643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->command.used = 0; 1663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->command.reserved = 0; 1673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz for(i = 0; i < vswc->surface.used + vswc->surface.staged; ++i) { 1693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_surface *vsurf = 1703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.handles[i]; 1713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz p_atomic_dec(&vsurf->validated); 1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL); 1733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.used = 0; 1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.reserved = 0; 1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 178383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca for(i = 0; i < vswc->region.used + vswc->region.staged; ++i) { 179383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca pb_reference(&vswc->region.relocs[i].buffer, NULL); 180383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca } 181383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 182383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.used = 0; 183383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.reserved = 0; 184383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 1853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG 1863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->must_flush = FALSE; 1873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif 188a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca vswc->preemptive_flush = FALSE; 189a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca vswc->seen_regions = 0; 1903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(pfence) 192e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom vmw_fence_reference(vswc->vws, pfence, fence); 193e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 194e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom vmw_fence_reference(vswc->vws, &fence, NULL); 1953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return ret; 1973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 1983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void * 2013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_reserve(struct svga_winsys_context *swc, 2023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32_t nr_bytes, uint32_t nr_relocs ) 2033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 2043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 2053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG 2073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* Check if somebody forgot to check the previous failure */ 2083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(vswc->must_flush) { 2093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz debug_printf("Forgot to flush:\n"); 2103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz debug_backtrace_dump(vswc->must_flush_stack, VMW_MUST_FLUSH_STACK); 2113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(!vswc->must_flush); 2123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 2133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif 2143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(nr_bytes <= vswc->command.size); 2163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(nr_bytes > vswc->command.size) 2173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return NULL; 2183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 219a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca if(vswc->preemptive_flush || 220a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca vswc->command.used + nr_bytes > vswc->command.size || 221383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->surface.used + nr_relocs > vswc->surface.size || 222383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.used + nr_relocs > vswc->region.size) { 2233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG 2243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->must_flush = TRUE; 2253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz debug_backtrace_capture(vswc->must_flush_stack, 1, 2263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz VMW_MUST_FLUSH_STACK); 2273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif 2283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return NULL; 2293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 2303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(vswc->command.used + nr_bytes <= vswc->command.size); 2323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(vswc->surface.used + nr_relocs <= vswc->surface.size); 233383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca assert(vswc->region.used + nr_relocs <= vswc->region.size); 234383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 2353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->command.reserved = nr_bytes; 2363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.reserved = nr_relocs; 2373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.staged = 0; 238383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.reserved = nr_relocs; 239383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.staged = 0; 240383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 2413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return vswc->command.buffer + vswc->command.used; 2423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 2433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void 2463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_surface_relocation(struct svga_winsys_context *swc, 2473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32 *where, 2483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_winsys_surface *surface, 2493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned flags) 2503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 2513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 2523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_surface *vsurf; 2533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(!surface) { 2553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *where = SVGA3D_INVALID_ID; 2563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return; 2573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 2583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(vswc->surface.staged < vswc->surface.reserved); 2603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vsurf = vmw_svga_winsys_surface(surface); 2623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *where = vsurf->sid; 2643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vmw_svga_winsys_surface_reference(&vswc->surface.handles[vswc->surface.used + vswc->surface.staged], vsurf); 2663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz p_atomic_inc(&vsurf->validated); 2673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ++vswc->surface.staged; 2683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 2693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void 2723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_region_relocation(struct svga_winsys_context *swc, 2733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct SVGAGuestPtr *where, 2743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_winsys_buffer *buffer, 2753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz uint32 offset, 2763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned flags) 2773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 2783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 279383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca struct vmw_region_relocation *reloc; 280aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz unsigned translated_flags; 2813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz enum pipe_error ret; 282383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 283383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca assert(vswc->region.staged < vswc->region.reserved); 2843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 285383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca reloc = &vswc->region.relocs[vswc->region.used + vswc->region.staged]; 286383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca reloc->where = where; 287383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca pb_reference(&reloc->buffer, vmw_pb_buffer(buffer)); 288383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca reloc->offset = offset; 2893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 290383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca ++vswc->region.staged; 2913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 292aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz translated_flags = vmw_translate_to_pb_flags(flags); 293aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz ret = pb_validate_add_buffer(vswc->validate, reloc->buffer, translated_flags); 2943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* TODO: Update pipebuffer to reserve buffers and not fail here */ 2953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(ret == PIPE_OK); 296f700370946972d26dae7ab54cbb186feea50579cJakob Bornecrantz (void)ret; 297a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca 298a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca /* 299a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * Flush preemptively the FIFO commands to keep the GMR working set within 300a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * the GMR pool size. 301a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * 302a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * This is necessary for applications like SPECviewperf that generate huge 303a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * amounts of immediate vertex data, so that we don't pile up too much of 304a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * that vertex data neither in the guest nor in the host. 305a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * 306a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * Note that in the current implementation if a region is referred twice in 307a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * a command stream, it will be accounted twice. We could detect repeated 308a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * regions and count only once, but there is no incentive to do that, since 309a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * regions are typically short-lived; always referred in a single command; 310a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * and at the worst we just flush the commands a bit sooner, which for the 311a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * SVGA virtual device it's not a performance issue since flushing commands 312a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca * to the FIFO won't cause flushing in the host. 313a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca */ 3144682e706012fe26627a2f827db01b5068cc62814Marek Olšák vswc->seen_regions += reloc->buffer->size; 315637ed52f597098ac556b27a4403056bd54343426José Fonseca if(vswc->seen_regions >= VMW_GMR_POOL_SIZE/3) 316a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca vswc->preemptive_flush = TRUE; 3173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void 3213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_commit(struct svga_winsys_context *swc) 3223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 3233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 3243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(vswc->command.reserved); 3263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(vswc->command.used + vswc->command.reserved <= vswc->command.size); 3273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->command.used += vswc->command.reserved; 3283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->command.reserved = 0; 3293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(vswc->surface.staged <= vswc->surface.reserved); 3313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(vswc->surface.used + vswc->surface.staged <= vswc->surface.size); 3323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.used += vswc->surface.staged; 3333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.staged = 0; 3343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.reserved = 0; 335383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 336383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca assert(vswc->region.staged <= vswc->region.reserved); 337383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca assert(vswc->region.used + vswc->region.staged <= vswc->region.size); 338383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.used += vswc->region.staged; 339383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.staged = 0; 340383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.reserved = 0; 3413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void 3453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_destroy(struct svga_winsys_context *swc) 3463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 3473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); 3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned i; 349383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 350383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca for(i = 0; i < vswc->region.used; ++i) { 351383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca pb_reference(&vswc->region.relocs[i].buffer, NULL); 352383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca } 353383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca 3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz for(i = 0; i < vswc->surface.used; ++i) { 3553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz p_atomic_dec(&vswc->surface.handles[i]->validated); 3563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL); 3573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 3583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz pb_validate_destroy(vswc->validate); 3593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vmw_ioctl_context_destroy(vswc->vws, swc->cid); 3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz FREE(vswc); 3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_winsys_context * 3653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_svga_winsys_context_create(struct svga_winsys_screen *sws) 3663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 3673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_winsys_screen *vws = vmw_winsys_screen(sws); 3683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_svga_winsys_context *vswc; 3693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc = CALLOC_STRUCT(vmw_svga_winsys_context); 3713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(!vswc) 3723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return NULL; 3733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->base.destroy = vmw_swc_destroy; 3753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->base.reserve = vmw_swc_reserve; 3763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->base.surface_relocation = vmw_swc_surface_relocation; 3773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->base.region_relocation = vmw_swc_region_relocation; 3783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->base.commit = vmw_swc_commit; 3793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->base.flush = vmw_swc_flush; 3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->base.cid = vmw_ioctl_context_create(vws); 3823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->vws = vws; 3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->command.size = VMW_COMMAND_SIZE; 3863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->surface.size = VMW_SURFACE_RELOCS; 387383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca vswc->region.size = VMW_REGION_RELOCS; 3883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz vswc->validate = pb_validate_create(); 3903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(!vswc->validate) { 3913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz FREE(vswc); 3923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return NULL; 3933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 3943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return &vswc->base; 3963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 397