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