13192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/********************************************************** 23192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Copyright 2008-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 27421f134028ea2930cb80c7189e552320a8a6e49fBrian Paul#include "os/os_thread.h" 283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipe/p_state.h" 293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipe/p_defines.h" 3028486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h" 313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_math.h" 323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_memory.h" 333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 34421f134028ea2930cb80c7189e552320a8a6e49fBrian Paul#include "svga_cmd.h" 353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_context.h" 36421f134028ea2930cb80c7189e552320a8a6e49fBrian Paul#include "svga_debug.h" 37287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_resource_buffer.h" 38287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_resource_buffer_upload.h" 39421f134028ea2930cb80c7189e552320a8a6e49fBrian Paul#include "svga_screen.h" 403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_winsys.h" 413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 43b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca/** 44b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca * Allocate a winsys_buffer (ie. DMA, aka GMR memory). 45b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca * 46b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca * It will flush and retry in case the first attempt to create a DMA buffer 47b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca * fails, so it should not be called from any function involved in flushing 48b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca * to avoid recursion. 493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_winsys_buffer * 51b84590994c4261d85485357263146d5e3d8827ebJosé Fonsecasvga_winsys_buffer_create( struct svga_context *svga, 5259d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul unsigned alignment, 533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned usage, 543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned size ) 553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 56b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); 57b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca struct svga_winsys_screen *sws = svgascreen->sws; 583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_winsys_buffer *buf; 5959d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* Just try */ 613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz buf = sws->buffer_create(sws, alignment, usage, size); 6229288249e35693a33b7873ed11b09c313b2e49f0José Fonseca if (!buf) { 6329288249e35693a33b7873ed11b09c313b2e49f0José Fonseca SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing context to find %d bytes GMR\n", 6459d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul size); 6559d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* Try flushing all pending DMAs */ 67b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca svga_context_flush(svga, NULL); 683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz buf = sws->buffer_create(sws, alignment, usage, size); 693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 7059d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return buf; 723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 75287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellvoid 76287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf) 77287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{ 78287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct svga_winsys_screen *sws = ss->sws; 79287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 80287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell assert(!sbuf->map.count); 81287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell assert(sbuf->hwbuf); 8259d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (sbuf->hwbuf) { 83287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sws->buffer_destroy(sws, sbuf->hwbuf); 84287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->hwbuf = NULL; 85287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell } 86287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell} 87287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 88287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 89287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/** 9159d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul * Allocate DMA'ble storage for the buffer. 9259d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul * 933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Called before mapping a buffer. 943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 95287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellenum pipe_error 963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_buffer_create_hw_storage(struct svga_screen *ss, 973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_buffer *sbuf) 983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 99b330928549b39e97e16aee636c335865504ffab9José Fonseca assert(!sbuf->user); 100b330928549b39e97e16aee636c335865504ffab9José Fonseca 10159d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!sbuf->hwbuf) { 102b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca struct svga_winsys_screen *sws = ss->sws; 103287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell unsigned alignment = 16; 1043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned usage = 0; 105287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell unsigned size = sbuf->b.b.width0; 10659d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 107b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca sbuf->hwbuf = sws->buffer_create(sws, alignment, usage, size); 10859d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!sbuf->hwbuf) 1093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return PIPE_ERROR_OUT_OF_MEMORY; 11059d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 111cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(!sbuf->dma.pending); 1123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 11359d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 1143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return PIPE_OK; 1153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 1163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 118287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 119287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellenum pipe_error 120287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_create_host_surface(struct svga_screen *ss, 121287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct svga_buffer *sbuf) 122287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{ 12374651f5738032466fceede8b8f0c3ce29a770551José Fonseca assert(!sbuf->user); 12474651f5738032466fceede8b8f0c3ce29a770551José Fonseca 12559d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!sbuf->handle) { 126287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.flags = 0; 12759d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 128287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.format = SVGA3D_BUFFER; 12959d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (sbuf->b.b.bind & PIPE_BIND_VERTEX_BUFFER) 130287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER; 13159d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (sbuf->b.b.bind & PIPE_BIND_INDEX_BUFFER) 132287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER; 13359d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 134287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.size.width = sbuf->b.b.width0; 135287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.size.height = 1; 136287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.size.depth = 1; 13759d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 138287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.numFaces = 1; 139287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.numMipLevels = 1; 140287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->key.cachable = 1; 14159d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 142287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->b.b.width0); 143287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 144287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->handle = svga_screen_surface_create(ss, &sbuf->key); 14559d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!sbuf->handle) 146287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return PIPE_ERROR_OUT_OF_MEMORY; 14759d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 148287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell /* Always set the discard flag on the first time the buffer is written 149287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * as svga_screen_surface_create might have passed a recycled host 150287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * buffer. 151287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */ 152287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell sbuf->dma.flags.discard = TRUE; 153287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 154287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->b.b.width0); 155287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell } 15659d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 157287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return PIPE_OK; 15859d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul} 159287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 160287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 161287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellvoid 162287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_destroy_host_surface(struct svga_screen *ss, 163287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct svga_buffer *sbuf) 164287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{ 16559d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (sbuf->handle) { 166287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell SVGA_DBG(DEBUG_DMA, " ungrab sid %p sz %d\n", sbuf->handle, sbuf->b.b.width0); 167287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle); 168287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell } 16959d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul} 170287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 171287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/** 1733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Variant of SVGA3D_BufferDMA which leaves the copy box temporarily in blank. 1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 1753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic enum pipe_error 1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_buffer_upload_command(struct svga_context *svga, 1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_buffer *sbuf) 1783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 1793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_winsys_context *swc = svga->swc; 180cf861335a44376609258a2ec399c215e35f9f075José Fonseca struct svga_winsys_buffer *guest = sbuf->hwbuf; 1813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_winsys_surface *host = sbuf->handle; 1823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM; 1833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA3dCmdSurfaceDMA *cmd; 184cf861335a44376609258a2ec399c215e35f9f075José Fonseca uint32 numBoxes = sbuf->map.num_ranges; 1853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA3dCopyBox *boxes; 1863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA3dCmdSurfaceDMASuffix *pSuffix; 1873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned region_flags; 1883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned surface_flags; 189287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *dummy; 1903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 19159d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (transfer == SVGA3D_WRITE_HOST_VRAM) { 192287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell region_flags = SVGA_RELOC_READ; 193287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell surface_flags = SVGA_RELOC_WRITE; 1943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 19559d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul else if (transfer == SVGA3D_READ_HOST_VRAM) { 196287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell region_flags = SVGA_RELOC_WRITE; 197287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell surface_flags = SVGA_RELOC_READ; 1983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 1993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz else { 2003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(0); 2013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return PIPE_ERROR_BAD_INPUT; 2023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 2033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(numBoxes); 2053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz cmd = SVGA3D_FIFOReserve(swc, 2073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA_3D_CMD_SURFACE_DMA, 2083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz sizeof *cmd + numBoxes * sizeof *boxes + sizeof *pSuffix, 2093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2); 21059d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!cmd) 2113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return PIPE_ERROR_OUT_OF_MEMORY; 2123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags); 2143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz cmd->guest.pitch = 0; 2153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags); 2173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz cmd->host.face = 0; 2183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz cmd->host.mipmap = 0; 2193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz cmd->transfer = transfer; 2213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 222cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->dma.boxes = (SVGA3dCopyBox *)&cmd[1]; 223cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->dma.svga = svga; 2243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* Increment reference count */ 2263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz dummy = NULL; 227287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&dummy, &sbuf->b.b); 2283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes); 2303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz pSuffix->suffixSize = sizeof *pSuffix; 231287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pSuffix->maximumOffset = sbuf->b.b.width0; 2322452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca pSuffix->flags = sbuf->dma.flags; 2333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2342452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca SVGA_FIFOCommitAll(swc); 2352452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 2362452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca sbuf->dma.flags.discard = FALSE; 2373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return PIPE_OK; 2393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 2403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/** 2433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Patch up the upload DMA command reserved by svga_buffer_upload_command 2443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * with the final ranges. 2453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 246ef33c82bfde788733aabc5dcc9647416c31ae254José Fonsecavoid 2473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_buffer_upload_flush(struct svga_context *svga, 2483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_buffer *sbuf) 2493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 2503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA3dCopyBox *boxes; 2513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned i; 252610c24b19d21f3d147fde4d96a3afaa107670f1eJosé Fonseca struct pipe_resource *dummy; 2533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 254ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca if (!sbuf->dma.pending) { 255ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca return; 256ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca } 257ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca 25859d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul assert(sbuf->handle); 259cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(sbuf->hwbuf); 260cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(sbuf->map.num_ranges); 261cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(sbuf->dma.svga == svga); 262cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(sbuf->dma.boxes); 26359d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 2643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* 2653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Patch the DMA command with the final copy box. 2663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 2673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle); 2693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 270cf861335a44376609258a2ec399c215e35f9f075José Fonseca boxes = sbuf->dma.boxes; 27159d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul for (i = 0; i < sbuf->map.num_ranges; ++i) { 2723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n", 273cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->map.ranges[i].start, sbuf->map.ranges[i].end); 2743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 275cf861335a44376609258a2ec399c215e35f9f075José Fonseca boxes[i].x = sbuf->map.ranges[i].start; 2763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz boxes[i].y = 0; 2773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz boxes[i].z = 0; 278cf861335a44376609258a2ec399c215e35f9f075José Fonseca boxes[i].w = sbuf->map.ranges[i].end - sbuf->map.ranges[i].start; 2793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz boxes[i].h = 1; 2803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz boxes[i].d = 1; 281cf861335a44376609258a2ec399c215e35f9f075José Fonseca boxes[i].srcx = sbuf->map.ranges[i].start; 2823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz boxes[i].srcy = 0; 2833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz boxes[i].srcz = 0; 2843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 2853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 286cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->map.num_ranges = 0; 2873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(sbuf->head.prev && sbuf->head.next); 2893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz LIST_DEL(&sbuf->head); 29050edefec2dd5ec2990ab2cd699478139173d5fd2José Fonseca#ifdef DEBUG 29159d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul sbuf->head.next = sbuf->head.prev = NULL; 29250edefec2dd5ec2990ab2cd699478139173d5fd2José Fonseca#endif 293cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->dma.pending = FALSE; 294ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca sbuf->dma.flags.discard = FALSE; 295ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca sbuf->dma.flags.unsynchronized = FALSE; 2963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 297cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->dma.svga = NULL; 298cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->dma.boxes = NULL; 2993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 300610c24b19d21f3d147fde4d96a3afaa107670f1eJosé Fonseca /* Decrement reference count (and potentially destroy) */ 301610c24b19d21f3d147fde4d96a3afaa107670f1eJosé Fonseca dummy = &sbuf->b.b; 302610c24b19d21f3d147fde4d96a3afaa107670f1eJosé Fonseca pipe_resource_reference(&dummy, NULL); 3033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/** 307cf861335a44376609258a2ec399c215e35f9f075José Fonseca * Note a dirty range. 3083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 3093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * This function only notes the range down. It doesn't actually emit a DMA 3103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * upload command. That only happens when a context tries to refer to this 31159d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul * buffer, and the DMA upload command is added to that context's command 31259d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul * buffer. 31359d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul * 3143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * We try to lump as many contiguous DMA transfers together as possible. 3153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 316287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellvoid 317cf861335a44376609258a2ec399c215e35f9f075José Fonsecasvga_buffer_add_range(struct svga_buffer *sbuf, 318cf861335a44376609258a2ec399c215e35f9f075José Fonseca unsigned start, 319cf861335a44376609258a2ec399c215e35f9f075José Fonseca unsigned end) 3203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 3213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned i; 322422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca unsigned nearest_range; 323422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca unsigned nearest_dist; 3243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(end > start); 32659d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 327cf861335a44376609258a2ec399c215e35f9f075José Fonseca if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) { 328cf861335a44376609258a2ec399c215e35f9f075José Fonseca nearest_range = sbuf->map.num_ranges; 329422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca nearest_dist = ~0; 330422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca } else { 331422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca nearest_range = SVGA_BUFFER_MAX_RANGES - 1; 332422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca nearest_dist = 0; 333422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca } 334422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca 3353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* 3363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Try to grow one of the ranges. 3373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 3383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 33959d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul for (i = 0; i < sbuf->map.num_ranges; ++i) { 340422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca int left_dist; 341422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca int right_dist; 342422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca int dist; 343422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca 344cf861335a44376609258a2ec399c215e35f9f075José Fonseca left_dist = start - sbuf->map.ranges[i].end; 345cf861335a44376609258a2ec399c215e35f9f075José Fonseca right_dist = sbuf->map.ranges[i].start - end; 346422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca dist = MAX2(left_dist, right_dist); 347422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca 348422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca if (dist <= 0) { 349422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca /* 350422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca * Ranges are contiguous or overlapping -- extend this one and return. 351ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca * 352ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca * Note that it is not this function's task to prevent overlapping 353ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca * ranges, as the GMR was already given so it is too late to do 354ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca * anything. If the ranges overlap here it must surely be because 355ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca * PIPE_TRANSFER_UNSYNCHRONIZED was set. 356422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca */ 357422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca 358cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->map.ranges[i].start = MIN2(sbuf->map.ranges[i].start, start); 359cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->map.ranges[i].end = MAX2(sbuf->map.ranges[i].end, end); 3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return; 3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 362422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca else { 363422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca /* 364422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca * Discontiguous ranges -- keep track of the nearest range. 365422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca */ 366422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca 367422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca if (dist < nearest_dist) { 368422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca nearest_range = i; 369422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca nearest_dist = dist; 370422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca } 371422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca } 3723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 3733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* 3753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * We cannot add a new range to an existing DMA command, so patch-up the 3763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * pending DMA upload and start clean. 3773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 3783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 379ef33c82bfde788733aabc5dcc9647416c31ae254José Fonseca svga_buffer_upload_flush(sbuf->dma.svga, sbuf); 3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 381cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(!sbuf->dma.pending); 382cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(!sbuf->dma.svga); 383cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(!sbuf->dma.boxes); 3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 385cf861335a44376609258a2ec399c215e35f9f075José Fonseca if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) { 386422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca /* 387422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca * Add a new range. 388422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca */ 3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 390cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->map.ranges[sbuf->map.num_ranges].start = start; 391cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->map.ranges[sbuf->map.num_ranges].end = end; 392cf861335a44376609258a2ec399c215e35f9f075José Fonseca ++sbuf->map.num_ranges; 393422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca } else { 394422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca /* 395422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca * Everything else failed, so just extend the nearest range. 396422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca * 397422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca * It is OK to do this because we always keep a local copy of the 398422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca * host buffer data, for SW TNL, and the host never modifies the buffer. 399422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca */ 400422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca 401422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca assert(nearest_range < SVGA_BUFFER_MAX_RANGES); 402cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(nearest_range < sbuf->map.num_ranges); 403cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->map.ranges[nearest_range].start = MIN2(sbuf->map.ranges[nearest_range].start, start); 404cf861335a44376609258a2ec399c215e35f9f075José Fonseca sbuf->map.ranges[nearest_range].end = MAX2(sbuf->map.ranges[nearest_range].end, end); 405422167a9b0dc5b6da7bc7c47621b5da1bc6d315bJosé Fonseca } 4063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 4073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 4083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 4093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 410d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca/** 411b330928549b39e97e16aee636c335865504ffab9José Fonseca * Copy the contents of the malloc buffer to a hardware buffer. 4123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 413daf4254d07328381ed013aac25e25d6021fbfd14Brian Paulstatic enum pipe_error 4143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf) 4153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 416b330928549b39e97e16aee636c335865504ffab9José Fonseca assert(!sbuf->user); 41759d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!sbuf->hwbuf) { 4183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz enum pipe_error ret; 4193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz void *map; 42059d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 4213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(sbuf->swbuf); 42259d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!sbuf->swbuf) 4233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return PIPE_ERROR; 42459d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 4253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ret = svga_buffer_create_hw_storage(ss, sbuf); 42659d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (ret != PIPE_OK) 4273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return ret; 4283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 4293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz pipe_mutex_lock(ss->swc_mutex); 430287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_TRANSFER_WRITE); 4313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(map); 43259d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!map) { 4333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz pipe_mutex_unlock(ss->swc_mutex); 4342452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca svga_buffer_destroy_hw_storage(ss, sbuf); 4352452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca return PIPE_ERROR; 4363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 4373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 438287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell memcpy(map, sbuf->swbuf, sbuf->b.b.width0); 439cf861335a44376609258a2ec399c215e35f9f075José Fonseca ss->sws->buffer_unmap(ss->sws, sbuf->hwbuf); 4403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 4413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz /* This user/malloc buffer is now indistinguishable from a gpu buffer */ 4423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(!sbuf->map.count); 44359d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!sbuf->map.count) { 44459d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (sbuf->user) 4453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz sbuf->user = FALSE; 4463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz else 4473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz align_free(sbuf->swbuf); 4483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz sbuf->swbuf = NULL; 4493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 45059d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 4512452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca pipe_mutex_unlock(ss->swc_mutex); 4523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 45359d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 4542452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca return PIPE_OK; 4552452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca} 4562452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 4572452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 4582452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca/** 4592452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * Upload the buffer to the host in a piecewise fashion. 4602452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * 4612452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * Used when the buffer is too big to fit in the GMR aperture. 4622452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca */ 463daf4254d07328381ed013aac25e25d6021fbfd14Brian Paulstatic enum pipe_error 4642452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonsecasvga_buffer_upload_piecewise(struct svga_screen *ss, 4652452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca struct svga_context *svga, 4662452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca struct svga_buffer *sbuf) 4672452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca{ 4682452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca struct svga_winsys_screen *sws = ss->sws; 469d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca const unsigned alignment = sizeof(void *); 4702452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca const unsigned usage = 0; 471d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca unsigned i; 472d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca 473d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca assert(sbuf->map.num_ranges); 474d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca assert(!sbuf->dma.pending); 4752452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 4762452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle); 4772452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 478d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca for (i = 0; i < sbuf->map.num_ranges; ++i) { 479d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca struct svga_buffer_range *range = &sbuf->map.ranges[i]; 480d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca unsigned offset = range->start; 481d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca unsigned size = range->end - range->start; 4822452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 483d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca while (offset < range->end) { 484d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca struct svga_winsys_buffer *hwbuf; 485d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca uint8_t *map; 486d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca enum pipe_error ret; 4872452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 488d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca if (offset + size > range->end) 489d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca size = range->end - offset; 4902452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 491b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca hwbuf = sws->buffer_create(sws, alignment, usage, size); 492d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca while (!hwbuf) { 493d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca size /= 2; 494d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca if (!size) 495d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca return PIPE_ERROR_OUT_OF_MEMORY; 496b84590994c4261d85485357263146d5e3d8827ebJosé Fonseca hwbuf = sws->buffer_create(sws, alignment, usage, size); 497d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca } 4982452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 499d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n", 500d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca offset, offset + size); 5012452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 502d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca map = sws->buffer_map(sws, hwbuf, 503287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell PIPE_TRANSFER_WRITE | 5047cd1c62b6be88072e3d937b67c499592490927f1Marek Olšák PIPE_TRANSFER_DISCARD_RANGE); 505d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca assert(map); 506d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca if (map) { 507d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca memcpy(map, sbuf->swbuf, size); 508d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca sws->buffer_unmap(sws, hwbuf); 509d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca } 5102452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 511d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca ret = SVGA3D_BufferDMA(svga->swc, 512d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca hwbuf, sbuf->handle, 513d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca SVGA3D_WRITE_HOST_VRAM, 5148ea7d8412c5c002b43824a5df5356cbe1a05ce20José Fonseca size, 0, offset, sbuf->dma.flags); 51559d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (ret != PIPE_OK) { 516d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca svga_context_flush(svga, NULL); 517d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca ret = SVGA3D_BufferDMA(svga->swc, 518d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca hwbuf, sbuf->handle, 519d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca SVGA3D_WRITE_HOST_VRAM, 5208ea7d8412c5c002b43824a5df5356cbe1a05ce20José Fonseca size, 0, offset, sbuf->dma.flags); 521d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca assert(ret == PIPE_OK); 522d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca } 5232452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 524d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca sbuf->dma.flags.discard = FALSE; 5252452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 526d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca sws->buffer_destroy(sws, hwbuf); 5272452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 528d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca offset += size; 529d1a022537195dc9afca7b487af70b188fbcfcd99José Fonseca } 5302452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca } 5312452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 5322452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca sbuf->map.num_ranges = 0; 5332452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 5343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return PIPE_OK; 5353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 5363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 5373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 538287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 539287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 540287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell/* Get (or create/upload) the winsys surface handle so that we can 541287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * refer to this buffer in fifo commands. 542287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */ 5433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_winsys_surface * 5443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_buffer_handle(struct svga_context *svga, 545287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *buf) 5463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 5473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pipe_screen *screen = svga->pipe.screen; 5483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_screen *ss = svga_screen(screen); 5493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_buffer *sbuf; 5503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz enum pipe_error ret; 5513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 55259d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!buf) 5533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return NULL; 5543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 5553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz sbuf = svga_buffer(buf); 55659d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 5573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz assert(!sbuf->map.count); 558b330928549b39e97e16aee636c335865504ffab9José Fonseca assert(!sbuf->user); 55959d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 56059d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (!sbuf->handle) { 5613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ret = svga_buffer_create_host_surface(ss, sbuf); 56259d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul if (ret != PIPE_OK) 5633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return NULL; 5643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 5653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 5662452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca assert(sbuf->handle); 5673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 5682452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca if (sbuf->map.num_ranges) { 5692452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca if (!sbuf->dma.pending) { 5702452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca /* 5712452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * No pending DMA upload yet, so insert a DMA upload command now. 5722452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca */ 5733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 5742452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca /* 5752452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * Migrate the data from swbuf -> hwbuf if necessary. 5762452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca */ 5772452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca ret = svga_buffer_update_hw(ss, sbuf); 5782452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca if (ret == PIPE_OK) { 5792452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca /* 5802452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * Queue a dma command. 5812452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca */ 5822452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 5832452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca ret = svga_buffer_upload_command(svga, sbuf); 5842452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca if (ret == PIPE_ERROR_OUT_OF_MEMORY) { 5852452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca svga_context_flush(svga, NULL); 5862452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca ret = svga_buffer_upload_command(svga, sbuf); 5872452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca assert(ret == PIPE_OK); 5882452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca } 5892452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca if (ret == PIPE_OK) { 5902452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca sbuf->dma.pending = TRUE; 5912452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca assert(!sbuf->head.prev && !sbuf->head.next); 5922452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers); 5932452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca } 5942452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca } 5952452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca else if (ret == PIPE_ERROR_OUT_OF_MEMORY) { 5962452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca /* 5972452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * The buffer is too big to fit in the GMR aperture, so break it in 5982452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * smaller pieces. 5992452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca */ 6002452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca ret = svga_buffer_upload_piecewise(ss, svga, sbuf); 6012452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca } 6022452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 6032452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca if (ret != PIPE_OK) { 6042452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca /* 6052452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * Something unexpected happened above. There is very little that 6062452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * we can do other than proceeding while ignoring the dirty ranges. 6072452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca */ 6082452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca assert(0); 6092452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca sbuf->map.num_ranges = 0; 6102452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca } 6112452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca } 6122452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca else { 6132452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca /* 6142452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca * There a pending dma already. Make sure it is from this context. 6152452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca */ 6162452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca assert(sbuf->dma.svga == svga); 6172452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca } 6183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 6193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 6202452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca assert(!sbuf->map.num_ranges || sbuf->dma.pending); 6212452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 6223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return sbuf->handle; 6233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 6243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 6252452921e5adb56a3d99e52fb2b963fcd2a0b75e9José Fonseca 6263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 6273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid 6283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_context_flush_buffers(struct svga_context *svga) 6293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 6303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct list_head *curr, *next; 6313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_buffer *sbuf; 6323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 6333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz curr = svga->dirty_buffers.next; 6343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz next = curr->next; 6353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz while(curr != &svga->dirty_buffers) { 6363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz sbuf = LIST_ENTRY(struct svga_buffer, curr, head); 6373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 638287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell assert(p_atomic_read(&sbuf->b.b.reference.count) != 0); 639cf861335a44376609258a2ec399c215e35f9f075José Fonseca assert(sbuf->dma.pending); 64059d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul 6413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz svga_buffer_upload_flush(svga, sbuf); 6423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 64359d2c4f8e5a00133c093137b2f4836313f633d60Brian Paul curr = next; 6443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz next = curr->next; 6453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 6463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 647