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 **************************************************************************/
29 * \brief Last stage of 'draw' pipeline: send tris to SPUs.
33 #include "cell_context.h"
34 #include "cell_render.h"
36 #include "util/u_memory.h"
37 #include "draw/draw_private.h"
41 struct draw_stage stage
; /**< This must be first (base class) */
43 struct cell_context
*cell
;
47 static INLINE
struct render_stage
*
48 render_stage(struct draw_stage
*stage
)
50 return (struct render_stage
*) stage
;
54 static void render_begin( struct draw_stage
*stage
)
57 struct render_stage
*render
= render_stage(stage
);
58 struct cell_context
*sp
= render
->cell
;
59 const struct pipe_shader_state
*fs
= &render
->cell
->fs
->shader
;
60 render
->quad
.nr_attrs
= render
->cell
->nr_frag_attrs
;
62 render
->firstFpInput
= fs
->input_semantic_name
[0];
64 sp
->quad
.first
->begin(sp
->quad
.first
);
69 static void render_end( struct draw_stage
*stage
)
74 static void reset_stipple_counter( struct draw_stage
*stage
)
76 struct render_stage
*render
= render_stage(stage
);
77 /*render->cell->line_stipple_counter = 0;*/
82 render_point(struct draw_stage
*stage
, struct prim_header
*prim
)
88 render_line(struct draw_stage
*stage
, struct prim_header
*prim
)
93 /** Write a vertex into the prim buffer */
95 save_vertex(struct cell_prim_buffer
*buf
, uint pos
,
96 const struct vertex_header
*vert
)
100 for (attr
= 0; attr
< 2; attr
++) {
101 for (j
= 0; j
< 4; j
++) {
102 buf
->vertex
[pos
][attr
][j
] = vert
->data
[attr
][j
];
106 /* update bounding box */
107 if (vert
->data
[0][0] < buf
->xmin
)
108 buf
->xmin
= vert
->data
[0][0];
109 if (vert
->data
[0][0] > buf
->xmax
)
110 buf
->xmax
= vert
->data
[0][0];
111 if (vert
->data
[0][1] < buf
->ymin
)
112 buf
->ymin
= vert
->data
[0][1];
113 if (vert
->data
[0][1] > buf
->ymax
)
114 buf
->ymax
= vert
->data
[0][1];
119 render_tri(struct draw_stage
*stage
, struct prim_header
*prim
)
121 struct render_stage
*rs
= render_stage(stage
);
122 struct cell_context
*cell
= rs
->cell
;
123 struct cell_prim_buffer
*buf
= &cell
->prim_buffer
;
126 if (buf
->num_verts
+ 3 > CELL_MAX_VERTS
) {
127 cell_flush_prim_buffer(cell
);
131 assert(i
+2 <= CELL_MAX_VERTS
);
132 save_vertex(buf
, i
+0, prim
->v
[0]);
133 save_vertex(buf
, i
+1, prim
->v
[1]);
134 save_vertex(buf
, i
+2, prim
->v
[2]);
140 * Send the a RENDER command to all SPUs to have them render the prims
141 * in the current prim_buffer.
144 cell_flush_prim_buffer(struct cell_context
*cell
)
148 if (cell
->prim_buffer
.num_verts
== 0)
151 for (i
= 0; i
< cell
->num_spus
; i
++) {
152 struct cell_command_render
*render
= &cell_global
.command
[i
].render
;
153 render
->prim_type
= PIPE_PRIM_TRIANGLES
;
154 render
->num_verts
= cell
->prim_buffer
.num_verts
;
155 render
->front_winding
= cell
->rasterizer
->front_winding
;
156 render
->vertex_size
= cell
->vertex_info
->size
* 4;
157 render
->xmin
= cell
->prim_buffer
.xmin
;
158 render
->ymin
= cell
->prim_buffer
.ymin
;
159 render
->xmax
= cell
->prim_buffer
.xmax
;
160 render
->ymax
= cell
->prim_buffer
.ymax
;
161 render
->vertex_data
= &cell
->prim_buffer
.vertex
;
162 ASSERT_ALIGN16(render
->vertex_data
);
163 send_mbox_message(cell_global
.spe_contexts
[i
], CELL_CMD_RENDER
);
166 cell
->prim_buffer
.num_verts
= 0;
168 cell
->prim_buffer
.xmin
= 1e100
;
169 cell
->prim_buffer
.ymin
= 1e100
;
170 cell
->prim_buffer
.xmax
= -1e100
;
171 cell
->prim_buffer
.ymax
= -1e100
;
173 /* XXX temporary, need to double-buffer the prim buffer until we get
174 * a real command buffer/list system.
176 cell_flush(&cell
->pipe
, 0x0);
181 static void render_destroy( struct draw_stage
*stage
)
188 * Create a new draw/render stage. This will be plugged into the
189 * draw module as the last pipeline stage.
191 struct draw_stage
*cell_draw_render_stage( struct cell_context
*cell
)
193 struct render_stage
*render
= CALLOC_STRUCT(render_stage
);
196 render
->stage
.draw
= cell
->draw
;
197 render
->stage
.begin
= render_begin
;
198 render
->stage
.point
= render_point
;
199 render
->stage
.line
= render_line
;
200 render
->stage
.tri
= render_tri
;
201 render
->stage
.end
= render_end
;
202 render
->stage
.reset_stipple_counter
= reset_stipple_counter
;
203 render
->stage
.destroy
= render_destroy
;
206 render->quad.coef = render->coef;
207 render->quad.posCoef = &render->posCoef;
210 return &render
->stage
;