r300-gallium: organize fragment/vertex shaders

Appart from separating r3xx/r5xx fragment shaders, a more consistent
naming scheme has been applied. From now on:
r300 = all chips
r3xx = R300/R400 only
r5xx = R500 only
This way r300_fragment_shader is the master struct, and the structs
r3xx_fragment_shader and r5xx_fragment_shader inherits it.
This commit is contained in:
Joakim Sindholt 2009-06-26 01:08:13 +02:00
parent 450b20d1ef
commit 622858884f
20 changed files with 674 additions and 495 deletions

View File

@ -4,20 +4,22 @@ include $(TOP)/configs/current
LIBNAME = r300
C_SOURCES = \
r3xx_fs.c \
r5xx_fs.c \
r300_chipset.c \
r300_clear.c \
r300_context.c \
r300_debug.c \
r300_emit.c \
r300_flush.c \
r300_fs.c \
r300_query.c \
r300_render.c \
r300_screen.c \
r300_state.c \
r300_state_derived.c \
r300_state_invariant.c \
r300_state_shader.c \
r300_state_tcl.c \
r300_vs.c \
r300_surface.c \
r300_texture.c

View File

@ -5,20 +5,22 @@ env = env.Clone()
r300 = env.ConvenienceLibrary(
target = 'r300',
source = [
'r3xx_fs.c',
'r5xx_fs.c',
'r300_chipset.c',
'r300_clear.c',
'r300_context.c',
'r300_debug.c',
'r300_emit.c',
'r300_flush.c',
'r300_fs.c',
'r300_query.c',
'r300_render.c',
'r300_screen.c',
'r300_state.c',
'r300_state_derived.c',
'r300_state_invariant.c',
'r300_state_shader.c',
'r300_state_tcl.c',
'r300_vs.c',
'r300_surface.c',
'r300_texture.c',
])

View File

@ -149,7 +149,7 @@ struct r300_constant_buffer {
unsigned count;
};
struct r3xx_fragment_shader {
struct r300_fragment_shader {
/* Parent class */
struct pipe_shader_state state;
struct tgsi_shader_info info;
@ -165,9 +165,9 @@ struct r3xx_fragment_shader {
boolean uses_imms;
};
struct r300_fragment_shader {
struct r3xx_fragment_shader {
/* Parent class */
struct r3xx_fragment_shader shader;
struct r300_fragment_shader shader;
/* Number of ALU instructions */
int alu_instruction_count;
@ -190,9 +190,9 @@ struct r300_fragment_shader {
} instructions[64]; /* XXX magic num */
};
struct r500_fragment_shader {
struct r5xx_fragment_shader {
/* Parent class */
struct r3xx_fragment_shader shader;
struct r300_fragment_shader shader;
/* Number of used instructions */
int instruction_count;
@ -300,7 +300,7 @@ struct r300_context {
/* Depth, stencil, and alpha state. */
struct r300_dsa_state* dsa_state;
/* Fragment shader. */
struct r3xx_fragment_shader* fs;
struct r300_fragment_shader* fs;
/* Framebuffer state. We currently don't need our own version of this. */
struct pipe_framebuffer_state framebuffer_state;
/* Rasterizer state. */

View File

@ -22,7 +22,7 @@
#include "r300_debug.h"
static void r300_dump_fs(struct r300_fragment_shader* fs)
void r3xx_dump_fs(struct r3xx_fragment_shader* fs)
{
int i;
@ -30,7 +30,7 @@ static void r300_dump_fs(struct r300_fragment_shader* fs)
}
}
void r500_fs_dump(struct r500_fragment_shader* fs)
void r5xx_fs_dump(struct r5xx_fragment_shader* fs)
{
int i;
uint32_t inst;
@ -58,8 +58,8 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
inst & R500_INST_NOP ? "NOP" : "",
inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : "");
debug_printf("wmask: %s omask: %s\n",
r500_fs_mask[(inst >> 11) & 0xf],
r500_fs_mask[(inst >> 15) & 0xf]);
r5xx_fs_mask[(inst >> 11) & 0xf],
r5xx_fs_mask[(inst >> 15) & 0xf]);
switch (inst & 0x3) {
case R500_INST_TYPE_ALU:
case R500_INST_TYPE_OUT:
@ -85,36 +85,36 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
debug_printf(" 3: RGB_INST 0x%08x:", inst);
debug_printf("rgb_A_src:%d %s/%s/%s %d "
"rgb_B_src:%d %s/%s/%s %d\n",
inst & 0x3, r500_fs_swiz[(inst >> 2) & 0x7],
r500_fs_swiz[(inst >> 5) & 0x7],
r500_fs_swiz[(inst >> 8) & 0x7],
inst & 0x3, r5xx_fs_swiz[(inst >> 2) & 0x7],
r5xx_fs_swiz[(inst >> 5) & 0x7],
r5xx_fs_swiz[(inst >> 8) & 0x7],
(inst >> 11) & 0x3, (inst >> 13) & 0x3,
r500_fs_swiz[(inst >> 15) & 0x7],
r500_fs_swiz[(inst >> 18) & 0x7],
r500_fs_swiz[(inst >> 21) & 0x7],
r5xx_fs_swiz[(inst >> 15) & 0x7],
r5xx_fs_swiz[(inst >> 18) & 0x7],
r5xx_fs_swiz[(inst >> 21) & 0x7],
(inst >> 24) & 0x3);
inst = fs->instructions[i].inst4;
debug_printf(" 4: ALPHA_INST 0x%08x:", inst);
debug_printf("%s dest:%d%s alp_A_src:%d %s %d "
"alp_B_src:%d %s %d w:%d\n",
r500_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,
r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,
inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3,
r500_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3,
(inst >> 19) & 0x3, r500_fs_swiz[(inst >> 21) & 0x7],
r5xx_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3,
(inst >> 19) & 0x3, r5xx_fs_swiz[(inst >> 21) & 0x7],
(inst >> 24) & 0x3, (inst >> 31) & 0x1);
inst = fs->instructions[i].inst5;
debug_printf(" 5: RGBA_INST 0x%08x:", inst);
debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d "
"alp_C_src:%d %s %d\n",
r500_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,
r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,
inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3,
r500_fs_swiz[(inst >> 14) & 0x7],
r500_fs_swiz[(inst >> 17) & 0x7],
r500_fs_swiz[(inst >> 20) & 0x7],
r5xx_fs_swiz[(inst >> 14) & 0x7],
r5xx_fs_swiz[(inst >> 17) & 0x7],
r5xx_fs_swiz[(inst >> 20) & 0x7],
(inst >> 23) & 0x3, (inst >> 25) & 0x3,
r500_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3);
r5xx_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3);
break;
case R500_INST_TYPE_FC:
/* XXX don't even bother yet */
@ -124,7 +124,7 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
debug_printf(" 1: TEX_INST 0x%08x: id: %d "
"op:%s, %s, %s %s\n",
inst, (inst >> 16) & 0xf,
r500_fs_tex[(inst >> 22) & 0x7],
r5xx_fs_tex[(inst >> 22) & 0x7],
(inst & (1 << 25)) ? "ACQ" : "",
(inst & (1 << 26)) ? "IGNUNC" : "",
(inst & (1 << 27)) ? "UNSCALED" : "SCALED");
@ -133,15 +133,15 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
debug_printf(" 2: TEX_ADDR 0x%08x: "
"src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n",
inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "",
r500_fs_swiz[(inst >> 8) & 0x3],
r500_fs_swiz[(inst >> 10) & 0x3],
r500_fs_swiz[(inst >> 12) & 0x3],
r500_fs_swiz[(inst >> 14) & 0x3],
r5xx_fs_swiz[(inst >> 8) & 0x3],
r5xx_fs_swiz[(inst >> 10) & 0x3],
r5xx_fs_swiz[(inst >> 12) & 0x3],
r5xx_fs_swiz[(inst >> 14) & 0x3],
(inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "",
r500_fs_swiz[(inst >> 24) & 0x3],
r500_fs_swiz[(inst >> 26) & 0x3],
r500_fs_swiz[(inst >> 28) & 0x3],
r500_fs_swiz[(inst >> 30) & 0x3]);
r5xx_fs_swiz[(inst >> 24) & 0x3],
r5xx_fs_swiz[(inst >> 26) & 0x3],
r5xx_fs_swiz[(inst >> 28) & 0x3],
r5xx_fs_swiz[(inst >> 30) & 0x3]);
inst = fs->instructions[i].inst3;
debug_printf(" 3: TEX_DXDY 0x%08x\n", inst);

View File

@ -24,10 +24,10 @@
#define R300_DEBUG_H
#include "r300_reg.h"
#include "r300_state_shader.h"
#include "r300_state_tcl.h"
#include "r300_fs.h"
#include "r300_vs.h"
static char* r500_fs_swiz[] = {
static char* r5xx_fs_swiz[] = {
" R",
" G",
" B",
@ -38,7 +38,7 @@ static char* r500_fs_swiz[] = {
" U",
};
static char* r500_fs_op_rgb[] = {
static char* r5xx_fs_op_rgb[] = {
"MAD",
"DP3",
"DP4",
@ -54,7 +54,7 @@ static char* r500_fs_op_rgb[] = {
"MDV",
};
static char* r500_fs_op_alpha[] = {
static char* r5xx_fs_op_alpha[] = {
"MAD",
" DP",
"MIN",
@ -73,7 +73,7 @@ static char* r500_fs_op_alpha[] = {
"MDV",
};
static char* r500_fs_mask[] = {
static char* r5xx_fs_mask[] = {
"NONE",
"R ",
" G ",
@ -92,7 +92,7 @@ static char* r500_fs_mask[] = {
"RGBA",
};
static char* r500_fs_tex[] = {
static char* r5xx_fs_tex[] = {
" NOP",
" LD",
"TEXKILL",
@ -203,7 +203,8 @@ static char* r300_vs_swiz_debug[] = {
"U",
};
void r500_fs_dump(struct r500_fragment_shader* fs);
void r5xx_fs_dump(struct r5xx_fragment_shader* fs);
void r3xx_dump_fs(struct r3xx_fragment_shader* fs);
void r300_vs_dump(struct r300_vertex_shader* vs);

View File

@ -110,7 +110,7 @@ void r300_emit_dsa_state(struct r300_context* r300,
}
void r300_emit_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs)
struct r3xx_fragment_shader* fs)
{
int i;
CS_LOCALS(r300);
@ -142,7 +142,7 @@ void r300_emit_fragment_shader(struct r300_context* r300,
}
void r500_emit_fragment_shader(struct r300_context* r300,
struct r500_fragment_shader* fs)
struct r5xx_fragment_shader* fs)
{
int i;
struct r300_constant_buffer* constants =
@ -570,10 +570,10 @@ validate:
if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
if (r300screen->caps->is_r500) {
r500_emit_fragment_shader(r300,
(struct r500_fragment_shader*)r300->fs);
(struct r5xx_fragment_shader*)r300->fs);
} else {
r300_emit_fragment_shader(r300,
(struct r300_fragment_shader*)r300->fs);
(struct r3xx_fragment_shader*)r300->fs);
}
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
}

View File

@ -43,10 +43,10 @@ void r300_emit_dsa_state(struct r300_context* r300,
struct r300_dsa_state* dsa);
void r300_emit_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs);
struct r3xx_fragment_shader* fs);
void r500_emit_fragment_shader(struct r300_context* r300,
struct r500_fragment_shader* fs);
struct r5xx_fragment_shader* fs);
void r300_emit_fb_state(struct r300_context* r300,
struct pipe_framebuffer_state* fb);

View File

@ -0,0 +1,109 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
* Joakim Sindholt <opensource@zhasha.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "r300_fs.h"
void r300_translate_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs)
{
struct tgsi_parse_context parser;
int i;
boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
struct r300_constant_buffer* consts =
&r300->shader_constants[PIPE_SHADER_FRAGMENT];
struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm);
if (assembler == NULL) {
return;
}
/* Setup starting offset for immediates. */
assembler->imm_offset = consts->user_count;
/* Enable depth writes, if needed. */
assembler->writes_depth = fs->info.writes_z;
/* Make sure we start at the beginning of the shader. */
if (is_r500) {
((struct r5xx_fragment_shader*)fs)->instruction_count = 0;
}
tgsi_parse_init(&parser, fs->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_IMMEDIATE:
debug_printf("r300: Emitting immediate to constant buffer, "
"position %d\n",
assembler->imm_offset + assembler->imm_count);
/* I am not amused by the length of these. */
for (i = 0; i < 4; i++) {
consts->constants[assembler->imm_offset +
assembler->imm_count][i] =
parser.FullToken.FullImmediate.u.ImmediateFloat32[i]
.Float;
}
assembler->imm_count++;
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
if (is_r500) {
r5xx_fs_instruction((struct r5xx_fragment_shader*)fs,
assembler, &parser.FullToken.FullInstruction);
} else {
r3xx_fs_instruction((struct r3xx_fragment_shader*)fs,
assembler, &parser.FullToken.FullInstruction);
}
break;
}
}
debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n",
assembler->tex_count, assembler->color_count,
assembler->tex_count + assembler->color_count);
consts->count = consts->user_count + assembler->imm_count;
fs->uses_imms = assembler->imm_count;
debug_printf("r300: fs: %d total constants, "
"%d from user and %d from immediates\n", consts->count,
consts->user_count, assembler->imm_count);
r3xx_fs_finalize(fs, assembler);
if (is_r500) {
r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler);
}
tgsi_dump(fs->state.tokens, 0);
/* XXX finish r300 dumper too */
if (is_r500) {
r5xx_fs_dump((struct r5xx_fragment_shader*)fs);
}
tgsi_parse_free(&parser);
FREE(assembler);
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
* Joakim Sindholt <opensource@zhasha.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef R300_FS_H
#define R300_FS_H
#include "tgsi/tgsi_dump.h"
#include "r300_context.h"
#include "r3xx_fs.h"
#include "r5xx_fs.h"
void r300_translate_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs);
#endif /* R300_FS_H */

View File

@ -0,0 +1,158 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
* Joakim Sindholt <opensource@zhasha.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef R300_FS_INLINES_H
#define R300_FS_INLINES_H
#include "tgsi/tgsi_parse.h"
#include "r300_context.h"
#include "r300_debug.h"
#include "r300_reg.h"
#include "r300_screen.h"
#include "r300_shader_inlines.h"
/* Temporary struct used to hold assembly state while putting together
* fragment programs. */
struct r300_fs_asm {
/* Pipe context. */
struct r300_context* r300;
/* 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;
/* Number of requested temporary registers. */
unsigned temp_count;
/* Offset for immediate constants. Neither R300 nor R500 can do four
* inline constants per source, so instead we copy immediates into the
* constant buffer. */
unsigned imm_offset;
/* Number of immediate constants. */
unsigned imm_count;
/* Are depth writes enabled? */
boolean writes_depth;
/* Depth write offset. This is the TGSI output that corresponds to
* depth writes. */
unsigned depth_output;
};
static INLINE 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_FOG:
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:
/* Depth write. Mark the position of the output so we can
* identify it later. */
if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
assembler->depth_output = decl->DeclarationRange.First;
}
break;
case TGSI_FILE_CONSTANT:
break;
case TGSI_FILE_TEMPORARY:
assembler->temp_count++;
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 unsigned r300_fs_src(struct r300_fs_asm* assembler,
struct tgsi_src_register* src)
{
switch (src->File) {
case TGSI_FILE_NULL:
return 0;
case TGSI_FILE_INPUT:
/* XXX may be wrong */
return src->Index;
break;
case TGSI_FILE_TEMPORARY:
return src->Index + assembler->temp_offset;
break;
case TGSI_FILE_IMMEDIATE:
return (src->Index + assembler->imm_offset) | (1 << 8);
break;
case TGSI_FILE_CONSTANT:
/* XXX magic */
return src->Index | (1 << 8);
break;
default:
debug_printf("r300: fs: Unimplemented src %d\n", src->File);
break;
}
return 0;
}
static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,
struct tgsi_dst_register* dst)
{
switch (dst->File) {
case TGSI_FILE_NULL:
/* This happens during KIL instructions. */
return 0;
break;
case TGSI_FILE_OUTPUT:
return 0;
break;
case TGSI_FILE_TEMPORARY:
return dst->Index + assembler->temp_offset;
break;
default:
debug_printf("r300: fs: Unimplemented dst %d\n", dst->File);
break;
}
return 0;
}
static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler,
struct tgsi_dst_register* dst)
{
return (assembler->writes_depth &&
(dst->File == TGSI_FILE_OUTPUT) &&
(dst->Index == assembler->depth_output));
}
#endif /* R300_FS_INLINES_H */

View File

@ -0,0 +1,47 @@
/*
* Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
* Joakim Sindholt <opensource@zhasha.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef R300_SHADER_INLINES_H
#define R300_SHADER_INLINES_H
/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're
* not using enough of it. */
static const struct tgsi_full_src_register r300_constant_zero = {
.SrcRegister.Extended = TRUE,
.SrcRegister.File = TGSI_FILE_NULL,
.SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO,
};
static const struct tgsi_full_src_register r300_constant_one = {
.SrcRegister.Extended = TRUE,
.SrcRegister.File = TGSI_FILE_NULL,
.SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE,
.SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE,
.SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE,
.SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE,
};
#endif /* R300_SHADER_INLINES_H */

View File

@ -29,7 +29,7 @@
#include "r300_context.h"
#include "r300_reg.h"
#include "r300_state_inlines.h"
#include "r300_state_shader.h"
#include "r300_fs.h"
/* r300_state: Functions used to intialize state context by translating
* Gallium state objects into semi-native r300 state objects. */
@ -283,14 +283,12 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
const struct pipe_shader_state* shader)
{
struct r300_context* r300 = r300_context(pipe);
struct r3xx_fragment_shader* fs = NULL;
struct r300_fragment_shader* fs = NULL;
if (r300_screen(r300->context.screen)->caps->is_r500) {
fs =
(struct r3xx_fragment_shader*)CALLOC_STRUCT(r500_fragment_shader);
fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader);
} else {
fs =
(struct r3xx_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);
fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader);
}
/* Copy state directly into shader. */
@ -306,7 +304,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader;
struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
if (fs == NULL) {
r300->fs = NULL;
@ -324,7 +322,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
/* Delete fragment shader state. */
static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
{
struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader;
struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
FREE(fs->state.tokens);
FREE(shader);
}

View File

@ -151,11 +151,11 @@ validate:
/* Fragment shader setup */
if (caps->is_r500) {
r500_emit_fragment_shader(r300, &r500_passthrough_fragment_shader);
r300_emit_rs_block_state(r300, &r500_rs_block_clear_state);
r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader);
r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);
} else {
r300_emit_fragment_shader(r300, &r300_passthrough_fragment_shader);
r300_emit_rs_block_state(r300, &r300_rs_block_clear_state);
r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader);
r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);
}
BEGIN_CS(26);
@ -291,11 +291,11 @@ validate:
/* Fragment shader setup */
if (caps->is_r500) {
r500_emit_fragment_shader(r300, &r500_texture_fragment_shader);
r300_emit_rs_block_state(r300, &r500_rs_block_copy_state);
r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader);
r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);
} else {
r300_emit_fragment_shader(r300, &r300_texture_fragment_shader);
r300_emit_rs_block_state(r300, &r300_rs_block_copy_state);
r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader);
r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);
}
BEGIN_CS(30);

View File

@ -31,8 +31,8 @@
#include "r300_context.h"
#include "r300_cs.h"
#include "r300_emit.h"
#include "r300_state_shader.h"
#include "r300_state_tcl.h"
#include "r300_fs.h"
#include "r300_vs.h"
#include "r300_state_inlines.h"
static struct r300_blend_state blend_clear_state = {
@ -72,7 +72,7 @@ static struct r300_rs_state rs_clear_state = {
.color_control = R300_SHADE_MODEL_FLAT,
};
static struct r300_rs_block r300_rs_block_clear_state = {
static struct r300_rs_block r3xx_rs_block_clear_state = {
.ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |
R500_RS_SEL_T(R300_RS_SEL_K0) |
R500_RS_SEL_R(R300_RS_SEL_K0) |
@ -82,7 +82,7 @@ static struct r300_rs_block r300_rs_block_clear_state = {
.inst_count = 0,
};
static struct r300_rs_block r500_rs_block_clear_state = {
static struct r300_rs_block r5xx_rs_block_clear_state = {
.ip[0] = R500_RS_SEL_S(R500_RS_IP_PTR_K0) |
R500_RS_SEL_T(R500_RS_IP_PTR_K0) |
R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
@ -94,7 +94,7 @@ static struct r300_rs_block r500_rs_block_clear_state = {
/* The following state is used for surface_copy only. */
static struct r300_rs_block r300_rs_block_copy_state = {
static struct r300_rs_block r3xx_rs_block_copy_state = {
.ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |
R500_RS_SEL_T(R300_RS_SEL_K0) |
R500_RS_SEL_R(R300_RS_SEL_K0) |
@ -104,7 +104,7 @@ static struct r300_rs_block r300_rs_block_copy_state = {
.inst_count = R300_RS_TX_OFFSET(0),
};
static struct r300_rs_block r500_rs_block_copy_state = {
static struct r300_rs_block r5xx_rs_block_copy_state = {
.ip[0] = R500_RS_SEL_S(0) |
R500_RS_SEL_T(1) |
R500_RS_SEL_R(R500_RS_IP_PTR_K0) |

View File

@ -20,7 +20,7 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "r300_state_tcl.h"
#include "r300_vs.h"
static void r300_vs_declare(struct r300_vs_asm* assembler,
struct tgsi_full_declaration* decl)
@ -403,7 +403,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0],
assembler->tab[1], assembler->tab[2], assembler->tab[3]);
tgsi_dump(vs->state.tokens);
tgsi_dump(vs->state.tokens, 0);
/* XXX finish r300 vertex shader dumper */
r300_vs_dump(vs);

View File

@ -20,15 +20,17 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef R300_STATE_TCL_H
#define R300_STATE_TCL_H
#ifndef R300_VS_H
#define R300_VS_H
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_dump.h"
#include "r300_context.h"
#include "r300_debug.h"
#include "r300_reg.h"
#include "r300_screen.h"
#include "r300_shader_inlines.h"
/* XXX get these to r300_reg */
#define R300_PVS_DST_OPCODE(x) ((x) << 0)
@ -84,15 +86,6 @@
(R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
static const struct tgsi_full_src_register r300_constant_zero = {
.SrcRegister.Extended = TRUE,
.SrcRegister.File = TGSI_FILE_NULL,
.SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO,
};
/* Temporary struct used to hold assembly state while putting together
* fragment programs. */
struct r300_vs_asm {
@ -161,4 +154,4 @@ static struct r300_vertex_shader r300_texture_vertex_shader = {
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);
#endif /* R300_STATE_TCL_H */
#endif /* R300_VS_H */

View File

@ -0,0 +1,96 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
* Joakim Sindholt <opensource@zhasha.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "r3xx_fs.h"
static INLINE uint32_t r3xx_rgb_op(unsigned op)
{
switch (op) {
case TGSI_OPCODE_MOV:
return R300_ALU_OUTC_CMP;
default:
return 0;
}
}
static INLINE uint32_t r3xx_alpha_op(unsigned op)
{
switch (op) {
case TGSI_OPCODE_MOV:
return R300_ALU_OUTA_CMP;
default:
return 0;
}
}
static INLINE void r3xx_emit_maths(struct r3xx_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_src_register* src,
struct tgsi_full_dst_register* dst,
unsigned op,
unsigned count)
{
int i = fs->alu_instruction_count;
fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
r3xx_rgb_op(op);
fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ;
fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
r3xx_alpha_op(op);
fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT;
fs->alu_instruction_count++;
}
void r3xx_fs_finalize(struct r300_fragment_shader* fs,
struct r300_fs_asm* assembler)
{
fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
}
void r3xx_fs_instruction(struct r3xx_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_instruction* inst)
{
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_MOV:
/* src0 -> src1 and src2 forced to zero */
inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
inst->FullSrcRegisters[2] = r300_constant_zero;
r3xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
case TGSI_OPCODE_END:
break;
default:
debug_printf("r300: fs: Bad opcode %d\n",
inst->Instruction.Opcode);
break;
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
* Joakim Sindholt <opensource@zhasha.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef R3XX_FS_H
#define R3XX_FS_H
#include "r300_fs_inlines.h"
static struct r3xx_fragment_shader r3xx_passthrough_fragment_shader = {
.alu_instruction_count = 1,
.tex_instruction_count = 0,
.indirections = 0,
.shader.stack_size = 1,
.instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
R300_ALU_OUTC_CMP,
.instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
.instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
R300_ALU_OUTA_CMP,
.instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
};
static struct r3xx_fragment_shader r3xx_texture_fragment_shader = {
.alu_instruction_count = 1,
.tex_instruction_count = 0,
.indirections = 0,
.shader.stack_size = 1,
.instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
R300_ALU_OUTC_CMP,
.instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
.instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
R300_ALU_OUTA_CMP,
.instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
};
void r3xx_fs_finalize(struct r300_fragment_shader* fs,
struct r300_fs_asm* assembler);
void r3xx_fs_instruction(struct r3xx_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_instruction* inst);
#endif /* R3XX_FS_H */

View File

@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
* Joakim Sindholt <opensource@zhasha.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -20,104 +21,9 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "r300_state_shader.h"
#include "r5xx_fs.h"
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_FOG:
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:
/* Depth write. Mark the position of the output so we can
* identify it later. */
if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
assembler->depth_output = decl->DeclarationRange.First;
}
break;
case TGSI_FILE_CONSTANT:
break;
case TGSI_FILE_TEMPORARY:
assembler->temp_count++;
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 unsigned r300_fs_src(struct r300_fs_asm* assembler,
struct tgsi_src_register* src)
{
switch (src->File) {
case TGSI_FILE_NULL:
return 0;
case TGSI_FILE_INPUT:
/* XXX may be wrong */
return src->Index;
break;
case TGSI_FILE_TEMPORARY:
return src->Index + assembler->temp_offset;
break;
case TGSI_FILE_IMMEDIATE:
return (src->Index + assembler->imm_offset) | (1 << 8);
break;
case TGSI_FILE_CONSTANT:
/* XXX magic */
return src->Index | (1 << 8);
break;
default:
debug_printf("r300: fs: Unimplemented src %d\n", src->File);
break;
}
return 0;
}
static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,
struct tgsi_dst_register* dst)
{
switch (dst->File) {
case TGSI_FILE_NULL:
/* This happens during KIL instructions. */
return 0;
break;
case TGSI_FILE_OUTPUT:
return 0;
break;
case TGSI_FILE_TEMPORARY:
return dst->Index + assembler->temp_offset;
break;
default:
debug_printf("r300: fs: Unimplemented dst %d\n", dst->File);
break;
}
return 0;
}
static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler,
struct tgsi_dst_register* dst)
{
return (assembler->writes_depth &&
(dst->File == TGSI_FILE_OUTPUT) &&
(dst->Index == assembler->depth_output));
}
static INLINE unsigned r500_fix_swiz(unsigned s)
static INLINE unsigned r5xx_fix_swiz(unsigned s)
{
/* For historical reasons, the swizzle values x, y, z, w, and 0 are
* equivalent to the actual machine code, but 1 is not. Thus, we just
@ -129,13 +35,13 @@ static INLINE unsigned r500_fix_swiz(unsigned s)
}
}
static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg)
static uint32_t r5xx_rgba_swiz(struct tgsi_full_src_register* reg)
{
if (reg->SrcRegister.Extended) {
return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) |
(r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) |
(r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) |
(r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);
return r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) |
(r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) |
(r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) |
(r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);
} else {
return reg->SrcRegister.SwizzleX |
(reg->SrcRegister.SwizzleY << 3) |
@ -144,7 +50,7 @@ static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg)
}
}
static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg)
static uint32_t r5xx_strq_swiz(struct tgsi_full_src_register* reg)
{
return reg->SrcRegister.SwizzleX |
(reg->SrcRegister.SwizzleY << 2) |
@ -152,43 +58,23 @@ static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg)
(reg->SrcRegister.SwizzleW << 6);
}
static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg)
static INLINE uint32_t r5xx_rgb_swiz(struct tgsi_full_src_register* reg)
{
/* Only the first 9 bits... */
return (r500_rgba_swiz(reg) & 0x1ff) |
return (r5xx_rgba_swiz(reg) & 0x1ff) |
(reg->SrcRegister.Negate ? (1 << 9) : 0) |
(reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
}
static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg)
static INLINE uint32_t r5xx_alpha_swiz(struct tgsi_full_src_register* reg)
{
/* Only the last 3 bits... */
return (r500_rgba_swiz(reg) >> 9) |
return (r5xx_rgba_swiz(reg) >> 9) |
(reg->SrcRegister.Negate ? (1 << 9) : 0) |
(reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
}
static INLINE uint32_t r300_rgb_op(unsigned op)
{
switch (op) {
case TGSI_OPCODE_MOV:
return R300_ALU_OUTC_CMP;
default:
return 0;
}
}
static INLINE uint32_t r300_alpha_op(unsigned op)
{
switch (op) {
case TGSI_OPCODE_MOV:
return R300_ALU_OUTA_CMP;
default:
return 0;
}
}
static INLINE uint32_t r500_rgba_op(unsigned op)
static INLINE uint32_t r5xx_rgba_op(unsigned op)
{
switch (op) {
case TGSI_OPCODE_COS:
@ -224,7 +110,7 @@ static INLINE uint32_t r500_rgba_op(unsigned op)
}
}
static INLINE uint32_t r500_alpha_op(unsigned op)
static INLINE uint32_t r5xx_alpha_op(unsigned op)
{
switch (op) {
case TGSI_OPCODE_COS:
@ -264,7 +150,7 @@ static INLINE uint32_t r500_alpha_op(unsigned op)
}
}
static INLINE uint32_t r500_tex_op(unsigned op)
static INLINE uint32_t r5xx_tex_op(unsigned op)
{
switch (op) {
case TGSI_OPCODE_KIL:
@ -280,33 +166,8 @@ static INLINE uint32_t r500_tex_op(unsigned op)
}
}
static INLINE void r300_emit_maths(struct r300_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_src_register* src,
struct tgsi_full_dst_register* dst,
unsigned op,
unsigned count)
{
int i = fs->alu_instruction_count;
fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
r300_rgb_op(op);
fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ;
fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
r300_alpha_op(op);
fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT;
fs->alu_instruction_count++;
}
/* Setup an ALU operation. */
static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
static INLINE void r5xx_emit_maths(struct r5xx_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_src_register* src,
struct tgsi_full_dst_register* dst,
@ -343,9 +204,9 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
fs->instructions[i].inst5 |=
R500_ALU_RGBA_SEL_C_SRC2 |
R500_SWIZ_RGBA_C(r500_rgb_swiz(&src[2])) |
R500_SWIZ_RGBA_C(r5xx_rgb_swiz(&src[2])) |
R500_ALU_RGBA_ALPHA_SEL_C_SRC2 |
R500_SWIZ_ALPHA_C(r500_alpha_swiz(&src[2]));
R500_SWIZ_ALPHA_C(r5xx_alpha_swiz(&src[2]));
case 2:
fs->instructions[i].inst1 |=
R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
@ -353,10 +214,10 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
fs->instructions[i].inst3 =
R500_ALU_RGB_SEL_B_SRC1 |
R500_SWIZ_RGB_B(r500_rgb_swiz(&src[1]));
R500_SWIZ_RGB_B(r5xx_rgb_swiz(&src[1]));
fs->instructions[i].inst4 |=
R500_ALPHA_SEL_B_SRC1 |
R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1]));
R500_SWIZ_ALPHA_B(r5xx_alpha_swiz(&src[1]));
case 1:
case 0:
default:
@ -366,20 +227,20 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
fs->instructions[i].inst3 |=
R500_ALU_RGB_SEL_A_SRC0 |
R500_SWIZ_RGB_A(r500_rgb_swiz(&src[0]));
R500_SWIZ_RGB_A(r5xx_rgb_swiz(&src[0]));
fs->instructions[i].inst4 |=
R500_ALPHA_SEL_A_SRC0 |
R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0]));
R500_SWIZ_ALPHA_A(r5xx_alpha_swiz(&src[0]));
break;
}
fs->instructions[i].inst4 |= r500_alpha_op(op);
fs->instructions[i].inst5 |= r500_rgba_op(op);
fs->instructions[i].inst4 |= r5xx_alpha_op(op);
fs->instructions[i].inst5 |= r5xx_rgba_op(op);
fs->instruction_count++;
}
static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,
static INLINE void r5xx_emit_tex(struct r5xx_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_src_register* src,
struct tgsi_full_dst_register* dst,
@ -392,10 +253,10 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,
R500_INST_TEX_SEM_WAIT;
fs->instructions[i].inst1 = R500_TEX_ID(0) |
R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED |
r500_tex_op(op);
r5xx_tex_op(op);
fs->instructions[i].inst2 =
R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) |
R500_SWIZ_TEX_STRQ(r500_strq_swiz(src)) |
R500_SWIZ_TEX_STRQ(r5xx_strq_swiz(src)) |
R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) |
R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
@ -412,37 +273,24 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,
src[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
src[1] = src[0];
src[2] = r500_constant_zero;
r500_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3);
src[2] = r300_constant_zero;
r5xx_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3);
} else {
fs->instruction_count++;
}
}
static void r300_fs_instruction(struct r300_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_instruction* inst)
void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
struct r300_fs_asm* assembler)
{
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_MOV:
/* src0 -> src1 and src2 forced to zero */
inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
inst->FullSrcRegisters[2] = r500_constant_zero;
r300_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
case TGSI_OPCODE_END:
break;
default:
debug_printf("r300: fs: Bad opcode %d\n",
inst->Instruction.Opcode);
break;
}
/* XXX should this just go with OPCODE_END? */
fs->instructions[fs->instruction_count - 1].inst0 |=
R500_INST_LAST;
}
static void r500_fs_instruction(struct r500_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_instruction* inst)
void r5xx_fs_instruction(struct r5xx_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
@ -465,7 +313,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
case TGSI_OPCODE_DDX:
case TGSI_OPCODE_DDY:
case TGSI_OPCODE_FRC:
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 1);
break;
@ -486,7 +334,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
/* Fall through */
case TGSI_OPCODE_DP3:
case TGSI_OPCODE_DP4:
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 2);
break;
@ -496,7 +344,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2];
inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0];
inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3];
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
@ -510,18 +358,18 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
/* Force src0 to one, move all registers over */
inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1];
inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
inst->FullSrcRegisters[0] = r500_constant_one;
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
inst->FullSrcRegisters[0] = r300_constant_one;
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
case TGSI_OPCODE_MUL:
/* Force our src2 to zero */
inst->FullSrcRegisters[2] = r500_constant_zero;
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
inst->FullSrcRegisters[2] = r300_constant_zero;
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
case TGSI_OPCODE_MAD:
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
@ -534,8 +382,8 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
case TGSI_OPCODE_SWZ:
/* src0 -> src1 and src2 forced to zero */
inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
inst->FullSrcRegisters[2] = r500_constant_zero;
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
inst->FullSrcRegisters[2] = r300_constant_zero;
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
@ -550,7 +398,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
inst->FullDstRegisters[0].DstRegister.Index =
assembler->temp_count;
inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
inst->FullSrcRegisters[2].SrcRegister.Index =
assembler->temp_count;
@ -563,7 +411,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
inst->FullSrcRegisters[0].SrcRegister.Negate =
!(inst->FullSrcRegisters[0].SrcRegister.Negate);
inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
break;
case TGSI_OPCODE_POW:
@ -576,7 +424,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
inst->FullDstRegisters[0].DstRegister.Index =
assembler->temp_count;
inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1);
inst->FullSrcRegisters[0].SrcRegister.Index =
assembler->temp_count;
@ -585,11 +433,11 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
inst->FullSrcRegisters[2] = r500_constant_zero;
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
inst->FullSrcRegisters[2] = r300_constant_zero;
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3);
inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1);
break;
@ -598,7 +446,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
case TGSI_OPCODE_TEX:
case TGSI_OPCODE_TXB:
case TGSI_OPCODE_TXP:
r500_emit_tex(fs, assembler, &inst->FullSrcRegisters[0],
r5xx_emit_tex(fs, assembler, &inst->FullSrcRegisters[0],
&inst->FullDstRegisters[0], inst->Instruction.Opcode);
break;
@ -617,102 +465,3 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP;
}
}
static void r300_fs_finalize(struct r3xx_fragment_shader* fs,
struct r300_fs_asm* assembler)
{
fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
}
static void r500_fs_finalize(struct r500_fragment_shader* fs,
struct r300_fs_asm* assembler)
{
/* XXX should this just go with OPCODE_END? */
fs->instructions[fs->instruction_count - 1].inst0 |=
R500_INST_LAST;
}
void r300_translate_fragment_shader(struct r300_context* r300,
struct r3xx_fragment_shader* fs)
{
struct tgsi_parse_context parser;
int i;
boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
struct r300_constant_buffer* consts =
&r300->shader_constants[PIPE_SHADER_FRAGMENT];
struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm);
if (assembler == NULL) {
return;
}
/* Setup starting offset for immediates. */
assembler->imm_offset = consts->user_count;
/* Enable depth writes, if needed. */
assembler->writes_depth = fs->info.writes_z;
/* Make sure we start at the beginning of the shader. */
if (is_r500) {
((struct r500_fragment_shader*)fs)->instruction_count = 0;
}
tgsi_parse_init(&parser, fs->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_IMMEDIATE:
debug_printf("r300: Emitting immediate to constant buffer, "
"position %d\n",
assembler->imm_offset + assembler->imm_count);
/* I am not amused by the length of these. */
for (i = 0; i < 4; i++) {
consts->constants[assembler->imm_offset +
assembler->imm_count][i] =
parser.FullToken.FullImmediate.u.ImmediateFloat32[i]
.Float;
}
assembler->imm_count++;
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
if (is_r500) {
r500_fs_instruction((struct r500_fragment_shader*)fs,
assembler, &parser.FullToken.FullInstruction);
} else {
r300_fs_instruction((struct r300_fragment_shader*)fs,
assembler, &parser.FullToken.FullInstruction);
}
break;
}
}
debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n",
assembler->tex_count, assembler->color_count,
assembler->tex_count + assembler->color_count);
consts->count = consts->user_count + assembler->imm_count;
fs->uses_imms = assembler->imm_count;
debug_printf("r300: fs: %d total constants, "
"%d from user and %d from immediates\n", consts->count,
consts->user_count, assembler->imm_count);
r300_fs_finalize(fs, assembler);
if (is_r500) {
r500_fs_finalize((struct r500_fragment_shader*)fs, assembler);
}
tgsi_dump(fs->state.tokens);
/* XXX finish r300 dumper too */
if (is_r500) {
r500_fs_dump((struct r500_fragment_shader*)fs);
}
tgsi_parse_free(&parser);
FREE(assembler);
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
* Joakim Sindholt <opensource@zhasha.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -20,15 +21,10 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef R300_STATE_SHADER_H
#define R300_STATE_SHADER_H
#ifndef R5XX_FS_H
#define R5XX_FS_H
#include "tgsi/tgsi_parse.h"
#include "r300_context.h"
#include "r300_debug.h"
#include "r300_reg.h"
#include "r300_screen.h"
#include "r300_fs_inlines.h"
/* XXX this all should find its way back to r300_reg */
/* Swizzle tools */
@ -59,78 +55,7 @@
#define R500_ALU_OMASK(x) ((x) << 15)
#define R500_W_OMASK (1 << 31)
/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're
* not using enough of it. */
static const struct tgsi_full_src_register r500_constant_zero = {
.SrcRegister.Extended = TRUE,
.SrcRegister.File = TGSI_FILE_NULL,
.SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO,
.SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO,
};
static const struct tgsi_full_src_register r500_constant_one = {
.SrcRegister.Extended = TRUE,
.SrcRegister.File = TGSI_FILE_NULL,
.SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE,
.SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE,
.SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE,
.SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE,
};
/* Temporary struct used to hold assembly state while putting together
* fragment programs. */
struct r300_fs_asm {
/* Pipe context. */
struct r300_context* r300;
/* 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;
/* Number of requested temporary registers. */
unsigned temp_count;
/* Offset for immediate constants. Neither R300 nor R500 can do four
* inline constants per source, so instead we copy immediates into the
* constant buffer. */
unsigned imm_offset;
/* Number of immediate constants. */
unsigned imm_count;
/* Are depth writes enabled? */
boolean writes_depth;
/* Depth write offset. This is the TGSI output that corresponds to
* depth writes. */
unsigned depth_output;
};
void r300_translate_fragment_shader(struct r300_context* r300,
struct r3xx_fragment_shader* fs);
static struct r300_fragment_shader r300_passthrough_fragment_shader = {
.alu_instruction_count = 1,
.tex_instruction_count = 0,
.indirections = 0,
.shader.stack_size = 1,
.instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
R300_ALU_OUTC_CMP,
.instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
.instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
R300_ALU_OUTA_CMP,
.instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
};
static struct r500_fragment_shader r500_passthrough_fragment_shader = {
static struct r5xx_fragment_shader r5xx_passthrough_fragment_shader = {
.shader.stack_size = 0,
.instruction_count = 1,
.instructions[0].inst0 = R500_INST_TYPE_OUT |
@ -156,27 +81,7 @@ static struct r500_fragment_shader r500_passthrough_fragment_shader = {
R500_ALU_RGBA_A_SWIZ_0,
};
static struct r300_fragment_shader r300_texture_fragment_shader = {
.alu_instruction_count = 1,
.tex_instruction_count = 0,
.indirections = 0,
.shader.stack_size = 1,
.instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
R300_ALU_OUTC_CMP,
.instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
.instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
R300_ALU_OUTA_CMP,
.instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
};
static struct r500_fragment_shader r500_texture_fragment_shader = {
static struct r5xx_fragment_shader r5xx_texture_fragment_shader = {
.shader.stack_size = 1,
.instruction_count = 2,
.instructions[0].inst0 = R500_INST_TYPE_TEX |
@ -217,4 +122,11 @@ static struct r500_fragment_shader r500_texture_fragment_shader = {
R500_ALU_RGBA_A_SWIZ_0,
};
#endif /* R300_STATE_SHADER_H */
void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
struct r300_fs_asm* assembler);
void r5xx_fs_instruction(struct r5xx_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_instruction* inst);
#endif /* R5XX_FS_H */