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