Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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_limits.h"
40
 
41
 
42
#define TILE_VECTOR_HEIGHT 4
43
#define TILE_VECTOR_WIDTH 4
44
 
45
/* If we crash in a jitted function, we can examine jit_line and jit_state
46
 * to get some info.  This is not thread-safe, however.
47
 */
48
#ifdef DEBUG
49
 
50
struct lp_rasterizer_task;
51
extern int jit_line;
52
extern const struct lp_rast_state *jit_state;
53
extern const struct lp_rasterizer_task *jit_task;
54
 
55
#define BEGIN_JIT_CALL(state, task)                  \
56
   do { \
57
      jit_line = __LINE__; \
58
      jit_state = state; \
59
      jit_task = task; \
60
   } while (0)
61
 
62
#define END_JIT_CALL() \
63
   do { \
64
      jit_line = 0; \
65
      jit_state = NULL; \
66
   } while (0)
67
 
68
#else
69
 
70
#define BEGIN_JIT_CALL(X, Y)
71
#define END_JIT_CALL()
72
 
73
#endif
74
 
75
 
76
struct lp_rasterizer;
77
struct cmd_bin;
78
 
79
/**
80
 * Per-thread rasterization state
81
 */
82
struct lp_rasterizer_task
83
{
84
   const struct cmd_bin *bin;
85
   const struct lp_rast_state *state;
86
 
87
   struct lp_scene *scene;
88
   unsigned x, y;          /**< Pos of this tile in framebuffer, in pixels */
89
   unsigned width, height; /**< width, height of current tile, in pixels */
90
 
91
   uint8_t *color_tiles[PIPE_MAX_COLOR_BUFS];
92
   uint8_t *depth_tile;
93
 
94
   /** "back" pointer */
95
   struct lp_rasterizer *rast;
96
 
97
   /** "my" index */
98
   unsigned thread_index;
99
 
100
   /* occlude counter for visible pixels */
101
   struct lp_jit_thread_data thread_data;
102
   uint64_t ps_invocations;
103
 
104
   pipe_semaphore work_ready;
105
   pipe_semaphore work_done;
106
};
107
 
108
 
109
/**
110
 * This is the state required while rasterizing tiles.
111
 * Note that this contains per-thread information too.
112
 * The tile size is TILE_SIZE x TILE_SIZE pixels.
113
 */
114
struct lp_rasterizer
115
{
116
   boolean exit_flag;
117
   boolean no_rast;  /**< For debugging/profiling */
118
 
119
   /** The incoming queue of scenes ready to rasterize */
120
   struct lp_scene_queue *full_scenes;
121
 
122
   /** The scene currently being rasterized by the threads */
123
   struct lp_scene *curr_scene;
124
 
125
   /** A task object for each rasterization thread */
126
   struct lp_rasterizer_task tasks[LP_MAX_THREADS];
127
 
128
   unsigned num_threads;
129
   pipe_thread threads[LP_MAX_THREADS];
130
 
131
   /** For synchronizing the rasterization threads */
132
   pipe_barrier barrier;
133
};
134
 
135
 
136
void
137
lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
138
                         const struct lp_rast_shader_inputs *inputs,
139
                         unsigned x, unsigned y,
140
                         unsigned mask);
141
 
142
 
143
 
144
/**
145
 * Get pointer to the unswizzled color tile
146
 */
147
static INLINE uint8_t *
148
lp_rast_get_unswizzled_color_tile_pointer(struct lp_rasterizer_task *task,
149
                                          unsigned buf, enum lp_texture_usage usage)
150
{
151
   const struct lp_scene *scene = task->scene;
152
   unsigned format_bytes;
153
 
154
   assert(task->x < scene->tiles_x * TILE_SIZE);
155
   assert(task->y < scene->tiles_y * TILE_SIZE);
156
   assert(task->x % TILE_SIZE == 0);
157
   assert(task->y % TILE_SIZE == 0);
158
   assert(buf < scene->fb.nr_cbufs);
159
 
160
   if (!task->color_tiles[buf]) {
161
      struct pipe_surface *cbuf = scene->fb.cbufs[buf];
162
      assert(cbuf);
163
 
164
      format_bytes = util_format_get_blocksize(cbuf->format);
165
      task->color_tiles[buf] = scene->cbufs[buf].map + scene->cbufs[buf].stride * task->y + format_bytes * task->x;
166
   }
167
 
168
   return task->color_tiles[buf];
169
}
170
 
171
 
172
/**
173
 * Get pointer to the unswizzled depth tile
174
 */
175
static INLINE uint8_t *
176
lp_rast_get_unswizzled_depth_tile_pointer(struct lp_rasterizer_task *task,
177
                                          enum lp_texture_usage usage)
178
{
179
   const struct lp_scene *scene = task->scene;
180
   unsigned format_bytes;
181
 
182
   assert(task->x < scene->tiles_x * TILE_SIZE);
183
   assert(task->y < scene->tiles_y * TILE_SIZE);
184
   assert(task->x % TILE_SIZE == 0);
185
   assert(task->y % TILE_SIZE == 0);
186
 
187
   if (!task->depth_tile) {
188
      struct pipe_surface *dbuf = scene->fb.zsbuf;
189
      assert(dbuf);
190
 
191
      format_bytes = util_format_get_blocksize(dbuf->format);
192
      task->depth_tile = scene->zsbuf.map + scene->zsbuf.stride * task->y + format_bytes * task->x;
193
   }
194
 
195
   return task->depth_tile;
196
}
197
 
198
 
199
/**
200
 * Get the pointer to an unswizzled 4x4 color block (within an unswizzled 64x64 tile).
201
 * \param x, y location of 4x4 block in window coords
202
 */
203
static INLINE uint8_t *
204
lp_rast_get_unswizzled_color_block_pointer(struct lp_rasterizer_task *task,
205
                                           unsigned buf, unsigned x, unsigned y,
206
                                           unsigned layer)
207
{
208
   unsigned px, py, pixel_offset, format_bytes;
209
   uint8_t *color;
210
 
211
   assert(x < task->scene->tiles_x * TILE_SIZE);
212
   assert(y < task->scene->tiles_y * TILE_SIZE);
213
   assert((x % TILE_VECTOR_WIDTH) == 0);
214
   assert((y % TILE_VECTOR_HEIGHT) == 0);
215
   assert(buf < task->scene->fb.nr_cbufs);
216
 
217
   format_bytes = util_format_get_blocksize(task->scene->fb.cbufs[buf]->format);
218
 
219
   color = lp_rast_get_unswizzled_color_tile_pointer(task, buf, LP_TEX_USAGE_READ_WRITE);
220
   assert(color);
221
 
222
   px = x % TILE_SIZE;
223
   py = y % TILE_SIZE;
224
   pixel_offset = px * format_bytes + py * task->scene->cbufs[buf].stride;
225
 
226
   color = color + pixel_offset;
227
 
228
   if (layer) {
229
      color += layer * task->scene->cbufs[buf].layer_stride;
230
   }
231
 
232
   assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format)));
233
   return color;
234
}
235
 
236
 
237
/**
238
 * Get the pointer to an unswizzled 4x4 depth block (within an unswizzled 64x64 tile).
239
 * \param x, y location of 4x4 block in window coords
240
 */
241
static INLINE uint8_t *
242
lp_rast_get_unswizzled_depth_block_pointer(struct lp_rasterizer_task *task,
243
                                           unsigned x, unsigned y, unsigned layer)
244
{
245
   unsigned px, py, pixel_offset, format_bytes;
246
   uint8_t *depth;
247
 
248
   assert(x < task->scene->tiles_x * TILE_SIZE);
249
   assert(y < task->scene->tiles_y * TILE_SIZE);
250
   assert((x % TILE_VECTOR_WIDTH) == 0);
251
   assert((y % TILE_VECTOR_HEIGHT) == 0);
252
 
253
   format_bytes = util_format_get_blocksize(task->scene->fb.zsbuf->format);
254
 
255
   depth = lp_rast_get_unswizzled_depth_tile_pointer(task, LP_TEX_USAGE_READ_WRITE);
256
   assert(depth);
257
 
258
   px = x % TILE_SIZE;
259
   py = y % TILE_SIZE;
260
   pixel_offset = px * format_bytes + py * task->scene->zsbuf.stride;
261
 
262
   depth = depth + pixel_offset;
263
 
264
   if (layer) {
265
      depth += layer * task->scene->zsbuf.layer_stride;
266
   }
267
 
268
   assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format)));
269
   return depth;
270
}
271
 
272
 
273
 
274
/**
275
 * Shade all pixels in a 4x4 block.  The fragment code omits the
276
 * triangle in/out tests.
277
 * \param x, y location of 4x4 block in window coords
278
 */
279
static INLINE void
280
lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
281
                         const struct lp_rast_shader_inputs *inputs,
282
                         unsigned x, unsigned y )
283
{
284
   const struct lp_scene *scene = task->scene;
285
   const struct lp_rast_state *state = task->state;
286
   struct lp_fragment_shader_variant *variant = state->variant;
287
   uint8_t *color[PIPE_MAX_COLOR_BUFS];
288
   unsigned stride[PIPE_MAX_COLOR_BUFS];
289
   uint8_t *depth = NULL;
290
   unsigned depth_stride = 0;
291
   unsigned i;
292
 
293
   /* color buffer */
294
   for (i = 0; i < scene->fb.nr_cbufs; i++) {
295
      stride[i] = scene->cbufs[i].stride;
296
      color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y, inputs->layer);
297
   }
298
 
299
   if (scene->zsbuf.map) {
300
      depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y, inputs->layer);
301
      depth_stride = scene->zsbuf.stride;
302
   }
303
 
304
   /*
305
    * The rasterizer may produce fragments outside our
306
    * allocated 4x4 blocks hence need to filter them out here.
307
    */
308
   if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) {
309
      /* not very accurate would need a popcount on the mask */
310
      /* always count this not worth bothering? */
311
      task->ps_invocations++;
312
 
313
      /* run shader on 4x4 block */
314
      BEGIN_JIT_CALL(state, task);
315
      variant->jit_function[RAST_WHOLE]( &state->jit_context,
316
                                         x, y,
317
                                         inputs->frontfacing,
318
                                         GET_A0(inputs),
319
                                         GET_DADX(inputs),
320
                                         GET_DADY(inputs),
321
                                         color,
322
                                         depth,
323
                                         0xffff,
324
                                         &task->thread_data,
325
                                         stride,
326
                                         depth_stride);
327
      END_JIT_CALL();
328
   }
329
}
330
 
331
void lp_rast_triangle_1( struct lp_rasterizer_task *,
332
                         const union lp_rast_cmd_arg );
333
void lp_rast_triangle_2( struct lp_rasterizer_task *,
334
                         const union lp_rast_cmd_arg );
335
void lp_rast_triangle_3( struct lp_rasterizer_task *,
336
                         const union lp_rast_cmd_arg );
337
void lp_rast_triangle_4( struct lp_rasterizer_task *,
338
                         const union lp_rast_cmd_arg );
339
void lp_rast_triangle_5( struct lp_rasterizer_task *,
340
                         const union lp_rast_cmd_arg );
341
void lp_rast_triangle_6( struct lp_rasterizer_task *,
342
                         const union lp_rast_cmd_arg );
343
void lp_rast_triangle_7( struct lp_rasterizer_task *,
344
                         const union lp_rast_cmd_arg );
345
void lp_rast_triangle_8( struct lp_rasterizer_task *,
346
                         const union lp_rast_cmd_arg );
347
 
348
void lp_rast_triangle_3_4(struct lp_rasterizer_task *,
349
			  const union lp_rast_cmd_arg );
350
 
351
void lp_rast_triangle_3_16( struct lp_rasterizer_task *,
352
                            const union lp_rast_cmd_arg );
353
 
354
void lp_rast_triangle_4_16( struct lp_rasterizer_task *,
355
                            const union lp_rast_cmd_arg );
356
 
357
void
358
lp_rast_set_state(struct lp_rasterizer_task *task,
359
                  const union lp_rast_cmd_arg arg);
360
 
361
void
362
lp_debug_bin( const struct cmd_bin *bin, int x, int y );
363
 
364
#endif