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 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "main/imports.h"
37 #include "tnl/t_context.h"
38 #include "tnl/t_pipeline.h"
39 #include "tnl/t_vp_build.h" /* USE_NEW_DRAW */
41 #include "st_context.h"
44 #include "st_cb_bufferobjects.h"
45 #include "pipe/p_context.h"
46 #include "pipe/p_defines.h"
47 #include "pipe/p_winsys.h"
49 #include "vbo/vbo_context.h"
52 * Enabling this causes the VBO module to call draw_vbo() below,
53 * bypassing the T&L module. This only works with VBO-based demos,
54 * such as progs/test/bufferobj.c
56 #define USE_NEW_DRAW 01
60 * TNL stage which feeds into the above.
62 * XXX: this needs to go into each driver using this code, because we
63 * cannot make the leap from ctx->draw_context in this file. The
64 * driver needs to customize tnl anyway, so this isn't a big deal.
66 static GLboolean
draw( GLcontext
* ctx
, struct tnl_pipeline_stage
*stage
)
68 struct st_context
*st
= st_context(ctx
);
69 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
71 /* Validate driver and pipe state:
73 st_validate_state( st
);
75 /* Call into the new draw code to handle the VB:
77 st
->pipe
->draw_vb( st
->pipe
, VB
);
84 const struct tnl_pipeline_stage st_draw
= {
85 "check state and draw",
93 static const struct tnl_pipeline_stage
*st_pipeline
[] = {
95 &_tnl_vertex_program_stage
,
97 &_tnl_vertex_transform_stage
,
98 &_tnl_vertex_cull_stage
,
99 &_tnl_normal_transform_stage
,
100 &_tnl_lighting_stage
,
101 &_tnl_fog_coordinate_stage
,
103 &_tnl_texture_transform_stage
,
104 &_tnl_point_attenuation_stage
,
105 &_tnl_vertex_program_stage
,
107 &st_draw
, /* ADD: escape to pipe */
114 pipe_vertex_format(GLenum format
, GLuint size
)
116 static const GLuint float_fmts
[4] = {
117 PIPE_FORMAT_R32_FLOAT
,
118 PIPE_FORMAT_R32G32_FLOAT
,
119 PIPE_FORMAT_R32G32B32_FLOAT
,
120 PIPE_FORMAT_R32G32B32A32_FLOAT
,
123 assert(format
>= GL_BYTE
);
124 assert(format
<= GL_DOUBLE
);
130 return float_fmts
[size
- 1];
139 * The default attribute buffer is basically a copy of the
140 * ctx->Current.Attrib[] array. It's used when the vertex program
141 * references an attribute for which we don't have a VBO/array.
144 create_default_attribs_buffer(struct st_context
*st
)
146 struct pipe_context
*pipe
= st
->pipe
;
147 st
->default_attrib_buffer
= pipe
->winsys
->buffer_create( pipe
->winsys
, 32 );
152 destroy_default_attribs_buffer(struct st_context
*st
)
154 struct pipe_context
*pipe
= st
->pipe
;
155 pipe
->winsys
->buffer_unreference(pipe
->winsys
, &st
->default_attrib_buffer
);
160 update_default_attribs_buffer(GLcontext
*ctx
)
162 struct pipe_context
*pipe
= ctx
->st
->pipe
;
163 struct pipe_buffer_handle
*buf
= ctx
->st
->default_attrib_buffer
;
164 const unsigned size
= sizeof(ctx
->Current
.Attrib
);
165 const void *data
= ctx
->Current
.Attrib
;
166 pipe
->winsys
->buffer_data(pipe
->winsys
, buf
, size
, data
);
171 * This function gets plugged into the VBO module and is called when
172 * we have something to render.
173 * Basically, translate the information into the format expected by pipe.
176 draw_vbo(GLcontext
*ctx
,
177 const struct gl_client_array
**arrays
,
178 const struct _mesa_prim
*prims
,
180 const struct _mesa_index_buffer
*ib
,
184 struct pipe_context
*pipe
= ctx
->st
->pipe
;
186 GLbitfield attrsNeeded
;
187 const unsigned attr0_offset
= (unsigned) arrays
[0]->Ptr
;
189 st_validate_state(ctx
->st
);
190 update_default_attribs_buffer(ctx
);
192 /* this must be after state validation */
193 attrsNeeded
= ctx
->st
->state
.vs
.inputs_read
;
195 /* tell pipe about the vertex array element/attributes */
196 for (attr
= 0; attr
< 16; attr
++) {
197 struct pipe_vertex_buffer vbuffer
;
198 struct pipe_vertex_element velement
;
200 vbuffer
.buffer
= NULL
;
202 velement
.src_offset
= 0;
203 velement
.vertex_buffer_index
= 0;
204 velement
.src_format
= 0;
206 if (attrsNeeded
& (1 << attr
)) {
207 struct gl_buffer_object
*bufobj
= arrays
[attr
]->BufferObj
;
209 if (bufobj
&& bufobj
->Name
) {
210 struct st_buffer_object
*stobj
= st_buffer_object(bufobj
);
211 /* Recall that for VBOs, the gl_client_array->Ptr field is
212 * really an offset from the start of the VBO, not a pointer.
214 unsigned offset
= (unsigned) arrays
[attr
]->Ptr
;
216 assert(stobj
->buffer
);
218 vbuffer
.buffer
= stobj
->buffer
;
219 vbuffer
.buffer_offset
= attr0_offset
; /* in bytes */
220 vbuffer
.pitch
= arrays
[attr
]->StrideB
; /* in bytes */
221 vbuffer
.max_index
= 0; /* need this? */
223 velement
.src_offset
= offset
- attr0_offset
; /* bytes */
224 velement
.vertex_buffer_index
= attr
;
225 velement
.dst_offset
= 0; /* need this? */
226 velement
.src_format
= pipe_vertex_format(arrays
[attr
]->Type
,
228 assert(velement
.src_format
);
231 /* use the default attribute buffer */
232 vbuffer
.buffer
= ctx
->st
->default_attrib_buffer
;
233 vbuffer
.buffer_offset
= 0;
234 vbuffer
.pitch
= 0; /* must be zero! */
235 vbuffer
.max_index
= 1;
237 velement
.src_offset
= attr
* 4 * sizeof(GLfloat
);
238 velement
.vertex_buffer_index
= attr
;
239 velement
.dst_offset
= 0;
240 velement
.src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
245 assert(vbuffer
.buffer
);
247 pipe
->set_vertex_buffer(pipe
, attr
, &vbuffer
);
248 pipe
->set_vertex_element(pipe
, attr
, &velement
);
251 /* do actual drawing */
253 /* indexed primitive */
254 struct gl_buffer_object
*bufobj
= ib
->obj
;
255 struct pipe_buffer_handle
*bh
= NULL
;
258 if (bufobj
&& bufobj
->Name
) {
259 /* elements/indexes are in a real VBO */
260 struct st_buffer_object
*stobj
= st_buffer_object(bufobj
);
263 case GL_UNSIGNED_INT
:
266 case GL_UNSIGNED_SHORT
:
277 for (i
= 0; i
< nr_prims
; i
++) {
278 pipe
->draw_elements(pipe
, bh
, indexSize
,
279 prims
[i
].mode
, prims
[i
].start
, prims
[i
].count
);
284 for (i
= 0; i
< nr_prims
; i
++) {
285 pipe
->draw_arrays(pipe
, prims
[i
].mode
, prims
[i
].start
, prims
[i
].count
);
293 /* This is all a hack to keep using tnl until we have vertex programs
296 void st_init_draw( struct st_context
*st
)
298 GLcontext
*ctx
= st
->ctx
;
301 struct vbo_context
*vbo
= (struct vbo_context
*) ctx
->swtnl_im
;
303 create_default_attribs_buffer(st
);
306 assert(vbo
->draw_prims
);
307 vbo
->draw_prims
= draw_vbo
;
310 _tnl_destroy_pipeline( ctx
);
311 _tnl_install_pipeline( ctx
, st_pipeline
);
314 _tnl_ProgramCacheInit( ctx
);
318 void st_destroy_draw( struct st_context
*st
)
320 destroy_default_attribs_buffer(st
);