lp_rast_priv.h revision e21e7ab4da859198dfa9845b4a7207c49db54771
1/**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#ifndef LP_RAST_PRIV_H
29#define LP_RAST_PRIV_H
30
31#include "os/os_thread.h"
32#include "util/u_format.h"
33#include "gallivm/lp_bld_debug.h"
34#include "lp_memory.h"
35#include "lp_rast.h"
36#include "lp_scene.h"
37#include "lp_state.h"
38#include "lp_texture.h"
39#include "lp_tile_soa.h"
40#include "lp_limits.h"
41
42
43struct lp_rasterizer;
44
45
46/**
47 * Per-thread rasterization state
48 */
49struct lp_rasterizer_task
50{
51   unsigned x, y;          /**< Pos of this tile in framebuffer, in pixels */
52
53   uint8_t *color_tiles[PIPE_MAX_COLOR_BUFS];
54   uint8_t *depth_tile;
55
56   /** "back" pointer */
57   struct lp_rasterizer *rast;
58
59   /** "my" index */
60   unsigned thread_index;
61
62   /* occlude counter for visiable pixels */
63   uint32_t vis_counter;
64
65   pipe_semaphore work_ready;
66   pipe_semaphore work_done;
67};
68
69
70/**
71 * This is the state required while rasterizing tiles.
72 * Note that this contains per-thread information too.
73 * The tile size is TILE_SIZE x TILE_SIZE pixels.
74 */
75struct lp_rasterizer
76{
77   boolean exit_flag;
78
79   /* Framebuffer stuff
80    */
81   struct {
82      uint8_t *map;
83      unsigned stride;
84      unsigned blocksize;
85   } zsbuf;
86
87   struct {
88      unsigned nr_cbufs;
89      unsigned clear_color;
90      unsigned clear_depth;
91      char clear_stencil;
92   } state;
93
94   /** The incoming queue of scenes ready to rasterize */
95   struct lp_scene_queue *full_scenes;
96
97   /**
98    * The outgoing queue of processed scenes to return to setup module
99    *
100    * XXX: while scenes are per-context but the rasterizer is
101    * (potentially) shared, these empty scenes should be returned to
102    * the context which created them rather than retained here.
103    */
104   /*   struct lp_scene_queue *empty_scenes; */
105
106   /** The scene currently being rasterized by the threads */
107   struct lp_scene *curr_scene;
108
109   /** A task object for each rasterization thread */
110   struct lp_rasterizer_task tasks[LP_MAX_THREADS];
111
112   unsigned num_threads;
113   pipe_thread threads[LP_MAX_THREADS];
114
115   /** For synchronizing the rasterization threads */
116   pipe_barrier barrier;
117};
118
119
120void
121lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
122                         const struct lp_rast_shader_inputs *inputs,
123                         unsigned x, unsigned y,
124                         unsigned mask);
125
126
127
128/**
129 * Get the pointer to a 4x4 depth/stencil block.
130 * We'll map the z/stencil buffer on demand here.
131 * Note that this may be called even when there's no z/stencil buffer - return
132 * NULL in that case.
133 * \param x, y location of 4x4 block in window coords
134 */
135static INLINE void *
136lp_rast_get_depth_block_pointer(struct lp_rasterizer_task *task,
137                                unsigned x, unsigned y)
138{
139   const struct lp_rasterizer *rast = task->rast;
140   void *depth;
141
142   assert((x % TILE_VECTOR_WIDTH) == 0);
143   assert((y % TILE_VECTOR_HEIGHT) == 0);
144
145   if (!rast->zsbuf.map) {
146      /* Either out of memory or no zsbuf.  Can't tell without access
147       * to the state.  Just use dummy tile memory, but don't print
148       * the oom warning as this most likely because there is no
149       * zsbuf.
150       */
151      return lp_get_dummy_tile_silent();
152   }
153
154   depth = (rast->zsbuf.map +
155            rast->zsbuf.stride * y +
156            rast->zsbuf.blocksize * x * TILE_VECTOR_HEIGHT);
157
158   assert(lp_check_alignment(depth, 16));
159   return depth;
160}
161
162
163/**
164 * Get pointer to the swizzled color tile
165 */
166static INLINE uint8_t *
167lp_rast_get_color_tile_pointer(struct lp_rasterizer_task *task,
168                               unsigned buf, enum lp_texture_usage usage)
169{
170   struct lp_rasterizer *rast = task->rast;
171
172   assert(task->x % TILE_SIZE == 0);
173   assert(task->y % TILE_SIZE == 0);
174   assert(buf < rast->state.nr_cbufs);
175
176   if (!task->color_tiles[buf]) {
177      struct pipe_surface *cbuf = rast->curr_scene->fb.cbufs[buf];
178      struct llvmpipe_resource *lpt;
179      assert(cbuf);
180      lpt = llvmpipe_resource(cbuf->texture);
181      task->color_tiles[buf] = llvmpipe_get_texture_tile(lpt,
182                                                         cbuf->face + cbuf->zslice,
183                                                         cbuf->level,
184                                                         usage,
185                                                         task->x,
186                                                         task->y);
187      if (!task->color_tiles[buf]) {
188         /* out of memory - use dummy tile memory */
189         return lp_get_dummy_tile();
190      }
191   }
192
193   return task->color_tiles[buf];
194}
195
196
197/**
198 * Get the pointer to a 4x4 color block (within a 64x64 tile).
199 * We'll map the color buffer on demand here.
200 * Note that this may be called even when there's no color buffers - return
201 * NULL in that case.
202 * \param x, y location of 4x4 block in window coords
203 */
204static INLINE uint8_t *
205lp_rast_get_color_block_pointer(struct lp_rasterizer_task *task,
206                                unsigned buf, unsigned x, unsigned y)
207{
208   unsigned px, py, pixel_offset;
209   uint8_t *color;
210
211   assert((x % TILE_VECTOR_WIDTH) == 0);
212   assert((y % TILE_VECTOR_HEIGHT) == 0);
213
214   color = lp_rast_get_color_tile_pointer(task, buf, LP_TEX_USAGE_READ_WRITE);
215   color = task->color_tiles[buf];
216   if (!color) {
217      /* out of memory - use dummy tile memory */
218      return lp_get_dummy_tile();
219   }
220
221   px = x % TILE_SIZE;
222   py = y % TILE_SIZE;
223   pixel_offset = tile_pixel_offset(px, py, 0);
224
225   color = color + pixel_offset;
226
227   assert(lp_check_alignment(color, 16));
228   return color;
229}
230
231
232
233/**
234 * Shade all pixels in a 4x4 block.  The fragment code omits the
235 * triangle in/out tests.
236 * \param x, y location of 4x4 block in window coords
237 */
238static INLINE void
239lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
240                         const struct lp_rast_shader_inputs *inputs,
241                         unsigned x, unsigned y )
242{
243   const struct lp_rasterizer *rast = task->rast;
244   const struct lp_rast_state *state = inputs->state;
245   struct lp_fragment_shader_variant *variant = state->variant;
246   uint8_t *color[PIPE_MAX_COLOR_BUFS];
247   void *depth;
248   unsigned i;
249
250   /* color buffer */
251   for (i = 0; i < rast->state.nr_cbufs; i++)
252      color[i] = lp_rast_get_color_block_pointer(task, i, x, y);
253
254   depth = lp_rast_get_depth_block_pointer(task, x, y);
255
256   /* run shader on 4x4 block */
257   variant->jit_function[RAST_WHOLE]( &state->jit_context,
258                                      x, y,
259                                      inputs->facing,
260                                      inputs->a0,
261                                      inputs->dadx,
262                                      inputs->dady,
263                                      color,
264                                      depth,
265                                      0xffff,
266                                      &task->vis_counter );
267}
268
269
270#endif
271