1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
30 * Zack Rusin zack@tungstengraphics.com
33 #include "pipe/p_util.h"
34 #include "draw_private.h"
35 #include "draw_context.h"
36 #include "draw_vertex.h"
40 #include "pipe/llvm/gallivm.h"
41 #include "pipe/tgsi/exec/tgsi_core.h"
46 fetch_attrib4(const void *ptr
, enum pipe_format format
, float attrib
[4])
53 case PIPE_FORMAT_R32G32B32A32_FLOAT
:
54 attrib
[3] = ((float *) ptr
)[3];
56 case PIPE_FORMAT_R32G32B32_FLOAT
:
57 attrib
[2] = ((float *) ptr
)[2];
59 case PIPE_FORMAT_R32G32_FLOAT
:
60 attrib
[1] = ((float *) ptr
)[1];
62 case PIPE_FORMAT_R32_FLOAT
:
63 attrib
[0] = ((float *) ptr
)[0];
72 * Fetch vertex attributes for 'count' vertices.
75 void vertex_fetch(struct draw_context
*draw
,
81 /* loop over vertex attributes (vertex shader inputs) */
82 for (attr
= 0; attr
< draw
->vertex_shader
->state
->num_inputs
; attr
++) {
84 unsigned buf
= draw
->vertex_element
[attr
].vertex_buffer_index
;
86 = (const void *) ((const ubyte
*) draw
->user
.vbuffer
[buf
]
87 + draw
->vertex_buffer
[buf
].buffer_offset
88 + draw
->vertex_element
[attr
].src_offset
89 + elt
* draw
->vertex_buffer
[buf
].pitch
);
90 fetch_attrib4(src
, draw
->vertex_element
[attr
].src_format
, inputs
[attr
]);
94 static INLINE
unsigned
95 compute_clipmask(const float *clip
, const float (*plane
)[4], unsigned nr
)
100 for (i
= 0; i
< nr
; i
++) {
101 if (dot4(clip
, plane
[i
]) < 0)
110 * Called by the draw module when the vertx cache needs to be flushed.
111 * This involves running the vertex shader.
113 void draw_vertex_shader_queue_flush_llvm(struct draw_context
*draw
)
117 struct vertex_header
*dests
[VS_QUEUE_LENGTH
];
118 float inputs
[VS_QUEUE_LENGTH
][PIPE_MAX_SHADER_INPUTS
][4];
119 float outputs
[VS_QUEUE_LENGTH
][PIPE_MAX_SHADER_INPUTS
][4];
120 float (*consts
)[4] = (float (*)[4]) draw
->user
.constants
;
121 struct gallivm_prog
*prog
= draw
->vertex_shader
->llvm_prog
;
122 const float *scale
= draw
->viewport
.scale
;
123 const float *trans
= draw
->viewport
.translate
;
125 /* fetch the inputs */
126 for (i
= 0; i
< draw
->vs
.queue_nr
; ++i
) {
127 unsigned elt
= draw
->vs
.queue
[i
].elt
;
128 dests
[i
] = draw
->vs
.queue
[i
].dest
;
129 vertex_fetch(draw
, elt
, inputs
[i
]);
132 /* batch execute the shaders on all the vertices */
133 gallivm_prog_exec(prog
, inputs
, outputs
, consts
,
135 draw
->vertex_shader
->state
->num_inputs
,
136 draw
->vertex_info
.num_attribs
);
138 /* store machine results */
139 for (int i
= 0; i
< draw
->vs
.queue_nr
; ++i
) {
142 struct vertex_header
*vOut
= draw
->vs
.queue
[i
].dest
;
143 float (*dests
)[4] = outputs
[i
];
145 /* Handle attr[0] (position) specially:
147 * XXX: Computing the clipmask should be done in the vertex
148 * program as a set of DP4 instructions appended to the
149 * user-provided code.
151 x
= vOut
->clip
[0] = dests
[0][0];
152 y
= vOut
->clip
[1] = dests
[0][1];
153 z
= vOut
->clip
[2] = dests
[0][2];
154 w
= vOut
->clip
[3] = dests
[0][3];
156 printf("output %d: %f %f %f %f\n", 0, x
, y
, z
, w
);
159 vOut
->clipmask
= compute_clipmask(vOut
->clip
, draw
->plane
, draw
->nr_planes
);
168 /* Viewport mapping */
169 vOut
->data
[0][0] = x
* scale
[0] + trans
[0];
170 vOut
->data
[0][1] = y
* scale
[1] + trans
[1];
171 vOut
->data
[0][2] = z
* scale
[2] + trans
[2];
172 vOut
->data
[0][3] = w
;
174 /* Remaining attributes are packed into sequential post-transform
175 * vertex attrib slots.
177 for (slot
= 1; slot
< draw
->vertex_info
.num_attribs
; slot
++) {
178 vOut
->data
[slot
][0] = dests
[slot
][0];
179 vOut
->data
[slot
][1] = dests
[slot
][1];
180 vOut
->data
[slot
][2] = dests
[slot
][2];
181 vOut
->data
[slot
][3] = dests
[slot
][3];
184 printf("output %d: %f %f %f %f\n", slot
,
188 vOut
->data
[slot
][3]);
191 } /* loop over vertices */
193 draw
->vs
.queue_nr
= 0;
196 #endif /* MESA_LLVM */