14a49301eSmrg/************************************************************************** 24a49301eSmrg * 3af69d88dSmrg * Copyright 2007 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 54a49301eSmrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 134a49301eSmrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 174a49301eSmrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 254a49301eSmrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 284a49301eSmrg/* Author: 29af69d88dSmrg * Keith Whitwell <keithw@vmware.com> 304a49301eSmrg */ 314a49301eSmrg 324a49301eSmrg 334a49301eSmrg#include "pipe/p_defines.h" 343464ebd5Sriastradh#include "pipe/p_screen.h" 354a49301eSmrg#include "draw/draw_context.h" 364a49301eSmrg#include "sp_flush.h" 374a49301eSmrg#include "sp_context.h" 384a49301eSmrg#include "sp_state.h" 394a49301eSmrg#include "sp_tile_cache.h" 404a49301eSmrg#include "sp_tex_tile_cache.h" 4101e04c3fSmrg#include "util/u_debug_image.h" 42af69d88dSmrg#include "util/u_memory.h" 43af69d88dSmrg#include "util/u_string.h" 444a49301eSmrg 454a49301eSmrg 464a49301eSmrgvoid 474a49301eSmrgsoftpipe_flush( struct pipe_context *pipe, 483464ebd5Sriastradh unsigned flags, 494a49301eSmrg struct pipe_fence_handle **fence ) 504a49301eSmrg{ 514a49301eSmrg struct softpipe_context *softpipe = softpipe_context(pipe); 524a49301eSmrg uint i; 534a49301eSmrg 544a49301eSmrg draw_flush(softpipe->draw); 554a49301eSmrg 563464ebd5Sriastradh if (flags & SP_FLUSH_TEXTURE_CACHE) { 57af69d88dSmrg unsigned sh; 58af69d88dSmrg 5901e04c3fSmrg for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) { 60af69d88dSmrg for (i = 0; i < softpipe->num_sampler_views[sh]; i++) { 61af69d88dSmrg sp_flush_tex_tile_cache(softpipe->tex_cache[sh][i]); 62af69d88dSmrg } 633464ebd5Sriastradh } 644a49301eSmrg } 654a49301eSmrg 663464ebd5Sriastradh /* If this is a swapbuffers, just flush color buffers. 673464ebd5Sriastradh * 683464ebd5Sriastradh * The zbuffer changes are not discarded, but held in the cache 693464ebd5Sriastradh * in the hope that a later clear will wipe them out. 703464ebd5Sriastradh */ 713464ebd5Sriastradh for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) 723464ebd5Sriastradh if (softpipe->cbuf_cache[i]) 733464ebd5Sriastradh sp_flush_tile_cache(softpipe->cbuf_cache[i]); 743464ebd5Sriastradh 753464ebd5Sriastradh if (softpipe->zsbuf_cache) 763464ebd5Sriastradh sp_flush_tile_cache(softpipe->zsbuf_cache); 773464ebd5Sriastradh 783464ebd5Sriastradh softpipe->dirty_render_cache = FALSE; 793464ebd5Sriastradh 804a49301eSmrg /* Enable to dump BMPs of the color/depth buffers each frame */ 814a49301eSmrg#if 0 82af69d88dSmrg if (flags & PIPE_FLUSH_END_OF_FRAME) { 834a49301eSmrg static unsigned frame_no = 1; 844a49301eSmrg static char filename[256]; 857ec681f3Smrg snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no); 86af69d88dSmrg debug_dump_surface_bmp(pipe, filename, softpipe->framebuffer.cbufs[0]); 877ec681f3Smrg snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no); 88af69d88dSmrg debug_dump_surface_bmp(pipe, filename, softpipe->framebuffer.zsbuf); 894a49301eSmrg ++frame_no; 904a49301eSmrg } 914a49301eSmrg#endif 923464ebd5Sriastradh 934a49301eSmrg if (fence) 943464ebd5Sriastradh *fence = (void*)(intptr_t)1; 954a49301eSmrg} 964a49301eSmrg 973464ebd5Sriastradhvoid 98af69d88dSmrgsoftpipe_flush_wrapped(struct pipe_context *pipe, 99af69d88dSmrg struct pipe_fence_handle **fence, 100af69d88dSmrg unsigned flags) 1013464ebd5Sriastradh{ 1023464ebd5Sriastradh softpipe_flush(pipe, SP_FLUSH_TEXTURE_CACHE, fence); 1033464ebd5Sriastradh} 1043464ebd5Sriastradh 1053464ebd5Sriastradh 1063464ebd5Sriastradh/** 1073464ebd5Sriastradh * Flush context if necessary. 1083464ebd5Sriastradh * 1093464ebd5Sriastradh * Returns FALSE if it would have block, but do_not_block was set, TRUE 1103464ebd5Sriastradh * otherwise. 1113464ebd5Sriastradh * 1123464ebd5Sriastradh * TODO: move this logic to an auxiliary library? 1133464ebd5Sriastradh */ 1143464ebd5Sriastradhboolean 1153464ebd5Sriastradhsoftpipe_flush_resource(struct pipe_context *pipe, 1163464ebd5Sriastradh struct pipe_resource *texture, 1173464ebd5Sriastradh unsigned level, 1183464ebd5Sriastradh int layer, 1193464ebd5Sriastradh unsigned flush_flags, 1203464ebd5Sriastradh boolean read_only, 1213464ebd5Sriastradh boolean cpu_access, 1223464ebd5Sriastradh boolean do_not_block) 1233464ebd5Sriastradh{ 1243464ebd5Sriastradh unsigned referenced; 1253464ebd5Sriastradh 1263464ebd5Sriastradh referenced = softpipe_is_resource_referenced(pipe, texture, level, layer); 1273464ebd5Sriastradh 1283464ebd5Sriastradh if ((referenced & SP_REFERENCED_FOR_WRITE) || 1293464ebd5Sriastradh ((referenced & SP_REFERENCED_FOR_READ) && !read_only)) { 1303464ebd5Sriastradh 1313464ebd5Sriastradh /* 1323464ebd5Sriastradh * TODO: The semantics of these flush flags are too obtuse. They should 1333464ebd5Sriastradh * disappear and the pipe driver should just ensure that all visible 1343464ebd5Sriastradh * side-effects happen when they need to happen. 1353464ebd5Sriastradh */ 1363464ebd5Sriastradh if (referenced & SP_REFERENCED_FOR_READ) 1373464ebd5Sriastradh flush_flags |= SP_FLUSH_TEXTURE_CACHE; 1383464ebd5Sriastradh 1393464ebd5Sriastradh if (cpu_access) { 1403464ebd5Sriastradh /* 1413464ebd5Sriastradh * Flush and wait. 1423464ebd5Sriastradh */ 1433464ebd5Sriastradh 1443464ebd5Sriastradh struct pipe_fence_handle *fence = NULL; 1453464ebd5Sriastradh 1463464ebd5Sriastradh if (do_not_block) 1473464ebd5Sriastradh return FALSE; 1483464ebd5Sriastradh 1493464ebd5Sriastradh softpipe_flush(pipe, flush_flags, &fence); 1503464ebd5Sriastradh 1513464ebd5Sriastradh if (fence) { 1523464ebd5Sriastradh /* 1533464ebd5Sriastradh * This is for illustrative purposes only, as softpipe does not 1543464ebd5Sriastradh * have fences. 1553464ebd5Sriastradh */ 15601e04c3fSmrg pipe->screen->fence_finish(pipe->screen, NULL, fence, 1573464ebd5Sriastradh PIPE_TIMEOUT_INFINITE); 1583464ebd5Sriastradh pipe->screen->fence_reference(pipe->screen, &fence, NULL); 1593464ebd5Sriastradh } 1603464ebd5Sriastradh } else { 1613464ebd5Sriastradh /* 1623464ebd5Sriastradh * Just flush. 1633464ebd5Sriastradh */ 1643464ebd5Sriastradh 1653464ebd5Sriastradh softpipe_flush(pipe, flush_flags, NULL); 1663464ebd5Sriastradh } 1673464ebd5Sriastradh } 1683464ebd5Sriastradh 1693464ebd5Sriastradh return TRUE; 1703464ebd5Sriastradh} 17101e04c3fSmrg 17201e04c3fSmrgvoid softpipe_texture_barrier(struct pipe_context *pipe, unsigned flags) 17301e04c3fSmrg{ 17401e04c3fSmrg struct softpipe_context *softpipe = softpipe_context(pipe); 17501e04c3fSmrg uint i, sh; 17601e04c3fSmrg 17701e04c3fSmrg for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) { 17801e04c3fSmrg for (i = 0; i < softpipe->num_sampler_views[sh]; i++) { 17901e04c3fSmrg sp_flush_tex_tile_cache(softpipe->tex_cache[sh][i]); 18001e04c3fSmrg } 18101e04c3fSmrg } 18201e04c3fSmrg 18301e04c3fSmrg for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) 18401e04c3fSmrg if (softpipe->cbuf_cache[i]) 18501e04c3fSmrg sp_flush_tile_cache(softpipe->cbuf_cache[i]); 18601e04c3fSmrg 18701e04c3fSmrg if (softpipe->zsbuf_cache) 18801e04c3fSmrg sp_flush_tile_cache(softpipe->zsbuf_cache); 18901e04c3fSmrg 19001e04c3fSmrg softpipe->dirty_render_cache = FALSE; 19101e04c3fSmrg} 19201e04c3fSmrg 19301e04c3fSmrgvoid softpipe_memory_barrier(struct pipe_context *pipe, unsigned flags) 19401e04c3fSmrg{ 1959f464c52Smaya if (!(flags & ~PIPE_BARRIER_UPDATE)) 1969f464c52Smaya return; 1979f464c52Smaya 19801e04c3fSmrg softpipe_texture_barrier(pipe, 0); 19901e04c3fSmrg} 200