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