Parcourir la source

r300-gallium: Begin R500 fragment shader assembler.

I love it so much. I also hate it a lot.
tags/mesa_20090313
Corbin Simpson il y a 16 ans
Parent
révision
8b21250305

+ 129
- 3
src/gallium/drivers/r300/r300_state_shader.c Voir le fichier

@@ -40,14 +40,140 @@ static void r500_copy_passthrough_shader(struct r500_fragment_shader* fs)
fs->instructions[0] = pt->instructions[0];
}

static void r300_fs_declare(struct r300_fs_asm* assembler,
struct tgsi_full_declaration* decl)
{
switch (decl->Declaration.File) {
case TGSI_FILE_INPUT:
switch (decl->Semantic.SemanticName) {
case TGSI_SEMANTIC_COLOR:
assembler->color_count++;
break;
case TGSI_SEMANTIC_GENERIC:
assembler->tex_count++;
break;
default:
debug_printf("r300: fs: Bad semantic declaration %d\n",
decl->Semantic.SemanticName);
break;
}
break;
case TGSI_FILE_OUTPUT:
break;
default:
debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File);
break;
}

assembler->temp_offset = assembler->color_count + assembler->tex_count;
}

static INLINE void r500_emit_mov(struct r500_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_src_register* src,
struct tgsi_full_dst_register* dst)
{
int i = fs->instruction_count;
fs->instructions[i].inst0 = R500_INST_TYPE_OUT |
R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP;
fs->instructions[i].inst1 =
R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST;
fs->instructions[i].inst2 =
R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST;
fs->instructions[i].inst3 =
R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
fs->instructions[i].inst4 =
R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A;
fs->instructions[i].inst5 =
R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
R500_ALU_RGBA_A_SWIZ_0;

fs->instruction_count++;
}

static void r500_fs_instruction(struct r500_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_instruction* inst)
{
/* Switch between opcodes. When possible, prefer using the official
* AMD/ATI names for opcodes, please, as it facilitates using the
* documentation. */
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_MOV:
r500_emit_mov(fs, assembler, &inst->FullSrcRegisters[0],
&inst->FullDstRegisters[0]);
break;
case TGSI_OPCODE_END:
break;
default:
debug_printf("r300: fs: Bad opcode %d\n",
inst->Instruction.Opcode);
break;
}
}

void r300_translate_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs)
struct r300_fragment_shader* fs)
{
struct tgsi_parse_context parser;

tgsi_parse_init(&parser, fs->shader.state.tokens);

while (!tgsi_parse_end_of_tokens(&parser)) {
tgsi_parse_token(&parser);
}

r300_copy_passthrough_shader(fs);
}

void r500_translate_fragment_shader(struct r300_context* r300,
struct r500_fragment_shader* fs)
struct r500_fragment_shader* fs)
{
r500_copy_passthrough_shader(fs);
struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm);
if (assembler == NULL) {
return;
}
struct tgsi_parse_context parser;

tgsi_parse_init(&parser, fs->shader.state.tokens);

while (!tgsi_parse_end_of_tokens(&parser)) {
tgsi_parse_token(&parser);

/* This is seriously the lamest way to create fragment programs ever.
* I blame TGSI. */
switch (parser.FullToken.Token.Type) {
case TGSI_TOKEN_TYPE_DECLARATION:
/* Allocated registers sitting at the beginning
* of the program. */
r300_fs_declare(assembler, &parser.FullToken.FullDeclaration);
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
r500_fs_instruction(fs, assembler,
&parser.FullToken.FullInstruction);
}

}

debug_printf("%d texs and %d colors, first free reg is %d\n",
assembler->tex_count, assembler->color_count,
assembler->tex_count + assembler->color_count);

/* XXX subtly wrong */
fs->shader.stack_size = assembler->temp_offset;

tgsi_dump(fs->shader.state.tokens);

//r500_copy_passthrough_shader(fs);

tgsi_parse_free(&parser);
FREE(assembler);
}

+ 15
- 0
src/gallium/drivers/r300/r300_state_shader.h Voir le fichier

@@ -23,10 +23,25 @@
#ifndef R300_STATE_SHADER_H
#define R300_STATE_SHADER_H

#include "tgsi/tgsi_parse.h"

#include "r300_context.h"
#include "r300_reg.h"
#include "r300_screen.h"

/* Temporary struct used to hold assembly state while putting together
* fragment programs. */
struct r300_fs_asm {
/* Number of colors. */
unsigned color_count;
/* Number of texcoords. */
unsigned tex_count;
/* Offset for temporary registers. Inputs and temporaries have no
* distinguishing markings, so inputs start at 0 and the first usable
* temporary register is after all inputs. */
unsigned temp_offset;
};

void r300_translate_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs);


Chargement…
Annuler
Enregistrer