sp_context.c revision af69d88d
1/************************************************************************** 2 * 3 * Copyright 2007 VMware, Inc. 4 * All Rights Reserved. 5 * Copyright 2008 VMware, Inc. All rights reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 29/* Author: 30 * Keith Whitwell <keithw@vmware.com> 31 */ 32 33#include "draw/draw_context.h" 34#include "draw/draw_vbuf.h" 35#include "pipe/p_defines.h" 36#include "util/u_math.h" 37#include "util/u_memory.h" 38#include "util/u_pstipple.h" 39#include "util/u_inlines.h" 40#include "tgsi/tgsi_exec.h" 41#include "sp_clear.h" 42#include "sp_context.h" 43#include "sp_flush.h" 44#include "sp_prim_vbuf.h" 45#include "sp_state.h" 46#include "sp_surface.h" 47#include "sp_tile_cache.h" 48#include "sp_tex_tile_cache.h" 49#include "sp_texture.h" 50#include "sp_query.h" 51#include "sp_screen.h" 52#include "sp_tex_sample.h" 53 54 55static void 56softpipe_destroy( struct pipe_context *pipe ) 57{ 58 struct softpipe_context *softpipe = softpipe_context( pipe ); 59 uint i, sh; 60 61#if DO_PSTIPPLE_IN_HELPER_MODULE 62 if (softpipe->pstipple.sampler) 63 pipe->delete_sampler_state(pipe, softpipe->pstipple.sampler); 64 65 pipe_resource_reference(&softpipe->pstipple.texture, NULL); 66 pipe_sampler_view_reference(&softpipe->pstipple.sampler_view, NULL); 67#endif 68 69 if (softpipe->blitter) { 70 util_blitter_destroy(softpipe->blitter); 71 } 72 73 if (softpipe->draw) 74 draw_destroy( softpipe->draw ); 75 76 if (softpipe->quad.shade) 77 softpipe->quad.shade->destroy( softpipe->quad.shade ); 78 79 if (softpipe->quad.depth_test) 80 softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); 81 82 if (softpipe->quad.blend) 83 softpipe->quad.blend->destroy( softpipe->quad.blend ); 84 85 if (softpipe->quad.pstipple) 86 softpipe->quad.pstipple->destroy( softpipe->quad.pstipple ); 87 88 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 89 sp_destroy_tile_cache(softpipe->cbuf_cache[i]); 90 pipe_surface_reference(&softpipe->framebuffer.cbufs[i], NULL); 91 } 92 93 sp_destroy_tile_cache(softpipe->zsbuf_cache); 94 pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL); 95 96 for (sh = 0; sh < Elements(softpipe->tex_cache); sh++) { 97 for (i = 0; i < Elements(softpipe->tex_cache[0]); i++) { 98 sp_destroy_tex_tile_cache(softpipe->tex_cache[sh][i]); 99 pipe_sampler_view_reference(&softpipe->sampler_views[sh][i], NULL); 100 } 101 } 102 103 for (sh = 0; sh < Elements(softpipe->constants); sh++) { 104 for (i = 0; i < Elements(softpipe->constants[0]); i++) { 105 if (softpipe->constants[sh][i]) { 106 pipe_resource_reference(&softpipe->constants[sh][i], NULL); 107 } 108 } 109 } 110 111 for (i = 0; i < softpipe->num_vertex_buffers; i++) { 112 pipe_resource_reference(&softpipe->vertex_buffer[i].buffer, NULL); 113 } 114 115 tgsi_exec_machine_destroy(softpipe->fs_machine); 116 117 for (i = 0; i < PIPE_SHADER_TYPES; i++) { 118 FREE(softpipe->tgsi.sampler[i]); 119 } 120 121 FREE( softpipe ); 122} 123 124 125/** 126 * if (the texture is being used as a framebuffer surface) 127 * return SP_REFERENCED_FOR_WRITE 128 * else if (the texture is a bound texture source) 129 * return SP_REFERENCED_FOR_READ 130 * else 131 * return SP_UNREFERENCED 132 */ 133unsigned int 134softpipe_is_resource_referenced( struct pipe_context *pipe, 135 struct pipe_resource *texture, 136 unsigned level, int layer) 137{ 138 struct softpipe_context *softpipe = softpipe_context( pipe ); 139 unsigned i, sh; 140 141 if (texture->target == PIPE_BUFFER) 142 return SP_UNREFERENCED; 143 144 /* check if any of the bound drawing surfaces are this texture */ 145 if (softpipe->dirty_render_cache) { 146 for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { 147 if (softpipe->framebuffer.cbufs[i] && 148 softpipe->framebuffer.cbufs[i]->texture == texture) { 149 return SP_REFERENCED_FOR_WRITE; 150 } 151 } 152 if (softpipe->framebuffer.zsbuf && 153 softpipe->framebuffer.zsbuf->texture == texture) { 154 return SP_REFERENCED_FOR_WRITE; 155 } 156 } 157 158 /* check if any of the tex_cache textures are this texture */ 159 for (sh = 0; sh < Elements(softpipe->tex_cache); sh++) { 160 for (i = 0; i < Elements(softpipe->tex_cache[0]); i++) { 161 if (softpipe->tex_cache[sh][i] && 162 softpipe->tex_cache[sh][i]->texture == texture) 163 return SP_REFERENCED_FOR_READ; 164 } 165 } 166 167 return SP_UNREFERENCED; 168} 169 170 171 172 173static void 174softpipe_render_condition( struct pipe_context *pipe, 175 struct pipe_query *query, 176 boolean condition, 177 uint mode ) 178{ 179 struct softpipe_context *softpipe = softpipe_context( pipe ); 180 181 softpipe->render_cond_query = query; 182 softpipe->render_cond_mode = mode; 183 softpipe->render_cond_cond = condition; 184} 185 186 187 188struct pipe_context * 189softpipe_create_context( struct pipe_screen *screen, 190 void *priv ) 191{ 192 struct softpipe_screen *sp_screen = softpipe_screen(screen); 193 struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); 194 uint i, sh; 195 196 util_init_math(); 197 198 for (i = 0; i < PIPE_SHADER_TYPES; i++) { 199 softpipe->tgsi.sampler[i] = sp_create_tgsi_sampler(); 200 } 201 202 softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE ); 203 softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE ); 204 205 softpipe->pipe.screen = screen; 206 softpipe->pipe.destroy = softpipe_destroy; 207 softpipe->pipe.priv = priv; 208 209 /* state setters */ 210 softpipe_init_blend_funcs(&softpipe->pipe); 211 softpipe_init_clip_funcs(&softpipe->pipe); 212 softpipe_init_query_funcs( softpipe ); 213 softpipe_init_rasterizer_funcs(&softpipe->pipe); 214 softpipe_init_sampler_funcs(&softpipe->pipe); 215 softpipe_init_shader_funcs(&softpipe->pipe); 216 softpipe_init_streamout_funcs(&softpipe->pipe); 217 softpipe_init_texture_funcs( &softpipe->pipe ); 218 softpipe_init_vertex_funcs(&softpipe->pipe); 219 220 softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; 221 222 softpipe->pipe.draw_vbo = softpipe_draw_vbo; 223 224 softpipe->pipe.clear = softpipe_clear; 225 softpipe->pipe.flush = softpipe_flush_wrapped; 226 227 softpipe->pipe.render_condition = softpipe_render_condition; 228 229 /* 230 * Alloc caches for accessing drawing surfaces and textures. 231 * Must be before quad stage setup! 232 */ 233 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) 234 softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe ); 235 softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe ); 236 237 /* Allocate texture caches */ 238 for (sh = 0; sh < Elements(softpipe->tex_cache); sh++) { 239 for (i = 0; i < Elements(softpipe->tex_cache[0]); i++) { 240 softpipe->tex_cache[sh][i] = sp_create_tex_tile_cache(&softpipe->pipe); 241 if (!softpipe->tex_cache[sh][i]) 242 goto fail; 243 } 244 } 245 246 softpipe->fs_machine = tgsi_exec_machine_create(); 247 248 /* setup quad rendering stages */ 249 softpipe->quad.shade = sp_quad_shade_stage(softpipe); 250 softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); 251 softpipe->quad.blend = sp_quad_blend_stage(softpipe); 252 softpipe->quad.pstipple = sp_quad_polygon_stipple_stage(softpipe); 253 254 255 /* 256 * Create drawing context and plug our rendering stage into it. 257 */ 258 if (sp_screen->use_llvm) 259 softpipe->draw = draw_create(&softpipe->pipe); 260 else 261 softpipe->draw = draw_create_no_llvm(&softpipe->pipe); 262 if (!softpipe->draw) 263 goto fail; 264 265 draw_texture_sampler(softpipe->draw, 266 PIPE_SHADER_VERTEX, 267 (struct tgsi_sampler *) 268 softpipe->tgsi.sampler[PIPE_SHADER_VERTEX]); 269 270 draw_texture_sampler(softpipe->draw, 271 PIPE_SHADER_GEOMETRY, 272 (struct tgsi_sampler *) 273 softpipe->tgsi.sampler[PIPE_SHADER_GEOMETRY]); 274 275 if (debug_get_bool_option( "SOFTPIPE_NO_RAST", FALSE )) 276 softpipe->no_rast = TRUE; 277 278 softpipe->vbuf_backend = sp_create_vbuf_backend(softpipe); 279 if (!softpipe->vbuf_backend) 280 goto fail; 281 282 softpipe->vbuf = draw_vbuf_stage(softpipe->draw, softpipe->vbuf_backend); 283 if (!softpipe->vbuf) 284 goto fail; 285 286 draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf); 287 draw_set_render(softpipe->draw, softpipe->vbuf_backend); 288 289 softpipe->blitter = util_blitter_create(&softpipe->pipe); 290 if (!softpipe->blitter) { 291 goto fail; 292 } 293 294 /* must be done before installing Draw stages */ 295 util_blitter_cache_all_shaders(softpipe->blitter); 296 297 /* plug in AA line/point stages */ 298 draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); 299 draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); 300 301 /* Do polygon stipple w/ texture map + frag prog? */ 302#if DO_PSTIPPLE_IN_DRAW_MODULE 303 draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); 304#endif 305 306 draw_wide_point_sprites(softpipe->draw, TRUE); 307 308 sp_init_surface_functions(softpipe); 309 310#if DO_PSTIPPLE_IN_HELPER_MODULE 311 /* create the polgon stipple sampler */ 312 softpipe->pstipple.sampler = util_pstipple_create_sampler(&softpipe->pipe); 313#endif 314 315 return &softpipe->pipe; 316 317 fail: 318 softpipe_destroy(&softpipe->pipe); 319 return NULL; 320} 321