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 * Build post-transformation, post-clipping vertex buffers and element
31 * lists by hooking into the end of the primitive pipeline and
32 * manipulating the vertex_id field in the vertex headers.
34 * XXX: work in progress
36 * \author José Fonseca <jrfonseca@tungstengraphics.com>
37 * \author Keith Whitwell <keith@tungstengraphics.com>
41 #include "draw/draw_vbuf.h"
42 #include "pipe/p_debug.h"
43 #include "pipe/p_util.h"
44 #include "pipe/p_inlines.h"
45 #include "pipe/p_winsys.h"
47 #include "i915_context.h"
49 #include "i915_winsys.h"
50 #include "i915_batch.h"
51 #include "i915_state.h"
55 * Primitive renderer for i915.
57 struct i915_vbuf_render
{
58 struct vbuf_render base
;
60 struct i915_context
*i915
;
62 /** Vertex size in bytes */
65 /** Hardware primitive */
71 * Basically a cast wrapper.
73 static INLINE
struct i915_vbuf_render
*
74 i915_vbuf_render( struct vbuf_render
*render
)
77 return (struct i915_vbuf_render
*)render
;
81 static const struct vertex_info
*
82 i915_vbuf_render_get_vertex_info( struct vbuf_render
*render
)
84 struct i915_vbuf_render
*i915_render
= i915_vbuf_render(render
);
85 struct i915_context
*i915
= i915_render
->i915
;
88 /* make sure we have up to date vertex layout */
89 i915_update_derived( i915
);
92 return &i915
->current
.vertex_info
;
97 i915_vbuf_render_allocate_vertices( struct vbuf_render
*render
,
101 struct i915_vbuf_render
*i915_render
= i915_vbuf_render(render
);
102 struct i915_context
*i915
= i915_render
->i915
;
103 struct pipe_winsys
*winsys
= i915
->pipe
.winsys
;
104 size_t size
= (size_t)vertex_size
* (size_t)nr_vertices
;
106 /* FIXME: handle failure */
108 i915
->vbo
= winsys
->buffer_create(winsys
, 64, I915_BUFFER_USAGE_LIT_VERTEX
,
111 i915
->dirty
|= I915_NEW_VBO
;
113 return winsys
->buffer_map(winsys
,
115 PIPE_BUFFER_USAGE_CPU_WRITE
);
120 i915_vbuf_render_set_primitive( struct vbuf_render
*render
,
123 struct i915_vbuf_render
*i915_render
= i915_vbuf_render(render
);
126 case PIPE_PRIM_POINTS
:
127 i915_render
->hwprim
= PRIM3D_POINTLIST
;
129 case PIPE_PRIM_LINES
:
130 i915_render
->hwprim
= PRIM3D_LINELIST
;
132 case PIPE_PRIM_TRIANGLES
:
133 i915_render
->hwprim
= PRIM3D_TRILIST
;
136 /* Actually, can handle a lot more just fine... Fixme.
144 i915_vbuf_render_draw( struct vbuf_render
*render
,
145 const ushort
*indices
,
148 struct i915_vbuf_render
*i915_render
= i915_vbuf_render(render
);
149 struct i915_context
*i915
= i915_render
->i915
;
154 /* this seems to be bogus, since we validate state right after this */
155 /*assert((i915->dirty & ~I915_NEW_VBO) == 0);*/
158 i915_update_derived( i915
);
160 if (i915
->hardware_dirty
)
161 i915_emit_hardware_state( i915
);
163 if (!BEGIN_BATCH( 1 + (nr_indices
+ 1)/2, 1 )) {
166 /* Make sure state is re-emitted after a flush:
168 i915_update_derived( i915
);
169 i915_emit_hardware_state( i915
);
171 if (!BEGIN_BATCH( 1 + (nr_indices
+ 1)/2, 1 )) {
177 OUT_BATCH( _3DPRIMITIVE
|
179 i915_render
->hwprim
|
182 for (i
= 0; i
+ 1 < nr_indices
; i
+= 2) {
183 OUT_BATCH( indices
[i
] |
184 (indices
[i
+ 1] << 16) );
186 if (i
< nr_indices
) {
187 OUT_BATCH( indices
[i
] );
193 i915_vbuf_render_release_vertices( struct vbuf_render
*render
,
195 unsigned vertex_size
,
196 unsigned vertices_used
)
198 struct i915_vbuf_render
*i915_render
= i915_vbuf_render(render
);
199 struct i915_context
*i915
= i915_render
->i915
;
200 struct pipe_winsys
*winsys
= i915
->pipe
.winsys
;
203 winsys
->buffer_unmap(winsys
, i915
->vbo
);
204 pipe_buffer_reference(winsys
, &i915
->vbo
, NULL
);
209 i915_vbuf_render_destroy( struct vbuf_render
*render
)
211 struct i915_vbuf_render
*i915_render
= i915_vbuf_render(render
);
217 * Create a new primitive render.
219 static struct vbuf_render
*
220 i915_vbuf_render_create( struct i915_context
*i915
)
222 struct i915_vbuf_render
*i915_render
= CALLOC_STRUCT(i915_vbuf_render
);
224 i915_render
->i915
= i915
;
226 i915_render
->base
.max_vertex_buffer_bytes
= 128*1024;
228 /* NOTE: it must be such that state and vertices indices fit in a single
231 i915_render
->base
.max_indices
= 16*1024;
233 i915_render
->base
.get_vertex_info
= i915_vbuf_render_get_vertex_info
;
234 i915_render
->base
.allocate_vertices
= i915_vbuf_render_allocate_vertices
;
235 i915_render
->base
.set_primitive
= i915_vbuf_render_set_primitive
;
236 i915_render
->base
.draw
= i915_vbuf_render_draw
;
237 i915_render
->base
.release_vertices
= i915_vbuf_render_release_vertices
;
238 i915_render
->base
.destroy
= i915_vbuf_render_destroy
;
240 return &i915_render
->base
;
245 * Create a new primitive vbuf/render stage.
247 struct draw_stage
*i915_draw_vbuf_stage( struct i915_context
*i915
)
249 struct vbuf_render
*render
;
250 struct draw_stage
*stage
;
252 render
= i915_vbuf_render_create(i915
);
256 stage
= draw_vbuf_stage( i915
->draw
, render
);
258 render
->destroy(render
);