14a49301eSmrg/************************************************************************** 24a49301eSmrg * 3af69d88dSmrg * Copyright 2007 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 54a49301eSmrg * Copyright 2008 VMware, Inc. All rights reserved. 64a49301eSmrg * 74a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 84a49301eSmrg * copy of this software and associated documentation files (the 94a49301eSmrg * "Software"), to deal in the Software without restriction, including 104a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 114a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 124a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 134a49301eSmrg * the following conditions: 144a49301eSmrg * 154a49301eSmrg * The above copyright notice and this permission notice (including the 164a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 174a49301eSmrg * of the Software. 184a49301eSmrg * 194a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 204a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 214a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 234a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 244a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 254a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 264a49301eSmrg * 274a49301eSmrg **************************************************************************/ 284a49301eSmrg 294a49301eSmrg/* Author: 30af69d88dSmrg * Keith Whitwell <keithw@vmware.com> 314a49301eSmrg */ 324a49301eSmrg 334a49301eSmrg#include "draw/draw_context.h" 344a49301eSmrg#include "draw/draw_vbuf.h" 354a49301eSmrg#include "pipe/p_defines.h" 364a49301eSmrg#include "util/u_math.h" 374a49301eSmrg#include "util/u_memory.h" 38af69d88dSmrg#include "util/u_pstipple.h" 39cdc920a0Smrg#include "util/u_inlines.h" 4001e04c3fSmrg#include "util/u_upload_mgr.h" 413464ebd5Sriastradh#include "tgsi/tgsi_exec.h" 4201e04c3fSmrg#include "sp_buffer.h" 434a49301eSmrg#include "sp_clear.h" 444a49301eSmrg#include "sp_context.h" 454a49301eSmrg#include "sp_flush.h" 464a49301eSmrg#include "sp_prim_vbuf.h" 474a49301eSmrg#include "sp_state.h" 484a49301eSmrg#include "sp_surface.h" 494a49301eSmrg#include "sp_tile_cache.h" 504a49301eSmrg#include "sp_tex_tile_cache.h" 513464ebd5Sriastradh#include "sp_texture.h" 524a49301eSmrg#include "sp_query.h" 53af69d88dSmrg#include "sp_screen.h" 54af69d88dSmrg#include "sp_tex_sample.h" 5501e04c3fSmrg#include "sp_image.h" 564a49301eSmrg 57af69d88dSmrgstatic void 58af69d88dSmrgsoftpipe_destroy( struct pipe_context *pipe ) 594a49301eSmrg{ 60af69d88dSmrg struct softpipe_context *softpipe = softpipe_context( pipe ); 61af69d88dSmrg uint i, sh; 624a49301eSmrg 63af69d88dSmrg#if DO_PSTIPPLE_IN_HELPER_MODULE 64af69d88dSmrg if (softpipe->pstipple.sampler) 65af69d88dSmrg pipe->delete_sampler_state(pipe, softpipe->pstipple.sampler); 664a49301eSmrg 67af69d88dSmrg pipe_resource_reference(&softpipe->pstipple.texture, NULL); 68af69d88dSmrg pipe_sampler_view_reference(&softpipe->pstipple.sampler_view, NULL); 69af69d88dSmrg#endif 704a49301eSmrg 71af69d88dSmrg if (softpipe->blitter) { 72af69d88dSmrg util_blitter_destroy(softpipe->blitter); 734a49301eSmrg } 744a49301eSmrg 754a49301eSmrg if (softpipe->draw) 764a49301eSmrg draw_destroy( softpipe->draw ); 774a49301eSmrg 783464ebd5Sriastradh if (softpipe->quad.shade) 793464ebd5Sriastradh softpipe->quad.shade->destroy( softpipe->quad.shade ); 803464ebd5Sriastradh 813464ebd5Sriastradh if (softpipe->quad.depth_test) 823464ebd5Sriastradh softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); 833464ebd5Sriastradh 843464ebd5Sriastradh if (softpipe->quad.blend) 853464ebd5Sriastradh softpipe->quad.blend->destroy( softpipe->quad.blend ); 863464ebd5Sriastradh 873464ebd5Sriastradh if (softpipe->quad.pstipple) 883464ebd5Sriastradh softpipe->quad.pstipple->destroy( softpipe->quad.pstipple ); 894a49301eSmrg 9001e04c3fSmrg if (softpipe->pipe.stream_uploader) 9101e04c3fSmrg u_upload_destroy(softpipe->pipe.stream_uploader); 9201e04c3fSmrg 934a49301eSmrg for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 944a49301eSmrg sp_destroy_tile_cache(softpipe->cbuf_cache[i]); 954a49301eSmrg pipe_surface_reference(&softpipe->framebuffer.cbufs[i], NULL); 964a49301eSmrg } 97cdc920a0Smrg 984a49301eSmrg sp_destroy_tile_cache(softpipe->zsbuf_cache); 994a49301eSmrg pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL); 1004a49301eSmrg 10101e04c3fSmrg for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) { 10201e04c3fSmrg for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) { 103af69d88dSmrg sp_destroy_tex_tile_cache(softpipe->tex_cache[sh][i]); 104af69d88dSmrg pipe_sampler_view_reference(&softpipe->sampler_views[sh][i], NULL); 105af69d88dSmrg } 106cdc920a0Smrg } 107cdc920a0Smrg 10801e04c3fSmrg for (sh = 0; sh < ARRAY_SIZE(softpipe->constants); sh++) { 10901e04c3fSmrg for (i = 0; i < ARRAY_SIZE(softpipe->constants[0]); i++) { 110af69d88dSmrg if (softpipe->constants[sh][i]) { 111af69d88dSmrg pipe_resource_reference(&softpipe->constants[sh][i], NULL); 112cdc920a0Smrg } 1134a49301eSmrg } 1144a49301eSmrg } 1154a49301eSmrg 1163464ebd5Sriastradh for (i = 0; i < softpipe->num_vertex_buffers; i++) { 11701e04c3fSmrg pipe_vertex_buffer_unreference(&softpipe->vertex_buffer[i]); 1183464ebd5Sriastradh } 1193464ebd5Sriastradh 1203464ebd5Sriastradh tgsi_exec_machine_destroy(softpipe->fs_machine); 1213464ebd5Sriastradh 122af69d88dSmrg for (i = 0; i < PIPE_SHADER_TYPES; i++) { 123af69d88dSmrg FREE(softpipe->tgsi.sampler[i]); 12401e04c3fSmrg FREE(softpipe->tgsi.image[i]); 12501e04c3fSmrg FREE(softpipe->tgsi.buffer[i]); 126af69d88dSmrg } 127af69d88dSmrg 1284a49301eSmrg FREE( softpipe ); 1294a49301eSmrg} 1304a49301eSmrg 1314a49301eSmrg 1324a49301eSmrg/** 1334a49301eSmrg * if (the texture is being used as a framebuffer surface) 1343464ebd5Sriastradh * return SP_REFERENCED_FOR_WRITE 1354a49301eSmrg * else if (the texture is a bound texture source) 1363464ebd5Sriastradh * return SP_REFERENCED_FOR_READ 1374a49301eSmrg * else 1383464ebd5Sriastradh * return SP_UNREFERENCED 1394a49301eSmrg */ 1403464ebd5Sriastradhunsigned int 1413464ebd5Sriastradhsoftpipe_is_resource_referenced( struct pipe_context *pipe, 1423464ebd5Sriastradh struct pipe_resource *texture, 1433464ebd5Sriastradh unsigned level, int layer) 1444a49301eSmrg{ 1454a49301eSmrg struct softpipe_context *softpipe = softpipe_context( pipe ); 146af69d88dSmrg unsigned i, sh; 1474a49301eSmrg 1483464ebd5Sriastradh if (texture->target == PIPE_BUFFER) 1493464ebd5Sriastradh return SP_UNREFERENCED; 1503464ebd5Sriastradh 1514a49301eSmrg /* check if any of the bound drawing surfaces are this texture */ 1524a49301eSmrg if (softpipe->dirty_render_cache) { 1534a49301eSmrg for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { 1544a49301eSmrg if (softpipe->framebuffer.cbufs[i] && 1554a49301eSmrg softpipe->framebuffer.cbufs[i]->texture == texture) { 1563464ebd5Sriastradh return SP_REFERENCED_FOR_WRITE; 1574a49301eSmrg } 1584a49301eSmrg } 1594a49301eSmrg if (softpipe->framebuffer.zsbuf && 1604a49301eSmrg softpipe->framebuffer.zsbuf->texture == texture) { 1613464ebd5Sriastradh return SP_REFERENCED_FOR_WRITE; 1624a49301eSmrg } 1634a49301eSmrg } 1644a49301eSmrg 1654a49301eSmrg /* check if any of the tex_cache textures are this texture */ 16601e04c3fSmrg for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) { 16701e04c3fSmrg for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) { 168af69d88dSmrg if (softpipe->tex_cache[sh][i] && 169af69d88dSmrg softpipe->tex_cache[sh][i]->texture == texture) 170af69d88dSmrg return SP_REFERENCED_FOR_READ; 171af69d88dSmrg } 1723464ebd5Sriastradh } 1733464ebd5Sriastradh 1743464ebd5Sriastradh return SP_UNREFERENCED; 1754a49301eSmrg} 1764a49301eSmrg 1774a49301eSmrg 1784a49301eSmrg 1794a49301eSmrg 180cdc920a0Smrgstatic void 18101e04c3fSmrgsoftpipe_render_condition(struct pipe_context *pipe, 18201e04c3fSmrg struct pipe_query *query, 1837ec681f3Smrg bool condition, 18401e04c3fSmrg enum pipe_render_cond_flag mode) 185cdc920a0Smrg{ 186cdc920a0Smrg struct softpipe_context *softpipe = softpipe_context( pipe ); 187cdc920a0Smrg 188cdc920a0Smrg softpipe->render_cond_query = query; 189cdc920a0Smrg softpipe->render_cond_mode = mode; 190af69d88dSmrg softpipe->render_cond_cond = condition; 191cdc920a0Smrg} 192cdc920a0Smrg 193cdc920a0Smrg 1947ec681f3Smrgstatic void 1957ec681f3Smrgsoftpipe_set_debug_callback(struct pipe_context *pipe, 1967ec681f3Smrg const struct pipe_debug_callback *cb) 1977ec681f3Smrg{ 1987ec681f3Smrg struct softpipe_context *softpipe = softpipe_context(pipe); 1997ec681f3Smrg 2007ec681f3Smrg if (cb) 2017ec681f3Smrg softpipe->debug = *cb; 2027ec681f3Smrg else 2037ec681f3Smrg memset(&softpipe->debug, 0, sizeof(softpipe->debug)); 2047ec681f3Smrg} 2057ec681f3Smrg 206cdc920a0Smrg 2074a49301eSmrgstruct pipe_context * 20801e04c3fSmrgsoftpipe_create_context(struct pipe_screen *screen, 20901e04c3fSmrg void *priv, unsigned flags) 2104a49301eSmrg{ 211af69d88dSmrg struct softpipe_screen *sp_screen = softpipe_screen(screen); 2124a49301eSmrg struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); 213af69d88dSmrg uint i, sh; 2144a49301eSmrg 2154a49301eSmrg util_init_math(); 2164a49301eSmrg 217af69d88dSmrg for (i = 0; i < PIPE_SHADER_TYPES; i++) { 218af69d88dSmrg softpipe->tgsi.sampler[i] = sp_create_tgsi_sampler(); 219af69d88dSmrg } 2204a49301eSmrg 22101e04c3fSmrg for (i = 0; i < PIPE_SHADER_TYPES; i++) { 22201e04c3fSmrg softpipe->tgsi.image[i] = sp_create_tgsi_image(); 22301e04c3fSmrg } 22401e04c3fSmrg 22501e04c3fSmrg for (i = 0; i < PIPE_SHADER_TYPES; i++) { 22601e04c3fSmrg softpipe->tgsi.buffer[i] = sp_create_tgsi_buffer(); 22701e04c3fSmrg } 22801e04c3fSmrg 2294a49301eSmrg softpipe->pipe.screen = screen; 2304a49301eSmrg softpipe->pipe.destroy = softpipe_destroy; 231cdc920a0Smrg softpipe->pipe.priv = priv; 2324a49301eSmrg 2334a49301eSmrg /* state setters */ 2343464ebd5Sriastradh softpipe_init_blend_funcs(&softpipe->pipe); 2353464ebd5Sriastradh softpipe_init_clip_funcs(&softpipe->pipe); 2363464ebd5Sriastradh softpipe_init_query_funcs( softpipe ); 2373464ebd5Sriastradh softpipe_init_rasterizer_funcs(&softpipe->pipe); 2383464ebd5Sriastradh softpipe_init_sampler_funcs(&softpipe->pipe); 2393464ebd5Sriastradh softpipe_init_shader_funcs(&softpipe->pipe); 2403464ebd5Sriastradh softpipe_init_streamout_funcs(&softpipe->pipe); 2413464ebd5Sriastradh softpipe_init_texture_funcs( &softpipe->pipe ); 2423464ebd5Sriastradh softpipe_init_vertex_funcs(&softpipe->pipe); 24301e04c3fSmrg softpipe_init_image_funcs(&softpipe->pipe); 2444a49301eSmrg 2453464ebd5Sriastradh softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; 2467ec681f3Smrg softpipe->pipe.set_debug_callback = softpipe_set_debug_callback; 2474a49301eSmrg 2483464ebd5Sriastradh softpipe->pipe.draw_vbo = softpipe_draw_vbo; 2494a49301eSmrg 25001e04c3fSmrg softpipe->pipe.launch_grid = softpipe_launch_grid; 25101e04c3fSmrg 2524a49301eSmrg softpipe->pipe.clear = softpipe_clear; 2533464ebd5Sriastradh softpipe->pipe.flush = softpipe_flush_wrapped; 25401e04c3fSmrg softpipe->pipe.texture_barrier = softpipe_texture_barrier; 25501e04c3fSmrg softpipe->pipe.memory_barrier = softpipe_memory_barrier; 256cdc920a0Smrg softpipe->pipe.render_condition = softpipe_render_condition; 257af69d88dSmrg 2584a49301eSmrg /* 2594a49301eSmrg * Alloc caches for accessing drawing surfaces and textures. 2604a49301eSmrg * Must be before quad stage setup! 2614a49301eSmrg */ 2624a49301eSmrg for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) 2633464ebd5Sriastradh softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe ); 2643464ebd5Sriastradh softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe ); 2653464ebd5Sriastradh 266af69d88dSmrg /* Allocate texture caches */ 26701e04c3fSmrg for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) { 26801e04c3fSmrg for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) { 269af69d88dSmrg softpipe->tex_cache[sh][i] = sp_create_tex_tile_cache(&softpipe->pipe); 270af69d88dSmrg if (!softpipe->tex_cache[sh][i]) 271af69d88dSmrg goto fail; 272af69d88dSmrg } 2733464ebd5Sriastradh } 2743464ebd5Sriastradh 27501e04c3fSmrg softpipe->fs_machine = tgsi_exec_machine_create(PIPE_SHADER_FRAGMENT); 2763464ebd5Sriastradh 2774a49301eSmrg /* setup quad rendering stages */ 2784a49301eSmrg softpipe->quad.shade = sp_quad_shade_stage(softpipe); 2794a49301eSmrg softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); 2804a49301eSmrg softpipe->quad.blend = sp_quad_blend_stage(softpipe); 2813464ebd5Sriastradh softpipe->quad.pstipple = sp_quad_polygon_stipple_stage(softpipe); 2824a49301eSmrg 28301e04c3fSmrg softpipe->pipe.stream_uploader = u_upload_create_default(&softpipe->pipe); 28401e04c3fSmrg if (!softpipe->pipe.stream_uploader) 28501e04c3fSmrg goto fail; 28601e04c3fSmrg softpipe->pipe.const_uploader = softpipe->pipe.stream_uploader; 2874a49301eSmrg 2884a49301eSmrg /* 2894a49301eSmrg * Create drawing context and plug our rendering stage into it. 2904a49301eSmrg */ 291af69d88dSmrg if (sp_screen->use_llvm) 292af69d88dSmrg softpipe->draw = draw_create(&softpipe->pipe); 293af69d88dSmrg else 294af69d88dSmrg softpipe->draw = draw_create_no_llvm(&softpipe->pipe); 2954a49301eSmrg if (!softpipe->draw) 2964a49301eSmrg goto fail; 2974a49301eSmrg 298af69d88dSmrg draw_texture_sampler(softpipe->draw, 299af69d88dSmrg PIPE_SHADER_VERTEX, 300af69d88dSmrg (struct tgsi_sampler *) 301af69d88dSmrg softpipe->tgsi.sampler[PIPE_SHADER_VERTEX]); 3024a49301eSmrg 303af69d88dSmrg draw_texture_sampler(softpipe->draw, 304af69d88dSmrg PIPE_SHADER_GEOMETRY, 305af69d88dSmrg (struct tgsi_sampler *) 306af69d88dSmrg softpipe->tgsi.sampler[PIPE_SHADER_GEOMETRY]); 3073464ebd5Sriastradh 30801e04c3fSmrg draw_image(softpipe->draw, 30901e04c3fSmrg PIPE_SHADER_VERTEX, 31001e04c3fSmrg (struct tgsi_image *) 31101e04c3fSmrg softpipe->tgsi.image[PIPE_SHADER_VERTEX]); 31201e04c3fSmrg 31301e04c3fSmrg draw_image(softpipe->draw, 31401e04c3fSmrg PIPE_SHADER_GEOMETRY, 31501e04c3fSmrg (struct tgsi_image *) 31601e04c3fSmrg softpipe->tgsi.image[PIPE_SHADER_GEOMETRY]); 31701e04c3fSmrg 31801e04c3fSmrg draw_buffer(softpipe->draw, 31901e04c3fSmrg PIPE_SHADER_VERTEX, 32001e04c3fSmrg (struct tgsi_buffer *) 32101e04c3fSmrg softpipe->tgsi.buffer[PIPE_SHADER_VERTEX]); 32201e04c3fSmrg 32301e04c3fSmrg draw_buffer(softpipe->draw, 32401e04c3fSmrg PIPE_SHADER_GEOMETRY, 32501e04c3fSmrg (struct tgsi_buffer *) 32601e04c3fSmrg softpipe->tgsi.buffer[PIPE_SHADER_GEOMETRY]); 32701e04c3fSmrg 3284a49301eSmrg softpipe->vbuf_backend = sp_create_vbuf_backend(softpipe); 3294a49301eSmrg if (!softpipe->vbuf_backend) 3304a49301eSmrg goto fail; 3314a49301eSmrg 3324a49301eSmrg softpipe->vbuf = draw_vbuf_stage(softpipe->draw, softpipe->vbuf_backend); 3334a49301eSmrg if (!softpipe->vbuf) 3344a49301eSmrg goto fail; 3354a49301eSmrg 3364a49301eSmrg draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf); 3374a49301eSmrg draw_set_render(softpipe->draw, softpipe->vbuf_backend); 3384a49301eSmrg 339af69d88dSmrg softpipe->blitter = util_blitter_create(&softpipe->pipe); 340af69d88dSmrg if (!softpipe->blitter) { 341af69d88dSmrg goto fail; 342af69d88dSmrg } 343af69d88dSmrg 344af69d88dSmrg /* must be done before installing Draw stages */ 345af69d88dSmrg util_blitter_cache_all_shaders(softpipe->blitter); 3464a49301eSmrg 3474a49301eSmrg /* plug in AA line/point stages */ 3484a49301eSmrg draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); 3494a49301eSmrg draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); 3504a49301eSmrg 3514a49301eSmrg /* Do polygon stipple w/ texture map + frag prog? */ 3523464ebd5Sriastradh#if DO_PSTIPPLE_IN_DRAW_MODULE 3534a49301eSmrg draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); 3543464ebd5Sriastradh#endif 3553464ebd5Sriastradh 3563464ebd5Sriastradh draw_wide_point_sprites(softpipe->draw, TRUE); 3574a49301eSmrg 3584a49301eSmrg sp_init_surface_functions(softpipe); 3594a49301eSmrg 360af69d88dSmrg#if DO_PSTIPPLE_IN_HELPER_MODULE 3617ec681f3Smrg /* create the polygon stipple sampler */ 362af69d88dSmrg softpipe->pstipple.sampler = util_pstipple_create_sampler(&softpipe->pipe); 363af69d88dSmrg#endif 364af69d88dSmrg 3654a49301eSmrg return &softpipe->pipe; 3664a49301eSmrg 3674a49301eSmrg fail: 3684a49301eSmrg softpipe_destroy(&softpipe->pipe); 3694a49301eSmrg return NULL; 3704a49301eSmrg} 371