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_inlines.h"
37848b8605Smrg#include "util/u_math.h"
38848b8605Smrg#include "util/u_memory.h"
39b8e80941Smrg#include "util/simple_list.h"
40b8e80941Smrg#include "util/u_upload_mgr.h"
41848b8605Smrg#include "lp_clear.h"
42848b8605Smrg#include "lp_context.h"
43848b8605Smrg#include "lp_flush.h"
44848b8605Smrg#include "lp_perf.h"
45848b8605Smrg#include "lp_state.h"
46848b8605Smrg#include "lp_surface.h"
47848b8605Smrg#include "lp_query.h"
48848b8605Smrg#include "lp_setup.h"
49848b8605Smrg
50b8e80941Smrg/* This is only safe if there's just one concurrent context */
51b8e80941Smrg#ifdef PIPE_SUBSYSTEM_EMBEDDED
52b8e80941Smrg#define USE_GLOBAL_LLVM_CONTEXT
53b8e80941Smrg#endif
54848b8605Smrg
55848b8605Smrgstatic void llvmpipe_destroy( struct pipe_context *pipe )
56848b8605Smrg{
57848b8605Smrg   struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
58848b8605Smrg   uint i, j;
59848b8605Smrg
60848b8605Smrg   lp_print_counters();
61848b8605Smrg
62848b8605Smrg   if (llvmpipe->blitter) {
63848b8605Smrg      util_blitter_destroy(llvmpipe->blitter);
64848b8605Smrg   }
65848b8605Smrg
66b8e80941Smrg   if (llvmpipe->pipe.stream_uploader)
67b8e80941Smrg      u_upload_destroy(llvmpipe->pipe.stream_uploader);
68b8e80941Smrg
69848b8605Smrg   /* This will also destroy llvmpipe->setup:
70848b8605Smrg    */
71848b8605Smrg   if (llvmpipe->draw)
72848b8605Smrg      draw_destroy( llvmpipe->draw );
73848b8605Smrg
74848b8605Smrg   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
75848b8605Smrg      pipe_surface_reference(&llvmpipe->framebuffer.cbufs[i], NULL);
76848b8605Smrg   }
77848b8605Smrg
78848b8605Smrg   pipe_surface_reference(&llvmpipe->framebuffer.zsbuf, NULL);
79848b8605Smrg
80b8e80941Smrg   for (i = 0; i < ARRAY_SIZE(llvmpipe->sampler_views[0]); i++) {
81848b8605Smrg      pipe_sampler_view_reference(&llvmpipe->sampler_views[PIPE_SHADER_FRAGMENT][i], NULL);
82848b8605Smrg   }
83848b8605Smrg
84b8e80941Smrg   for (i = 0; i < ARRAY_SIZE(llvmpipe->sampler_views[0]); i++) {
85848b8605Smrg      pipe_sampler_view_reference(&llvmpipe->sampler_views[PIPE_SHADER_VERTEX][i], NULL);
86848b8605Smrg   }
87848b8605Smrg
88b8e80941Smrg   for (i = 0; i < ARRAY_SIZE(llvmpipe->sampler_views[0]); i++) {
89848b8605Smrg      pipe_sampler_view_reference(&llvmpipe->sampler_views[PIPE_SHADER_GEOMETRY][i], NULL);
90848b8605Smrg   }
91848b8605Smrg
92b8e80941Smrg   for (i = 0; i < ARRAY_SIZE(llvmpipe->constants); i++) {
93b8e80941Smrg      for (j = 0; j < ARRAY_SIZE(llvmpipe->constants[i]); j++) {
94848b8605Smrg         pipe_resource_reference(&llvmpipe->constants[i][j].buffer, NULL);
95848b8605Smrg      }
96848b8605Smrg   }
97848b8605Smrg
98848b8605Smrg   for (i = 0; i < llvmpipe->num_vertex_buffers; i++) {
99b8e80941Smrg      pipe_vertex_buffer_unreference(&llvmpipe->vertex_buffer[i]);
100848b8605Smrg   }
101848b8605Smrg
102848b8605Smrg   lp_delete_setup_variants(llvmpipe);
103848b8605Smrg
104b8e80941Smrg#ifndef USE_GLOBAL_LLVM_CONTEXT
105b8e80941Smrg   LLVMContextDispose(llvmpipe->context);
106b8e80941Smrg#endif
107b8e80941Smrg   llvmpipe->context = NULL;
108b8e80941Smrg
109848b8605Smrg   align_free( llvmpipe );
110848b8605Smrg}
111848b8605Smrg
112848b8605Smrgstatic void
113848b8605Smrgdo_flush( struct pipe_context *pipe,
114848b8605Smrg          struct pipe_fence_handle **fence,
115848b8605Smrg          unsigned flags)
116848b8605Smrg{
117848b8605Smrg   llvmpipe_flush(pipe, fence, __FUNCTION__);
118848b8605Smrg}
119848b8605Smrg
120848b8605Smrg
121848b8605Smrgstatic void
122b8e80941Smrgllvmpipe_render_condition(struct pipe_context *pipe,
123b8e80941Smrg                          struct pipe_query *query,
124b8e80941Smrg                          boolean condition,
125b8e80941Smrg                          enum pipe_render_cond_flag mode)
126848b8605Smrg{
127848b8605Smrg   struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
128848b8605Smrg
129848b8605Smrg   llvmpipe->render_cond_query = query;
130848b8605Smrg   llvmpipe->render_cond_mode = mode;
131848b8605Smrg   llvmpipe->render_cond_cond = condition;
132848b8605Smrg}
133848b8605Smrg
134848b8605Smrgstruct pipe_context *
135b8e80941Smrgllvmpipe_create_context(struct pipe_screen *screen, void *priv,
136b8e80941Smrg                        unsigned flags)
137848b8605Smrg{
138848b8605Smrg   struct llvmpipe_context *llvmpipe;
139848b8605Smrg
140848b8605Smrg   llvmpipe = align_malloc(sizeof(struct llvmpipe_context), 16);
141848b8605Smrg   if (!llvmpipe)
142848b8605Smrg      return NULL;
143848b8605Smrg
144848b8605Smrg   util_init_math();
145848b8605Smrg
146848b8605Smrg   memset(llvmpipe, 0, sizeof *llvmpipe);
147848b8605Smrg
148848b8605Smrg   make_empty_list(&llvmpipe->fs_variants_list);
149848b8605Smrg
150848b8605Smrg   make_empty_list(&llvmpipe->setup_variants_list);
151848b8605Smrg
152848b8605Smrg
153848b8605Smrg   llvmpipe->pipe.screen = screen;
154848b8605Smrg   llvmpipe->pipe.priv = priv;
155848b8605Smrg
156848b8605Smrg   /* Init the pipe context methods */
157848b8605Smrg   llvmpipe->pipe.destroy = llvmpipe_destroy;
158848b8605Smrg   llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
159848b8605Smrg   llvmpipe->pipe.clear = llvmpipe_clear;
160848b8605Smrg   llvmpipe->pipe.flush = do_flush;
161848b8605Smrg
162848b8605Smrg   llvmpipe->pipe.render_condition = llvmpipe_render_condition;
163848b8605Smrg
164848b8605Smrg   llvmpipe_init_blend_funcs(llvmpipe);
165848b8605Smrg   llvmpipe_init_clip_funcs(llvmpipe);
166848b8605Smrg   llvmpipe_init_draw_funcs(llvmpipe);
167848b8605Smrg   llvmpipe_init_sampler_funcs(llvmpipe);
168848b8605Smrg   llvmpipe_init_query_funcs( llvmpipe );
169848b8605Smrg   llvmpipe_init_vertex_funcs(llvmpipe);
170848b8605Smrg   llvmpipe_init_so_funcs(llvmpipe);
171848b8605Smrg   llvmpipe_init_fs_funcs(llvmpipe);
172848b8605Smrg   llvmpipe_init_vs_funcs(llvmpipe);
173848b8605Smrg   llvmpipe_init_gs_funcs(llvmpipe);
174848b8605Smrg   llvmpipe_init_rasterizer_funcs(llvmpipe);
175848b8605Smrg   llvmpipe_init_context_resource_funcs( &llvmpipe->pipe );
176848b8605Smrg   llvmpipe_init_surface_functions(llvmpipe);
177848b8605Smrg
178b8e80941Smrg#ifdef USE_GLOBAL_LLVM_CONTEXT
179b8e80941Smrg   llvmpipe->context = LLVMGetGlobalContext();
180b8e80941Smrg#else
181b8e80941Smrg   llvmpipe->context = LLVMContextCreate();
182b8e80941Smrg#endif
183b8e80941Smrg
184b8e80941Smrg   if (!llvmpipe->context)
185b8e80941Smrg      goto fail;
186b8e80941Smrg
187848b8605Smrg   /*
188848b8605Smrg    * Create drawing context and plug our rendering stage into it.
189848b8605Smrg    */
190b8e80941Smrg   llvmpipe->draw = draw_create_with_llvm_context(&llvmpipe->pipe,
191b8e80941Smrg                                                  llvmpipe->context);
192848b8605Smrg   if (!llvmpipe->draw)
193848b8605Smrg      goto fail;
194848b8605Smrg
195848b8605Smrg   /* FIXME: devise alternative to draw_texture_samplers */
196848b8605Smrg
197848b8605Smrg   llvmpipe->setup = lp_setup_create( &llvmpipe->pipe,
198848b8605Smrg                                      llvmpipe->draw );
199848b8605Smrg   if (!llvmpipe->setup)
200848b8605Smrg      goto fail;
201848b8605Smrg
202b8e80941Smrg   llvmpipe->pipe.stream_uploader = u_upload_create_default(&llvmpipe->pipe);
203b8e80941Smrg   if (!llvmpipe->pipe.stream_uploader)
204b8e80941Smrg      goto fail;
205b8e80941Smrg   llvmpipe->pipe.const_uploader = llvmpipe->pipe.stream_uploader;
206b8e80941Smrg
207848b8605Smrg   llvmpipe->blitter = util_blitter_create(&llvmpipe->pipe);
208848b8605Smrg   if (!llvmpipe->blitter) {
209848b8605Smrg      goto fail;
210848b8605Smrg   }
211848b8605Smrg
212848b8605Smrg   /* must be done before installing Draw stages */
213848b8605Smrg   util_blitter_cache_all_shaders(llvmpipe->blitter);
214848b8605Smrg
215848b8605Smrg   /* plug in AA line/point stages */
216848b8605Smrg   draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe);
217848b8605Smrg   draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe);
218848b8605Smrg   draw_install_pstipple_stage(llvmpipe->draw, &llvmpipe->pipe);
219848b8605Smrg
220848b8605Smrg   /* convert points and lines into triangles:
221848b8605Smrg    * (otherwise, draw points and lines natively)
222848b8605Smrg    */
223848b8605Smrg   draw_wide_point_sprites(llvmpipe->draw, FALSE);
224848b8605Smrg   draw_enable_point_sprites(llvmpipe->draw, FALSE);
225848b8605Smrg   draw_wide_point_threshold(llvmpipe->draw, 10000.0);
226848b8605Smrg   draw_wide_line_threshold(llvmpipe->draw, 10000.0);
227848b8605Smrg
228848b8605Smrg   lp_reset_counters();
229848b8605Smrg
230b8e80941Smrg   /* If llvmpipe_set_scissor_states() is never called, we still need to
231b8e80941Smrg    * make sure that derived scissor state is computed.
232b8e80941Smrg    * See https://bugs.freedesktop.org/show_bug.cgi?id=101709
233b8e80941Smrg    */
234b8e80941Smrg   llvmpipe->dirty |= LP_NEW_SCISSOR;
235b8e80941Smrg
236848b8605Smrg   return &llvmpipe->pipe;
237848b8605Smrg
238848b8605Smrg fail:
239848b8605Smrg   llvmpipe_destroy(&llvmpipe->pipe);
240848b8605Smrg   return NULL;
241848b8605Smrg}
242848b8605Smrg
243