1 /********************************************************** 2 * Copyright 2008-2009 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26 #include "svga_cmd.h" 27 28 #include "pipe/p_defines.h" 29 #include "util/u_inlines.h" 30 #include "pipe/p_screen.h" 31 #include "util/u_memory.h" 32 #include "util/u_bitmask.h" 33 #include "util/u_upload_mgr.h" 34 35 #include "svga_context.h" 36 #include "svga_screen.h" 37 #include "svga_surface.h" 38 #include "svga_resource_texture.h" 39 #include "svga_resource_buffer.h" 40 #include "svga_resource.h" 41 #include "svga_winsys.h" 42 #include "svga_swtnl.h" 43 #include "svga_draw.h" 44 #include "svga_debug.h" 45 #include "svga_state.h" 46 47 DEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", FALSE) 48 DEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", FALSE); 49 DEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", FALSE); 50 DEBUG_GET_ONCE_NUM_OPTION(disable_shader, "SVGA_DISABLE_SHADER", ~0); 51 DEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", FALSE); 52 DEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", FALSE); 53 54 static void svga_destroy( struct pipe_context *pipe ) 55 { 56 struct svga_context *svga = svga_context( pipe ); 57 unsigned shader; 58 59 svga_cleanup_framebuffer( svga ); 60 svga_cleanup_tss_binding( svga ); 61 62 svga_hwtnl_destroy( svga->hwtnl ); 63 64 svga_cleanup_vertex_state(svga); 65 66 svga->swc->destroy(svga->swc); 67 68 svga_destroy_swtnl( svga ); 69 70 u_upload_destroy( svga->upload_vb ); 71 u_upload_destroy( svga->upload_ib ); 72 73 util_bitmask_destroy( svga->vs_bm ); 74 util_bitmask_destroy( svga->fs_bm ); 75 76 for(shader = 0; shader < PIPE_SHADER_TYPES; ++shader) 77 pipe_resource_reference( &svga->curr.cb[shader], NULL ); 78 79 FREE( svga ); 80 } 81 82 83 84 struct pipe_context *svga_context_create( struct pipe_screen *screen, 85 void *priv ) 86 { 87 struct svga_screen *svgascreen = svga_screen(screen); 88 struct svga_context *svga = NULL; 89 enum pipe_error ret; 90 91 svga = CALLOC_STRUCT(svga_context); 92 if (svga == NULL) 93 goto no_svga; 94 95 svga->pipe.screen = screen; 96 svga->pipe.priv = priv; 97 svga->pipe.destroy = svga_destroy; 98 svga->pipe.clear = svga_clear; 99 100 svga->swc = svgascreen->sws->context_create(svgascreen->sws); 101 if(!svga->swc) 102 goto no_swc; 103 104 svga_init_resource_functions(svga); 105 svga_init_blend_functions(svga); 106 svga_init_blit_functions(svga); 107 svga_init_depth_stencil_functions(svga); 108 svga_init_draw_functions(svga); 109 svga_init_flush_functions(svga); 110 svga_init_misc_functions(svga); 111 svga_init_rasterizer_functions(svga); 112 svga_init_sampler_functions(svga); 113 svga_init_fs_functions(svga); 114 svga_init_vs_functions(svga); 115 svga_init_vertex_functions(svga); 116 svga_init_constbuffer_functions(svga); 117 svga_init_query_functions(svga); 118 svga_init_surface_functions(svga); 119 120 121 /* debug */ 122 svga->debug.no_swtnl = debug_get_option_no_swtnl(); 123 svga->debug.force_swtnl = debug_get_option_force_swtnl(); 124 svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap(); 125 svga->debug.disable_shader = debug_get_option_disable_shader(); 126 svga->debug.no_line_width = debug_get_option_no_line_width(); 127 svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple(); 128 129 svga->fs_bm = util_bitmask_create(); 130 if (svga->fs_bm == NULL) 131 goto no_fs_bm; 132 133 svga->vs_bm = util_bitmask_create(); 134 if (svga->vs_bm == NULL) 135 goto no_vs_bm; 136 137 svga->upload_ib = u_upload_create( &svga->pipe, 138 32 * 1024, 139 16, 140 PIPE_BIND_INDEX_BUFFER ); 141 if (svga->upload_ib == NULL) 142 goto no_upload_ib; 143 144 svga->upload_vb = u_upload_create( &svga->pipe, 145 128 * 1024, 146 16, 147 PIPE_BIND_VERTEX_BUFFER ); 148 if (svga->upload_vb == NULL) 149 goto no_upload_vb; 150 151 svga->hwtnl = svga_hwtnl_create( svga, 152 svga->upload_ib, 153 svga->swc ); 154 if (svga->hwtnl == NULL) 155 goto no_hwtnl; 156 157 if (!svga_init_swtnl(svga)) 158 goto no_swtnl; 159 160 ret = svga_emit_initial_state( svga ); 161 if (ret != PIPE_OK) 162 goto no_state; 163 164 /* Avoid shortcircuiting state with initial value of zero. 165 */ 166 memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear)); 167 memset(&svga->state.hw_clear.framebuffer, 0x0, 168 sizeof(svga->state.hw_clear.framebuffer)); 169 170 memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw)); 171 memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views)); 172 svga->state.hw_draw.num_views = 0; 173 174 svga->dirty = ~0; 175 176 LIST_INITHEAD(&svga->dirty_buffers); 177 178 return &svga->pipe; 179 180 no_state: 181 svga_destroy_swtnl(svga); 182 no_swtnl: 183 svga_hwtnl_destroy( svga->hwtnl ); 184 no_hwtnl: 185 u_upload_destroy( svga->upload_vb ); 186 no_upload_vb: 187 u_upload_destroy( svga->upload_ib ); 188 no_upload_ib: 189 util_bitmask_destroy( svga->vs_bm ); 190 no_vs_bm: 191 util_bitmask_destroy( svga->fs_bm ); 192 no_fs_bm: 193 svga->swc->destroy(svga->swc); 194 no_swc: 195 FREE(svga); 196 no_svga: 197 return NULL; 198 } 199 200 201 void svga_context_flush( struct svga_context *svga, 202 struct pipe_fence_handle **pfence ) 203 { 204 struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); 205 struct pipe_fence_handle *fence = NULL; 206 207 svga->curr.nr_fbs = 0; 208 209 /* Flush the upload managers to ensure recycling of upload buffers 210 * without throttling. This should really be conditioned on 211 * pipe_buffer_map_range not supporting PIPE_TRANSFER_UNSYNCHRONIZED. 212 */ 213 214 u_upload_flush(svga->upload_vb); 215 u_upload_flush(svga->upload_ib); 216 217 /* Ensure that texture dma uploads are processed 218 * before submitting commands. 219 */ 220 svga_context_flush_buffers(svga); 221 222 /* Flush pending commands to hardware: 223 */ 224 svga->swc->flush(svga->swc, &fence); 225 226 svga_screen_cache_flush(svgascreen, fence); 227 228 /* To force the re-emission of rendertargets and texture sampler bindings on 229 * the next command buffer. 230 */ 231 svga->rebind.rendertargets = TRUE; 232 svga->rebind.texture_samplers = TRUE; 233 234 if (SVGA_DEBUG & DEBUG_SYNC) { 235 if (fence) 236 svga->pipe.screen->fence_finish( svga->pipe.screen, fence, 237 PIPE_TIMEOUT_INFINITE); 238 } 239 240 if(pfence) 241 svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence); 242 243 svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL); 244 } 245 246 247 void svga_hwtnl_flush_retry( struct svga_context *svga ) 248 { 249 enum pipe_error ret = PIPE_OK; 250 251 ret = svga_hwtnl_flush( svga->hwtnl ); 252 if (ret == PIPE_ERROR_OUT_OF_MEMORY) { 253 svga_context_flush( svga, NULL ); 254 ret = svga_hwtnl_flush( svga->hwtnl ); 255 } 256 257 assert(ret == 0); 258 } 259 260 261 /** 262 * Flush the primitive queue if this buffer is referred. 263 * 264 * Otherwise DMA commands on the referred buffer will be emitted too late. 265 */ 266 void svga_hwtnl_flush_buffer( struct svga_context *svga, 267 struct pipe_resource *buffer ) 268 { 269 if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) { 270 svga_hwtnl_flush_retry(svga); 271 } 272 } 273 274 275 /* Emit all operations pending on host surfaces. 276 */ 277 void svga_surfaces_flush(struct svga_context *svga) 278 { 279 unsigned i; 280 281 /* Emit buffered drawing commands. 282 */ 283 svga_hwtnl_flush_retry( svga ); 284 285 /* Emit back-copy from render target view to texture. 286 */ 287 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 288 if (svga->curr.framebuffer.cbufs[i]) 289 svga_propagate_surface(svga, svga->curr.framebuffer.cbufs[i]); 290 } 291 292 if (svga->curr.framebuffer.zsbuf) 293 svga_propagate_surface(svga, svga->curr.framebuffer.zsbuf); 294 295 } 296 297 298 struct svga_winsys_context * 299 svga_winsys_context( struct pipe_context *pipe ) 300 { 301 return svga_context( pipe )->swc; 302 } 303