From 364f75d9dbc2b8e19c884b9cc74676ab6cbee60d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 28 May 2008 22:19:58 +0900 Subject: draw: Use PIPE_CDECL. --- src/gallium/auxiliary/draw/draw_vs_aos.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/gallium/auxiliary/draw/draw_vs_aos.c') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index d3770b2c53..0cd82ff599 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1189,7 +1189,7 @@ static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } -static PIPE_CDECL void do_lit( struct aos_machine *machine, +static void PIPE_CDECL do_lit( struct aos_machine *machine, float *result, const float *in, unsigned count ) @@ -1223,7 +1223,7 @@ static PIPE_CDECL void do_lit( struct aos_machine *machine, } -static PIPE_CDECL void do_lit_lut( struct aos_machine *machine, +static void PIPE_CDECL do_lit_lut( struct aos_machine *machine, float *result, const float *in, unsigned count ) @@ -2119,10 +2119,10 @@ static void vaos_destroy( struct draw_vs_varient *varient ) FREE(vaos); } -static void vaos_run_elts( struct draw_vs_varient *varient, - const unsigned *elts, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; @@ -2133,10 +2133,10 @@ static void vaos_run_elts( struct draw_vs_varient *varient, output_buffer ); } -static void vaos_run_linear( struct draw_vs_varient *varient, - unsigned start, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; -- cgit v1.2.3 From 728d1f7f43b6db9f4f42c2d16ba223c492d1147d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 28 May 2008 23:54:18 +0100 Subject: draw: enable FSE by default --- src/gallium/auxiliary/draw/draw_pt.c | 11 ++- src/gallium/auxiliary/draw/draw_vs.h | 4 ++ src/gallium/auxiliary/draw/draw_vs_aos.c | 105 +++++++++++++++++++++------- src/gallium/auxiliary/draw/draw_vs_aos.h | 34 +++++---- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 25 ++++--- src/gallium/auxiliary/draw/draw_vs_sse.c | 14 ++-- 6 files changed, 129 insertions(+), 64 deletions(-) (limited to 'src/gallium/auxiliary/draw/draw_vs_aos.c') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 75f44d503e..d48c6c220d 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -75,7 +75,7 @@ draw_pt_arrays(struct draw_context *draw, if (opt == 0) middle = draw->pt.middle.fetch_emit; - else if (opt == PT_SHADE && draw->pt.test_fse) + else if (opt == PT_SHADE) middle = draw->pt.middle.fetch_shade_emit; else middle = draw->pt.middle.general; @@ -118,12 +118,9 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.middle.fetch_emit) return FALSE; - if (draw->pt.test_fse) { - draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw ); - if (!draw->pt.middle.fetch_shade_emit) - return FALSE; - } - + draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw ); + if (!draw->pt.middle.fetch_shade_emit) + return FALSE; draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit( draw ); if (!draw->pt.middle.general) diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 01171bc23d..7aa0415baf 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -123,6 +123,10 @@ struct draw_vertex_shader { struct tgsi_shader_info info; + /* Extracted from shader: + */ + const float (*immediates)[4]; + /* */ struct draw_vs_varient *varient[16]; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 0cd82ff599..9056785e7a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -66,6 +66,37 @@ static INLINE boolean eq( struct x86_reg a, a.disp == b.disp); } +struct x86_reg aos_get_x86( struct aos_compilation *cp, + unsigned value ) +{ + if (cp->ebp != value) { + unsigned offset; + + switch (value) { + case X86_IMMEDIATES: + offset = Offset(struct aos_machine, immediates); + break; + case X86_CONSTANTS: + offset = Offset(struct aos_machine, constants); + break; + case X86_ATTRIBS: + offset = Offset(struct aos_machine, attrib); + break; + default: + assert(0); + offset = 0; + } + + x86_mov(cp->func, cp->temp_EBP, + x86_make_disp(cp->machine_EDX, offset)); + /* x86_deref(x86_make_disp(cp->machine_EDX, offset))); */ + + cp->ebp = value; + } + + return cp->temp_EBP; +} + static struct x86_reg get_reg_ptr(struct aos_compilation *cp, unsigned file, @@ -83,15 +114,15 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, case TGSI_FILE_TEMPORARY: return x86_make_disp(ptr, Offset(struct aos_machine, temp[idx])); - case TGSI_FILE_IMMEDIATE: - return x86_make_disp(ptr, Offset(struct aos_machine, immediate[idx])); - - case TGSI_FILE_CONSTANT: - return x86_make_disp(ptr, Offset(struct aos_machine, constant[idx])); - case AOS_FILE_INTERNAL: return x86_make_disp(ptr, Offset(struct aos_machine, internal[idx])); + case TGSI_FILE_IMMEDIATE: + return x86_make_disp(aos_get_x86(cp, X86_IMMEDIATES), idx * 4 * sizeof(float)); + + case TGSI_FILE_CONSTANT: + return x86_make_disp(aos_get_x86(cp, X86_CONSTANTS), idx * 4 * sizeof(float)); + default: ERROR(cp, "unknown reg file"); return x86_make_reg(0,0); @@ -1865,6 +1896,7 @@ static boolean emit_rhw_viewport( struct aos_compilation *cp ) } +#if 0 static boolean note_immediate( struct aos_compilation *cp, struct tgsi_full_immediate *imm ) { @@ -1877,6 +1909,7 @@ static boolean note_immediate( struct aos_compilation *cp, return TRUE; } +#endif @@ -1939,6 +1972,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, cp.outbuf_ECX = x86_make_reg(file_REG32, reg_CX); cp.machine_EDX = x86_make_reg(file_REG32, reg_DX); cp.count_ESI = x86_make_reg(file_REG32, reg_SI); + cp.temp_EBP = x86_make_reg(file_REG32, reg_BP); x86_init_func(cp.func); @@ -1946,6 +1980,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, x86_push(cp.func, cp.idx_EBX); x86_push(cp.func, cp.count_ESI); + x86_push(cp.func, cp.temp_EBP); /* Load arguments into regs: @@ -1988,8 +2023,10 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, switch (parse.FullToken.Token.Type) { case TGSI_TOKEN_TYPE_IMMEDIATE: +#if 0 if (!note_immediate( &cp, &parse.FullToken.FullImmediate )) goto fail; +#endif break; case TGSI_TOKEN_TYPE_INSTRUCTION: @@ -2072,6 +2109,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, if (cp.func->need_emms) mmx_emms(cp.func); + x86_pop(cp.func, cp.temp_EBP); x86_pop(cp.func, cp.count_ESI); x86_pop(cp.func, cp.idx_EBX); @@ -2098,26 +2136,14 @@ static void vaos_set_buffer( struct draw_vs_varient *varient, for (i = 0; i < vaos->base.key.nr_inputs; i++) { if (vaos->base.key.element[i].in.buffer == buf) { - vaos->machine->attrib[i].input_ptr = ((char *)ptr + - vaos->base.key.element[i].in.offset); - vaos->machine->attrib[i].input_stride = stride; + vaos->attrib[i].input_ptr = ((char *)ptr + + vaos->base.key.element[i].in.offset); + vaos->attrib[i].input_stride = stride; } } } -static void vaos_destroy( struct draw_vs_varient *varient ) -{ - struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - - if (vaos->machine) - align_free( vaos->machine ); - - x86_release_func( &vaos->func[0] ); - x86_release_func( &vaos->func[1] ); - - FREE(vaos); -} static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, const unsigned *elts, @@ -2127,6 +2153,10 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; + vaos->machine->constants = vaos->draw->pt.user.constants; + vaos->machine->immediates = vaos->base.vs->immediates; + vaos->machine->attrib = vaos->attrib; + vaos->gen_run_elts( varient, elts, count, @@ -2141,6 +2171,10 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; + vaos->machine->constants = vaos->draw->pt.user.constants; + vaos->machine->immediates = vaos->base.vs->immediates; + vaos->machine->attrib = vaos->attrib; + vaos->gen_run_linear( varient, start, count, @@ -2153,10 +2187,6 @@ static void vaos_set_constants( struct draw_vs_varient *varient, { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - memcpy(vaos->machine->constant, - constants, - (vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1) * 4 * sizeof(float)); - #if 0 unsigned i; for (i =0; i < vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1; i++) @@ -2187,6 +2217,21 @@ static void vaos_set_viewport( struct draw_vs_varient *varient, memcpy(vaos->machine->translate, viewport->translate, 4 * sizeof(float)); } +static void vaos_destroy( struct draw_vs_varient *varient ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + + if (vaos->machine) + align_free( vaos->machine ); + + FREE( vaos->attrib ); + + x86_release_func( &vaos->func[0] ); + x86_release_func( &vaos->func[1] ); + + FREE(vaos); +} + static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, @@ -2207,6 +2252,11 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, vaos->base.run_elts = vaos_run_elts; vaos->draw = vs->draw; + + vaos->attrib = MALLOC( key->nr_inputs * sizeof(vaos->attrib[0]) ); + if (!vaos->attrib) + goto fail; + vaos->machine = align_malloc( sizeof(struct aos_machine), 16 ); if (!vaos->machine) goto fail; @@ -2233,7 +2283,10 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, return &vaos->base; fail: - if (vaos->machine) + if (vaos && vaos->attrib) + FREE(vaos->attrib); + + if (vaos && vaos->machine) align_free( vaos->machine ); if (vaos) diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 837b32794f..295d2cb3fe 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -78,6 +78,14 @@ struct lit_info { #define MAX_SHINE_TAB 4 #define MAX_LIT_INFO 16 +struct aos_attrib { + const void *input_ptr; + unsigned input_stride; +}; + + + + /* This is the temporary storage used by all the aos_sse vs varients. * Create one per context and reuse by passing a pointer in at * vs_varient creation?? @@ -86,8 +94,6 @@ struct aos_machine { float input [MAX_INPUTS ][4]; float output [MAX_OUTPUTS ][4]; float temp [MAX_TEMPS ][4]; - float constant [MAX_CONSTANTS ][4]; /* fixme -- should just be a pointer */ - float immediate[MAX_IMMEDIATES][4]; /* fixme -- should just be a pointer */ float internal [MAX_INTERNALS ][4]; float scale[4]; /* viewport */ @@ -105,12 +111,10 @@ struct aos_machine { ushort fpu_restore; ushort fpucntl; /* one of FPU_* above */ - struct { - const void *input_ptr; - unsigned input_stride; + const float (*immediates)[4]; /* points to shader data */ + const float (*constants)[4]; /* points to draw data */ - unsigned output_offset; - } attrib[PIPE_MAX_ATTRIBS]; + const struct aos_attrib *attrib; /* points to ? */ }; @@ -132,6 +136,7 @@ struct aos_compilation { unsigned last_used; } xmm[8]; + unsigned ebp; /* one of X86_* */ boolean input_fetched[PIPE_MAX_ATTRIBS]; unsigned output_last_write[PIPE_MAX_ATTRIBS]; @@ -148,6 +153,7 @@ struct aos_compilation { struct x86_reg outbuf_ECX; struct x86_reg machine_EDX; struct x86_reg count_ESI; /* decrements to zero */ + struct x86_reg temp_EBP; }; struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ); @@ -192,20 +198,20 @@ do { \ } while (0) +#define X86_NULL 0 +#define X86_IMMEDIATES 1 +#define X86_CONSTANTS 2 +#define X86_ATTRIBS 3 - +struct x86_reg aos_get_x86( struct aos_compilation *cp, + unsigned value ); struct draw_vs_varient_aos_sse { struct draw_vs_varient base; struct draw_context *draw; -#if 0 - struct { - const void *ptr; - unsigned stride; - } attrib[PIPE_MAX_ATTRIBS]; -#endif + struct aos_attrib *attrib; struct aos_machine *machine; /* XXX: temporarily unshared */ diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 836110f382..45e2092209 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -91,25 +91,25 @@ static void emit_load_R8G8B8A8_UNORM( struct aos_compilation *cp, -static void get_src_ptr( struct x86_function *func, +static void get_src_ptr( struct aos_compilation *cp, struct x86_reg src, - struct x86_reg machine, struct x86_reg elt, unsigned a ) { - struct x86_reg input_ptr = - x86_make_disp(machine, - Offset(struct aos_machine, attrib[a].input_ptr)); + struct x86_reg attrib = x86_make_disp(aos_get_x86( cp, X86_ATTRIBS ), + a * sizeof(struct aos_attrib)); - struct x86_reg input_stride = - x86_make_disp(machine, - Offset(struct aos_machine, attrib[a].input_stride)); + struct x86_reg input_ptr = x86_make_disp(attrib, + Offset(struct aos_attrib, input_ptr)); + + struct x86_reg input_stride = x86_make_disp(attrib, + Offset(struct aos_attrib, input_stride)); /* Calculate pointer to current attrib: */ - x86_mov(func, src, input_stride); - x86_imul(func, src, elt); - x86_add(func, src, input_ptr); + x86_mov(cp->func, src, input_stride); + x86_imul(cp->func, src, elt); + x86_add(cp->func, src, input_ptr); } @@ -134,9 +134,8 @@ static boolean load_input( struct aos_compilation *cp, /* Figure out source pointer address: */ - get_src_ptr(cp->func, + get_src_ptr(cp, src, - cp->machine_EDX, linear ? cp->idx_EBX : x86_deref(cp->idx_EBX), idx); diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 7781782ae8..24f619a278 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -68,8 +68,6 @@ struct draw_sse_vertex_shader { codegen_function func; struct tgsi_exec_machine *machine; - - float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; @@ -107,7 +105,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base, machine->Outputs, (float (*)[4])constants, machine->Temps, - shader->immediates, + (float (*)[4])shader->base.immediates, input, base->info.num_inputs, input_stride, @@ -130,6 +128,8 @@ vs_sse_delete( struct draw_vertex_shader *base ) x86_release_func( &shader->sse2_program ); + align_free(shader->base.immediates); + FREE( (void*) shader->base.state.tokens ); FREE( shader ); } @@ -161,12 +161,18 @@ draw_create_vs_sse(struct draw_context *draw, vs->base.prepare = vs_sse_prepare; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; + + vs->base.immediates = align_malloc(TGSI_EXEC_NUM_IMMEDIATES * 4 * + sizeof(float), 16); + vs->machine = &draw->vs.machine; x86_init_func( &vs->sse2_program ); if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state.tokens, - &vs->sse2_program, vs->immediates, TRUE )) + &vs->sse2_program, + (float (*)[4])vs->base.immediates, + TRUE )) goto fail; vs->func = (codegen_function) x86_get_func( &vs->sse2_program ); -- cgit v1.2.3 From 62628c4d3d497cbca73fde869c9069fa90e6453e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 00:17:53 +0100 Subject: draw: share machine --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_context.c | 3 + src/gallium/auxiliary/draw/draw_private.h | 9 + .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 6 - src/gallium/auxiliary/draw/draw_vs.c | 43 ++- src/gallium/auxiliary/draw/draw_vs.h | 24 +- src/gallium/auxiliary/draw/draw_vs_aos.c | 282 ++----------------- src/gallium/auxiliary/draw/draw_vs_aos.h | 25 +- src/gallium/auxiliary/draw/draw_vs_aos_machine.c | 297 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_varient.c | 49 +--- 11 files changed, 412 insertions(+), 328 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_vs_aos_machine.c (limited to 'src/gallium/auxiliary/draw/draw_vs_aos.c') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 9a88ecc070..f2e36a89e9 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -37,6 +37,7 @@ C_SOURCES = \ draw_vs_varient.c \ draw_vs_aos.c \ draw_vs_aos_io.c \ + draw_vs_aos_machine.c \ draw_vs_exec.c \ draw_vs_llvm.c \ draw_vs_sse.c diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 26919a2298..925e668f22 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -36,6 +36,7 @@ draw = env.ConvenienceLibrary( 'draw_vs.c', 'draw_vs_aos.c', 'draw_vs_aos_io.c', + 'draw_vs_aos_machine.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 2242074965..8509baf865 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -174,6 +174,8 @@ void draw_set_viewport_state( struct draw_context *draw, viewport->translate[1] == 0.0f && viewport->translate[2] == 0.0f && viewport->translate[3] == 0.0f); + + draw_vs_set_viewport( draw, viewport ); } @@ -218,6 +220,7 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer) { draw->pt.user.constants = buffer; + draw_vs_set_constants( draw, (const float (*)[4])buffer ); } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index c095bf3d7b..4cbccc8b5b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -183,6 +183,10 @@ struct draw_context */ struct gallivm_cpu_engine *engine; + /* Here's another one: + */ + struct aos_machine *aos_machine; + struct translate *fetch; struct translate_cache *fetch_cache; @@ -215,6 +219,11 @@ struct draw_context boolean draw_vs_init( struct draw_context *draw ); void draw_vs_destroy( struct draw_context *draw ); +void draw_vs_set_viewport( struct draw_context *, + const struct pipe_viewport_state * ); + +void draw_vs_set_constants( struct draw_context *, + const float (*constants)[4] ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 729c7db999..5265a13160 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -189,12 +189,6 @@ static void fse_prepare( struct draw_pt_middle_end *middle, draw->pt.vertex_buffer[buf].pitch ); } - fse->active->set_constants( fse->active, - (const float (*)[4])draw->pt.user.constants ); - - fse->active->set_viewport( fse->active, - &draw->viewport ); - //return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 9b899d404e..a8b6d0c90d 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -41,6 +41,22 @@ + +void draw_vs_set_constants( struct draw_context *draw, + const float (*constants)[4] ) +{ + draw_vs_aos_machine_constants( draw->vs.aos_machine, constants ); +} + + +void draw_vs_set_viewport( struct draw_context *draw, + const struct pipe_viewport_state *viewport ) +{ + draw_vs_aos_machine_viewport( draw->vs.aos_machine, viewport ); +} + + + struct draw_vertex_shader * draw_create_vertex_shader(struct draw_context *draw, const struct pipe_shader_state *shader) @@ -83,6 +99,13 @@ void draw_delete_vertex_shader(struct draw_context *draw, struct draw_vertex_shader *dvs) { + unsigned i; + + for (i = 0; i < dvs->nr_varients; i++) + dvs->varient[i]->destroy( dvs->varient[i] ); + + dvs->nr_varients = 0; + dvs->delete( dvs ); } @@ -110,6 +133,10 @@ draw_vs_init( struct draw_context *draw ) draw->vs.fetch_cache = translate_cache_create(); if (!draw->vs.fetch_cache) return FALSE; + + draw->vs.aos_machine = draw_vs_aos_machine(); + if (!draw->vs.aos_machine) + return FALSE; return TRUE; } @@ -129,6 +156,9 @@ draw_vs_destroy( struct draw_context *draw ) if (draw->vs.emit_cache) translate_cache_destroy(draw->vs.emit_cache); + if (draw->vs.aos_machine) + draw_vs_aos_machine_destroy(draw->vs.aos_machine); + tgsi_exec_machine_free_data(&draw->vs.machine); } @@ -153,10 +183,17 @@ draw_vs_lookup_varient( struct draw_vertex_shader *vs, if (varient == NULL) return NULL; - /* Add it to our list: + /* Add it to our list, could be smarter: */ - assert(vs->nr_varients < Elements(vs->varient)); - vs->varient[vs->nr_varients++] = varient; + if (vs->nr_varients < Elements(vs->varient)) { + vs->varient[vs->nr_varients++] = varient; + } + else { + vs->last_varient++; + vs->last_varient %= Elements(vs->varient); + vs->varient[vs->last_varient]->destroy(vs->varient[vs->last_varient]); + vs->varient[vs->last_varient] = varient; + } /* Done */ diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 7aa0415baf..08c6de8ba8 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -70,16 +70,6 @@ struct draw_vs_varient_key { struct draw_vs_varient; -typedef void (PIPE_CDECL *vsv_run_elts_func)( struct draw_vs_varient *, - const unsigned *elts, - unsigned count, - void *output_buffer); - -typedef void (PIPE_CDECL *vsv_run_linear_func)( struct draw_vs_varient *, - unsigned start, - unsigned count, - void *output_buffer); - struct draw_vs_varient { struct draw_vs_varient_key key; @@ -91,12 +81,6 @@ struct draw_vs_varient { const void *ptr, unsigned stride ); - void (*set_constants)( struct draw_vs_varient *, - const float (*constants)[4] ); - - void (*set_viewport)( struct draw_vs_varient *, - const struct pipe_viewport_state * ); - void (PIPE_CDECL *run_linear)( struct draw_vs_varient *shader, unsigned start, unsigned count, @@ -131,6 +115,7 @@ struct draw_vertex_shader { */ struct draw_vs_varient *varient[16]; unsigned nr_varients; + unsigned last_varient; struct draw_vs_varient *(*create_varient)( struct draw_vertex_shader *shader, const struct draw_vs_varient_key *key ); @@ -217,7 +202,14 @@ static INLINE int draw_vs_varient_key_compare( const struct draw_vs_varient_key } +struct aos_machine *draw_vs_aos_machine( void ); +void draw_vs_aos_machine_destroy( struct aos_machine *machine ); + +void draw_vs_aos_machine_constants( struct aos_machine *machine, + const float (*constants)[4] ); +void draw_vs_aos_machine_viewport( struct aos_machine *machine, + const struct pipe_viewport_state *viewport ); #define MAX_TGSI_VERTICES 4 diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 9056785e7a..b5e4e1e7b1 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -149,70 +149,7 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, #define X87_CW_ROUND_MASK (3<<10) #define X87_CW_INFINITY (1<<12) -static void do_populate_lut( struct shine_tab *tab, - float unclamped_exponent ) -{ - const float epsilon = 1.0F / 256.0F; - float exponent = CLAMP(unclamped_exponent, -(128.0F - epsilon), (128.0F - epsilon)); - unsigned i; - tab->exponent = unclamped_exponent; /* for later comparison */ - - tab->values[0] = 0; - if (exponent == 0) { - for (i = 1; i < 258; i++) { - tab->values[i] = 1.0; - } - } - else { - for (i = 1; i < 258; i++) { - tab->values[i] = powf((float)i * epsilon, exponent); - } - } -} - -static void init_internals( struct aos_machine *machine ) -{ - unsigned i; - float inv = 1.0f/255.0f; - float f255 = 255.0f; - - ASSIGN_4V(machine->internal[IMM_SWZ], 1.0f, -1.0f, 0.0f, 1.0f); - *(unsigned *)&machine->internal[IMM_SWZ][3] = 0xffffffff; - - ASSIGN_4V(machine->internal[IMM_ONES], 1.0f, 1.0f, 1.0f, 1.0f); - ASSIGN_4V(machine->internal[IMM_NEGS], -1.0f, -1.0f, -1.0f, -1.0f); - ASSIGN_4V(machine->internal[IMM_IDENTITY], 0.0f, 0.0f, 0.0f, 1.0f); - ASSIGN_4V(machine->internal[IMM_INV_255], inv, inv, inv, inv); - ASSIGN_4V(machine->internal[IMM_255], f255, f255, f255, f255); - ASSIGN_4V(machine->internal[IMM_RSQ], -.5f, 1.5f, 0.0f, 0.0f); - - - machine->fpu_rnd_nearest = (X87_CW_EXCEPTION_INV_OP | - X87_CW_EXCEPTION_DENORM_OP | - X87_CW_EXCEPTION_ZERO_DIVIDE | - X87_CW_EXCEPTION_OVERFLOW | - X87_CW_EXCEPTION_UNDERFLOW | - X87_CW_EXCEPTION_PRECISION | - (1<<6) | - X87_CW_ROUND_NEAREST | - X87_CW_PRECISION_DOUBLE_EXT); - - assert(machine->fpu_rnd_nearest == 0x37f); - - machine->fpu_rnd_neg_inf = (X87_CW_EXCEPTION_INV_OP | - X87_CW_EXCEPTION_DENORM_OP | - X87_CW_EXCEPTION_ZERO_DIVIDE | - X87_CW_EXCEPTION_OVERFLOW | - X87_CW_EXCEPTION_UNDERFLOW | - X87_CW_EXCEPTION_PRECISION | - (1<<6) | - X87_CW_ROUND_DOWN | - X87_CW_PRECISION_DOUBLE_EXT); - - for (i = 0; i < MAX_SHINE_TAB; i++) - do_populate_lut( &machine->shine_tab[i], 1.0f ); -} static void spill( struct aos_compilation *cp, unsigned idx ) @@ -1220,136 +1157,6 @@ static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } -static void PIPE_CDECL do_lit( struct aos_machine *machine, - float *result, - const float *in, - unsigned count ) -{ - if (in[0] > 0) - { - if (in[1] <= 0.0) - { - result[0] = 1.0F; - result[1] = in[0]; - result[2] = 1.0; - result[3] = 1.0F; - } - else - { - const float epsilon = 1.0F / 256.0F; - float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); - result[0] = 1.0F; - result[1] = in[0]; - result[2] = powf(in[1], exponent); - result[3] = 1.0; - } - } - else - { - result[0] = 1.0F; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 1.0F; - } -} - - -static void PIPE_CDECL do_lit_lut( struct aos_machine *machine, - float *result, - const float *in, - unsigned count ) -{ - if (in[0] > 0) - { - if (in[1] <= 0.0) - { - result[0] = 1.0F; - result[1] = in[0]; - result[2] = 1.0; - result[3] = 1.0F; - return; - } - - if (machine->lit_info[count].shine_tab->exponent != in[3]) { - machine->lit_info[count].func = do_lit; - goto no_luck; - } - - if (in[1] <= 1.0) - { - const float *tab = machine->lit_info[count].shine_tab->values; - float f = in[1] * 256; - int k = (int)f; - float frac = f - (float)k; - - result[0] = 1.0F; - result[1] = in[0]; - result[2] = tab[k] + frac*(tab[k+1]-tab[k]); - result[3] = 1.0; - return; - } - - no_luck: - { - const float epsilon = 1.0F / 256.0F; - float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); - result[0] = 1.0F; - result[1] = in[0]; - result[2] = powf(in[1], exponent); - result[3] = 1.0; - } - } - else - { - result[0] = 1.0F; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 1.0F; - } -} - - - -static void PIPE_CDECL populate_lut( struct aos_machine *machine, - float *result, - const float *in, - unsigned count ) -{ - unsigned i, tab; - - /* Search for an existing table for this value. Note that without - * static analysis we don't really know if in[3] will be constant, - * but it usually is... - */ - for (tab = 0; tab < 4; tab++) { - if (machine->shine_tab[tab].exponent == in[3]) { - goto found; - } - } - - for (tab = 0, i = 1; i < 4; i++) { - if (machine->shine_tab[i].last_used < machine->shine_tab[tab].last_used) - tab = i; - } - - if (machine->shine_tab[tab].last_used == machine->now) { - /* No unused tables (this is not a ffvertex program...). Just - * call pow each time: - */ - machine->lit_info[count].func = do_lit; - machine->lit_info[count].func( machine, result, in, count ); - return; - } - else { - do_populate_lut( &machine->shine_tab[tab], in[3] ); - } - - found: - machine->shine_tab[tab].last_used = machine->now; - machine->lit_info[count].shine_tab = &machine->shine_tab[tab]; - machine->lit_info[count].func = do_lit_lut; - machine->lit_info[count].func( machine, result, in, count ); -} @@ -1413,7 +1220,7 @@ static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_inst Offset(struct lit_info, func))); } else { - x86_mov_reg_imm( cp->func, ecx, (int)do_lit ); + x86_mov_reg_imm( cp->func, ecx, (int)aos_do_lit ); } x86_call( cp->func, ecx ); @@ -1434,7 +1241,7 @@ static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } - +#if 0 static boolean emit_inline_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); @@ -1495,6 +1302,7 @@ static boolean emit_inline_LIT( struct aos_compilation *cp, const struct tgsi_fu return TRUE; } +#endif @@ -1945,7 +1753,7 @@ static void find_last_write_outputs( struct aos_compilation *cp ) } -#define ARG_VARIENT 1 +#define ARG_MACHINE 1 #define ARG_START_ELTS 2 #define ARG_COUNT 3 #define ARG_OUTBUF 4 @@ -1985,7 +1793,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, /* Load arguments into regs: */ - x86_mov(cp.func, cp.machine_EDX, x86_fn_arg(cp.func, ARG_VARIENT)); + x86_mov(cp.func, cp.machine_EDX, x86_fn_arg(cp.func, ARG_MACHINE)); x86_mov(cp.func, cp.idx_EBX, x86_fn_arg(cp.func, ARG_START_ELTS)); x86_mov(cp.func, cp.count_ESI, x86_fn_arg(cp.func, ARG_COUNT)); x86_mov(cp.func, cp.outbuf_ECX, x86_fn_arg(cp.func, ARG_OUTBUF)); @@ -1997,11 +1805,6 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, x86_cmp(cp.func, cp.count_ESI, cp.tmp_EAX); fixup = x86_jcc_forward(cp.func, cc_E); - /* Dig out the machine pointer from inside the varient arg - */ - x86_mov(cp.func, cp.machine_EDX, - x86_make_disp(cp.machine_EDX, - Offset( struct draw_vs_varient_aos_sse, machine ))); save_fpu_state( &cp ); set_fpu_round_nearest( &cp ); @@ -2151,13 +1954,14 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, void *output_buffer ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + struct aos_machine *machine = vaos->draw->vs.aos_machine; - vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - vaos->machine->constants = vaos->draw->pt.user.constants; - vaos->machine->immediates = vaos->base.vs->immediates; - vaos->machine->attrib = vaos->attrib; + machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; + machine->constants = (const float (*)[4])vaos->draw->pt.user.constants; + machine->immediates = vaos->base.vs->immediates; + machine->attrib = vaos->attrib; - vaos->gen_run_elts( varient, + vaos->gen_run_elts( machine, elts, count, output_buffer ); @@ -2169,61 +1973,25 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, void *output_buffer ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + struct aos_machine *machine = vaos->draw->vs.aos_machine; - vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - vaos->machine->constants = vaos->draw->pt.user.constants; - vaos->machine->immediates = vaos->base.vs->immediates; - vaos->machine->attrib = vaos->attrib; + machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; + machine->constants = (const float (*)[4])vaos->draw->pt.user.constants; + machine->immediates = vaos->base.vs->immediates; + machine->attrib = vaos->attrib; - vaos->gen_run_linear( varient, + vaos->gen_run_linear( machine, start, count, output_buffer ); } -static void vaos_set_constants( struct draw_vs_varient *varient, - const float (*constants)[4] ) -{ - struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - -#if 0 - unsigned i; - for (i =0; i < vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1; i++) - debug_printf("state %d: %f %f %f %f\n", - i, - constants[i][0], - constants[i][1], - constants[i][2], - constants[i][3]); -#endif - - { - unsigned i; - for (i = 0; i < MAX_LIT_INFO; i++) { - vaos->machine->lit_info[i].func = populate_lut; - vaos->machine->now++; - } - } -} - - -static void vaos_set_viewport( struct draw_vs_varient *varient, - const struct pipe_viewport_state *viewport ) -{ - struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - - memcpy(vaos->machine->scale, viewport->scale, 4 * sizeof(float)); - memcpy(vaos->machine->translate, viewport->translate, 4 * sizeof(float)); -} static void vaos_destroy( struct draw_vs_varient *varient ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - if (vaos->machine) - align_free( vaos->machine ); - FREE( vaos->attrib ); x86_release_func( &vaos->func[0] ); @@ -2245,8 +2013,6 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, vaos->base.key = *key; vaos->base.vs = vs; vaos->base.set_input = vaos_set_buffer; - vaos->base.set_constants = vaos_set_constants; - vaos->base.set_viewport = vaos_set_viewport; vaos->base.destroy = vaos_destroy; vaos->base.run_linear = vaos_run_linear; vaos->base.run_elts = vaos_run_elts; @@ -2257,13 +2023,6 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, if (!vaos->attrib) goto fail; - vaos->machine = align_malloc( sizeof(struct aos_machine), 16 ); - if (!vaos->machine) - goto fail; - - memset(vaos->machine, 0, sizeof(struct aos_machine)); - init_internals(vaos->machine); - tgsi_dump(vs->state.tokens, 0); if (!build_vertex_program( vaos, TRUE )) @@ -2272,11 +2031,11 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, if (!build_vertex_program( vaos, FALSE )) goto fail; - vaos->gen_run_linear = (vsv_run_linear_func)x86_get_func(&vaos->func[0]); + vaos->gen_run_linear = (vaos_run_linear_func)x86_get_func(&vaos->func[0]); if (!vaos->gen_run_linear) goto fail; - vaos->gen_run_elts = (vsv_run_elts_func)x86_get_func(&vaos->func[1]); + vaos->gen_run_elts = (vaos_run_elts_func)x86_get_func(&vaos->func[1]); if (!vaos->gen_run_elts) goto fail; @@ -2286,9 +2045,6 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, if (vaos && vaos->attrib) FREE(vaos->attrib); - if (vaos && vaos->machine) - align_free( vaos->machine ); - if (vaos) x86_release_func( &vaos->func[0] ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 295d2cb3fe..89a9174151 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -60,10 +60,16 @@ struct x86_function; #define FPU_RND_NEAREST 2 struct aos_machine; -typedef void (PIPE_CDECL *lit_func)( struct aos_machine *, +typedef void PIPE_CDECL (*lit_func)( struct aos_machine *, float *result, const float *in, unsigned count ); + +PIPE_CDECL void aos_do_lit( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ); + struct shine_tab { float exponent; float values[258]; @@ -207,16 +213,25 @@ struct x86_reg aos_get_x86( struct aos_compilation *cp, unsigned value ); +typedef void (PIPE_CDECL *vaos_run_elts_func)( struct aos_machine *, + const unsigned *elts, + unsigned count, + void *output_buffer); + +typedef void (PIPE_CDECL *vaos_run_linear_func)( struct aos_machine *, + unsigned start, + unsigned count, + void *output_buffer); + + struct draw_vs_varient_aos_sse { struct draw_vs_varient base; struct draw_context *draw; struct aos_attrib *attrib; - struct aos_machine *machine; /* XXX: temporarily unshared */ - - vsv_run_linear_func gen_run_linear; - vsv_run_elts_func gen_run_elts; + vaos_run_linear_func gen_run_linear; + vaos_run_elts_func gen_run_elts; struct x86_function func[2]; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c new file mode 100644 index 0000000000..53e999b191 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c @@ -0,0 +1,297 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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 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 TUNGSTEN GRAPHICS AND/OR ITS 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 "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi/exec/tgsi_exec.h" +#include "draw_vs.h" +#include "draw_vs_aos.h" +#include "draw_vertex.h" + +#include "rtasm/rtasm_x86sse.h" + + +#define X87_CW_EXCEPTION_INV_OP (1<<0) +#define X87_CW_EXCEPTION_DENORM_OP (1<<1) +#define X87_CW_EXCEPTION_ZERO_DIVIDE (1<<2) +#define X87_CW_EXCEPTION_OVERFLOW (1<<3) +#define X87_CW_EXCEPTION_UNDERFLOW (1<<4) +#define X87_CW_EXCEPTION_PRECISION (1<<5) +#define X87_CW_PRECISION_SINGLE (0<<8) +#define X87_CW_PRECISION_RESERVED (1<<8) +#define X87_CW_PRECISION_DOUBLE (2<<8) +#define X87_CW_PRECISION_DOUBLE_EXT (3<<8) +#define X87_CW_PRECISION_MASK (3<<8) +#define X87_CW_ROUND_NEAREST (0<<10) +#define X87_CW_ROUND_DOWN (1<<10) +#define X87_CW_ROUND_UP (2<<10) +#define X87_CW_ROUND_ZERO (3<<10) +#define X87_CW_ROUND_MASK (3<<10) +#define X87_CW_INFINITY (1<<12) + + +PIPE_CDECL void aos_do_lit( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + if (in[0] > 0) + { + if (in[1] <= 0.0) + { + result[0] = 1.0F; + result[1] = in[0]; + result[2] = 1.0; + result[3] = 1.0F; + } + else + { + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); + result[0] = 1.0F; + result[1] = in[0]; + result[2] = powf(in[1], exponent); + result[3] = 1.0; + } + } + else + { + result[0] = 1.0F; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 1.0F; + } +} + + +static PIPE_CDECL void do_lit_lut( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + if (in[0] > 0) + { + if (in[1] <= 0.0) + { + result[0] = 1.0F; + result[1] = in[0]; + result[2] = 1.0; + result[3] = 1.0F; + return; + } + + if (machine->lit_info[count].shine_tab->exponent != in[3]) { + machine->lit_info[count].func = aos_do_lit; + goto no_luck; + } + + if (in[1] <= 1.0) + { + const float *tab = machine->lit_info[count].shine_tab->values; + float f = in[1] * 256; + int k = (int)f; + float frac = f - (float)k; + + result[0] = 1.0F; + result[1] = in[0]; + result[2] = tab[k] + frac*(tab[k+1]-tab[k]); + result[3] = 1.0; + return; + } + + no_luck: + { + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); + result[0] = 1.0F; + result[1] = in[0]; + result[2] = powf(in[1], exponent); + result[3] = 1.0; + } + } + else + { + result[0] = 1.0F; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 1.0F; + } +} + + +static void do_populate_lut( struct shine_tab *tab, + float unclamped_exponent ) +{ + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(unclamped_exponent, -(128.0F - epsilon), (128.0F - epsilon)); + unsigned i; + + tab->exponent = unclamped_exponent; /* for later comparison */ + + tab->values[0] = 0; + if (exponent == 0) { + for (i = 1; i < 258; i++) { + tab->values[i] = 1.0; + } + } + else { + for (i = 1; i < 258; i++) { + tab->values[i] = powf((float)i * epsilon, exponent); + } + } +} + + + + +static void PIPE_CDECL populate_lut( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + unsigned i, tab; + + /* Search for an existing table for this value. Note that without + * static analysis we don't really know if in[3] will be constant, + * but it usually is... + */ + for (tab = 0; tab < 4; tab++) { + if (machine->shine_tab[tab].exponent == in[3]) { + goto found; + } + } + + for (tab = 0, i = 1; i < 4; i++) { + if (machine->shine_tab[i].last_used < machine->shine_tab[tab].last_used) + tab = i; + } + + if (machine->shine_tab[tab].last_used == machine->now) { + /* No unused tables (this is not a ffvertex program...). Just + * call pow each time: + */ + machine->lit_info[count].func = aos_do_lit; + machine->lit_info[count].func( machine, result, in, count ); + return; + } + else { + do_populate_lut( &machine->shine_tab[tab], in[3] ); + } + + found: + machine->shine_tab[tab].last_used = machine->now; + machine->lit_info[count].shine_tab = &machine->shine_tab[tab]; + machine->lit_info[count].func = do_lit_lut; + machine->lit_info[count].func( machine, result, in, count ); +} + + +void draw_vs_aos_machine_constants( struct aos_machine *machine, + const float (*constants)[4] ) +{ + machine->constants = constants; + + { + unsigned i; + for (i = 0; i < MAX_LIT_INFO; i++) { + machine->lit_info[i].func = populate_lut; + machine->now++; + } + } +} + + +void draw_vs_aos_machine_viewport( struct aos_machine *machine, + const struct pipe_viewport_state *viewport ) +{ + memcpy(machine->scale, viewport->scale, 4 * sizeof(float)); + memcpy(machine->translate, viewport->translate, 4 * sizeof(float)); +} + + + +void draw_vs_aos_machine_destroy( struct aos_machine *machine ) +{ + align_free(machine); +} + +struct aos_machine *draw_vs_aos_machine( void ) +{ + struct aos_machine *machine; + unsigned i; + float inv = 1.0f/255.0f; + float f255 = 255.0f; + + machine = align_malloc(sizeof(struct aos_machine), 16); + if (!machine) + return NULL; + + memset(machine, 0, sizeof(*machine)); + + ASSIGN_4V(machine->internal[IMM_SWZ], 1.0f, -1.0f, 0.0f, 1.0f); + *(unsigned *)&machine->internal[IMM_SWZ][3] = 0xffffffff; + + ASSIGN_4V(machine->internal[IMM_ONES], 1.0f, 1.0f, 1.0f, 1.0f); + ASSIGN_4V(machine->internal[IMM_NEGS], -1.0f, -1.0f, -1.0f, -1.0f); + ASSIGN_4V(machine->internal[IMM_IDENTITY], 0.0f, 0.0f, 0.0f, 1.0f); + ASSIGN_4V(machine->internal[IMM_INV_255], inv, inv, inv, inv); + ASSIGN_4V(machine->internal[IMM_255], f255, f255, f255, f255); + ASSIGN_4V(machine->internal[IMM_RSQ], -.5f, 1.5f, 0.0f, 0.0f); + + + machine->fpu_rnd_nearest = (X87_CW_EXCEPTION_INV_OP | + X87_CW_EXCEPTION_DENORM_OP | + X87_CW_EXCEPTION_ZERO_DIVIDE | + X87_CW_EXCEPTION_OVERFLOW | + X87_CW_EXCEPTION_UNDERFLOW | + X87_CW_EXCEPTION_PRECISION | + (1<<6) | + X87_CW_ROUND_NEAREST | + X87_CW_PRECISION_DOUBLE_EXT); + + assert(machine->fpu_rnd_nearest == 0x37f); + + machine->fpu_rnd_neg_inf = (X87_CW_EXCEPTION_INV_OP | + X87_CW_EXCEPTION_DENORM_OP | + X87_CW_EXCEPTION_ZERO_DIVIDE | + X87_CW_EXCEPTION_OVERFLOW | + X87_CW_EXCEPTION_UNDERFLOW | + X87_CW_EXCEPTION_PRECISION | + (1<<6) | + X87_CW_ROUND_DOWN | + X87_CW_PRECISION_DOUBLE_EXT); + + for (i = 0; i < MAX_SHINE_TAB; i++) + do_populate_lut( &machine->shine_tab[i], 1.0f ); + + return machine; +} + + diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 784ae41205..18cb06e374 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -44,8 +44,6 @@ struct draw_vs_varient_generic { struct draw_vs_varient base; - struct pipe_viewport_state viewport; - struct draw_vertex_shader *shader; struct draw_context *draw; @@ -57,21 +55,11 @@ struct draw_vs_varient_generic { */ struct translate *fetch; struct translate *emit; - - const float (*constants)[4]; }; -static void vsvg_set_constants( struct draw_vs_varient *varient, - const float (*constants)[4] ) -{ - struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; - - vsvg->constants = constants; -} - static void vsvg_set_input( struct draw_vs_varient *varient, unsigned buffer, @@ -94,8 +82,8 @@ static void do_rhw_viewport( struct draw_vs_varient_generic *vsvg, void *output_buffer ) { char *ptr = (char *)output_buffer; - const float *scale = vsvg->viewport.scale; - const float *trans = vsvg->viewport.translate; + const float *scale = vsvg->base.vs->draw->viewport.scale; + const float *trans = vsvg->base.vs->draw->viewport.translate; unsigned stride = vsvg->base.key.output_stride; unsigned j; @@ -115,8 +103,8 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, void *output_buffer ) { char *ptr = (char *)output_buffer; - const float *scale = vsvg->viewport.scale; - const float *trans = vsvg->viewport.translate; + const float *scale = vsvg->base.vs->draw->viewport.scale; + const float *trans = vsvg->base.vs->draw->viewport.translate; unsigned stride = vsvg->base.key.output_stride; unsigned j; @@ -130,10 +118,10 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, } -static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, - const unsigned *elts, - unsigned count, - void *output_buffer ) +static void vsvg_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; @@ -150,7 +138,7 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, vsvg->base.vs->run_linear( vsvg->base.vs, output_buffer, output_buffer, - vsvg->constants, + (const float (*)[4])vsvg->base.vs->draw->pt.user.constants, count, vsvg->base.key.output_stride, vsvg->base.key.output_stride); @@ -186,10 +174,10 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, } -static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, - unsigned start, - unsigned count, - void *output_buffer ) +static void vsvg_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; @@ -206,7 +194,7 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, vsvg->base.vs->run_linear( vsvg->base.vs, output_buffer, output_buffer, - vsvg->constants, + (const float (*)[4])vsvg->base.vs->draw->pt.user.constants, count, vsvg->base.key.output_stride, vsvg->base.key.output_stride); @@ -245,13 +233,6 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, -static void vsvg_set_viewport( struct draw_vs_varient *varient, - const struct pipe_viewport_state *viewport ) -{ - struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; - - vsvg->viewport = *viewport; -} static void vsvg_destroy( struct draw_vs_varient *varient ) { @@ -272,8 +253,6 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, vsvg->base.key = *key; vsvg->base.vs = vs; vsvg->base.set_input = vsvg_set_input; - vsvg->base.set_constants = vsvg_set_constants; - vsvg->base.set_viewport = vsvg_set_viewport; vsvg->base.run_elts = vsvg_run_elts; vsvg->base.run_linear = vsvg_run_linear; vsvg->base.destroy = vsvg_destroy; -- cgit v1.2.3 From bb2e13b9e82b68ec3b9fc56a4c35e7ead8fd138f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 12:38:49 +0100 Subject: draw: make sure constant buffer data is aligned before passing to aos.c --- src/gallium/auxiliary/draw/draw_context.c | 5 +++-- src/gallium/auxiliary/draw/draw_context.h | 3 ++- src/gallium/auxiliary/draw/draw_private.h | 9 ++++++++- src/gallium/auxiliary/draw/draw_vs.c | 19 ++++++++++++++++++- src/gallium/auxiliary/draw/draw_vs_aos.c | 4 ++-- src/gallium/drivers/i915simple/i915_context.c | 4 +++- src/gallium/drivers/softpipe/sp_draw_arrays.c | 5 +++-- src/mesa/state_tracker/st_draw.c | 7 ++++--- 8 files changed, 43 insertions(+), 13 deletions(-) (limited to 'src/gallium/auxiliary/draw/draw_vs_aos.c') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index bcec85c2ef..2f263cf06a 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -217,10 +217,11 @@ draw_set_mapped_vertex_buffer(struct draw_context *draw, void draw_set_mapped_constant_buffer(struct draw_context *draw, - const void *buffer) + const void *buffer, + unsigned size ) { draw->pt.user.constants = buffer; - draw_vs_set_constants( draw, (const float (*)[4])buffer ); + draw_vs_set_constants( draw, (const float (*)[4])buffer, size ); } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 8dd03cb79e..b8f2bfa332 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -133,7 +133,8 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer); void draw_set_mapped_constant_buffer(struct draw_context *draw, - const void *buffer); + const void *buffer, + unsigned size ); void draw_set_edgeflags( struct draw_context *draw, const unsigned *edgeflag ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 40f1d978f2..88a7224b62 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -190,6 +190,12 @@ struct draw_context struct aos_machine *aos_machine; + const float (*aligned_constants)[4]; + + const float (*aligned_constant_storage)[4]; + unsigned const_storage_size; + + struct translate *fetch; struct translate_cache *fetch_cache; struct translate *emit; @@ -225,7 +231,8 @@ void draw_vs_set_viewport( struct draw_context *, const struct pipe_viewport_state * ); void draw_vs_set_constants( struct draw_context *, - const float (*constants)[4] ); + const float (*constants)[4], + unsigned size ); diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index a8b6d0c90d..ce35112fc1 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -43,8 +43,22 @@ void draw_vs_set_constants( struct draw_context *draw, - const float (*constants)[4] ) + const float (*constants)[4], + unsigned size ) { + if (((unsigned)constants) & 0xf) { + if (size > draw->vs.const_storage_size) { + if (draw->vs.aligned_constant_storage) + align_free(draw->vs.aligned_constant_storage); + draw->vs.aligned_constant_storage = align_malloc( size, 16 ); + } + memcpy( draw->vs.aligned_constant_storage, + constants, + size ); + constants = draw->vs.aligned_constant_storage; + } + + draw->vs.aligned_constants = constants; draw_vs_aos_machine_constants( draw->vs.aos_machine, constants ); } @@ -159,6 +173,9 @@ draw_vs_destroy( struct draw_context *draw ) if (draw->vs.aos_machine) draw_vs_aos_machine_destroy(draw->vs.aos_machine); + if (draw->vs.aligned_constant_storage) + align_free(draw->vs.aligned_constant_storage); + tgsi_exec_machine_free_data(&draw->vs.machine); } diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index b5e4e1e7b1..55cabb6df9 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1957,7 +1957,7 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, struct aos_machine *machine = vaos->draw->vs.aos_machine; machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - machine->constants = (const float (*)[4])vaos->draw->pt.user.constants; + machine->constants = vaos->draw->vs.aligned_constants; machine->immediates = vaos->base.vs->immediates; machine->attrib = vaos->attrib; @@ -1976,7 +1976,7 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, struct aos_machine *machine = vaos->draw->vs.aos_machine; machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - machine->constants = (const float (*)[4])vaos->draw->pt.user.constants; + machine->constants = vaos->draw->vs.aligned_constants; machine->immediates = vaos->base.vs->immediates; machine->attrib = vaos->attrib; diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 4bef21619c..c609d16a5a 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -86,7 +86,9 @@ i915_draw_elements( struct pipe_context *pipe, draw_set_mapped_constant_buffer(draw, - i915->current.constants[PIPE_SHADER_VERTEX]); + i915->current.constants[PIPE_SHADER_VERTEX], + ( i915->current.num_user_constants[PIPE_SHADER_VERTEX] * + 4 * sizeof(float) )); /* draw! */ draw_arrays(i915->draw, prim, start, count); diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index dbecf6865f..d4d5fa744f 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -54,7 +54,8 @@ softpipe_map_constant_buffers(struct softpipe_context *sp) } draw_set_mapped_constant_buffer(sp->draw, - sp->mapped_constants[PIPE_SHADER_VERTEX]); + sp->mapped_constants[PIPE_SHADER_VERTEX], + sp->constants[i].size); } static void @@ -68,7 +69,7 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp) */ draw_flush(sp->draw); - draw_set_mapped_constant_buffer(sp->draw, NULL); + draw_set_mapped_constant_buffer(sp->draw, NULL, 0); for (i = 0; i < 2; i++) { if (sp->constants[i].size) diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 551860452a..5300848ef6 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -596,9 +596,10 @@ st_feedback_draw_vbo(GLcontext *ctx, /* map constant buffers */ mapped_constants = pipe_buffer_map(pipe, - st->state.constants[PIPE_SHADER_VERTEX].buffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_constant_buffer(st->draw, mapped_constants); + st->state.constants[PIPE_SHADER_VERTEX].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_constant_buffer(st->draw, mapped_constants, + st->state.constants[PIPE_SHADER_VERTEX].buffer->size); /* draw here */ -- cgit v1.2.3 From 8f887b4252208e60e7e86217ec3b72fb639a4e82 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 13:26:01 +0100 Subject: draw: michal's patch for calling powf... teapot still not quite right --- src/gallium/auxiliary/draw/draw_vs_aos.c | 46 ++++++++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_aos.h | 1 + 2 files changed, 47 insertions(+) (limited to 'src/gallium/auxiliary/draw/draw_vs_aos.c') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 55cabb6df9..725f36b502 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1372,11 +1372,20 @@ static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } +/* A wrapper for powf(). + * Makes sure it is cdecl and operates on floats. + */ +static float PIPE_CDECL _powerf( float x, float y ) +{ + return powf( x, y ); +} + /* Really not sufficient -- need to check for conditions that could * generate inf/nan values, which will slow things down hugely. */ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { +#if 0 x87_fld_src(cp, &op->FullSrcRegisters[1], 0); /* a1.x */ x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* a0.x a1.x */ x87_fyl2x(cp->func); /* a1*log2(a0) */ @@ -1384,6 +1393,42 @@ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_inst x87_emit_ex2( cp ); /* 2^(a1*log2(a0)) */ x87_fstp_dest4(cp, &op->FullDstRegisters[0]); +#else + uint i; + + /* For absolute correctness, need to spill/invalidate all XMM regs + * too. + */ + for (i = 0; i < 8; i++) { + if (cp->xmm[i].dirty) + spill(cp, i); + aos_release_xmm_reg(cp, i); + } + + /* Push caller-save (ie scratch) regs. + */ + x86_cdecl_caller_push_regs( cp->func ); + + x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, -8) ); + + x87_fld_src( cp, &op->FullSrcRegisters[1], 0 ); + x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 4 ) ); + x87_fld_src( cp, &op->FullSrcRegisters[0], 0 ); + x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 0 ) ); + + x86_mov_reg_imm( cp->func, cp->tmp_EAX, (unsigned long) _powerf ); + x86_call( cp->func, cp->tmp_EAX ); + + x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, 8) ); + + x86_cdecl_caller_pop_regs( cp->func ); + + /* Note retval on x87 stack: + */ + cp->func->x87_stack++; + + x87_fstp_dest4( cp, &op->FullDstRegisters[0] ); +#endif return TRUE; } @@ -1781,6 +1826,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, cp.machine_EDX = x86_make_reg(file_REG32, reg_DX); cp.count_ESI = x86_make_reg(file_REG32, reg_SI); cp.temp_EBP = x86_make_reg(file_REG32, reg_BP); + cp.stack_ESP = x86_make_reg( file_REG32, reg_SP ); x86_init_func(cp.func); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 665b425e68..fb6d43d32e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -160,6 +160,7 @@ struct aos_compilation { struct x86_reg machine_EDX; struct x86_reg count_ESI; /* decrements to zero */ struct x86_reg temp_EBP; + struct x86_reg stack_ESP; }; struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ); -- cgit v1.2.3