mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
gallium: implement immediates (aka literals) for SSE fragment shaders
This commit is contained in:
parent
097301395d
commit
e3cf0cd6a9
3 changed files with 88 additions and 8 deletions
|
|
@ -225,6 +225,15 @@ get_coef_base( void )
|
|||
return get_output_base();
|
||||
}
|
||||
|
||||
static struct x86_reg
|
||||
get_immediate_base( void )
|
||||
{
|
||||
return x86_make_reg(
|
||||
file_REG32,
|
||||
reg_DI );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data access helpers.
|
||||
*/
|
||||
|
|
@ -238,6 +247,16 @@ get_argument(
|
|||
(index + 1) * 4 );
|
||||
}
|
||||
|
||||
static struct x86_reg
|
||||
get_immediate(
|
||||
unsigned vec,
|
||||
unsigned chan )
|
||||
{
|
||||
return x86_make_disp(
|
||||
get_immediate_base(),
|
||||
(vec * 4 + chan) * 4 );
|
||||
}
|
||||
|
||||
static struct x86_reg
|
||||
get_const(
|
||||
unsigned vec,
|
||||
|
|
@ -572,6 +591,25 @@ emit_const(
|
|||
SHUF( 0, 0, 0, 0 ) );
|
||||
}
|
||||
|
||||
static void
|
||||
emit_immediate(
|
||||
struct x86_function *func,
|
||||
unsigned xmm,
|
||||
unsigned vec,
|
||||
unsigned chan )
|
||||
{
|
||||
emit_movss(
|
||||
func,
|
||||
make_xmm( xmm ),
|
||||
get_immediate( vec, chan ) );
|
||||
emit_shufps(
|
||||
func,
|
||||
make_xmm( xmm ),
|
||||
make_xmm( xmm ),
|
||||
SHUF( 0, 0, 0, 0 ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a shader input to xmm register
|
||||
* \param xmm the destination xmm register
|
||||
|
|
@ -1191,6 +1229,14 @@ emit_fetch(
|
|||
swizzle );
|
||||
break;
|
||||
|
||||
case TGSI_FILE_IMMEDIATE:
|
||||
emit_immediate(
|
||||
func,
|
||||
xmm,
|
||||
reg->SrcRegister.Index,
|
||||
swizzle );
|
||||
break;
|
||||
|
||||
case TGSI_FILE_INPUT:
|
||||
emit_inputf(
|
||||
func,
|
||||
|
|
@ -2343,15 +2389,21 @@ tgsi_emit_sse2(
|
|||
* DECLARATION and INSTRUCTION phase.
|
||||
* GP register holding the output argument is aliased with the coeff argument,
|
||||
* as outputs are not needed in the DECLARATION phase.
|
||||
*
|
||||
* \param tokens the TGSI input shader
|
||||
* \param func the output SSE code/function
|
||||
* \param immediates buffer to place immediates, later passed to SSE func
|
||||
*/
|
||||
unsigned
|
||||
tgsi_emit_sse2_fs(
|
||||
struct tgsi_token *tokens,
|
||||
struct x86_function *func )
|
||||
struct x86_function *func,
|
||||
float (*immediates)[4])
|
||||
{
|
||||
struct tgsi_parse_context parse;
|
||||
boolean instruction_phase = FALSE;
|
||||
unsigned ok = 1;
|
||||
uint num_immediates = 0;
|
||||
|
||||
DUMP_START();
|
||||
|
||||
|
|
@ -2362,6 +2414,7 @@ tgsi_emit_sse2_fs(
|
|||
func,
|
||||
get_input_base(),
|
||||
get_argument( 0 ) );
|
||||
/* skipping outputs argument here */
|
||||
emit_mov(
|
||||
func,
|
||||
get_const_base(),
|
||||
|
|
@ -2374,6 +2427,10 @@ tgsi_emit_sse2_fs(
|
|||
func,
|
||||
get_coef_base(),
|
||||
get_argument( 4 ) );
|
||||
emit_mov(
|
||||
func,
|
||||
get_immediate_base(),
|
||||
get_argument( 5 ) );
|
||||
|
||||
tgsi_parse_init( &parse, tokens );
|
||||
|
||||
|
|
@ -2407,9 +2464,26 @@ tgsi_emit_sse2_fs(
|
|||
break;
|
||||
|
||||
case TGSI_TOKEN_TYPE_IMMEDIATE:
|
||||
/* XXX implement this */
|
||||
ok = 0;
|
||||
debug_printf("failed to emit immediate value to SSE\n");
|
||||
/* simply copy the immediate values into the next immediates[] slot */
|
||||
{
|
||||
const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1;
|
||||
uint i;
|
||||
assert(size <= 4);
|
||||
assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES);
|
||||
for( i = 0; i < size; i++ ) {
|
||||
immediates[num_immediates][i] =
|
||||
parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
|
||||
}
|
||||
#if 0
|
||||
debug_printf("SSE FS immediate[%d] = %f %f %f %f\n",
|
||||
num_immediates,
|
||||
immediates[num_immediates][0],
|
||||
immediates[num_immediates][1],
|
||||
immediates[num_immediates][2],
|
||||
immediates[num_immediates][3]);
|
||||
#endif
|
||||
num_immediates++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ tgsi_emit_sse2(
|
|||
unsigned
|
||||
tgsi_emit_sse2_fs(
|
||||
struct tgsi_token *tokens,
|
||||
struct x86_function *function );
|
||||
struct x86_function *function,
|
||||
float (*immediates)[4]
|
||||
);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ typedef void (XSTDCALL *codegen_function)(
|
|||
struct tgsi_exec_vector *output,
|
||||
float (*constant)[4],
|
||||
struct tgsi_exec_vector *temporary,
|
||||
const struct tgsi_interp_coef *coef
|
||||
const struct tgsi_interp_coef *coef,
|
||||
float (*immediates)[4]
|
||||
//, const struct tgsi_exec_vector *quadPos
|
||||
);
|
||||
|
||||
|
|
@ -60,6 +61,7 @@ struct sp_sse_fragment_shader {
|
|||
struct sp_fragment_shader base;
|
||||
struct x86_function sse2_program;
|
||||
codegen_function func;
|
||||
float immediates[TGSI_EXEC_NUM_IMMEDIATES][4];
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -96,7 +98,8 @@ fs_sse_run( struct sp_fragment_shader *base,
|
|||
machine->Outputs,
|
||||
machine->Consts,
|
||||
machine->Temps,
|
||||
machine->InterpCoefs
|
||||
machine->InterpCoefs,
|
||||
shader->immediates
|
||||
// , &machine->QuadPos
|
||||
);
|
||||
|
||||
|
|
@ -129,7 +132,8 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe,
|
|||
|
||||
x86_init_func( &shader->sse2_program );
|
||||
|
||||
if (!tgsi_emit_sse2_fs( templ->tokens, &shader->sse2_program )) {
|
||||
if (!tgsi_emit_sse2_fs( templ->tokens, &shader->sse2_program,
|
||||
shader->immediates)) {
|
||||
FREE(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue