2 * (C) Copyright IBM Corporation 2008
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * \file cell_vertex_shader.c
27 * Vertex shader interface routines for Cell.
29 * \author Ian Romanick <idr@us.ibm.com>
32 #include "pipe/p_defines.h"
33 #include "pipe/p_context.h"
34 #include "util/u_math.h"
36 #include "cell_context.h"
37 #include "cell_draw_arrays.h"
38 #include "cell_flush.h"
40 #include "cell_batch.h"
42 #include "cell/common.h"
43 #include "draw/draw_context.h"
44 #include "draw/draw_private.h"
47 * Run the vertex shader on all vertices in the vertex queue.
48 * Called by the draw module when the vertx cache needs to be flushed.
51 cell_vertex_shader_queue_flush(struct draw_context
*draw
)
54 struct cell_context
*const cell
=
55 (struct cell_context
*) draw
->driver_private
;
56 struct cell_command_vs
*const vs
= &cell_global
.command
[0].vs
;
58 struct cell_array_info
*array_info
;
60 struct cell_attribute_fetch_code
*cf
;
62 assert(draw
->vs
.queue_nr
!= 0);
64 /* XXX: do this on statechange:
66 draw_update_vertex_fetch(draw
);
67 cell_update_vertex_fetch(draw
);
70 batch
= cell_batch_alloc(cell
, sizeof(batch
[0]) + sizeof(*cf
));
71 batch
[0] = CELL_CMD_STATE_ATTRIB_FETCH
;
72 cf
= (struct cell_attribute_fetch_code
*) (&batch
[1]);
73 cf
->base
= (uint64_t) cell
->attrib_fetch
.store
;
74 cf
->size
= ROUNDUP16((unsigned)((void *) cell
->attrib_fetch
.csr
75 - (void *) cell
->attrib_fetch
.store
));
78 for (i
= 0; i
< draw
->vertex_fetch
.nr_attrs
; i
++) {
79 const enum pipe_format format
= draw
->vertex_element
[i
].src_format
;
80 const unsigned count
= ((pf_size_x(format
) != 0)
81 + (pf_size_y(format
) != 0)
82 + (pf_size_z(format
) != 0)
83 + (pf_size_w(format
) != 0));
84 const unsigned size
= pf_size_x(format
) * count
;
86 batch
= cell_batch_alloc(cell
, sizeof(batch
[0]) + sizeof(*array_info
));
88 batch
[0] = CELL_CMD_STATE_VS_ARRAY_INFO
;
90 array_info
= (struct cell_array_info
*) &batch
[1];
91 assert(draw
->vertex_fetch
.src_ptr
[i
] != NULL
);
92 array_info
->base
= (uintptr_t) draw
->vertex_fetch
.src_ptr
[i
];
94 array_info
->pitch
= draw
->vertex_fetch
.pitch
[i
];
95 array_info
->size
= size
;
96 array_info
->function_offset
= cell
->attrib_fetch_offsets
[i
];
99 batch
= cell_batch_alloc(cell
, sizeof(batch
[0])
100 + sizeof(struct pipe_viewport_state
));
101 batch
[0] = CELL_CMD_STATE_VIEWPORT
;
102 (void) memcpy(&batch
[1], &draw
->viewport
,
103 sizeof(struct pipe_viewport_state
));
106 uint64_t uniforms
= (uintptr_t) draw
->user
.constants
;
108 batch
= cell_batch_alloc(cell
, 2 *sizeof(batch
[0]));
109 batch
[0] = CELL_CMD_STATE_UNIFORMS
;
113 cell_batch_flush(cell
);
115 vs
->opcode
= CELL_CMD_VS_EXECUTE
;
116 vs
->nr_attrs
= draw
->vertex_fetch
.nr_attrs
;
118 (void) memcpy(vs
->plane
, draw
->plane
, sizeof(draw
->plane
));
119 vs
->nr_planes
= draw
->nr_planes
;
121 for (i
= 0; i
< draw
->vs
.queue_nr
; i
+= SPU_VERTS_PER_BATCH
) {
122 const unsigned n
= MIN2(SPU_VERTS_PER_BATCH
, draw
->vs
.queue_nr
- i
);
124 for (j
= 0; j
< n
; j
++) {
125 vs
->elts
[j
] = draw
->vs
.queue
[i
+ j
].elt
;
126 vs
->vOut
[j
] = (uintptr_t) draw
->vs
.queue
[i
+ j
].vertex
;
129 for (/* empty */; j
< SPU_VERTS_PER_BATCH
; j
++) {
130 vs
->elts
[j
] = vs
->elts
[0];
131 vs
->vOut
[j
] = (uintptr_t) draw
->vs
.queue
[i
+ j
].vertex
;
135 send_mbox_message(cell_global
.spe_contexts
[0], CELL_CMD_VS_EXECUTE
);
137 cell_flush_int(cell
, CELL_FLUSH_WAIT
);
140 draw
->vs
.post_nr
= draw
->vs
.queue_nr
;
141 draw
->vs
.queue_nr
= 0;