draw_private.h revision aadbb1d7fbbaada6e378cb60194e5861cadf98d1
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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/** 29 * Private data structures, etc for the draw module. 30 */ 31 32 33/** 34 * Authors: 35 * Keith Whitwell <keith@tungstengraphics.com> 36 * Brian Paul 37 */ 38 39 40#ifndef DRAW_PRIVATE_H 41#define DRAW_PRIVATE_H 42 43 44#include "pipe/p_state.h" 45#include "pipe/p_defines.h" 46 47#include "rtasm/rtasm_x86sse.h" 48#include "tgsi/exec/tgsi_exec.h" 49#include "tgsi/util/tgsi_scan.h" 50 51 52struct pipe_context; 53struct gallivm_prog; 54struct gallivm_cpu_engine; 55 56struct draw_pt_middle_end; 57struct draw_pt_front_end; 58 59#define MAX_SHADER_VERTICES 128 60 61/** 62 * Basic vertex info. 63 * Carry some useful information around with the vertices in the prim pipe. 64 */ 65struct vertex_header { 66 unsigned clipmask:12; 67 unsigned edgeflag:1; 68 unsigned pad:3; 69 unsigned vertex_id:16; 70 71 float clip[4]; 72 73 float data[][4]; /* Note variable size */ 74}; 75 76/* NOTE: It should match vertex_id size above */ 77#define UNDEFINED_VERTEX_ID 0xffff 78 79/* XXX This is too large */ 80#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) 81 82 83 84/** 85 * Basic info for a point/line/triangle primitive. 86 */ 87struct prim_header { 88 float det; /**< front/back face determinant */ 89 unsigned reset_line_stipple:1; 90 unsigned edgeflags:3; 91 unsigned pad:28; 92 struct vertex_header *v[3]; /**< 1 to 3 vertex pointers */ 93}; 94 95 96 97struct draw_context; 98 99/** 100 * Base class for all primitive drawing stages. 101 */ 102struct draw_stage 103{ 104 struct draw_context *draw; /**< parent context */ 105 106 struct draw_stage *next; /**< next stage in pipeline */ 107 108 struct vertex_header **tmp; /**< temp vert storage, such as for clipping */ 109 unsigned nr_tmps; 110 111 void (*point)( struct draw_stage *, 112 struct prim_header * ); 113 114 void (*line)( struct draw_stage *, 115 struct prim_header * ); 116 117 void (*tri)( struct draw_stage *, 118 struct prim_header * ); 119 120 void (*flush)( struct draw_stage *, 121 unsigned flags ); 122 123 void (*reset_stipple_counter)( struct draw_stage * ); 124 125 void (*destroy)( struct draw_stage * ); 126}; 127 128 129#define PRIM_QUEUE_LENGTH 32 130#define VCACHE_SIZE 32 131#define VCACHE_OVERFLOW 4 132#define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ 133 134/** 135 * Private version of the compiled vertex_shader 136 */ 137struct draw_vertex_shader { 138 139 /* This member will disappear shortly: 140 */ 141 struct pipe_shader_state state; 142 143 struct tgsi_shader_info info; 144 145 void (*prepare)( struct draw_vertex_shader *shader, 146 struct draw_context *draw ); 147 148 /* Run the shader - this interface will get cleaned up in the 149 * future: 150 */ 151 void (*run)( struct draw_vertex_shader *shader, 152 struct draw_context *draw, 153 const unsigned *elts, 154 unsigned count, 155 struct vertex_header *vOut[] ); 156 157 158 void (*delete)( struct draw_vertex_shader * ); 159}; 160 161 162/* Internal function for vertex fetch. 163 */ 164typedef void (*fetch_func)(const void *ptr, float *attrib); 165 166fetch_func draw_get_fetch_func( enum pipe_format format ); 167 168 169 170typedef void (*full_fetch_func)( struct draw_context *draw, 171 struct tgsi_exec_machine *machine, 172 const unsigned *elts, 173 unsigned count ); 174 175typedef void (*pt_fetch_func)( struct draw_context *draw, 176 float *out, 177 unsigned start, 178 unsigned count ); 179 180 181struct vbuf_render; 182 183/** 184 * Private context for the drawing module. 185 */ 186struct draw_context 187{ 188 /** Drawing/primitive pipeline stages */ 189 struct { 190 struct draw_stage *first; /**< one of the following */ 191 192 struct draw_stage *validate; 193 194 /* stages (in logical order) */ 195 struct draw_stage *flatshade; 196 struct draw_stage *clip; 197 struct draw_stage *cull; 198 struct draw_stage *twoside; 199 struct draw_stage *offset; 200 struct draw_stage *unfilled; 201 struct draw_stage *stipple; 202 struct draw_stage *aapoint; 203 struct draw_stage *aaline; 204 struct draw_stage *pstipple; 205 struct draw_stage *wide_line; 206 struct draw_stage *wide_point; 207 struct draw_stage *rasterize; 208 } pipeline; 209 210 211 struct vbuf_render *render; 212 213 /* Support prototype passthrough path: 214 */ 215 struct { 216 unsigned prim; /* XXX: to be removed */ 217 unsigned hw_vertex_size; /* XXX: to be removed */ 218 219 struct { 220 struct draw_pt_middle_end *fetch_emit; 221 struct draw_pt_middle_end *fetch_pipeline; 222 struct draw_pt_middle_end *fetch_shade_emit; 223 struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit; 224 } middle; 225 226 struct { 227 struct draw_pt_front_end *noop; 228 struct draw_pt_front_end *split_arrays; 229 struct draw_pt_front_end *vcache; 230 } front; 231 232 struct { 233 char *verts; 234 unsigned vertex_stride; 235 unsigned vertex_count; 236 } pipeline; 237 238 } pt; 239 240 boolean flushing; 241 242 /* pipe state that we need: */ 243 const struct pipe_rasterizer_state *rasterizer; 244 struct pipe_viewport_state viewport; 245 struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; 246 struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; 247 struct draw_vertex_shader *vertex_shader; 248 249 boolean identity_viewport; 250 251 uint num_vs_outputs; /**< convenience, from vertex_shader */ 252 253 /* user-space vertex data, buffers */ 254 struct { 255 const unsigned *edgeflag; 256 257 /** vertex element/index buffer (ex: glDrawElements) */ 258 const void *elts; 259 /** bytes per index (0, 1, 2 or 4) */ 260 unsigned eltSize; 261 262 /** vertex arrays */ 263 const void *vbuffer[PIPE_MAX_ATTRIBS]; 264 265 /** constant buffer (for vertex shader) */ 266 const void *constants; 267 } user; 268 269 /* Clip derived state: 270 */ 271 float plane[12][4]; 272 unsigned nr_planes; 273 274 float wide_point_threshold; /**< convert pnts to tris if larger than this */ 275 float wide_line_threshold; /**< convert lines to tris if wider than this */ 276 boolean line_stipple; /**< do line stipple? */ 277 boolean point_sprite; /**< convert points to quads for sprites? */ 278 boolean use_sse; 279 280 /* If a prim stage introduces new vertex attributes, they'll be stored here 281 */ 282 struct { 283 uint semantic_name; 284 uint semantic_index; 285 int slot; 286 } extra_vp_outputs; 287 288 unsigned reduced_prim; 289 290 /** TGSI program interpreter runtime state */ 291 struct tgsi_exec_machine machine; 292 293 /* Vertex fetch internal state 294 */ 295 struct { 296 const ubyte *src_ptr[PIPE_MAX_ATTRIBS]; 297 unsigned pitch[PIPE_MAX_ATTRIBS]; 298 fetch_func fetch[PIPE_MAX_ATTRIBS]; 299 unsigned nr_attrs; 300 full_fetch_func fetch_func; 301 pt_fetch_func pt_fetch; 302 } vertex_fetch; 303 304 /* Post-tnl vertex cache: 305 */ 306 struct { 307 unsigned referenced; /**< bitfield */ 308 309 struct { 310 unsigned in; /* client array element */ 311 unsigned out; /* index in vs queue/array */ 312 } idx[VCACHE_SIZE + VCACHE_OVERFLOW]; 313 314 unsigned overflow; 315 316 /** To find space in the vertex cache: */ 317 struct vertex_header *(*get_vertex)( struct draw_context *draw, 318 unsigned i ); 319 } vcache; 320 321 /* Vertex shader queue: 322 */ 323 struct { 324 struct { 325 unsigned elt; /**< index into the user's vertex arrays */ 326 struct vertex_header *vertex; 327 } queue[VS_QUEUE_LENGTH]; 328 unsigned queue_nr; 329 unsigned post_nr; 330 } vs; 331 332 /** 333 * Run the vertex shader on all vertices in the vertex queue. 334 */ 335 void (*shader_queue_flush)(struct draw_context *draw); 336 337 /* Prim pipeline queue: 338 */ 339 struct { 340 /* Need to queue up primitives until their vertices have been 341 * transformed by a vs queue flush. 342 */ 343 struct prim_header queue[PRIM_QUEUE_LENGTH]; 344 unsigned queue_nr; 345 } pq; 346 347 348 /* This (and the tgsi_exec_machine struct) probably need to be moved somewhere private. 349 */ 350 struct gallivm_cpu_engine *engine; 351 void *driver_private; 352}; 353 354 355 356extern struct draw_stage *draw_unfilled_stage( struct draw_context *context ); 357extern struct draw_stage *draw_twoside_stage( struct draw_context *context ); 358extern struct draw_stage *draw_offset_stage( struct draw_context *context ); 359extern struct draw_stage *draw_clip_stage( struct draw_context *context ); 360extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); 361extern struct draw_stage *draw_cull_stage( struct draw_context *context ); 362extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); 363extern struct draw_stage *draw_wide_line_stage( struct draw_context *context ); 364extern struct draw_stage *draw_wide_point_stage( struct draw_context *context ); 365extern struct draw_stage *draw_validate_stage( struct draw_context *context ); 366 367 368extern void draw_free_temp_verts( struct draw_stage *stage ); 369 370extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); 371 372extern void draw_reset_vertex_ids( struct draw_context *draw ); 373 374 375extern int draw_vertex_cache_check_space( struct draw_context *draw, 376 unsigned nr_verts ); 377 378extern void draw_vertex_cache_invalidate( struct draw_context *draw ); 379extern void draw_vertex_cache_unreference( struct draw_context *draw ); 380extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); 381 382extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); 383 384extern void draw_update_vertex_fetch( struct draw_context *draw ); 385 386extern boolean draw_need_pipeline(const struct draw_context *draw, 387 unsigned prim ); 388 389 390/* Passthrough mode (second attempt): 391 */ 392boolean draw_pt_init( struct draw_context *draw ); 393void draw_pt_destroy( struct draw_context *draw ); 394boolean draw_pt_arrays( struct draw_context *draw, 395 unsigned prim, 396 unsigned start, 397 unsigned count ); 398 399void draw_pt_reset_vertex_ids( struct draw_context *draw ); 400void draw_pt_run_pipeline( struct draw_context *draw, 401 unsigned prim, 402 char *verts, 403 unsigned vertex_stride, 404 unsigned vertex_count, 405 const ushort *elts, 406 unsigned count ); 407 408 409#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ 410#define DRAW_FLUSH_PRIM_QUEUE 0x2 411#define DRAW_FLUSH_VERTEX_CACHE 0x4 412#define DRAW_FLUSH_STATE_CHANGE 0x8 413#define DRAW_FLUSH_BACKEND 0x10 414 415 416void draw_do_flush( struct draw_context *draw, unsigned flags ); 417 418boolean draw_get_edgeflag( struct draw_context *draw, 419 unsigned idx ); 420 421 422/** 423 * Get a writeable copy of a vertex. 424 * \param stage drawing stage info 425 * \param vert the vertex to copy (source) 426 * \param idx index into stage's tmp[] array to put the copy (dest) 427 * \return pointer to the copied vertex 428 */ 429static INLINE struct vertex_header * 430dup_vert( struct draw_stage *stage, 431 const struct vertex_header *vert, 432 unsigned idx ) 433{ 434 struct vertex_header *tmp = stage->tmp[idx]; 435 const uint vsize = sizeof(struct vertex_header) 436 + stage->draw->num_vs_outputs * 4 * sizeof(float); 437 memcpy(tmp, vert, vsize); 438 tmp->vertex_id = UNDEFINED_VERTEX_ID; 439 return tmp; 440} 441 442static INLINE float 443dot4(const float *a, const float *b) 444{ 445 float result = (a[0]*b[0] + 446 a[1]*b[1] + 447 a[2]*b[2] + 448 a[3]*b[3]); 449 450 return result; 451} 452 453#endif /* DRAW_PRIVATE_H */ 454