convert vbo->draw_prims() to pipe->draw_arrays(): works in very limited cases, disabl...
[mesa.git] / src / mesa / state_tracker / st_draw.c
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 * Authors:
30 * Keith Whitwell <keith@tungstengraphics.com>
31 */
32
33 #include "main/imports.h"
34
35 #include "vbo/vbo.h"
36
37 #include "tnl/t_context.h"
38 #include "tnl/t_pipeline.h"
39
40 #include "st_context.h"
41 #include "st_atom.h"
42 #include "st_draw.h"
43 #include "st_cb_bufferobjects.h"
44 #include "pipe/p_context.h"
45 #include "pipe/p_defines.h"
46
47 #include "vbo/vbo_context.h"
48
49 /*
50 * Enabling this causes the VBO module to call draw_vbo() below,
51 * bypassing the T&L module. This only works with VBO-based demos,
52 * such as progs/test/bufferobj.c
53 */
54 #define USE_NEW_DRAW 0
55
56
57 /*
58 * TNL stage which feeds into the above.
59 *
60 * XXX: this needs to go into each driver using this code, because we
61 * cannot make the leap from ctx->draw_context in this file. The
62 * driver needs to customize tnl anyway, so this isn't a big deal.
63 */
64 static GLboolean draw( GLcontext * ctx, struct tnl_pipeline_stage *stage )
65 {
66 struct st_context *st = st_context(ctx);
67 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
68
69 /* Validate driver and pipe state:
70 */
71 st_validate_state( st );
72
73 /* Call into the new draw code to handle the VB:
74 */
75 st->pipe->draw_vb( st->pipe, VB );
76
77 /* Finished
78 */
79 return GL_FALSE;
80 }
81
82 const struct tnl_pipeline_stage st_draw = {
83 "check state and draw",
84 NULL,
85 NULL,
86 NULL,
87 NULL,
88 draw
89 };
90
91 static const struct tnl_pipeline_stage *st_pipeline[] = {
92 &_tnl_vertex_transform_stage,
93 &_tnl_vertex_cull_stage,
94 &_tnl_normal_transform_stage,
95 &_tnl_lighting_stage,
96 &_tnl_fog_coordinate_stage,
97 &_tnl_texgen_stage,
98 &_tnl_texture_transform_stage,
99 &_tnl_point_attenuation_stage,
100 &_tnl_vertex_program_stage,
101 &st_draw, /* ADD: escape to pipe */
102 0,
103 };
104
105
106
107 static GLuint
108 pipe_vertex_format(GLenum format, GLuint size)
109 {
110 static const GLuint float_fmts[4] = {
111 PIPE_FORMAT_R32_FLOAT,
112 PIPE_FORMAT_R32G32_FLOAT,
113 PIPE_FORMAT_R32G32B32_FLOAT,
114 PIPE_FORMAT_R32G32B32A32_FLOAT,
115 };
116
117 assert(format >= GL_BYTE);
118 assert(format <= GL_DOUBLE);
119 assert(size >= 1);
120 assert(size <= 4);
121
122 switch (format) {
123 case GL_FLOAT:
124 return float_fmts[size - 1];
125 default:
126 assert(0);
127 }
128 }
129
130
131
132 /**
133 * This function gets plugged into the VBO module and is called when
134 * we have something to render.
135 * Basically, translate the information into the format expected by pipe.
136 */
137 static void
138 draw_vbo(GLcontext *ctx,
139 const struct gl_client_array **arrays,
140 const struct _mesa_prim *prims,
141 GLuint nr_prims,
142 const struct _mesa_index_buffer *ib,
143 GLuint min_index,
144 GLuint max_index)
145 {
146 struct pipe_context *pipe = ctx->st->pipe;
147 GLuint attr, i;
148
149 /* tell pipe about the vertex array element/attributes */
150 for (attr = 0; attr < 16; attr++) {
151 struct gl_buffer_object *bufobj = arrays[attr]->BufferObj;
152 struct pipe_vertex_buffer vbuffer;
153 struct pipe_vertex_element velement;
154
155 if (bufobj && bufobj->Name) {
156 struct st_buffer_object *stobj = st_buffer_object(bufobj);
157
158 assert(stobj->buffer);
159
160 vbuffer.pitch = arrays[attr]->StrideB; /* in bytes */
161 vbuffer.max_index = 0;
162 vbuffer.buffer = stobj->buffer;
163 vbuffer.buffer_offset = 0;
164
165 /* Recall that for VBOs, the gl_client_array->Ptr field is
166 * really an offset from the start of the VBO, not a pointer.
167 */
168 velement.src_offset = (unsigned) arrays[attr]->Ptr;
169 velement.vertex_buffer_index = attr;
170 velement.dst_offset = 0;
171 velement.src_format = pipe_vertex_format(arrays[attr]->Type,
172 arrays[attr]->Size);
173 }
174 else {
175 /* vertex attribute data is not an a real buffer! */
176 /* XXX we'll want to handle that someday... */
177
178 vbuffer.buffer = NULL;
179 }
180
181 pipe->set_vertex_buffer(pipe, attr, &vbuffer);
182 pipe->set_vertex_element(pipe, attr, &velement);
183 }
184
185 /* do actual drawing */
186 for (i = 0; i < nr_prims; i++) {
187 pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count);
188 }
189 }
190
191
192
193
194 /* This is all a hack to keep using tnl until we have vertex programs
195 * up and running.
196 */
197 void st_init_draw( struct st_context *st )
198 {
199 GLcontext *ctx = st->ctx;
200
201 #if USE_NEW_DRAW
202 struct vbo_context *vbo = (struct vbo_context *) ctx->swtnl_im;
203
204 assert(vbo);
205 assert(vbo->draw_prims);
206 vbo->draw_prims = draw_vbo;
207
208 #else
209 _tnl_destroy_pipeline( ctx );
210 _tnl_install_pipeline( ctx, st_pipeline );
211 #endif
212
213 }
214
215
216 void st_destroy_draw( struct st_context *st )
217 {
218 /* Nothing to do.
219 */
220 }
221
222