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" 36cdc920a0Smrg#include "util/u_inlines.h" 374a49301eSmrg#include "util/u_math.h" 384a49301eSmrg#include "util/u_memory.h" 3901e04c3fSmrg#include "util/simple_list.h" 4001e04c3fSmrg#include "util/u_upload_mgr.h" 414a49301eSmrg#include "lp_clear.h" 424a49301eSmrg#include "lp_context.h" 434a49301eSmrg#include "lp_flush.h" 44cdc920a0Smrg#include "lp_perf.h" 454a49301eSmrg#include "lp_state.h" 464a49301eSmrg#include "lp_surface.h" 474a49301eSmrg#include "lp_query.h" 48cdc920a0Smrg#include "lp_setup.h" 497ec681f3Smrg#include "lp_screen.h" 504a49301eSmrg 5101e04c3fSmrg/* This is only safe if there's just one concurrent context */ 527ec681f3Smrg#ifdef EMBEDDED_DEVICE 5301e04c3fSmrg#define USE_GLOBAL_LLVM_CONTEXT 5401e04c3fSmrg#endif 554a49301eSmrg 564a49301eSmrgstatic void llvmpipe_destroy( struct pipe_context *pipe ) 574a49301eSmrg{ 584a49301eSmrg struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); 597ec681f3Smrg uint i; 604a49301eSmrg 61cdc920a0Smrg lp_print_counters(); 62cdc920a0Smrg 637ec681f3Smrg if (llvmpipe->csctx) { 647ec681f3Smrg lp_csctx_destroy(llvmpipe->csctx); 657ec681f3Smrg } 66af69d88dSmrg if (llvmpipe->blitter) { 67af69d88dSmrg util_blitter_destroy(llvmpipe->blitter); 68af69d88dSmrg } 693464ebd5Sriastradh 7001e04c3fSmrg if (llvmpipe->pipe.stream_uploader) 7101e04c3fSmrg u_upload_destroy(llvmpipe->pipe.stream_uploader); 7201e04c3fSmrg 73cdc920a0Smrg /* This will also destroy llvmpipe->setup: 74cdc920a0Smrg */ 754a49301eSmrg if (llvmpipe->draw) 764a49301eSmrg draw_destroy( llvmpipe->draw ); 774a49301eSmrg 784a49301eSmrg for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 794a49301eSmrg pipe_surface_reference(&llvmpipe->framebuffer.cbufs[i], NULL); 804a49301eSmrg } 81cdc920a0Smrg 824a49301eSmrg pipe_surface_reference(&llvmpipe->framebuffer.zsbuf, NULL); 834a49301eSmrg 847ec681f3Smrg for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) { 857ec681f3Smrg for (i = 0; i < ARRAY_SIZE(llvmpipe->sampler_views[0]); i++) { 867ec681f3Smrg pipe_sampler_view_reference(&llvmpipe->sampler_views[s][i], NULL); 877ec681f3Smrg } 887ec681f3Smrg for (i = 0; i < LP_MAX_TGSI_SHADER_IMAGES; i++) { 897ec681f3Smrg pipe_resource_reference(&llvmpipe->images[s][i].resource, NULL); 907ec681f3Smrg } 917ec681f3Smrg for (i = 0; i < LP_MAX_TGSI_SHADER_BUFFERS; i++) { 927ec681f3Smrg pipe_resource_reference(&llvmpipe->ssbos[s][i].buffer, NULL); 937ec681f3Smrg } 947ec681f3Smrg for (i = 0; i < ARRAY_SIZE(llvmpipe->constants[s]); i++) { 957ec681f3Smrg pipe_resource_reference(&llvmpipe->constants[s][i].buffer, NULL); 964a49301eSmrg } 974a49301eSmrg } 984a49301eSmrg 993464ebd5Sriastradh for (i = 0; i < llvmpipe->num_vertex_buffers; i++) { 10001e04c3fSmrg pipe_vertex_buffer_unreference(&llvmpipe->vertex_buffer[i]); 1013464ebd5Sriastradh } 1024a49301eSmrg 103af69d88dSmrg lp_delete_setup_variants(llvmpipe); 1044a49301eSmrg 10501e04c3fSmrg#ifndef USE_GLOBAL_LLVM_CONTEXT 10601e04c3fSmrg LLVMContextDispose(llvmpipe->context); 10701e04c3fSmrg#endif 10801e04c3fSmrg llvmpipe->context = NULL; 10901e04c3fSmrg 1103464ebd5Sriastradh align_free( llvmpipe ); 1114a49301eSmrg} 1124a49301eSmrg 1133464ebd5Sriastradhstatic void 1143464ebd5Sriastradhdo_flush( struct pipe_context *pipe, 115af69d88dSmrg struct pipe_fence_handle **fence, 116af69d88dSmrg unsigned flags) 1174a49301eSmrg{ 1183464ebd5Sriastradh llvmpipe_flush(pipe, fence, __FUNCTION__); 1194a49301eSmrg} 1204a49301eSmrg 1213464ebd5Sriastradh 122af69d88dSmrgstatic void 12301e04c3fSmrgllvmpipe_render_condition(struct pipe_context *pipe, 12401e04c3fSmrg struct pipe_query *query, 1257ec681f3Smrg bool condition, 12601e04c3fSmrg enum pipe_render_cond_flag mode) 127af69d88dSmrg{ 128af69d88dSmrg struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); 129af69d88dSmrg 130af69d88dSmrg llvmpipe->render_cond_query = query; 131af69d88dSmrg llvmpipe->render_cond_mode = mode; 132af69d88dSmrg llvmpipe->render_cond_cond = condition; 133af69d88dSmrg} 134af69d88dSmrg 1357ec681f3Smrgstatic void 1367ec681f3Smrgllvmpipe_render_condition_mem(struct pipe_context *pipe, 1377ec681f3Smrg struct pipe_resource *buffer, 1387ec681f3Smrg unsigned offset, 1397ec681f3Smrg bool condition) 1407ec681f3Smrg{ 1417ec681f3Smrg struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); 1427ec681f3Smrg 1437ec681f3Smrg llvmpipe->render_cond_buffer = llvmpipe_resource(buffer); 1447ec681f3Smrg llvmpipe->render_cond_offset = offset; 1457ec681f3Smrg llvmpipe->render_cond_cond = condition; 1467ec681f3Smrg} 1477ec681f3Smrg 1487ec681f3Smrgstatic void 1497ec681f3Smrgllvmpipe_texture_barrier(struct pipe_context *pipe, unsigned flags) 1507ec681f3Smrg{ 1517ec681f3Smrg llvmpipe_flush(pipe, NULL, __FUNCTION__); 1527ec681f3Smrg} 1537ec681f3Smrg 1547ec681f3Smrgstatic void lp_draw_disk_cache_find_shader(void *cookie, 1557ec681f3Smrg struct lp_cached_code *cache, 1567ec681f3Smrg unsigned char ir_sha1_cache_key[20]) 1577ec681f3Smrg{ 1587ec681f3Smrg struct llvmpipe_screen *screen = cookie; 1597ec681f3Smrg lp_disk_cache_find_shader(screen, cache, ir_sha1_cache_key); 1607ec681f3Smrg} 1617ec681f3Smrg 1627ec681f3Smrgstatic void lp_draw_disk_cache_insert_shader(void *cookie, 1637ec681f3Smrg struct lp_cached_code *cache, 1647ec681f3Smrg unsigned char ir_sha1_cache_key[20]) 1657ec681f3Smrg{ 1667ec681f3Smrg struct llvmpipe_screen *screen = cookie; 1677ec681f3Smrg lp_disk_cache_insert_shader(screen, cache, ir_sha1_cache_key); 1687ec681f3Smrg} 1697ec681f3Smrg 1707ec681f3Smrgstatic enum pipe_reset_status 1717ec681f3Smrgllvmpipe_get_device_reset_status(struct pipe_context *pipe) 1727ec681f3Smrg{ 1737ec681f3Smrg return PIPE_NO_RESET; 1747ec681f3Smrg} 1757ec681f3Smrg 1764a49301eSmrgstruct pipe_context * 17701e04c3fSmrgllvmpipe_create_context(struct pipe_screen *screen, void *priv, 17801e04c3fSmrg unsigned flags) 1794a49301eSmrg{ 1804a49301eSmrg struct llvmpipe_context *llvmpipe; 1814a49301eSmrg 1827ec681f3Smrg if (!llvmpipe_screen_late_init(llvmpipe_screen(screen))) 1837ec681f3Smrg return NULL; 1847ec681f3Smrg 1854a49301eSmrg llvmpipe = align_malloc(sizeof(struct llvmpipe_context), 16); 1864a49301eSmrg if (!llvmpipe) 1874a49301eSmrg return NULL; 1884a49301eSmrg 1894a49301eSmrg memset(llvmpipe, 0, sizeof *llvmpipe); 1904a49301eSmrg 1913464ebd5Sriastradh make_empty_list(&llvmpipe->fs_variants_list); 1924a49301eSmrg 1933464ebd5Sriastradh make_empty_list(&llvmpipe->setup_variants_list); 1944a49301eSmrg 1957ec681f3Smrg make_empty_list(&llvmpipe->cs_variants_list); 1964a49301eSmrg 1973464ebd5Sriastradh llvmpipe->pipe.screen = screen; 1983464ebd5Sriastradh llvmpipe->pipe.priv = priv; 1994a49301eSmrg 2003464ebd5Sriastradh /* Init the pipe context methods */ 2013464ebd5Sriastradh llvmpipe->pipe.destroy = llvmpipe_destroy; 2024a49301eSmrg llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state; 2034a49301eSmrg llvmpipe->pipe.clear = llvmpipe_clear; 2043464ebd5Sriastradh llvmpipe->pipe.flush = do_flush; 2057ec681f3Smrg llvmpipe->pipe.texture_barrier = llvmpipe_texture_barrier; 2064a49301eSmrg 207af69d88dSmrg llvmpipe->pipe.render_condition = llvmpipe_render_condition; 2087ec681f3Smrg llvmpipe->pipe.render_condition_mem = llvmpipe_render_condition_mem; 209af69d88dSmrg 2107ec681f3Smrg llvmpipe->pipe.get_device_reset_status = llvmpipe_get_device_reset_status; 2113464ebd5Sriastradh llvmpipe_init_blend_funcs(llvmpipe); 2123464ebd5Sriastradh llvmpipe_init_clip_funcs(llvmpipe); 2133464ebd5Sriastradh llvmpipe_init_draw_funcs(llvmpipe); 2147ec681f3Smrg llvmpipe_init_compute_funcs(llvmpipe); 2153464ebd5Sriastradh llvmpipe_init_sampler_funcs(llvmpipe); 2164a49301eSmrg llvmpipe_init_query_funcs( llvmpipe ); 2173464ebd5Sriastradh llvmpipe_init_vertex_funcs(llvmpipe); 2183464ebd5Sriastradh llvmpipe_init_so_funcs(llvmpipe); 2193464ebd5Sriastradh llvmpipe_init_fs_funcs(llvmpipe); 2203464ebd5Sriastradh llvmpipe_init_vs_funcs(llvmpipe); 2213464ebd5Sriastradh llvmpipe_init_gs_funcs(llvmpipe); 2227ec681f3Smrg llvmpipe_init_tess_funcs(llvmpipe); 2233464ebd5Sriastradh llvmpipe_init_rasterizer_funcs(llvmpipe); 2243464ebd5Sriastradh llvmpipe_init_context_resource_funcs( &llvmpipe->pipe ); 2253464ebd5Sriastradh llvmpipe_init_surface_functions(llvmpipe); 2263464ebd5Sriastradh 22701e04c3fSmrg#ifdef USE_GLOBAL_LLVM_CONTEXT 22801e04c3fSmrg llvmpipe->context = LLVMGetGlobalContext(); 22901e04c3fSmrg#else 23001e04c3fSmrg llvmpipe->context = LLVMContextCreate(); 23101e04c3fSmrg#endif 23201e04c3fSmrg 23301e04c3fSmrg if (!llvmpipe->context) 23401e04c3fSmrg goto fail; 23501e04c3fSmrg 2364a49301eSmrg /* 2374a49301eSmrg * Create drawing context and plug our rendering stage into it. 2384a49301eSmrg */ 23901e04c3fSmrg llvmpipe->draw = draw_create_with_llvm_context(&llvmpipe->pipe, 24001e04c3fSmrg llvmpipe->context); 2413464ebd5Sriastradh if (!llvmpipe->draw) 2424a49301eSmrg goto fail; 2434a49301eSmrg 2447ec681f3Smrg draw_set_disk_cache_callbacks(llvmpipe->draw, 2457ec681f3Smrg llvmpipe_screen(screen), 2467ec681f3Smrg lp_draw_disk_cache_find_shader, 2477ec681f3Smrg lp_draw_disk_cache_insert_shader); 2487ec681f3Smrg 2497ec681f3Smrg draw_set_constant_buffer_stride(llvmpipe->draw, lp_get_constant_buffer_stride(screen)); 2507ec681f3Smrg 251cdc920a0Smrg /* FIXME: devise alternative to draw_texture_samplers */ 2524a49301eSmrg 253cdc920a0Smrg llvmpipe->setup = lp_setup_create( &llvmpipe->pipe, 254cdc920a0Smrg llvmpipe->draw ); 255cdc920a0Smrg if (!llvmpipe->setup) 2564a49301eSmrg goto fail; 2574a49301eSmrg 2587ec681f3Smrg llvmpipe->csctx = lp_csctx_create( &llvmpipe->pipe ); 2597ec681f3Smrg if (!llvmpipe->csctx) 2607ec681f3Smrg goto fail; 26101e04c3fSmrg llvmpipe->pipe.stream_uploader = u_upload_create_default(&llvmpipe->pipe); 26201e04c3fSmrg if (!llvmpipe->pipe.stream_uploader) 26301e04c3fSmrg goto fail; 26401e04c3fSmrg llvmpipe->pipe.const_uploader = llvmpipe->pipe.stream_uploader; 26501e04c3fSmrg 266af69d88dSmrg llvmpipe->blitter = util_blitter_create(&llvmpipe->pipe); 267af69d88dSmrg if (!llvmpipe->blitter) { 268af69d88dSmrg goto fail; 269af69d88dSmrg } 270af69d88dSmrg 271af69d88dSmrg /* must be done before installing Draw stages */ 272af69d88dSmrg util_blitter_cache_all_shaders(llvmpipe->blitter); 273af69d88dSmrg 2744a49301eSmrg /* plug in AA line/point stages */ 2754a49301eSmrg draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe); 2764a49301eSmrg draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe); 2773464ebd5Sriastradh draw_install_pstipple_stage(llvmpipe->draw, &llvmpipe->pipe); 2783464ebd5Sriastradh 2793464ebd5Sriastradh /* convert points and lines into triangles: 2803464ebd5Sriastradh * (otherwise, draw points and lines natively) 2813464ebd5Sriastradh */ 2823464ebd5Sriastradh draw_wide_point_sprites(llvmpipe->draw, FALSE); 2833464ebd5Sriastradh draw_enable_point_sprites(llvmpipe->draw, FALSE); 2843464ebd5Sriastradh draw_wide_point_threshold(llvmpipe->draw, 10000.0); 2853464ebd5Sriastradh draw_wide_line_threshold(llvmpipe->draw, 10000.0); 2864a49301eSmrg 2877ec681f3Smrg /* initial state for clipping - enabled, with no guardband */ 2887ec681f3Smrg draw_set_driver_clipping(llvmpipe->draw, FALSE, FALSE, FALSE, TRUE); 2897ec681f3Smrg 290cdc920a0Smrg lp_reset_counters(); 291cdc920a0Smrg 29201e04c3fSmrg /* If llvmpipe_set_scissor_states() is never called, we still need to 29301e04c3fSmrg * make sure that derived scissor state is computed. 29401e04c3fSmrg * See https://bugs.freedesktop.org/show_bug.cgi?id=101709 29501e04c3fSmrg */ 29601e04c3fSmrg llvmpipe->dirty |= LP_NEW_SCISSOR; 29701e04c3fSmrg 2984a49301eSmrg return &llvmpipe->pipe; 2994a49301eSmrg 3004a49301eSmrg fail: 3014a49301eSmrg llvmpipe_destroy(&llvmpipe->pipe); 3024a49301eSmrg return NULL; 3034a49301eSmrg} 3044a49301eSmrg 305