1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2007 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * Copyright 2008 VMware, Inc. All rights reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the 9848b8605Smrg * "Software"), to deal in the Software without restriction, including 10848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 11848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 12848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 13848b8605Smrg * the following conditions: 14848b8605Smrg * 15848b8605Smrg * The above copyright notice and this permission notice (including the 16848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 17848b8605Smrg * of the Software. 18848b8605Smrg * 19848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26848b8605Smrg * 27848b8605Smrg **************************************************************************/ 28848b8605Smrg 29848b8605Smrg/* Author: 30848b8605Smrg * Keith Whitwell <keithw@vmware.com> 31848b8605Smrg */ 32848b8605Smrg 33848b8605Smrg#include "draw/draw_context.h" 34848b8605Smrg#include "draw/draw_vbuf.h" 35848b8605Smrg#include "pipe/p_defines.h" 36848b8605Smrg#include "util/u_math.h" 37848b8605Smrg#include "util/u_memory.h" 38848b8605Smrg#include "util/u_pstipple.h" 39848b8605Smrg#include "util/u_inlines.h" 40b8e80941Smrg#include "util/u_upload_mgr.h" 41848b8605Smrg#include "tgsi/tgsi_exec.h" 42b8e80941Smrg#include "sp_buffer.h" 43848b8605Smrg#include "sp_clear.h" 44848b8605Smrg#include "sp_context.h" 45848b8605Smrg#include "sp_flush.h" 46848b8605Smrg#include "sp_prim_vbuf.h" 47848b8605Smrg#include "sp_state.h" 48848b8605Smrg#include "sp_surface.h" 49848b8605Smrg#include "sp_tile_cache.h" 50848b8605Smrg#include "sp_tex_tile_cache.h" 51848b8605Smrg#include "sp_texture.h" 52848b8605Smrg#include "sp_query.h" 53848b8605Smrg#include "sp_screen.h" 54848b8605Smrg#include "sp_tex_sample.h" 55b8e80941Smrg#include "sp_image.h" 56848b8605Smrg 57848b8605Smrgstatic void 58848b8605Smrgsoftpipe_destroy( struct pipe_context *pipe ) 59848b8605Smrg{ 60848b8605Smrg struct softpipe_context *softpipe = softpipe_context( pipe ); 61848b8605Smrg uint i, sh; 62848b8605Smrg 63848b8605Smrg#if DO_PSTIPPLE_IN_HELPER_MODULE 64848b8605Smrg if (softpipe->pstipple.sampler) 65848b8605Smrg pipe->delete_sampler_state(pipe, softpipe->pstipple.sampler); 66848b8605Smrg 67848b8605Smrg pipe_resource_reference(&softpipe->pstipple.texture, NULL); 68848b8605Smrg pipe_sampler_view_reference(&softpipe->pstipple.sampler_view, NULL); 69848b8605Smrg#endif 70848b8605Smrg 71848b8605Smrg if (softpipe->blitter) { 72848b8605Smrg util_blitter_destroy(softpipe->blitter); 73848b8605Smrg } 74848b8605Smrg 75848b8605Smrg if (softpipe->draw) 76848b8605Smrg draw_destroy( softpipe->draw ); 77848b8605Smrg 78848b8605Smrg if (softpipe->quad.shade) 79848b8605Smrg softpipe->quad.shade->destroy( softpipe->quad.shade ); 80848b8605Smrg 81848b8605Smrg if (softpipe->quad.depth_test) 82848b8605Smrg softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); 83848b8605Smrg 84848b8605Smrg if (softpipe->quad.blend) 85848b8605Smrg softpipe->quad.blend->destroy( softpipe->quad.blend ); 86848b8605Smrg 87848b8605Smrg if (softpipe->quad.pstipple) 88848b8605Smrg softpipe->quad.pstipple->destroy( softpipe->quad.pstipple ); 89848b8605Smrg 90b8e80941Smrg if (softpipe->pipe.stream_uploader) 91b8e80941Smrg u_upload_destroy(softpipe->pipe.stream_uploader); 92b8e80941Smrg 93848b8605Smrg for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 94848b8605Smrg sp_destroy_tile_cache(softpipe->cbuf_cache[i]); 95848b8605Smrg pipe_surface_reference(&softpipe->framebuffer.cbufs[i], NULL); 96848b8605Smrg } 97848b8605Smrg 98848b8605Smrg sp_destroy_tile_cache(softpipe->zsbuf_cache); 99848b8605Smrg pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL); 100848b8605Smrg 101b8e80941Smrg for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) { 102b8e80941Smrg for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) { 103848b8605Smrg sp_destroy_tex_tile_cache(softpipe->tex_cache[sh][i]); 104848b8605Smrg pipe_sampler_view_reference(&softpipe->sampler_views[sh][i], NULL); 105848b8605Smrg } 106848b8605Smrg } 107848b8605Smrg 108b8e80941Smrg for (sh = 0; sh < ARRAY_SIZE(softpipe->constants); sh++) { 109b8e80941Smrg for (i = 0; i < ARRAY_SIZE(softpipe->constants[0]); i++) { 110848b8605Smrg if (softpipe->constants[sh][i]) { 111848b8605Smrg pipe_resource_reference(&softpipe->constants[sh][i], NULL); 112848b8605Smrg } 113848b8605Smrg } 114848b8605Smrg } 115848b8605Smrg 116848b8605Smrg for (i = 0; i < softpipe->num_vertex_buffers; i++) { 117b8e80941Smrg pipe_vertex_buffer_unreference(&softpipe->vertex_buffer[i]); 118848b8605Smrg } 119848b8605Smrg 120848b8605Smrg tgsi_exec_machine_destroy(softpipe->fs_machine); 121848b8605Smrg 122848b8605Smrg for (i = 0; i < PIPE_SHADER_TYPES; i++) { 123848b8605Smrg FREE(softpipe->tgsi.sampler[i]); 124b8e80941Smrg FREE(softpipe->tgsi.image[i]); 125b8e80941Smrg FREE(softpipe->tgsi.buffer[i]); 126848b8605Smrg } 127848b8605Smrg 128848b8605Smrg FREE( softpipe ); 129848b8605Smrg} 130848b8605Smrg 131848b8605Smrg 132848b8605Smrg/** 133848b8605Smrg * if (the texture is being used as a framebuffer surface) 134848b8605Smrg * return SP_REFERENCED_FOR_WRITE 135848b8605Smrg * else if (the texture is a bound texture source) 136848b8605Smrg * return SP_REFERENCED_FOR_READ 137848b8605Smrg * else 138848b8605Smrg * return SP_UNREFERENCED 139848b8605Smrg */ 140848b8605Smrgunsigned int 141848b8605Smrgsoftpipe_is_resource_referenced( struct pipe_context *pipe, 142848b8605Smrg struct pipe_resource *texture, 143848b8605Smrg unsigned level, int layer) 144848b8605Smrg{ 145848b8605Smrg struct softpipe_context *softpipe = softpipe_context( pipe ); 146848b8605Smrg unsigned i, sh; 147848b8605Smrg 148848b8605Smrg if (texture->target == PIPE_BUFFER) 149848b8605Smrg return SP_UNREFERENCED; 150848b8605Smrg 151848b8605Smrg /* check if any of the bound drawing surfaces are this texture */ 152848b8605Smrg if (softpipe->dirty_render_cache) { 153848b8605Smrg for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { 154848b8605Smrg if (softpipe->framebuffer.cbufs[i] && 155848b8605Smrg softpipe->framebuffer.cbufs[i]->texture == texture) { 156848b8605Smrg return SP_REFERENCED_FOR_WRITE; 157848b8605Smrg } 158848b8605Smrg } 159848b8605Smrg if (softpipe->framebuffer.zsbuf && 160848b8605Smrg softpipe->framebuffer.zsbuf->texture == texture) { 161848b8605Smrg return SP_REFERENCED_FOR_WRITE; 162848b8605Smrg } 163848b8605Smrg } 164848b8605Smrg 165848b8605Smrg /* check if any of the tex_cache textures are this texture */ 166b8e80941Smrg for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) { 167b8e80941Smrg for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) { 168848b8605Smrg if (softpipe->tex_cache[sh][i] && 169848b8605Smrg softpipe->tex_cache[sh][i]->texture == texture) 170848b8605Smrg return SP_REFERENCED_FOR_READ; 171848b8605Smrg } 172848b8605Smrg } 173848b8605Smrg 174848b8605Smrg return SP_UNREFERENCED; 175848b8605Smrg} 176848b8605Smrg 177848b8605Smrg 178848b8605Smrg 179848b8605Smrg 180848b8605Smrgstatic void 181b8e80941Smrgsoftpipe_render_condition(struct pipe_context *pipe, 182b8e80941Smrg struct pipe_query *query, 183b8e80941Smrg boolean condition, 184b8e80941Smrg enum pipe_render_cond_flag mode) 185848b8605Smrg{ 186848b8605Smrg struct softpipe_context *softpipe = softpipe_context( pipe ); 187848b8605Smrg 188848b8605Smrg softpipe->render_cond_query = query; 189848b8605Smrg softpipe->render_cond_mode = mode; 190848b8605Smrg softpipe->render_cond_cond = condition; 191848b8605Smrg} 192848b8605Smrg 193848b8605Smrg 194848b8605Smrg 195848b8605Smrgstruct pipe_context * 196b8e80941Smrgsoftpipe_create_context(struct pipe_screen *screen, 197b8e80941Smrg void *priv, unsigned flags) 198848b8605Smrg{ 199848b8605Smrg struct softpipe_screen *sp_screen = softpipe_screen(screen); 200848b8605Smrg struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); 201848b8605Smrg uint i, sh; 202848b8605Smrg 203848b8605Smrg util_init_math(); 204848b8605Smrg 205848b8605Smrg for (i = 0; i < PIPE_SHADER_TYPES; i++) { 206848b8605Smrg softpipe->tgsi.sampler[i] = sp_create_tgsi_sampler(); 207848b8605Smrg } 208848b8605Smrg 209b8e80941Smrg for (i = 0; i < PIPE_SHADER_TYPES; i++) { 210b8e80941Smrg softpipe->tgsi.image[i] = sp_create_tgsi_image(); 211b8e80941Smrg } 212b8e80941Smrg 213b8e80941Smrg for (i = 0; i < PIPE_SHADER_TYPES; i++) { 214b8e80941Smrg softpipe->tgsi.buffer[i] = sp_create_tgsi_buffer(); 215b8e80941Smrg } 216b8e80941Smrg 217848b8605Smrg softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE ); 218848b8605Smrg softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE ); 219b8e80941Smrg softpipe->dump_cs = debug_get_bool_option( "SOFTPIPE_DUMP_CS", FALSE ); 220848b8605Smrg 221848b8605Smrg softpipe->pipe.screen = screen; 222848b8605Smrg softpipe->pipe.destroy = softpipe_destroy; 223848b8605Smrg softpipe->pipe.priv = priv; 224848b8605Smrg 225848b8605Smrg /* state setters */ 226848b8605Smrg softpipe_init_blend_funcs(&softpipe->pipe); 227848b8605Smrg softpipe_init_clip_funcs(&softpipe->pipe); 228848b8605Smrg softpipe_init_query_funcs( softpipe ); 229848b8605Smrg softpipe_init_rasterizer_funcs(&softpipe->pipe); 230848b8605Smrg softpipe_init_sampler_funcs(&softpipe->pipe); 231848b8605Smrg softpipe_init_shader_funcs(&softpipe->pipe); 232848b8605Smrg softpipe_init_streamout_funcs(&softpipe->pipe); 233848b8605Smrg softpipe_init_texture_funcs( &softpipe->pipe ); 234848b8605Smrg softpipe_init_vertex_funcs(&softpipe->pipe); 235b8e80941Smrg softpipe_init_image_funcs(&softpipe->pipe); 236848b8605Smrg 237848b8605Smrg softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; 238848b8605Smrg 239848b8605Smrg softpipe->pipe.draw_vbo = softpipe_draw_vbo; 240848b8605Smrg 241b8e80941Smrg softpipe->pipe.launch_grid = softpipe_launch_grid; 242b8e80941Smrg 243848b8605Smrg softpipe->pipe.clear = softpipe_clear; 244848b8605Smrg softpipe->pipe.flush = softpipe_flush_wrapped; 245b8e80941Smrg softpipe->pipe.texture_barrier = softpipe_texture_barrier; 246b8e80941Smrg softpipe->pipe.memory_barrier = softpipe_memory_barrier; 247848b8605Smrg softpipe->pipe.render_condition = softpipe_render_condition; 248848b8605Smrg 249848b8605Smrg /* 250848b8605Smrg * Alloc caches for accessing drawing surfaces and textures. 251848b8605Smrg * Must be before quad stage setup! 252848b8605Smrg */ 253848b8605Smrg for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) 254848b8605Smrg softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe ); 255848b8605Smrg softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe ); 256848b8605Smrg 257848b8605Smrg /* Allocate texture caches */ 258b8e80941Smrg for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) { 259b8e80941Smrg for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) { 260848b8605Smrg softpipe->tex_cache[sh][i] = sp_create_tex_tile_cache(&softpipe->pipe); 261848b8605Smrg if (!softpipe->tex_cache[sh][i]) 262848b8605Smrg goto fail; 263848b8605Smrg } 264848b8605Smrg } 265848b8605Smrg 266b8e80941Smrg softpipe->fs_machine = tgsi_exec_machine_create(PIPE_SHADER_FRAGMENT); 267848b8605Smrg 268848b8605Smrg /* setup quad rendering stages */ 269848b8605Smrg softpipe->quad.shade = sp_quad_shade_stage(softpipe); 270848b8605Smrg softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); 271848b8605Smrg softpipe->quad.blend = sp_quad_blend_stage(softpipe); 272848b8605Smrg softpipe->quad.pstipple = sp_quad_polygon_stipple_stage(softpipe); 273848b8605Smrg 274b8e80941Smrg softpipe->pipe.stream_uploader = u_upload_create_default(&softpipe->pipe); 275b8e80941Smrg if (!softpipe->pipe.stream_uploader) 276b8e80941Smrg goto fail; 277b8e80941Smrg softpipe->pipe.const_uploader = softpipe->pipe.stream_uploader; 278848b8605Smrg 279848b8605Smrg /* 280848b8605Smrg * Create drawing context and plug our rendering stage into it. 281848b8605Smrg */ 282848b8605Smrg if (sp_screen->use_llvm) 283848b8605Smrg softpipe->draw = draw_create(&softpipe->pipe); 284848b8605Smrg else 285848b8605Smrg softpipe->draw = draw_create_no_llvm(&softpipe->pipe); 286848b8605Smrg if (!softpipe->draw) 287848b8605Smrg goto fail; 288848b8605Smrg 289848b8605Smrg draw_texture_sampler(softpipe->draw, 290848b8605Smrg PIPE_SHADER_VERTEX, 291848b8605Smrg (struct tgsi_sampler *) 292848b8605Smrg softpipe->tgsi.sampler[PIPE_SHADER_VERTEX]); 293848b8605Smrg 294848b8605Smrg draw_texture_sampler(softpipe->draw, 295848b8605Smrg PIPE_SHADER_GEOMETRY, 296848b8605Smrg (struct tgsi_sampler *) 297848b8605Smrg softpipe->tgsi.sampler[PIPE_SHADER_GEOMETRY]); 298848b8605Smrg 299b8e80941Smrg draw_image(softpipe->draw, 300b8e80941Smrg PIPE_SHADER_VERTEX, 301b8e80941Smrg (struct tgsi_image *) 302b8e80941Smrg softpipe->tgsi.image[PIPE_SHADER_VERTEX]); 303b8e80941Smrg 304b8e80941Smrg draw_image(softpipe->draw, 305b8e80941Smrg PIPE_SHADER_GEOMETRY, 306b8e80941Smrg (struct tgsi_image *) 307b8e80941Smrg softpipe->tgsi.image[PIPE_SHADER_GEOMETRY]); 308b8e80941Smrg 309b8e80941Smrg draw_buffer(softpipe->draw, 310b8e80941Smrg PIPE_SHADER_VERTEX, 311b8e80941Smrg (struct tgsi_buffer *) 312b8e80941Smrg softpipe->tgsi.buffer[PIPE_SHADER_VERTEX]); 313b8e80941Smrg 314b8e80941Smrg draw_buffer(softpipe->draw, 315b8e80941Smrg PIPE_SHADER_GEOMETRY, 316b8e80941Smrg (struct tgsi_buffer *) 317b8e80941Smrg softpipe->tgsi.buffer[PIPE_SHADER_GEOMETRY]); 318b8e80941Smrg 319848b8605Smrg if (debug_get_bool_option( "SOFTPIPE_NO_RAST", FALSE )) 320848b8605Smrg softpipe->no_rast = TRUE; 321848b8605Smrg 322848b8605Smrg softpipe->vbuf_backend = sp_create_vbuf_backend(softpipe); 323848b8605Smrg if (!softpipe->vbuf_backend) 324848b8605Smrg goto fail; 325848b8605Smrg 326848b8605Smrg softpipe->vbuf = draw_vbuf_stage(softpipe->draw, softpipe->vbuf_backend); 327848b8605Smrg if (!softpipe->vbuf) 328848b8605Smrg goto fail; 329848b8605Smrg 330848b8605Smrg draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf); 331848b8605Smrg draw_set_render(softpipe->draw, softpipe->vbuf_backend); 332848b8605Smrg 333848b8605Smrg softpipe->blitter = util_blitter_create(&softpipe->pipe); 334848b8605Smrg if (!softpipe->blitter) { 335848b8605Smrg goto fail; 336848b8605Smrg } 337848b8605Smrg 338848b8605Smrg /* must be done before installing Draw stages */ 339848b8605Smrg util_blitter_cache_all_shaders(softpipe->blitter); 340848b8605Smrg 341848b8605Smrg /* plug in AA line/point stages */ 342848b8605Smrg draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); 343848b8605Smrg draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); 344848b8605Smrg 345848b8605Smrg /* Do polygon stipple w/ texture map + frag prog? */ 346848b8605Smrg#if DO_PSTIPPLE_IN_DRAW_MODULE 347848b8605Smrg draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); 348848b8605Smrg#endif 349848b8605Smrg 350848b8605Smrg draw_wide_point_sprites(softpipe->draw, TRUE); 351848b8605Smrg 352848b8605Smrg sp_init_surface_functions(softpipe); 353848b8605Smrg 354848b8605Smrg#if DO_PSTIPPLE_IN_HELPER_MODULE 355848b8605Smrg /* create the polgon stipple sampler */ 356848b8605Smrg softpipe->pstipple.sampler = util_pstipple_create_sampler(&softpipe->pipe); 357848b8605Smrg#endif 358848b8605Smrg 359848b8605Smrg return &softpipe->pipe; 360848b8605Smrg 361848b8605Smrg fail: 362848b8605Smrg softpipe_destroy(&softpipe->pipe); 363848b8605Smrg return NULL; 364848b8605Smrg} 365