Cell: emit vertex shaders and uniforms more intelligently

This commit is contained in:
Ian Romanick
2008-02-18 18:55:39 -08:00
parent 4362c6e59d
commit 66be2810c3
7 changed files with 87 additions and 62 deletions
+11 -11
View File
@@ -87,10 +87,12 @@
#define CELL_CMD_STATE_TEXTURE 13
#define CELL_CMD_STATE_VERTEX_INFO 14
#define CELL_CMD_STATE_VIEWPORT 15
#define CELL_CMD_STATE_VS_ARRAY_INFO 16
#define CELL_CMD_STATE_BLEND 17
#define CELL_CMD_VS_EXECUTE 18
#define CELL_CMD_STATE_ATTRIB_FETCH 19
#define CELL_CMD_STATE_UNIFORMS 16
#define CELL_CMD_STATE_VS_ARRAY_INFO 17
#define CELL_CMD_STATE_BIND_VS 18
#define CELL_CMD_STATE_BLEND 19
#define CELL_CMD_STATE_ATTRIB_FETCH 20
#define CELL_CMD_VS_EXECUTE 21
#define CELL_NUM_BUFFERS 4
@@ -144,14 +146,13 @@ struct cell_attribute_fetch_code {
struct cell_shader_info
{
unsigned num_outputs;
uint64_t declarations;
unsigned num_declarations;
uint64_t instructions;
unsigned num_instructions;
uint64_t uniforms;
uint64_t immediates;
unsigned num_outputs;
unsigned num_declarations;
unsigned num_instructions;
unsigned num_immediates;
} ALIGN16_ATTRIB;
@@ -160,10 +161,9 @@ struct cell_shader_info
struct cell_command_vs
{
uint64_t opcode; /**< CELL_CMD_VS_EXECUTE */
struct cell_shader_info shader;
uint64_t vOut[SPU_VERTS_PER_BATCH];
unsigned num_elts;
unsigned elts[SPU_VERTS_PER_BATCH];
uint64_t vOut[SPU_VERTS_PER_BATCH];
float plane[12][4];
unsigned nr_planes;
unsigned nr_attrs;
@@ -31,6 +31,8 @@
#include "cell_state_emit.h"
#include "cell_batch.h"
#include "cell_texture.h"
#include "draw/draw_context.h"
#include "draw/draw_private.h"
static void
@@ -100,4 +102,20 @@ cell_emit_state(struct cell_context *cell)
emit_state_cmd(cell, CELL_CMD_STATE_VERTEX_INFO,
&cell->vertex_info, sizeof(struct vertex_info));
}
if (cell->dirty & CELL_NEW_VS) {
const struct draw_context *const draw = cell->draw;
struct cell_shader_info info;
info.num_outputs = draw->num_vs_outputs;
info.declarations = (uintptr_t) draw->machine.Declarations;
info.num_declarations = draw->machine.NumDeclarations;
info.instructions = (uintptr_t) draw->machine.Instructions;
info.num_instructions = draw->machine.NumInstructions;
info.immediates = (uintptr_t) draw->machine.Imms;
info.num_immediates = draw->machine.ImmLimit / 4;
emit_state_cmd(cell, CELL_CMD_STATE_BIND_VS,
& info, sizeof(info));
}
}
@@ -54,6 +54,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
struct cell_command_vs *const vs = &cell_global.command[0].vs;
uint64_t *batch;
struct cell_array_info *array_info;
struct cell_shader_info *shader_info;
unsigned i, j;
struct cell_attribute_fetch_code *cf;
@@ -100,17 +101,17 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
(void) memcpy(&batch[1], &draw->viewport,
sizeof(struct pipe_viewport_state));
{
uint64_t uniforms = (uintptr_t) draw->user.constants;
batch = cell_batch_alloc(cell, 2 *sizeof(batch[0]));
batch[0] = CELL_CMD_STATE_UNIFORMS;
batch[1] = uniforms;
}
cell_batch_flush(cell);
vs->opcode = CELL_CMD_VS_EXECUTE;
vs->shader.num_outputs = draw->num_vs_outputs;
vs->shader.declarations = (uintptr_t) draw->machine.Declarations;
vs->shader.num_declarations = draw->machine.NumDeclarations;
vs->shader.instructions = (uintptr_t) draw->machine.Instructions;
vs->shader.num_instructions = draw->machine.NumInstructions;
vs->shader.uniforms = (uintptr_t) draw->user.constants;
vs->shader.immediates = (uintptr_t) draw->machine.Imms;
vs->shader.num_immediates = draw->machine.ImmLimit / 4;
vs->nr_attrs = draw->vertex_fetch.nr_attrs;
(void) memcpy(vs->plane, draw->plane, sizeof(draw->plane));
+9
View File
@@ -433,10 +433,19 @@ cmd_batch(uint opcode)
sizeof(struct pipe_viewport_state));
pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8);
break;
case CELL_CMD_STATE_UNIFORMS:
draw.constants = (float (*)[4]) (uintptr_t) buffer[pos + 1];
pos += 2;
break;
case CELL_CMD_STATE_VS_ARRAY_INFO:
cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8);
break;
case CELL_CMD_STATE_BIND_VS:
spu_bind_vertex_shader(&draw,
(struct cell_shader_info *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8);
break;
case CELL_CMD_STATE_ATTRIB_FETCH: {
struct cell_attribute_fetch_code *code =
(struct cell_attribute_fetch_code *) &buffer[pos+1];
@@ -64,7 +64,7 @@ typedef void (*spu_fetch_func)(qword *out, const qword *in,
const qword *shuffle_data);
static const qword fetch_shuffle_data[] = {
static const qword fetch_shuffle_data[5] ALIGN16_ATTRIB = {
/* Shuffle used by CVT_64_FLOAT
*/
{
@@ -108,7 +108,7 @@ static const qword fetch_shuffle_data[] = {
static INLINE void
fetch_unaligned(qword *dst, unsigned ea, unsigned size)
{
qword tmp[4];
qword tmp[4] ALIGN16_ATTRIB;
const int shift = ea & 0x0f;
const unsigned aligned_start_ea = ea & ~0x0f;
const unsigned aligned_end_ea = (ea + size) & ~0x0f;
@@ -169,7 +169,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw,
unsigned idx;
const unsigned bytes_per_entry = draw->vertex_fetch.size[attr];
const unsigned quads_per_entry = (bytes_per_entry + 15) / 16;
qword in[2 * 4];
qword in[2 * 4] ALIGN16_ATTRIB;
/* Fetch four attributes for four vertices.
@@ -165,64 +165,56 @@ run_vertex_program(struct spu_vs_context *draw,
}
static void
spu_bind_vertex_shader(struct spu_vs_context *draw,
void *uniforms,
void *planes,
unsigned nr_planes,
unsigned num_outputs
)
{
draw->constants = (float (*)[4]) uniforms;
unsigned char immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32]
ALIGN16_ATTRIB;
(void) memcpy(draw->plane, planes, sizeof(float) * 4 * nr_planes);
draw->nr_planes = nr_planes;
draw->num_vs_outputs = num_outputs;
void
spu_bind_vertex_shader(struct spu_vs_context *draw,
struct cell_shader_info *vs)
{
const unsigned immediate_addr = vs->immediates;
const unsigned immediate_size =
ROUNDUP16((sizeof(float) * 4 * vs->num_immediates)
+ (immediate_addr & 0x0f));
mfc_get(immediates, immediate_addr & ~0x0f, immediate_size,
TAG_VERTEX_BUFFER, 0, 0);
draw->machine.Instructions = (struct tgsi_full_instruction *)
vs->instructions;
draw->machine.NumInstructions = vs->num_instructions;
draw->machine.Declarations = (struct tgsi_full_declaration *)
vs->declarations;
draw->machine.NumDeclarations = vs->num_declarations;
draw->num_vs_outputs = vs->num_outputs;
/* specify the shader to interpret/execute */
spu_exec_machine_init(&draw->machine,
PIPE_MAX_SAMPLERS,
NULL /*samplers*/,
PIPE_SHADER_VERTEX);
wait_on_mask(1 << TAG_VERTEX_BUFFER);
(void) memcpy(& draw->machine.Imms, &immediates[immediate_addr & 0x0f],
sizeof(float) * 4 * vs->num_immediates);
}
unsigned char immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32]
ALIGN16_ATTRIB;
void
spu_execute_vertex_shader(struct spu_vs_context *draw,
const struct cell_command_vs *vs)
{
unsigned i;
const uint64_t immediate_addr = vs->shader.immediates;
const unsigned immediate_size =
ROUNDUP16((sizeof(float) * 4 * vs->shader.num_immediates)
+ (immediate_addr & 0x0f));
mfc_get(immediates, immediate_addr & ~0x0f, immediate_size,
TAG_VERTEX_BUFFER, 0, 0);
draw->machine.Instructions = (struct tgsi_full_instruction *)
vs->shader.instructions;
draw->machine.NumInstructions = vs->shader.num_instructions;
draw->machine.Declarations = (struct tgsi_full_declaration *)
vs->shader.declarations;
draw->machine.NumDeclarations = vs->shader.num_declarations;
(void) memcpy(draw->plane, vs->plane, sizeof(float) * 4 * vs->nr_planes);
draw->nr_planes = vs->nr_planes;
draw->vertex_fetch.nr_attrs = vs->nr_attrs;
wait_on_mask(1 << TAG_VERTEX_BUFFER);
(void) memcpy(& draw->machine.Imms, &immediates[immediate_addr & 0x0f],
sizeof(float) * 4 * vs->shader.num_immediates);
spu_bind_vertex_shader(draw, vs->shader.uniforms,
vs->plane, vs->nr_planes,
vs->shader.num_outputs);
for (i = 0; i < vs->num_elts; i += 4) {
const unsigned batch_size = MIN2(vs->num_elts - i, 4);
@@ -1,6 +1,7 @@
#ifndef SPU_VERTEX_SHADER_H
#define SPU_VERTEX_SHADER_H
#include "cell/common.h"
#include "pipe/p_format.h"
#include "spu_exec.h"
@@ -54,6 +55,10 @@ static INLINE void spu_vertex_fetch(struct spu_vs_context *draw,
struct cell_command_vs;
extern void
spu_bind_vertex_shader(struct spu_vs_context *draw,
struct cell_shader_info *vs);
extern void
spu_execute_vertex_shader(struct spu_vs_context *draw,
const struct cell_command_vs *vs);