diff options
Diffstat (limited to 'src/gallium')
315 files changed, 9354 insertions, 10263 deletions
diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 6c0e7a518d1..e5e9578b5e4 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -25,4 +25,4 @@ SConscript('targets/SConscript') if platform != 'embedded': SConscript('tests/unit/SConscript') - #SConscript('tests/raw/SConscript') + #SConscript('tests/graw/SConscript') diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index e0d9b313544..1abf12e95bd 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -168,7 +168,8 @@ GALLIVM_SOURCES = \ draw/draw_pt_fetch_shade_pipeline_llvm.c \ draw/draw_llvm_translate.c -GALLIVM_CPP_SOURCES = +GALLIVM_CPP_SOURCES = \ + gallivm/lp_bld_misc.cpp GENERATED_SOURCES = \ indices/u_indices_gen.c \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 29a1bd0ecba..7039d5f0c55 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -205,6 +205,7 @@ if env['llvm']: 'gallivm/lp_bld_intr.c', 'gallivm/lp_bld_logic.c', 'gallivm/lp_bld_init.c', + 'gallivm/lp_bld_misc.cpp', 'gallivm/lp_bld_pack.c', 'gallivm/lp_bld_printf.c', 'gallivm/lp_bld_sample.c', diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 02abddf1491..61980c3e4f5 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -566,7 +566,7 @@ draw_get_rasterizer_no_cull( struct draw_context *draw, memset(&rast, 0, sizeof(rast)); rast.scissor = scissor; rast.flatshade = flatshade; - rast.front_winding = PIPE_WINDING_CCW; + rast.front_ccw = 1; rast.gl_rasterization_rules = draw->rasterizer->gl_rasterization_rules; draw->rasterizer_no_cull[scissor][flatshade] = diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index ea9b7c90a51..7ea51621f72 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -12,6 +12,7 @@ #include "gallivm/lp_bld_printf.h" #include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_dump.h" #include "util/u_cpu_detect.h" #include "util/u_string.h" @@ -21,6 +22,34 @@ #define DEBUG_STORE 0 +/** cast wrapper */ +static INLINE draw_jit_vert_func_elts +voidptr_to_draw_vert_func_elts(void *v) +{ + union { + void *v; + draw_jit_vert_func_elts f; + } u; + assert(sizeof(u.v) == sizeof(u.f)); + u.v = v; + return u.f; +} + + +/** cast wrapper */ +static INLINE draw_jit_vert_func +voidptr_to_draw_jit_vert_func(void *v) +{ + union { + void *v; + draw_jit_vert_func f; + } u; + assert(sizeof(u.v) == sizeof(u.f)); + u.v = v; + return u.f; +} + + /* generates the draw jit function */ static void draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var); @@ -161,9 +190,16 @@ create_vertex_header(struct draw_llvm *llvm, int data_elems) struct draw_llvm * draw_llvm_create(struct draw_context *draw) { - struct draw_llvm *llvm = CALLOC_STRUCT( draw_llvm ); + struct draw_llvm *llvm; +#ifdef PIPE_ARCH_X86 util_cpu_detect(); + /* require SSE2 due to LLVM PR6960. */ + if (!util_cpu_caps.has_sse2) + return NULL; +#endif + + llvm = CALLOC_STRUCT( draw_llvm ); llvm->draw = draw; llvm->engine = draw->engine; @@ -179,27 +215,34 @@ draw_llvm_create(struct draw_context *draw) llvm->pass = LLVMCreateFunctionPassManager(llvm->provider); LLVMAddTargetData(llvm->target, llvm->pass); - /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, - * but there are more on SVN. */ - /* TODO: Add more passes */ - LLVMAddCFGSimplificationPass(llvm->pass); - LLVMAddPromoteMemoryToRegisterPass(llvm->pass); - LLVMAddConstantPropagationPass(llvm->pass); - if(util_cpu_caps.has_sse4_1) { - /* FIXME: There is a bug in this pass, whereby the combination of fptosi - * and sitofp (necessary for trunc/floor/ceil/round implementation) - * somehow becomes invalid code. + + if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) { + /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, + * but there are more on SVN. */ + /* TODO: Add more passes */ + LLVMAddCFGSimplificationPass(llvm->pass); + LLVMAddPromoteMemoryToRegisterPass(llvm->pass); + LLVMAddConstantPropagationPass(llvm->pass); + if(util_cpu_caps.has_sse4_1) { + /* FIXME: There is a bug in this pass, whereby the combination of fptosi + * and sitofp (necessary for trunc/floor/ceil/round implementation) + * somehow becomes invalid code. + */ + LLVMAddInstructionCombiningPass(llvm->pass); + } + LLVMAddGVNPass(llvm->pass); + } else { + /* We need at least this pass to prevent the backends to fail in + * unexpected ways. */ - LLVMAddInstructionCombiningPass(llvm->pass); + LLVMAddPromoteMemoryToRegisterPass(llvm->pass); } - LLVMAddGVNPass(llvm->pass); init_globals(llvm); - -#if 0 - LLVMDumpModule(llvm->module); -#endif + if (gallivm_debug & GALLIVM_DEBUG_IR) { + LLVMDumpModule(llvm->module); + } return llvm; } @@ -248,7 +291,10 @@ generate_vs(struct draw_llvm *llvm, num_vs = 4; /* number of vertices per block */ #endif - /*tgsi_dump(tokens, 0);*/ + if (gallivm_debug & GALLIVM_DEBUG_IR) { + tgsi_dump(tokens, 0); + } + lp_build_tgsi_soa(builder, tokens, vs_type, @@ -579,6 +625,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) struct lp_type vs_type = lp_type_float_vec(32); const int max_vertices = 4; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; + void *code; arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ @@ -684,21 +731,24 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) */ #ifdef DEBUG if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) { - LLVMDumpValue(variant->function); + lp_debug_dump_value(variant->function); assert(0); } #endif LLVMRunFunctionPassManager(llvm->pass, variant->function); - if (0) { - LLVMDumpValue(variant->function); + if (gallivm_debug & GALLIVM_DEBUG_IR) { + lp_debug_dump_value(variant->function); debug_printf("\n"); } - variant->jit_func = (draw_jit_vert_func)LLVMGetPointerToGlobal(llvm->draw->engine, variant->function); - if (0) - lp_disassemble(variant->jit_func); + code = LLVMGetPointerToGlobal(llvm->draw->engine, variant->function); + variant->jit_func = voidptr_to_draw_jit_vert_func(code); + + if (gallivm_debug & GALLIVM_DEBUG_ASM) { + lp_disassemble(code); + } } @@ -721,6 +771,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian const int max_vertices = 4; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; LLVMValueRef fetch_max; + void *code; arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ @@ -835,22 +886,24 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian */ #ifdef DEBUG if(LLVMVerifyFunction(variant->function_elts, LLVMPrintMessageAction)) { - LLVMDumpValue(variant->function_elts); + lp_debug_dump_value(variant->function_elts); assert(0); } #endif LLVMRunFunctionPassManager(llvm->pass, variant->function_elts); - if (0) { - LLVMDumpValue(variant->function_elts); + if (gallivm_debug & GALLIVM_DEBUG_IR) { + lp_debug_dump_value(variant->function_elts); debug_printf("\n"); } - variant->jit_func_elts = (draw_jit_vert_func_elts)LLVMGetPointerToGlobal( - llvm->draw->engine, variant->function_elts); - if (0) - lp_disassemble(variant->jit_func_elts); + code = LLVMGetPointerToGlobal(llvm->draw->engine, variant->function_elts); + variant->jit_func_elts = voidptr_to_draw_vert_func_elts(code); + + if (gallivm_debug & GALLIVM_DEBUG_ASM) { + lp_disassemble(code); + } } void diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 64c35025081..7ea04e38193 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -170,7 +170,25 @@ static void do_triangle( struct draw_context *draw, * Set up macros for draw_pt_decompose.h template code. * This code uses vertex indexes / elements. */ -#define QUAD(i0,i1,i2,i3) \ + +/* emit first quad vertex as first vertex in triangles */ +#define QUAD_FIRST_PV(i0,i1,i2,i3) \ + do_triangle( draw, \ + ( DRAW_PIPE_RESET_STIPPLE | \ + DRAW_PIPE_EDGE_FLAG_0 | \ + DRAW_PIPE_EDGE_FLAG_1 ), \ + verts + stride * elts[i0], \ + verts + stride * elts[i1], \ + verts + stride * elts[i2]); \ + do_triangle( draw, \ + ( DRAW_PIPE_EDGE_FLAG_1 | \ + DRAW_PIPE_EDGE_FLAG_2 ), \ + verts + stride * elts[i0], \ + verts + stride * elts[i2], \ + verts + stride * elts[i3]) + +/* emit last quad vertex as last vertex in triangles */ +#define QUAD_LAST_PV(i0,i1,i2,i3) \ do_triangle( draw, \ ( DRAW_PIPE_RESET_STIPPLE | \ DRAW_PIPE_EDGE_FLAG_0 | \ @@ -261,9 +279,27 @@ void draw_pipeline_run( struct draw_context *draw, /* * Set up macros for draw_pt_decompose.h template code. - * This code is for non-indexed rendering (no elts). + * This code is for non-indexed (aka linear) rendering (no elts). */ -#define QUAD(i0,i1,i2,i3) \ + +/* emit first quad vertex as first vertex in triangles */ +#define QUAD_FIRST_PV(i0,i1,i2,i3) \ + do_triangle( draw, \ + ( DRAW_PIPE_RESET_STIPPLE | \ + DRAW_PIPE_EDGE_FLAG_0 | \ + DRAW_PIPE_EDGE_FLAG_1 ), \ + verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i1), \ + verts + stride * (i2)); \ + do_triangle( draw, \ + ( DRAW_PIPE_EDGE_FLAG_1 | \ + DRAW_PIPE_EDGE_FLAG_2 ), \ + verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i2), \ + verts + stride * (i3)) + +/* emit last quad vertex as last vertex in triangles */ +#define QUAD_LAST_PV(i0,i1,i2,i3) \ do_triangle( draw, \ ( DRAW_PIPE_RESET_STIPPLE | \ DRAW_PIPE_EDGE_FLAG_0 | \ diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 51a6115ebf5..df8d82e367d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -157,6 +157,10 @@ static void interp( const struct clip_stage *clip, } +/** + * Emit a post-clip polygon to the next pipeline stage. The polygon + * will be convex and the provoking vertex will always be vertex[0]. + */ static void emit_poly( struct draw_stage *stage, struct vertex_header **inlist, unsigned n, @@ -164,10 +168,18 @@ static void emit_poly( struct draw_stage *stage, { struct prim_header header; unsigned i; + ushort edge_first, edge_middle, edge_last; - const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; - const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; + if (stage->draw->rasterizer->flatshade_first) { + edge_first = DRAW_PIPE_EDGE_FLAG_0; + edge_middle = DRAW_PIPE_EDGE_FLAG_1; + edge_last = DRAW_PIPE_EDGE_FLAG_2; + } + else { + edge_first = DRAW_PIPE_EDGE_FLAG_2; + edge_middle = DRAW_PIPE_EDGE_FLAG_0; + edge_last = DRAW_PIPE_EDGE_FLAG_1; + } /* later stages may need the determinant, but only the sign matters */ header.det = origPrim->det; @@ -175,9 +187,17 @@ static void emit_poly( struct draw_stage *stage, header.pad = 0; for (i = 2; i < n; i++, header.flags = edge_middle) { - header.v[0] = inlist[i-1]; - header.v[1] = inlist[i]; - header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ + /* order the triangle verts to respect the provoking vertex mode */ + if (stage->draw->rasterizer->flatshade_first) { + header.v[0] = inlist[0]; /* the provoking vertex */ + header.v[1] = inlist[i-1]; + header.v[2] = inlist[i]; + } + else { + header.v[0] = inlist[i-1]; + header.v[1] = inlist[i]; + header.v[2] = inlist[0]; /* the provoking vertex */ + } if (i == n-1) header.flags |= edge_last; @@ -185,7 +205,8 @@ static void emit_poly( struct draw_stage *stage, if (0) { const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader; uint j, k; - debug_printf("Clipped tri:\n"); + debug_printf("Clipped tri: (flat-shade-first = %d)\n", + stage->draw->rasterizer->flatshade_first); for (j = 0; j < 3; j++) { for (k = 0; k < vs->info.num_outputs; k++) { debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, @@ -291,12 +312,21 @@ do_clip_tri( struct draw_stage *stage, } } - /* If flat-shading, copy color to new provoking vertex. + /* If flat-shading, copy provoking vertex color to polygon vertex[0] */ - if (clipper->flat && inlist[0] != header->v[2]) { - inlist[0] = dup_vert(stage, inlist[0], tmpnr++); - - copy_colors(stage, inlist[0], header->v[2]); + if (clipper->flat) { + if (stage->draw->rasterizer->flatshade_first) { + if (inlist[0] != header->v[0]) { + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); + copy_colors(stage, inlist[0], header->v[0]); + } + } + else { + if (inlist[0] != header->v[2]) { + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); + copy_colors(stage, inlist[0], header->v[2]); + } + } } /* Emit the polygon as triangles to the setup stage: diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index dc66c65a56c..bf84ce30ed1 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -40,7 +40,8 @@ struct cull_stage { struct draw_stage stage; - unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ + unsigned cull_face; /**< which face(s) to cull (one of PIPE_FACE_x) */ + unsigned front_ccw; }; @@ -73,9 +74,12 @@ static void cull_tri( struct draw_stage *stage, /* if det < 0 then Z points toward the camera and the triangle is * counter-clockwise winding. */ - unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; + unsigned ccw = (header->det < 0); + unsigned face = ((ccw == cull_stage(stage)->front_ccw) ? + PIPE_FACE_FRONT : + PIPE_FACE_BACK); - if ((winding & cull_stage(stage)->winding) == 0) { + if ((face & cull_stage(stage)->cull_face) == 0) { /* triangle is not culled, pass to next stage */ stage->next->tri( stage->next, header ); } @@ -88,7 +92,8 @@ static void cull_first_tri( struct draw_stage *stage, { struct cull_stage *cull = cull_stage(stage); - cull->winding = stage->draw->rasterizer->cull_mode; + cull->cull_face = stage->draw->rasterizer->cull_face; + cull->front_ccw = stage->draw->rasterizer->front_ccw; stage->tri = cull_tri; stage->tri( stage, header ); diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index eef0238b157..808b2fb0b58 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -141,7 +141,7 @@ static void twoside_first_tri( struct draw_stage *stage, * if the triangle is back-facing (negative). * sign = -1 for CCW, +1 for CW */ - twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; + twoside->sign = stage->draw->rasterizer->front_ccw ? -1.0f : 1.0f; stage->tri = twoside_tri; stage->tri( stage, header ); diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index 03bb842e20a..e333d26a932 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -105,6 +105,23 @@ static void lines( struct draw_stage *stage, } +/** For debugging */ +static void +print_header_flags(unsigned flags) +{ + debug_printf("header->flags = "); + if (flags & DRAW_PIPE_RESET_STIPPLE) + debug_printf("RESET_STIPPLE "); + if (flags & DRAW_PIPE_EDGE_FLAG_0) + debug_printf("EDGE_FLAG_0 "); + if (flags & DRAW_PIPE_EDGE_FLAG_1) + debug_printf("EDGE_FLAG_1 "); + if (flags & DRAW_PIPE_EDGE_FLAG_2) + debug_printf("EDGE_FLAG_2 "); + debug_printf("\n"); +} + + /* Unfilled tri: * * Note edgeflags in the vertex struct is not sufficient as we will @@ -117,8 +134,12 @@ static void unfilled_tri( struct draw_stage *stage, struct prim_header *header ) { struct unfilled_stage *unfilled = unfilled_stage(stage); - unsigned mode = unfilled->mode[header->det >= 0.0]; + unsigned cw = header->det >= 0.0; + unsigned mode = unfilled->mode[cw]; + if (0) + print_header_flags(header->flags); + switch (mode) { case PIPE_POLYGON_MODE_FILL: stage->next->tri( stage->next, header ); @@ -139,9 +160,10 @@ static void unfilled_first_tri( struct draw_stage *stage, struct prim_header *header ) { struct unfilled_stage *unfilled = unfilled_stage(stage); + const struct pipe_rasterizer_state *rast = stage->draw->rasterizer; - unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ - unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ + unfilled->mode[0] = rast->front_ccw ? rast->fill_front : rast->fill_back; + unfilled->mode[1] = rast->front_ccw ? rast->fill_back : rast->fill_front; stage->tri = unfilled_tri; stage->tri( stage, header ); diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index 2a50af7a414..eafa29276ff 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -122,12 +122,14 @@ draw_need_pipeline(const struct draw_context *draw, return TRUE; /* unfilled polygons */ - if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) + if (rasterizer->fill_front != PIPE_POLYGON_MODE_FILL || + rasterizer->fill_back != PIPE_POLYGON_MODE_FILL) return TRUE; /* polygon offset */ - if (rasterizer->offset_cw || rasterizer->offset_ccw) + if (rasterizer->offset_point || + rasterizer->offset_line || + rasterizer->offset_tri) return TRUE; /* two-side lighting */ @@ -222,8 +224,8 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.pstipple; } - if (rast->fill_cw != PIPE_POLYGON_MODE_FILL || - rast->fill_ccw != PIPE_POLYGON_MODE_FILL) { + if (rast->fill_front != PIPE_POLYGON_MODE_FILL || + rast->fill_back != PIPE_POLYGON_MODE_FILL) { draw->pipeline.unfilled->next = next; next = draw->pipeline.unfilled; precalc_flat = TRUE; /* only needed for triangles really */ @@ -235,8 +237,9 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.flatshade; } - if (rast->offset_cw || - rast->offset_ccw) { + if (rast->offset_point || + rast->offset_line || + rast->offset_tri) { draw->pipeline.offset->next = next; next = draw->pipeline.offset; need_det = TRUE; @@ -255,7 +258,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) * to less work emitting vertices, smaller vertex buffers, etc. * It's difficult to say whether this will be true in general. */ - if (need_det || rast->cull_mode) { + if (need_det || rast->cull_face != PIPE_FACE_NONE) { draw->pipeline.cull->next = next; next = draw->pipeline.cull; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index abbf6247ab8..3c93c9014a6 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -159,19 +159,8 @@ vbuf_tri( struct draw_stage *stage, check_space( vbuf, 3 ); - if (vbuf->stage.draw->rasterizer->flatshade_first) { - /* Put provoking vertex in position expected by the driver. - * Emit last provoking vertex in first pos. - * Swap verts 0 & 1 to preserve polygon winding. - */ - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[2] ); - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[1] ); - } - else { - for (i = 0; i < 3; i++) { - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); - } + for (i = 0; i < 3; i++) { + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); } } @@ -335,9 +324,9 @@ vbuf_flush_vertices( struct vbuf_stage *vbuf ) if (vbuf->nr_indices) { - vbuf->render->draw(vbuf->render, - vbuf->indices, - vbuf->nr_indices ); + vbuf->render->draw_elements(vbuf->render, + vbuf->indices, + vbuf->nr_indices ); vbuf->nr_indices = 0; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index ab167065815..d7ac95b7405 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -77,8 +77,11 @@ static void wideline_line( struct draw_stage *stage, const float dx = fabsf(pos0[0] - pos2[0]); const float dy = fabsf(pos0[1] - pos2[1]); + const boolean gl_rasterization_rules = + stage->draw->rasterizer->gl_rasterization_rules; + /* small tweak to meet GL specification */ - const float bias = 0.125f; + const float bias = gl_rasterization_rules ? 0.125f : 0.0f; /* * Draw wide line as a quad (two tris) by "stretching" the line along @@ -92,19 +95,21 @@ static void wideline_line( struct draw_stage *stage, pos1[1] = pos1[1] + half_width - bias; pos2[1] = pos2[1] - half_width - bias; pos3[1] = pos3[1] + half_width - bias; - if (pos0[0] < pos2[0]) { - /* left to right line */ - pos0[0] -= 0.5f; - pos1[0] -= 0.5f; - pos2[0] -= 0.5f; - pos3[0] -= 0.5f; - } - else { - /* right to left line */ - pos0[0] += 0.5f; - pos1[0] += 0.5f; - pos2[0] += 0.5f; - pos3[0] += 0.5f; + if (gl_rasterization_rules) { + if (pos0[0] < pos2[0]) { + /* left to right line */ + pos0[0] -= 0.5f; + pos1[0] -= 0.5f; + pos2[0] -= 0.5f; + pos3[0] -= 0.5f; + } + else { + /* right to left line */ + pos0[0] += 0.5f; + pos1[0] += 0.5f; + pos2[0] += 0.5f; + pos3[0] += 0.5f; + } } } else { @@ -113,19 +118,21 @@ static void wideline_line( struct draw_stage *stage, pos1[0] = pos1[0] + half_width + bias; pos2[0] = pos2[0] - half_width + bias; pos3[0] = pos3[0] + half_width + bias; - if (pos0[1] < pos2[1]) { - /* top to bottom line */ - pos0[1] -= 0.5f; - pos1[1] -= 0.5f; - pos2[1] -= 0.5f; - pos3[1] -= 0.5f; - } - else { - /* bottom to top line */ - pos0[1] += 0.5f; - pos1[1] += 0.5f; - pos2[1] += 0.5f; - pos3[1] += 0.5f; + if (gl_rasterization_rules) { + if (pos0[1] < pos2[1]) { + /* top to bottom line */ + pos0[1] -= 0.5f; + pos1[1] -= 0.5f; + pos2[1] -= 0.5f; + pos3[1] -= 0.5f; + } + else { + /* bottom to top line */ + pos0[1] += 0.5f; + pos1[1] += 0.5f; + pos2[1] += 0.5f; + pos3[1] += 0.5f; + } } } diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h index 3c44f7c11ee..52f9593d46e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_decompose.h +++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h @@ -47,33 +47,26 @@ static void FUNC( ARGS, case PIPE_PRIM_TRIANGLES: for (i = 0; i+2 < count; i += 3) { - if (flatfirst) { - /* put provoking vertex in last pos for clipper */ - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 1), - (i + 2), - (i + 0 )); - } - else { - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 0), - (i + 1), - (i + 2 )); - } + TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + (i + 0), + (i + 1), + (i + 2 )); } break; case PIPE_PRIM_TRIANGLE_STRIP: if (flatfirst) { for (i = 0; i+2 < count; i++) { + /* Emit first triangle vertex as first triangle vertex */ TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + (i + 0), (i + 1 + (i&1)), - (i + 2 - (i&1)), - (i + 0) ); + (i + 2 - (i&1)) ); } } else { for (i = 0; i+2 < count; i++) { + /* Emit last triangle vertex as last triangle vertex */ TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, (i + 0 + (i&1)), (i + 1 - (i&1)), @@ -87,9 +80,9 @@ static void FUNC( ARGS, if (flatfirst) { for (i = 0; i+2 < count; i++) { TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + (i + 1), (i + 2), - 0, - (i + 1) ); + 0 ); } } else { @@ -105,24 +98,52 @@ static void FUNC( ARGS, case PIPE_PRIM_QUADS: - for (i = 0; i+3 < count; i += 4) { - QUAD( (i + 0), - (i + 1), - (i + 2), - (i + 3)); + /* GL quads don't follow provoking vertex convention */ + if (flatfirst) { + for (i = 0; i+3 < count; i += 4) { + /* emit last quad vertex as first triangle vertex */ + QUAD_FIRST_PV( (i + 3), + (i + 0), + (i + 1), + (i + 2) ); + } + } + else { + for (i = 0; i+3 < count; i += 4) { + /* emit last quad vertex as last triangle vertex */ + QUAD_LAST_PV( (i + 0), + (i + 1), + (i + 2), + (i + 3) ); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 0; i+3 < count; i += 2) { - QUAD( (i + 2), - (i + 0), - (i + 1), - (i + 3)); + /* GL quad strips don't follow provoking vertex convention */ + if (flatfirst) { + for (i = 0; i+3 < count; i += 2) { + /* emit last quad vertex as first triangle vertex */ + QUAD_FIRST_PV( (i + 3), + (i + 2), + (i + 0), + (i + 1) ); + + } + } + else { + for (i = 0; i+3 < count; i += 2) { + /* emit last quad vertex as last triangle vertex */ + QUAD_LAST_PV( (i + 2), + (i + 0), + (i + 1), + (i + 3) ); + } } break; case PIPE_PRIM_POLYGON: + /* GL polygons don't follow provoking vertex convention */ { /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. @@ -138,10 +159,20 @@ static void FUNC( ARGS, if (i + 3 == count) flags |= edge_last; - TRIANGLE( flags, - (i + 1), - (i + 2), - (0)); + if (flatfirst) { + /* emit first polygon vertex as first triangle vertex */ + TRIANGLE( flags, + (0), + (i + 1), + (i + 2) ); + } + else { + /* emit first polygon vertex as last triangle vertex */ + TRIANGLE( flags, + (i + 1), + (i + 2), + (0)); + } } } break; @@ -156,7 +187,8 @@ static void FUNC( ARGS, #undef TRIANGLE -#undef QUAD +#undef QUAD_FIRST_PV +#undef QUAD_LAST_PV #undef POINT #undef LINE #undef FUNC diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index ad48fa39a4f..f623c0743da 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -190,9 +190,9 @@ void draw_pt_emit( struct pt_emit *emit, 0, vertex_count - 1 ); - render->draw(render, - elts, - count); + render->draw_elements(render, + elts, + count); render->release_vertices(render); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index d7735bf1ac9..5158c6341c0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -254,9 +254,9 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, /* XXX: Draw arrays path to avoid re-emitting index list again and * again. */ - draw->render->draw( draw->render, - draw_elts, - draw_count ); + draw->render->draw_elements( draw->render, + draw_elts, + draw_count ); /* Done -- that was easy, wasn't it: */ @@ -363,9 +363,9 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle, /* XXX: Draw arrays path to avoid re-emitting index list again and * again. */ - draw->render->draw( draw->render, - draw_elts, - draw_count ); + draw->render->draw_elements( draw->render, + draw_elts, + draw_count ); /* Done -- that was easy, wasn't it: */ 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 cbb5b6c9605..f0fc591bf55 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -307,9 +307,9 @@ fse_run(struct draw_pt_middle_end *middle, draw->render->unmap_vertices( draw->render, 0, (ushort)(fetch_count - 1) ); - draw->render->draw( draw->render, - draw_elts, - draw_count ); + draw->render->draw_elements( draw->render, + draw_elts, + draw_count ); draw->render->release_vertices( draw->render ); @@ -357,9 +357,9 @@ static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle, hw_verts ); - draw->render->draw( draw->render, - draw_elts, - draw_count ); + draw->render->draw_elements( draw->render, + draw_elts, + draw_count ); draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index 6d00b0fbd44..d56889b5f65 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -32,7 +32,6 @@ #include "draw/draw_vertex.h" #include "draw/draw_pt.h" #include "draw/draw_vs.h" -#include "draw/draw_gs.h" #include "draw/draw_llvm.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 37ffbac4f92..6a48e61e624 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -183,8 +183,16 @@ vcache_quad( struct vcache_frontend *vcache, unsigned i2, unsigned i3 ) { - vcache_triangle( vcache, i0, i1, i3 ); - vcache_triangle( vcache, i1, i2, i3 ); + if (vcache->draw->rasterizer->flatshade_first) { + /* pass last quad vertex as first triangle vertex */ + vcache_triangle( vcache, i3, i0, i1 ); + vcache_triangle( vcache, i3, i1, i2 ); + } + else { + /* pass last quad vertex as last triangle vertex */ + vcache_triangle( vcache, i0, i1, i3 ); + vcache_triangle( vcache, i1, i2, i3 ); + } } static INLINE void @@ -195,18 +203,20 @@ vcache_ef_quad( struct vcache_frontend *vcache, unsigned i3 ) { if (vcache->draw->rasterizer->flatshade_first) { + /* pass last quad vertex as first triangle vertex */ vcache_triangle_flags( vcache, ( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1 ), - i0, i1, i2 ); + i3, i0, i1 ); vcache_triangle_flags( vcache, - ( DRAW_PIPE_EDGE_FLAG_2 | - DRAW_PIPE_EDGE_FLAG_1 ), - i0, i2, i3 ); + ( DRAW_PIPE_EDGE_FLAG_1 | + DRAW_PIPE_EDGE_FLAG_2 ), + i3, i1, i2 ); } else { + /* pass last quad vertex as last triangle vertex */ vcache_triangle_flags( vcache, ( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_0 | diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h index f7a63de3ba9..dac68ad4398 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h @@ -142,20 +142,21 @@ static void FUNC( struct draw_pt_front_end *frontend, /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. */ - const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; - const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; ushort edge_next, edge_finish; if (flatfirst) { - flags = DRAW_PIPE_RESET_STIPPLE | edge_middle | edge_last; - edge_next = edge_last; - edge_finish = edge_first; + flags = (DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_1 | + DRAW_PIPE_EDGE_FLAG_2); + edge_next = DRAW_PIPE_EDGE_FLAG_2; + edge_finish = DRAW_PIPE_EDGE_FLAG_0; } else { - flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; - edge_next = edge_middle; - edge_finish = edge_last; + flags = (DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_2 | + DRAW_PIPE_EDGE_FLAG_0); + edge_next = DRAW_PIPE_EDGE_FLAG_0; + edge_finish = DRAW_PIPE_EDGE_FLAG_1; } for (i = 0; i+2 < count; i++, flags = edge_next) { diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h index cccd3bf4358..83ae26a9c2b 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.h +++ b/src/gallium/auxiliary/draw/draw_vbuf.h @@ -98,14 +98,14 @@ struct vbuf_render { boolean (*set_primitive)( struct vbuf_render *, unsigned prim ); /** - * DrawElements, note indices are ushort. The driver must complete - * this call, if necessary splitting the index list itself. + * Draw indexed primitives. Note that indices are ushort. The driver + * must complete this call, if necessary splitting the index list itself. */ - void (*draw)( struct vbuf_render *, - const ushort *indices, - uint nr_indices ); + void (*draw_elements)( struct vbuf_render *, + const ushort *indices, + uint nr_indices ); - /* Draw Arrays path too. + /* Draw non-indexed primitives. */ void (*draw_arrays)( struct vbuf_render *, unsigned start, diff --git a/src/gallium/auxiliary/gallivm/f.cpp b/src/gallium/auxiliary/gallivm/f.cpp new file mode 100644 index 00000000000..5eb09c01ab3 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/f.cpp @@ -0,0 +1,85 @@ +/************************************************************************** + * + * (C) Copyright VMware, Inc 2010. + * (C) Copyright John Maddock 2006. + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + **************************************************************************/ + + +/* + * This file allows to compute the minimax polynomial coefficients we use + * for fast exp2/log2. + * + * How to use this source: + * + * - Download and abuild the NTL library from + * http://shoup.net/ntl/download.html + * + * - Download boost source code matching to your distro. + * + * - Goto libs/math/minimax and replace f.cpp with this file. + * + * - Build as + * + * g++ -o minimax -I /path/to/ntl/include main.cpp f.cpp /path/to/ntl/src/ntl.a -lboost_math_tr1 + * + * - Run as + * + * ./minimax + * + * - For example, to compute exp2 5th order polynomial between [0, 1] do: + * + * variant 1 + * range 0 1 + * order 5 0 + * steps 200 + * info + * + * - For more info see + * http://www.boost.org/doc/libs/1_36_0/libs/math/doc/sf_and_dist/html/math_toolkit/toolkit/internals2/minimax.html + */ + +#define L22 +#include <boost/math/bindings/rr.hpp> +#include <boost/math/tools/polynomial.hpp> + +#include <cmath> + + +boost::math::ntl::RR f(const boost::math::ntl::RR& x, int variant) +{ + static const boost::math::ntl::RR tiny = boost::math::tools::min_value<boost::math::ntl::RR>() * 64; + + switch(variant) + { + case 0: + // log2(x)/(x - 1) + return log(x)/log(2.0)/(x - 1.0); + + case 1: + // exp2(x) + return exp(x*log(2.0)); + } + + return 0; +} + + +void show_extra( + const boost::math::tools::polynomial<boost::math::ntl::RR>& n, + const boost::math::tools::polynomial<boost::math::ntl::RR>& d, + const boost::math::ntl::RR& x_offset, + const boost::math::ntl::RR& y_offset, + int variant) +{ + switch(variant) + { + default: + // do nothing here... + ; + } +} + diff --git a/src/gallium/auxiliary/gallivm/lp_bld.h b/src/gallium/auxiliary/gallivm/lp_bld.h index 2fa682f4009..8103bc917fc 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld.h +++ b/src/gallium/auxiliary/gallivm/lp_bld.h @@ -35,6 +35,17 @@ #define LP_BLD_H +/** + * @file + * LLVM IR building helpers interfaces. + * + * We use LLVM-C bindings for now. They are not documented, but follow the C++ + * interfaces very closely, and appear to be complete enough for code + * genration. See + * http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html + * for a standalone example. + */ + #include <llvm-c/Core.h> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c index f372a48846f..b55c863aa04 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c @@ -54,6 +54,7 @@ #include "lp_bld_type.h" #include "lp_bld_const.h" #include "lp_bld_intr.h" +#include "lp_bld_init.h" /* for lp_build_engine */ #include "lp_bld_logic.h" #include "lp_bld_pack.h" #include "lp_bld_debug.h" @@ -239,7 +240,7 @@ lp_build_sum_vector(struct lp_build_context *bld, { const struct lp_type type = bld->type; LLVMValueRef index, res; - int i; + unsigned i; if (a == bld->zero) return bld->zero; @@ -675,26 +676,13 @@ lp_build_abs(struct lp_build_context *bld, if(type.floating) { /* Mask out the sign bit */ - if (type.length == 1) { - LLVMTypeRef int_type = LLVMIntType(type.width); - LLVMTypeRef float_type = LLVMFloatType(); - unsigned long long absMask = ~(1ULL << (type.width - 1)); - LLVMValueRef mask = LLVMConstInt(int_type, absMask, 0); - a = LLVMBuildBitCast(bld->builder, a, int_type, ""); - a = LLVMBuildAnd(bld->builder, a, mask, ""); - a = LLVMBuildBitCast(bld->builder, a, float_type, ""); - return a; - } - else { - /* vector of floats */ - LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); - unsigned long long absMask = ~(1ULL << (type.width - 1)); - LLVMValueRef mask = lp_build_const_int_vec(type, ((unsigned long long) absMask)); - a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); - a = LLVMBuildAnd(bld->builder, a, mask, ""); - a = LLVMBuildBitCast(bld->builder, a, vec_type, ""); - return a; - } + LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); + unsigned long long absMask = ~(1ULL << (type.width - 1)); + LLVMValueRef mask = lp_build_const_int_vec(type, ((unsigned long long) absMask)); + a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); + a = LLVMBuildAnd(bld->builder, a, mask, ""); + a = LLVMBuildBitCast(bld->builder, a, vec_type, ""); + return a; } if(type.width*type.length == 128 && util_cpu_caps.has_ssse3) { @@ -742,17 +730,9 @@ lp_build_sgn(struct lp_build_context *bld, LLVMValueRef one; unsigned long long maskBit = (unsigned long long)1 << (type.width - 1); - if (type.length == 1) { - int_type = lp_build_int_elem_type(type); - vec_type = lp_build_elem_type(type); - mask = LLVMConstInt(int_type, maskBit, 0); - } - else { - /* vector */ - int_type = lp_build_int_vec_type(type); - vec_type = lp_build_vec_type(type); - mask = lp_build_const_int_vec(type, maskBit); - } + int_type = lp_build_int_vec_type(type); + vec_type = lp_build_vec_type(type); + mask = lp_build_const_int_vec(type, maskBit); /* Take the sign bit and add it to 1 constant */ sign = LLVMBuildBitCast(bld->builder, a, int_type, ""); @@ -819,21 +799,11 @@ lp_build_int_to_float(struct lp_build_context *bld, LLVMValueRef a) { const struct lp_type type = bld->type; + LLVMTypeRef vec_type = lp_build_vec_type(type); assert(type.floating); - /*assert(lp_check_value(type, a));*/ - if (type.length == 1) { - LLVMTypeRef float_type = LLVMFloatType(); - return LLVMBuildSIToFP(bld->builder, a, float_type, ""); - } - else { - LLVMTypeRef vec_type = lp_build_vec_type(type); - /*LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);*/ - LLVMValueRef res; - res = LLVMBuildSIToFP(bld->builder, a, vec_type, ""); - return res; - } + return LLVMBuildSIToFP(bld->builder, a, vec_type, ""); } @@ -887,7 +857,7 @@ lp_build_trunc(struct lp_build_context *bld, assert(type.floating); assert(lp_check_value(type, a)); - if(util_cpu_caps.has_sse4_1) + if (util_cpu_caps.has_sse4_1 && type.width*type.length == 128) return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_TRUNCATE); else { LLVMTypeRef vec_type = lp_build_vec_type(type); @@ -909,7 +879,7 @@ lp_build_round(struct lp_build_context *bld, assert(type.floating); assert(lp_check_value(type, a)); - if(util_cpu_caps.has_sse4_1) + if (util_cpu_caps.has_sse4_1 && type.width*type.length == 128) return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_NEAREST); else { LLVMTypeRef vec_type = lp_build_vec_type(type); @@ -928,15 +898,9 @@ lp_build_floor(struct lp_build_context *bld, const struct lp_type type = bld->type; assert(type.floating); + assert(lp_check_value(type, a)); - if (type.length == 1) { - LLVMValueRef res; - res = lp_build_ifloor(bld, a); - res = LLVMBuildSIToFP(bld->builder, res, LLVMFloatType(), ""); - return res; - } - - if(util_cpu_caps.has_sse4_1) + if (util_cpu_caps.has_sse4_1 && type.width*type.length == 128) return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR); else { LLVMTypeRef vec_type = lp_build_vec_type(type); @@ -957,7 +921,7 @@ lp_build_ceil(struct lp_build_context *bld, assert(type.floating); assert(lp_check_value(type, a)); - if(util_cpu_caps.has_sse4_1) + if (util_cpu_caps.has_sse4_1 && type.width*type.length == 128) return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL); else { LLVMTypeRef vec_type = lp_build_vec_type(type); @@ -991,18 +955,12 @@ lp_build_itrunc(struct lp_build_context *bld, LLVMValueRef a) { const struct lp_type type = bld->type; + LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); assert(type.floating); + assert(lp_check_value(type, a)); - if (type.length == 1) { - LLVMTypeRef int_type = LLVMIntType(type.width); - return LLVMBuildFPToSI(bld->builder, a, int_type, ""); - } - else { - LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); - assert(lp_check_value(type, a)); - return LLVMBuildFPToSI(bld->builder, a, int_vec_type, ""); - } + return LLVMBuildFPToSI(bld->builder, a, int_vec_type, ""); } @@ -1019,17 +977,9 @@ lp_build_iround(struct lp_build_context *bld, assert(type.floating); - if (type.length == 1) { - /* scalar float to int */ - LLVMTypeRef int_type = LLVMIntType(type.width); - /* XXX we want rounding here! */ - res = LLVMBuildFPToSI(bld->builder, a, int_type, ""); - return res; - } - assert(lp_check_value(type, a)); - if(util_cpu_caps.has_sse4_1) { + if (util_cpu_caps.has_sse4_1 && type.width*type.length == 128) { res = lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_NEAREST); } else { @@ -1069,17 +1019,9 @@ lp_build_ifloor(struct lp_build_context *bld, LLVMValueRef res; assert(type.floating); - - if (type.length == 1) { - /* scalar float to int */ - LLVMTypeRef int_type = LLVMIntType(type.width); - res = LLVMBuildFPToSI(bld->builder, a, int_type, ""); - return res; - } - assert(lp_check_value(type, a)); - if(util_cpu_caps.has_sse4_1) { + if (util_cpu_caps.has_sse4_1 && type.width*type.length == 128) { res = lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR); } else { @@ -1127,10 +1069,11 @@ lp_build_iceil(struct lp_build_context *bld, assert(type.floating); assert(lp_check_value(type, a)); - if(util_cpu_caps.has_sse4_1) { + if (util_cpu_caps.has_sse4_1 && type.width*type.length == 128) { res = lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL); } else { + /* TODO: mimic lp_build_ifloor() here */ assert(0); res = bld->undef; } @@ -1228,6 +1171,92 @@ lp_build_rsqrt(struct lp_build_context *bld, } +#ifdef PIPE_OS_WINDOWS + +/* + * XXX: X86 backend translates llvm.cos.v4f32 to 4 calls to CRT's cosf() + * which is neither efficient nor does the CRT linkage work on Windows + * causing segmentation fault. + * + * XXX: With LLVM 2.7 both schemes cause an assertion failure. + */ +static LLVMValueRef +lp_build_sincos(struct lp_build_context *bld, + const char *name, + float (*func)(float), + LLVMValueRef a) +{ + LLVMModuleRef module = + LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld->builder))); + LLVMValueRef function; + LLVMValueRef res; + unsigned i; + + assert(bld->type.floating); + assert(bld->type.width == 32); + + function = LLVMGetNamedFunction(module, name); + if (!function) { + LLVMTypeRef ret_type; + LLVMTypeRef arg_types[1]; + LLVMTypeRef function_type; + + ret_type = LLVMFloatType(); + arg_types[0] = LLVMFloatType(); + function_type = LLVMFunctionType(ret_type, arg_types, Elements(arg_types), 0); + function = LLVMAddFunction(module, name, function_type); + + LLVMSetFunctionCallConv(function, LLVMCCallConv); + LLVMSetLinkage(function, LLVMPrivateLinkage); + + assert(LLVMIsDeclaration(function)); + + LLVMAddGlobalMapping(lp_build_engine, function, func); + } + + res = bld->undef; + + for (i = 0; i < bld->type.length; ++i) { + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); + LLVMValueRef args[1]; + LLVMValueRef tmp; + + args[0] = LLVMBuildExtractElement(bld->builder, a, index, ""); + + tmp = LLVMBuildCall(bld->builder, function, args, Elements(args), ""); + + res = LLVMBuildInsertElement(bld->builder, res, tmp, index, ""); + } + + return res; +} + +static float c_cosf( float f ) +{ + return (float) cos( (double) f ); +} + +static float c_sinf( float f ) +{ + return (float) sin( (double) f ); +} + +LLVMValueRef +lp_build_cos(struct lp_build_context *bld, + LLVMValueRef a) +{ + return lp_build_sincos(bld, "cosf", &c_cosf, a); +} + +LLVMValueRef +lp_build_sin(struct lp_build_context *bld, + LLVMValueRef a) +{ + return lp_build_sincos(bld, "sinf", &c_sinf, a); +} + +#else /* !PIPE_OS_WINDOWS */ + /** * Generate cos(a) */ @@ -1235,14 +1264,6 @@ LLVMValueRef lp_build_cos(struct lp_build_context *bld, LLVMValueRef a) { -#ifdef PIPE_OS_WINDOWS - /* - * FIXME: X86 backend translates llvm.cos.v4f32 to 4 calls to CRT's cosf() - * which is neither efficient nor does the CRT linkage work on Windows - * causing segmentation fault. So simply disable the code for now. - */ - return bld->one; -#else const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); char intrinsic[32]; @@ -1253,7 +1274,6 @@ lp_build_cos(struct lp_build_context *bld, util_snprintf(intrinsic, sizeof intrinsic, "llvm.cos.v%uf%u", type.length, type.width); return lp_build_intrinsic_unary(bld->builder, intrinsic, vec_type, a); -#endif } @@ -1264,14 +1284,6 @@ LLVMValueRef lp_build_sin(struct lp_build_context *bld, LLVMValueRef a) { -#ifdef PIPE_OS_WINDOWS - /* - * FIXME: X86 backend translates llvm.sin.v4f32 to 4 calls to CRT's sinf() - * which is neither efficient nor does the CRT linkage work on Windows - * causing segmentation fault. So simply disable the code for now. - */ - return bld->zero; -#else const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); char intrinsic[32]; @@ -1282,9 +1294,10 @@ lp_build_sin(struct lp_build_context *bld, util_snprintf(intrinsic, sizeof intrinsic, "llvm.sin.v%uf%u", type.length, type.width); return lp_build_intrinsic_unary(bld->builder, intrinsic, vec_type, a); -#endif } +#endif /* !PIPE_OS_WINDOWS */ + /** * Generate pow(x, y) @@ -1346,7 +1359,6 @@ lp_build_polynomial(struct lp_build_context *bld, unsigned num_coeffs) { const struct lp_type type = bld->type; - LLVMTypeRef float_type = LLVMFloatType(); LLVMValueRef res = NULL; unsigned i; @@ -1358,10 +1370,7 @@ lp_build_polynomial(struct lp_build_context *bld, for (i = num_coeffs; i--; ) { LLVMValueRef coeff; - if (type.length == 1) - coeff = LLVMConstReal(float_type, coeffs[i]); - else - coeff = lp_build_const_vec(type, coeffs[i]); + coeff = lp_build_const_vec(type, coeffs[i]); if(res) res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res)); @@ -1377,17 +1386,31 @@ lp_build_polynomial(struct lp_build_context *bld, /** - * Minimax polynomial fit of 2**x, in range [-0.5, 0.5[ + * Minimax polynomial fit of 2**x, in range [0, 1[ */ const double lp_build_exp2_polynomial[] = { #if EXP_POLY_DEGREE == 5 - 9.9999994e-1, 6.9315308e-1, 2.4015361e-1, 5.5826318e-2, 8.9893397e-3, 1.8775767e-3 + 0.999999999690134838155, + 0.583974334321735217258, + 0.164553105719676828492, + 0.0292811063701710962255, + 0.00354944426657875141846, + 0.000296253726543423377365 #elif EXP_POLY_DEGREE == 4 - 1.0000026, 6.9300383e-1, 2.4144275e-1, 5.2011464e-2, 1.3534167e-2 + 1.00000001502262084505, + 0.563586057338685991394, + 0.150436017652442413623, + 0.0243220604213317927308, + 0.0025359088446580436489 #elif EXP_POLY_DEGREE == 3 - 9.9992520e-1, 6.9583356e-1, 2.2606716e-1, 7.8024521e-2 + 0.999925218562710312959, + 0.695833540494823811697, + 0.226067155427249155588, + 0.0780245226406372992967 #elif EXP_POLY_DEGREE == 2 - 1.0017247, 6.5763628e-1, 3.3718944e-1 + 1.00172476321474503578, + 0.657636275736077639316, + 0.33718943461968720704 #else #error #endif @@ -1421,17 +1444,16 @@ lp_build_exp2_approx(struct lp_build_context *bld, x = lp_build_min(bld, x, lp_build_const_vec(type, 129.0)); x = lp_build_max(bld, x, lp_build_const_vec(type, -126.99999)); - /* ipart = int(x - 0.5) */ - ipart = LLVMBuildSub(bld->builder, x, lp_build_const_vec(type, 0.5f), ""); - ipart = LLVMBuildFPToSI(bld->builder, ipart, int_vec_type, ""); + /* ipart = floor(x) */ + ipart = lp_build_floor(bld, x); /* fpart = x - ipart */ - fpart = LLVMBuildSIToFP(bld->builder, ipart, vec_type, ""); - fpart = LLVMBuildSub(bld->builder, x, fpart, ""); + fpart = LLVMBuildSub(bld->builder, x, ipart, ""); } if(p_exp2_int_part || p_exp2) { /* expipart = (float) (1 << ipart) */ + ipart = LLVMBuildFPToSI(bld->builder, ipart, int_vec_type, ""); expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_const_int_vec(type, 127), ""); expipart = LLVMBuildShl(bld->builder, expipart, lp_build_const_int_vec(type, 23), ""); expipart = LLVMBuildBitCast(bld->builder, expipart, vec_type, ""); @@ -1472,13 +1494,27 @@ lp_build_exp2(struct lp_build_context *bld, */ const double lp_build_log2_polynomial[] = { #if LOG_POLY_DEGREE == 6 - 3.11578814719469302614, -3.32419399085241980044, 2.59883907202499966007, -1.23152682416275988241, 0.318212422185251071475, -0.0344359067839062357313 + 3.11578814719469302614, + -3.32419399085241980044, + 2.59883907202499966007, + -1.23152682416275988241, + 0.318212422185251071475, + -0.0344359067839062357313 #elif LOG_POLY_DEGREE == 5 - 2.8882704548164776201, -2.52074962577807006663, 1.48116647521213171641, -0.465725644288844778798, 0.0596515482674574969533 + 2.8882704548164776201, + -2.52074962577807006663, + 1.48116647521213171641, + -0.465725644288844778798, + 0.0596515482674574969533 #elif LOG_POLY_DEGREE == 4 - 2.61761038894603480148, -1.75647175389045657003, 0.688243882994381274313, -0.107254423828329604454 + 2.61761038894603480148, + -1.75647175389045657003, + 0.688243882994381274313, + -0.107254423828329604454 #elif LOG_POLY_DEGREE == 3 - 2.28330284476918490682, -1.04913055217340124191, 0.204446009836232697516 + 2.28330284476918490682, + -1.04913055217340124191, + 0.204446009836232697516 #else #error #endif @@ -1558,89 +1594,11 @@ lp_build_log2_approx(struct lp_build_context *bld, } -/** scalar version of above function */ -static void -lp_build_float_log2_approx(struct lp_build_context *bld, - LLVMValueRef x, - LLVMValueRef *p_exp, - LLVMValueRef *p_floor_log2, - LLVMValueRef *p_log2) -{ - const struct lp_type type = bld->type; - LLVMTypeRef float_type = LLVMFloatType(); - LLVMTypeRef int_type = LLVMIntType(type.width); - - LLVMValueRef expmask = LLVMConstInt(int_type, 0x7f800000, 0); - LLVMValueRef mantmask = LLVMConstInt(int_type, 0x007fffff, 0); - LLVMValueRef one = LLVMConstBitCast(bld->one, int_type); - - LLVMValueRef i = NULL; - LLVMValueRef exp = NULL; - LLVMValueRef mant = NULL; - LLVMValueRef logexp = NULL; - LLVMValueRef logmant = NULL; - LLVMValueRef res = NULL; - - if(p_exp || p_floor_log2 || p_log2) { - /* TODO: optimize the constant case */ - if(LLVMIsConstant(x)) - debug_printf("%s: inefficient/imprecise constant arithmetic\n", - __FUNCTION__); - - assert(type.floating && type.width == 32); - - i = LLVMBuildBitCast(bld->builder, x, int_type, ""); - - /* exp = (float) exponent(x) */ - exp = LLVMBuildAnd(bld->builder, i, expmask, ""); - } - - if(p_floor_log2 || p_log2) { - LLVMValueRef c23 = LLVMConstInt(int_type, 23, 0); - LLVMValueRef c127 = LLVMConstInt(int_type, 127, 0); - logexp = LLVMBuildLShr(bld->builder, exp, c23, ""); - logexp = LLVMBuildSub(bld->builder, logexp, c127, ""); - logexp = LLVMBuildSIToFP(bld->builder, logexp, float_type, ""); - } - - if(p_log2) { - /* mant = (float) mantissa(x) */ - mant = LLVMBuildAnd(bld->builder, i, mantmask, ""); - mant = LLVMBuildOr(bld->builder, mant, one, ""); - mant = LLVMBuildBitCast(bld->builder, mant, float_type, ""); - - logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial, - Elements(lp_build_log2_polynomial)); - - /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/ - logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), ""); - - res = LLVMBuildAdd(bld->builder, logmant, logexp, ""); - } - - if(p_exp) { - exp = LLVMBuildBitCast(bld->builder, exp, float_type, ""); - *p_exp = exp; - } - - if(p_floor_log2) - *p_floor_log2 = logexp; - - if(p_log2) - *p_log2 = res; -} - - LLVMValueRef lp_build_log2(struct lp_build_context *bld, LLVMValueRef x) { LLVMValueRef res; - if (bld->type.length == 1) { - lp_build_float_log2_approx(bld, x, NULL, NULL, &res); - } - else { - lp_build_log2_approx(bld, x, NULL, NULL, &res); - } + lp_build_log2_approx(bld, x, NULL, NULL, &res); return res; } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c index 57843e9a60c..031ce9d1a37 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_const.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c @@ -301,6 +301,9 @@ lp_build_const_vec(struct lp_type type, elems[0] = LLVMConstInt(elem_type, val*dscale + 0.5, 0); } + if (type.length == 1) + return elems[0]; + for(i = 1; i < type.length; ++i) elems[i] = elems[0]; @@ -321,6 +324,9 @@ lp_build_const_int_vec(struct lp_type type, for(i = 0; i < type.length; ++i) elems[i] = LLVMConstInt(elem_type, val, type.sign ? 1 : 0); + if (type.length == 1) + return elems[0]; + return LLVMConstVector(elems, type.length); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h index 7b010cbdb09..858002b34fe 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h @@ -36,6 +36,19 @@ #include "util/u_string.h" +#define GALLIVM_DEBUG_TGSI 0x1 +#define GALLIVM_DEBUG_IR 0x2 +#define GALLIVM_DEBUG_ASM 0x4 +#define GALLIVM_DEBUG_NO_OPT 0x8 + + +#ifdef DEBUG +extern unsigned gallivm_debug; +#else +#define gallivm_debug 0 +#endif + + static INLINE void lp_build_name(LLVMValueRef val, const char *format, ...) { @@ -53,6 +66,10 @@ lp_build_name(LLVMValueRef val, const char *format, ...) } +void +lp_debug_dump_value(LLVMValueRef value); + + boolean lp_check_alignment(const void *ptr, unsigned alignment); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c index 8f15b1d287d..823a8ec7b70 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_flow.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c @@ -821,8 +821,11 @@ lp_build_alloca(LLVMBuilderRef builder, LLVMBuilderRef first_builder = LLVMCreateBuilder(); LLVMValueRef res; - LLVMPositionBuilderAtEnd(first_builder, first_block); - LLVMPositionBuilderBefore(first_builder, first_instr); + if (first_instr) { + LLVMPositionBuilderBefore(first_builder, first_instr); + } else { + LLVMPositionBuilderAtEnd(first_builder, first_block); + } res = LLVMBuildAlloca(first_builder, type, name); @@ -840,7 +843,7 @@ lp_build_alloca(LLVMBuilderRef builder, * first block may prevent the X86 backend from successfully align the stack as * required. * - * Also the scalarrepl pass is supossedly more powerful and can promote + * Also the scalarrepl pass is supposedly more powerful and can promote * arrays in many cases. * * See also: @@ -859,7 +862,11 @@ lp_build_array_alloca(LLVMBuilderRef builder, LLVMBuilderRef first_builder = LLVMCreateBuilder(); LLVMValueRef res; - LLVMPositionBuilderBefore(first_builder, first_instr); + if (first_instr) { + LLVMPositionBuilderBefore(first_builder, first_instr); + } else { + LLVMPositionBuilderAtEnd(first_builder, first_block); + } res = LLVMBuildArrayAlloca(first_builder, type, count, name); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h index 085937588ff..5f5036e7bdc 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h @@ -40,6 +40,7 @@ struct util_format_description; struct lp_type; +struct lp_build_context; /* @@ -70,16 +71,16 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder, void lp_build_format_swizzle_soa(const struct util_format_description *format_desc, - struct lp_type type, + struct lp_build_context *bld, const LLVMValueRef *unswizzled, - LLVMValueRef *swizzled); + LLVMValueRef swizzled_out[4]); void lp_build_unpack_rgba_soa(LLVMBuilderRef builder, const struct util_format_description *format_desc, struct lp_type type, LLVMValueRef packed, - LLVMValueRef *rgba); + LLVMValueRef rgba_out[4]); void @@ -90,7 +91,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder, LLVMValueRef offsets, LLVMValueRef i, LLVMValueRef j, - LLVMValueRef *rgba); + LLVMValueRef rgba_out[4]); #endif /* !LP_BLD_FORMAT_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c index 6257e9a4047..eb492042387 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c @@ -47,7 +47,8 @@ /** * Unpack a single pixel into its RGBA components. * - * @param packed integer. + * @param desc the pixel format for the packed pixel value + * @param packed integer pixel in a format such as PIPE_FORMAT_B8G8R8A8_UNORM * * @return RGBA in a 4 floats vector. */ @@ -62,9 +63,9 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, LLVMValueRef scales[4]; LLVMValueRef swizzles[4]; LLVMValueRef aux[4]; - bool normalized; + boolean normalized; int empty_channel; - bool needs_uitofp; + boolean needs_uitofp; unsigned shift; unsigned i; @@ -79,7 +80,10 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, if (desc->block.bits < 32) packed = LLVMBuildZExt(builder, packed, LLVMInt32Type(), ""); - /* Broadcast the packed value to all four channels */ + /* Broadcast the packed value to all four channels + * before: packed = BGRA + * after: packed = {BGRA, BGRA, BGRA, BGRA} + */ packed = LLVMBuildInsertElement(builder, LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)), packed, @@ -96,6 +100,8 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, needs_uitofp = FALSE; empty_channel = -1; shift = 0; + + /* Loop over 4 color components */ for (i = 0; i < 4; ++i) { unsigned bits = desc->channel[i].size; @@ -128,8 +134,13 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, shift += bits; } + /* Ex: convert packed = {BGRA, BGRA, BGRA, BGRA} + * into masked = {B, G, R, A} + */ shifted = LLVMBuildLShr(builder, packed, LLVMConstVector(shifts, 4), ""); masked = LLVMBuildAnd(builder, shifted, LLVMConstVector(masks, 4), ""); + + if (!needs_uitofp) { /* UIToFP can't be expressed in SSE2 */ casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), ""); @@ -137,6 +148,11 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, casted = LLVMBuildUIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), ""); } + /* At this point 'casted' may be a vector of floats such as + * {255.0, 255.0, 255.0, 255.0}. Next, if the pixel values are normalized + * we'll scale this to {1.0, 1.0, 1.0, 1.0}. + */ + if (normalized) scaled = LLVMBuildMul(builder, casted, LLVMConstVector(scales, 4), ""); else @@ -145,6 +161,7 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, for (i = 0; i < 4; ++i) aux[i] = LLVMGetUndef(LLVMFloatType()); + /* Build swizzles vector to put components into R,G,B,A order */ for (i = 0; i < 4; ++i) { enum util_format_swizzle swizzle; @@ -185,7 +202,8 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, } } - return LLVMBuildShuffleVector(builder, scaled, LLVMConstVector(aux, 4), LLVMConstVector(swizzles, 4), ""); + return LLVMBuildShuffleVector(builder, scaled, LLVMConstVector(aux, 4), + LLVMConstVector(swizzles, 4), ""); } @@ -208,7 +226,7 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder, LLVMValueRef shifted, casted, scaled, unswizzled; LLVMValueRef shifts[4]; LLVMValueRef scales[4]; - bool normalized; + boolean normalized; unsigned shift; unsigned i, j; @@ -292,10 +310,29 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder, } +typedef void (*fetch_func)(float *, const uint8_t *, unsigned, unsigned); + +/** cast wrapper */ +static void * +fetch_func_ptr_to_voidptr(fetch_func f) +{ + union { + void *v; + fetch_func f; + } u; + u.f = f; + return u.v; +} + + /** * Fetch a pixel into a 4 float AoS. * - * i and j are the sub-block pixel coordinates. + * \param format_desc describes format of the image we're fetching from + * \param ptr address of the pixel block (or the texel if uncompressed) + * \param i, j the sub-block pixel coordinates. For non-compressed formats + * these will always be (0,). + * \return valueRef with the float[4] RGBA pixel */ LLVMValueRef lp_build_fetch_rgba_aos(LLVMBuilderRef builder, @@ -368,7 +405,8 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder, assert(LLVMIsDeclaration(function)); - LLVMAddGlobalMapping(lp_build_engine, function, format_desc->fetch_rgba_float); + LLVMAddGlobalMapping(lp_build_engine, function, + fetch_func_ptr_to_voidptr(format_desc->fetch_rgba_float)); } tmp = lp_build_alloca(builder, LLVMVectorType(LLVMFloatType(), 4), ""); @@ -384,7 +422,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder, args[2] = i; args[3] = j; - LLVMBuildCall(builder, function, args, 4, ""); + LLVMBuildCall(builder, function, args, Elements(args), ""); return LLVMBuildLoad(builder, tmp, ""); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index 26b947b3b1c..e1b94adc85a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c @@ -26,6 +26,8 @@ **************************************************************************/ +#include "pipe/p_defines.h" + #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -33,51 +35,38 @@ #include "lp_bld_type.h" #include "lp_bld_const.h" #include "lp_bld_conv.h" +#include "lp_bld_swizzle.h" #include "lp_bld_sample.h" /* for lp_build_gather */ #include "lp_bld_format.h" -static LLVMValueRef -lp_build_format_swizzle_chan_soa(struct lp_type type, - const LLVMValueRef *unswizzled, - enum util_format_swizzle swizzle) -{ - switch (swizzle) { - case UTIL_FORMAT_SWIZZLE_X: - case UTIL_FORMAT_SWIZZLE_Y: - case UTIL_FORMAT_SWIZZLE_Z: - case UTIL_FORMAT_SWIZZLE_W: - return unswizzled[swizzle]; - case UTIL_FORMAT_SWIZZLE_0: - return lp_build_zero(type); - case UTIL_FORMAT_SWIZZLE_1: - return lp_build_one(type); - case UTIL_FORMAT_SWIZZLE_NONE: - return lp_build_undef(type); - default: - assert(0); - return lp_build_undef(type); - } -} - - void lp_build_format_swizzle_soa(const struct util_format_description *format_desc, - struct lp_type type, + struct lp_build_context *bld, const LLVMValueRef *unswizzled, - LLVMValueRef *swizzled) + LLVMValueRef swizzled_out[4]) { - if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { + assert(UTIL_FORMAT_SWIZZLE_0 == PIPE_SWIZZLE_ZERO); + assert(UTIL_FORMAT_SWIZZLE_1 == PIPE_SWIZZLE_ONE); + + if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { + /* + * Return zzz1 for depth-stencil formats. + * + * XXX: Allow to control the depth swizzle with an additional parameter, + * as the caller may wish another depth swizzle, or retain the stencil + * value. + */ enum util_format_swizzle swizzle = format_desc->swizzle[0]; - LLVMValueRef depth = lp_build_format_swizzle_chan_soa(type, unswizzled, swizzle); - swizzled[2] = swizzled[1] = swizzled[0] = depth; - swizzled[3] = lp_build_one(type); + LLVMValueRef depth = lp_build_swizzle_soa_channel(bld, unswizzled, swizzle); + swizzled_out[2] = swizzled_out[1] = swizzled_out[0] = depth; + swizzled_out[3] = bld->one; } else { unsigned chan; for (chan = 0; chan < 4; ++chan) { enum util_format_swizzle swizzle = format_desc->swizzle[chan]; - swizzled[chan] = lp_build_format_swizzle_chan_soa(type, unswizzled, swizzle); + swizzled_out[chan] = lp_build_swizzle_soa_channel(bld, unswizzled, swizzle); } } } @@ -100,14 +89,20 @@ lp_build_format_swizzle_soa(const struct util_format_description *format_desc, * It requires that a packed pixel fits into an element of the output * channels. The common case is when converting pixel with a depth of 32 bit or * less into floats. + * + * \param format_desc the format of the 'packed' incoming pixel vector + * \param type the desired type for rgba_out (type.length = n, above) + * \param packed the incoming vector of packed pixels + * \param rgba_out returns the SoA R,G,B,A vectors */ void lp_build_unpack_rgba_soa(LLVMBuilderRef builder, const struct util_format_description *format_desc, struct lp_type type, LLVMValueRef packed, - LLVMValueRef *rgba) + LLVMValueRef rgba_out[4]) { + struct lp_build_context bld; LLVMValueRef inputs[4]; unsigned start; unsigned chan; @@ -120,11 +115,13 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, assert(type.floating); assert(type.width == 32); + lp_build_context_init(&bld, builder, type); + /* Decode the input vector components */ start = 0; for (chan = 0; chan < format_desc->nr_channels; ++chan) { - unsigned width = format_desc->channel[chan].size; - unsigned stop = start + width; + const unsigned width = format_desc->channel[chan].size; + const unsigned stop = start + width; LLVMValueRef input; input = packed; @@ -250,14 +247,24 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, start = stop; } - lp_build_format_swizzle_soa(format_desc, type, inputs, rgba); + lp_build_format_swizzle_soa(format_desc, &bld, inputs, rgba_out); } /** - * Fetch a pixel into a SoA. + * Fetch a texels from a texture, returning them in SoA layout. * - * i and j are the sub-block pixel coordinates. + * \param type the desired return type for 'rgba'. The vector length + * is the number of texels to fetch + * + * \param base_ptr points to start of the texture image block. For non- + * compressed formats, this simply points to the texel. + * For compressed formats, it points to the start of the + * compressed data block. + * + * \param i, j the sub-block pixel coordinates. For non-compressed formats + * these will always be (0,0). For compressed formats, i will + * be in [0, block_width-1] and j will be in [0, block_height-1]. */ void lp_build_fetch_rgba_soa(LLVMBuilderRef builder, @@ -267,7 +274,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder, LLVMValueRef offset, LLVMValueRef i, LLVMValueRef j, - LLVMValueRef *rgba) + LLVMValueRef rgba_out[4]) { if (format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && @@ -281,7 +288,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder, { /* * The packed pixel fits into an element of the destination format. Put - * the packed pixels into a vector and estract each component for all + * the packed pixels into a vector and extract each component for all * vector elements in parallel. */ @@ -289,6 +296,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder, /* * gather the texels from the texture + * Ex: packed = {BGRA, BGRA, BGRA, BGRA}. */ packed = lp_build_gather(builder, type.length, @@ -302,16 +310,16 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder, lp_build_unpack_rgba_soa(builder, format_desc, type, - packed, rgba); + packed, rgba_out); } else { /* * Fallback to calling lp_build_fetch_rgba_aos for each pixel. * - * This is not the most efficient way of fetching pixels, as - * we miss some opportunities to do vectorization, but this it is a - * convenient for formats or scenarios for which there was no opportunity - * or incentive to optimize. + * This is not the most efficient way of fetching pixels, as we + * miss some opportunities to do vectorization, but this is + * convenient for formats or scenarios for which there was no + * opportunity or incentive to optimize. */ unsigned k, chan; @@ -319,9 +327,10 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder, assert(type.floating); for (chan = 0; chan < 4; ++chan) { - rgba[chan] = lp_build_undef(type); + rgba_out[chan] = lp_build_undef(type); } + /* loop over number of pixels */ for(k = 0; k < type.length; ++k) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), k, 0); LLVMValueRef offset_elem; @@ -335,16 +344,19 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder, i_elem = LLVMBuildExtractElement(builder, i, index, ""); j_elem = LLVMBuildExtractElement(builder, j, index, ""); - tmp = lp_build_fetch_rgba_aos(builder, format_desc, ptr, i_elem, j_elem); + /* Get a single float[4]={R,G,B,A} pixel */ + tmp = lp_build_fetch_rgba_aos(builder, format_desc, ptr, + i_elem, j_elem); /* - * AoS to SoA + * Insert the AoS tmp value channels into the SoA result vectors at + * position = 'index'. */ - for (chan = 0; chan < 4; ++chan) { LLVMValueRef chan_val = LLVMConstInt(LLVMInt32Type(), chan, 0), tmp_chan = LLVMBuildExtractElement(builder, tmp, chan_val, ""); - rgba[chan] = LLVMBuildInsertElement(builder, rgba[chan], tmp_chan, index, ""); + rgba_out[chan] = LLVMBuildInsertElement(builder, rgba_out[chan], + tmp_chan, index, ""); } } } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c index 5067d0a164f..bd080f397aa 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c @@ -29,9 +29,23 @@ #include "pipe/p_compiler.h" #include "util/u_cpu_detect.h" #include "util/u_debug.h" +#include "lp_bld_debug.h" #include "lp_bld_init.h" +#ifdef DEBUG +unsigned gallivm_debug = 0; + +static const struct debug_named_value lp_bld_debug_flags[] = { + { "tgsi", GALLIVM_DEBUG_TGSI }, + { "ir", GALLIVM_DEBUG_IR }, + { "asm", GALLIVM_DEBUG_ASM }, + { "nopt", GALLIVM_DEBUG_NO_OPT }, + {NULL, 0} +}; +#endif + + LLVMModuleRef lp_build_module = NULL; LLVMExecutionEngineRef lp_build_engine = NULL; LLVMModuleProviderRef lp_build_provider = NULL; @@ -41,6 +55,10 @@ LLVMTargetDataRef lp_build_target = NULL; void lp_build_init(void) { +#ifdef DEBUG + gallivm_debug = debug_get_flags_option("GALLIVM_DEBUG", lp_bld_debug_flags, 0 ); +#endif + LLVMInitializeNativeTarget(); LLVMLinkInJIT(); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_limits.h b/src/gallium/auxiliary/gallivm/lp_bld_limits.h index e095a0abe3a..369c8121b5c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_limits.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_limits.h @@ -42,6 +42,8 @@ #define LP_MAX_TGSI_IMMEDIATES 256 +#define LP_MAX_TGSI_PREDS 16 + /** * Maximum control flow nesting * diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp new file mode 100644 index 00000000000..db0ca606e58 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 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 COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + + +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS +#endif + +#ifndef __STDC_CONSTANT_MACROS +#define __STDC_CONSTANT_MACROS +#endif + +#include "llvm-c/Core.h" + +#include "pipe/p_config.h" +#include "util/u_debug.h" + + +#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED) + +#include "llvm/Support/raw_ostream.h" + +class raw_debug_ostream : + public llvm::raw_ostream +{ + uint64_t pos; + + void write_impl(const char *Ptr, size_t Size); + uint64_t current_pos() { return pos; } + uint64_t current_pos() const { return pos; } + +#if HAVE_LLVM >= 0x207 + uint64_t preferred_buffer_size() { return 512; } +#else + size_t preferred_buffer_size() { return 512; } +#endif +}; + + +void +raw_debug_ostream::write_impl(const char *Ptr, size_t Size) +{ + if (Size > 0) { + char *lastPtr = (char *)&Ptr[Size]; + char last = *lastPtr; + *lastPtr = 0; + _debug_printf("%*s", Size, Ptr); + *lastPtr = last; + pos += Size; + } +} + + +/** + * Same as LLVMDumpValue, but through our debugging channels. + */ +extern "C" void +lp_debug_dump_value(LLVMValueRef value) +{ + raw_debug_ostream os; + llvm::unwrap(value)->print(os); + os.flush(); +} + + +#else + + +extern "C" void +lp_debug_dump_value(LLVMValueRef value) +{ + LLVMDumpValue(value); +} + + +#endif diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c index 195a4953ab1..c7f9b1083b1 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c @@ -120,10 +120,12 @@ lp_sampler_static_state(struct lp_sampler_static_state *state, /** * Gather elements from scatter positions in memory into a single vector. + * Use for fetching texels from a texture. + * For SSE, typical values are length=4, src_width=32, dst_width=32. * - * @param src_width src element width - * @param dst_width result element width (source will be expanded to fit) - * @param length length of the offsets, + * @param length length of the offsets + * @param src_width src element width in bits + * @param dst_width result element width in bits (src will be expanded to fit) * @param base_ptr base pointer, should be a i8 pointer type. * @param offsets vector with offsets */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index 955b1d21ee5..51e98ab2f9e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -56,14 +56,14 @@ struct lp_sampler_static_state { /* pipe_sampler_view's state */ enum pipe_format format; - unsigned swizzle_r:3; + unsigned swizzle_r:3; /**< PIPE_SWIZZLE_* */ unsigned swizzle_g:3; unsigned swizzle_b:3; unsigned swizzle_a:3; /* pipe_texture's state */ - unsigned target:3; - unsigned pot_width:1; + unsigned target:3; /**< PIPE_TEXTURE_* */ + unsigned pot_width:1; /**< is the width a power of two? */ unsigned pot_height:1; unsigned pot_depth:1; @@ -97,40 +97,40 @@ struct lp_sampler_dynamic_state /** Obtain the base texture width. */ LLVMValueRef - (*width)( struct lp_sampler_dynamic_state *state, + (*width)( const struct lp_sampler_dynamic_state *state, LLVMBuilderRef builder, unsigned unit); /** Obtain the base texture height. */ LLVMValueRef - (*height)( struct lp_sampler_dynamic_state *state, + (*height)( const struct lp_sampler_dynamic_state *state, LLVMBuilderRef builder, unsigned unit); /** Obtain the base texture depth. */ LLVMValueRef - (*depth)( struct lp_sampler_dynamic_state *state, + (*depth)( const struct lp_sampler_dynamic_state *state, LLVMBuilderRef builder, unsigned unit); /** Obtain the number of mipmap levels (minus one). */ LLVMValueRef - (*last_level)( struct lp_sampler_dynamic_state *state, + (*last_level)( const struct lp_sampler_dynamic_state *state, LLVMBuilderRef builder, unsigned unit); LLVMValueRef - (*row_stride)( struct lp_sampler_dynamic_state *state, + (*row_stride)( const struct lp_sampler_dynamic_state *state, LLVMBuilderRef builder, unsigned unit); LLVMValueRef - (*img_stride)( struct lp_sampler_dynamic_state *state, + (*img_stride)( const struct lp_sampler_dynamic_state *state, LLVMBuilderRef builder, unsigned unit); LLVMValueRef - (*data_ptr)( struct lp_sampler_dynamic_state *state, + (*data_ptr)( const struct lp_sampler_dynamic_state *state, LLVMBuilderRef builder, unsigned unit); @@ -177,7 +177,7 @@ lp_build_sample_soa(LLVMBuilderRef builder, const LLVMValueRef *ddy, LLVMValueRef lod_bias, LLVMValueRef explicit_lod, - LLVMValueRef *texel); + LLVMValueRef texel_out[4]); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 3f0ea05b795..bc7213db8b3 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -186,50 +186,18 @@ texture_dims(enum pipe_texture_target tex) } -static LLVMValueRef -lp_build_swizzle_chan_soa(struct lp_type type, - const LLVMValueRef *unswizzled, - enum util_format_swizzle swizzle) -{ - switch (swizzle) { - case PIPE_SWIZZLE_RED: - case PIPE_SWIZZLE_GREEN: - case PIPE_SWIZZLE_BLUE: - case PIPE_SWIZZLE_ALPHA: - return unswizzled[swizzle]; - case PIPE_SWIZZLE_ZERO: - return lp_build_zero(type); - case PIPE_SWIZZLE_ONE: - return lp_build_one(type); - default: - assert(0); - return lp_build_undef(type); - } -} - - static void -lp_build_swizzle_soa(struct lp_build_sample_context *bld, - LLVMValueRef *texel) +apply_sampler_swizzle(struct lp_build_sample_context *bld, + LLVMValueRef *texel) { - LLVMValueRef unswizzled[4]; unsigned char swizzles[4]; - unsigned chan; - - for (chan = 0; chan < 4; ++chan) { - unswizzled[chan] = texel[chan]; - } swizzles[0] = bld->static_state->swizzle_r; swizzles[1] = bld->static_state->swizzle_g; swizzles[2] = bld->static_state->swizzle_b; swizzles[3] = bld->static_state->swizzle_a; - for (chan = 0; chan < 4; ++chan) { - unsigned swizzle = swizzles[chan]; - texel[chan] = lp_build_swizzle_chan_soa(bld->texel_type, - unswizzled, swizzle); - } + lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles); } @@ -254,7 +222,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld, LLVMValueRef y_stride, LLVMValueRef z_stride, LLVMValueRef data_ptr, - LLVMValueRef *texel) + LLVMValueRef texel_out[4]) { const int dims = texture_dims(bld->static_state->target); struct lp_build_context *int_coord_bld = &bld->int_coord_bld; @@ -343,9 +311,9 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld, bld->texel_type, data_ptr, offset, i, j, - texel); + texel_out); - lp_build_swizzle_soa(bld, texel); + apply_sampler_swizzle(bld, texel_out); /* * Note: if we find an app which frequently samples the texture border @@ -369,8 +337,8 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld, LLVMValueRef border_chan = lp_build_const_vec(bld->texel_type, bld->static_state->border_color[chan]); - texel[chan] = lp_build_select(&bld->texel_bld, use_border, - border_chan, texel[chan]); + texel_out[chan] = lp_build_select(&bld->texel_bld, use_border, + border_chan, texel_out[chan]); } } } @@ -950,7 +918,8 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, } else { const int dims = texture_dims(bld->static_state->target); - LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy; + LLVMValueRef dsdx, dsdy; + LLVMValueRef dtdx = NULL, dtdy = NULL, drdx = NULL, drdy = NULL; LLVMValueRef rho; /* @@ -1078,8 +1047,10 @@ lp_build_linear_mip_levels(struct lp_build_sample_context *bld, int_bld->zero, last_level); /* compute level 1 and clamp to legal range of levels */ - *level1_out = lp_build_add(int_bld, *level0_out, int_bld->one); - *level1_out = lp_build_min(int_bld, *level1_out, last_level); + level = lp_build_add(int_bld, level, int_bld->one); + *level1_out = lp_build_clamp(int_bld, level, + int_bld->zero, + last_level); *weight_out = lp_build_fract(float_bld, lod); } @@ -1830,7 +1801,7 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld, LLVMValueRef height, LLVMValueRef stride_array, LLVMValueRef data_array, - LLVMValueRef *texel) + LLVMValueRef texel_out[4]) { LLVMBuilderRef builder = bld->builder; struct lp_build_context i32, h16, u8n; @@ -2023,17 +1994,17 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld, packed, unswizzled); lp_build_format_swizzle_soa(bld->format_desc, - bld->texel_type, unswizzled, - texel); + &bld->texel_bld, + unswizzled, texel_out); - lp_build_swizzle_soa(bld, texel); + apply_sampler_swizzle(bld, texel_out); } static void lp_build_sample_compare(struct lp_build_sample_context *bld, LLVMValueRef p, - LLVMValueRef *texel) + LLVMValueRef texel[4]) { struct lp_build_context *texel_bld = &bld->texel_bld; LLVMValueRef res; @@ -2071,14 +2042,14 @@ lp_build_sample_compare(struct lp_build_sample_context *bld, */ static void lp_build_sample_nop(struct lp_build_sample_context *bld, - LLVMValueRef *texel) + LLVMValueRef texel_out[4]) { struct lp_build_context *texel_bld = &bld->texel_bld; unsigned chan; for (chan = 0; chan < 4; chan++) { /*lp_bld_mov(texel_bld, texel, texel_bld->one);*/ - texel[chan] = texel_bld->one; + texel_out[chan] = texel_bld->one; } } @@ -2101,7 +2072,7 @@ lp_build_sample_soa(LLVMBuilderRef builder, const LLVMValueRef *ddy, LLVMValueRef lod_bias, /* optional */ LLVMValueRef explicit_lod, /* optional */ - LLVMValueRef *texel) + LLVMValueRef texel_out[4]) { struct lp_build_sample_context bld; LLVMValueRef width, width_vec; @@ -2113,6 +2084,11 @@ lp_build_sample_soa(LLVMBuilderRef builder, LLVMValueRef t; LLVMValueRef r; + if (0) { + enum pipe_format fmt = static_state->format; + debug_printf("Sample from %s\n", util_format_name(fmt)); + } + /* Setup our build context */ memset(&bld, 0, sizeof bld); bld.builder = builder; @@ -2153,7 +2129,7 @@ lp_build_sample_soa(LLVMBuilderRef builder, if (0) { /* For debug: no-op texture sampling */ - lp_build_sample_nop(&bld, texel); + lp_build_sample_nop(&bld, texel_out); } else if (util_format_is_rgba8_variant(bld.format_desc) && static_state->target == PIPE_TEXTURE_2D && @@ -2164,7 +2140,7 @@ lp_build_sample_soa(LLVMBuilderRef builder, is_simple_wrap_mode(static_state->wrap_t)) { /* special case */ lp_build_sample_2d_linear_aos(&bld, s, t, width_vec, height_vec, - row_stride_array, data_array, texel); + row_stride_array, data_array, texel_out); } else { lp_build_sample_general(&bld, unit, s, t, r, ddx, ddy, @@ -2173,8 +2149,8 @@ lp_build_sample_soa(LLVMBuilderRef builder, width_vec, height_vec, depth_vec, row_stride_array, img_stride_array, data_array, - texel); + texel_out); } - lp_build_sample_compare(&bld, r, texel); + lp_build_sample_compare(&bld, r, texel_out); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c index 278c838eaca..3c8a7bc09ea 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c @@ -60,21 +60,38 @@ lp_build_broadcast(LLVMBuilderRef builder, } +/** + * Broadcast + */ LLVMValueRef lp_build_broadcast_scalar(struct lp_build_context *bld, LLVMValueRef scalar) { const struct lp_type type = bld->type; - LLVMValueRef res; - unsigned i; - res = bld->undef; - for(i = 0; i < type.length; ++i) { - LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); - res = LLVMBuildInsertElement(bld->builder, res, scalar, index, ""); - } + assert(lp_check_elem_type(type, LLVMTypeOf(scalar))); - return res; + if (type.length == 1) { + return scalar; + } + else { + LLVMValueRef res; +#if HAVE_LLVM >= 0x207 + res = LLVMBuildInsertElement(bld->builder, bld->undef, scalar, + LLVMConstInt(LLVMInt32Type(), 0, 0), ""); + res = LLVMBuildShuffleVector(bld->builder, res, bld->undef, + lp_build_const_int_vec(type, 0), ""); +#else + /* XXX: The above path provokes a bug in LLVM 2.6 */ + unsigned i; + res = bld->undef; + for(i = 0; i < type.length; ++i) { + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); + res = LLVMBuildInsertElement(bld->builder, res, scalar, index, ""); + } +#endif + return res; + } } @@ -237,3 +254,78 @@ lp_build_swizzle2_aos(struct lp_build_context *bld, } +/** + * Extended swizzle of a single channel of a SoA vector. + * + * @param bld building context + * @param unswizzled array with the 4 unswizzled values + * @param swizzle one of the PIPE_SWIZZLE_* + * + * @return the swizzled value. + */ +LLVMValueRef +lp_build_swizzle_soa_channel(struct lp_build_context *bld, + const LLVMValueRef *unswizzled, + unsigned swizzle) +{ + switch (swizzle) { + case PIPE_SWIZZLE_RED: + case PIPE_SWIZZLE_GREEN: + case PIPE_SWIZZLE_BLUE: + case PIPE_SWIZZLE_ALPHA: + return unswizzled[swizzle]; + case PIPE_SWIZZLE_ZERO: + return bld->zero; + case PIPE_SWIZZLE_ONE: + return bld->one; + default: + assert(0); + return bld->undef; + } +} + + +/** + * Extended swizzle of a SoA vector. + * + * @param bld building context + * @param unswizzled array with the 4 unswizzled values + * @param swizzles array of PIPE_SWIZZLE_* + * @param swizzled output swizzled values + */ +void +lp_build_swizzle_soa(struct lp_build_context *bld, + const LLVMValueRef *unswizzled, + const unsigned char swizzles[4], + LLVMValueRef *swizzled) +{ + unsigned chan; + + for (chan = 0; chan < 4; ++chan) { + swizzled[chan] = lp_build_swizzle_soa_channel(bld, unswizzled, + swizzles[chan]); + } +} + + +/** + * Do an extended swizzle of a SoA vector inplace. + * + * @param bld building context + * @param values intput/output array with the 4 values + * @param swizzles array of PIPE_SWIZZLE_* + */ +void +lp_build_swizzle_soa_inplace(struct lp_build_context *bld, + LLVMValueRef *values, + const unsigned char swizzles[4]) +{ + LLVMValueRef unswizzled[4]; + unsigned chan; + + for (chan = 0; chan < 4; ++chan) { + unswizzled[chan] = values[chan]; + } + + lp_build_swizzle_soa(bld, unswizzled, swizzles, values); +} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h index 138ca620e63..4f4fa777c93 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h @@ -88,4 +88,23 @@ lp_build_swizzle2_aos(struct lp_build_context *bld, const unsigned char swizzle[4]); +LLVMValueRef +lp_build_swizzle_soa_channel(struct lp_build_context *bld, + const LLVMValueRef *unswizzled, + unsigned swizzle); + + +void +lp_build_swizzle_soa(struct lp_build_context *bld, + const LLVMValueRef *unswizzled, + const unsigned char swizzles[4], + LLVMValueRef *swizzled); + + +void +lp_build_swizzle_soa_inplace(struct lp_build_context *bld, + LLVMValueRef *values, + const unsigned char swizzles[4]); + + #endif /* !LP_BLD_SWIZZLE_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 5ce1385c480..4d415b6d416 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -59,7 +59,7 @@ struct lp_build_sampler_soa (*destroy)( struct lp_build_sampler_soa *sampler ); void - (*emit_fetch_texel)( struct lp_build_sampler_soa *sampler, + (*emit_fetch_texel)( const struct lp_build_sampler_soa *sampler, LLVMBuilderRef builder, struct lp_type type, unsigned unit, @@ -83,7 +83,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, const LLVMValueRef (*inputs)[4], LLVMValueRef (*outputs)[4], struct lp_build_sampler_soa *sampler, - struct tgsi_shader_info *info); + const struct tgsi_shader_info *info); #endif /* LP_BLD_TGSI_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 0b1a28a7ab7..40ea94c4935 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -81,6 +81,8 @@ #define QUAD_BOTTOM_LEFT 2 #define QUAD_BOTTOM_RIGHT 3 +#define LP_MAX_INSTRUCTIONS 256 + struct lp_exec_mask { struct lp_build_context *bld; @@ -93,18 +95,24 @@ struct lp_exec_mask { int cond_stack_size; LLVMValueRef cond_mask; - LLVMValueRef break_stack[LP_MAX_TGSI_NESTING]; - int break_stack_size; - LLVMValueRef break_mask; - - LLVMValueRef cont_stack[LP_MAX_TGSI_NESTING]; - int cont_stack_size; + LLVMBasicBlockRef loop_block; LLVMValueRef cont_mask; - - LLVMBasicBlockRef loop_stack[LP_MAX_TGSI_NESTING]; + LLVMValueRef break_mask; + LLVMValueRef break_var; + struct { + LLVMBasicBlockRef loop_block; + LLVMValueRef cont_mask; + LLVMValueRef break_mask; + LLVMValueRef break_var; + } loop_stack[LP_MAX_TGSI_NESTING]; int loop_stack_size; - LLVMBasicBlockRef loop_block; + LLVMValueRef ret_mask; + struct { + int pc; + LLVMValueRef ret_mask; + } call_stack[LP_MAX_TGSI_NESTING]; + int call_stack_size; LLVMValueRef exec_mask; }; @@ -113,16 +121,20 @@ struct lp_build_tgsi_soa_context { struct lp_build_context base; + /* Builder for integer masks and indices */ + struct lp_build_context int_bld; + LLVMValueRef consts_ptr; const LLVMValueRef *pos; const LLVMValueRef (*inputs)[NUM_CHANNELS]; LLVMValueRef (*outputs)[NUM_CHANNELS]; - struct lp_build_sampler_soa *sampler; + const struct lp_build_sampler_soa *sampler; LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][NUM_CHANNELS]; LLVMValueRef temps[LP_MAX_TGSI_TEMPS][NUM_CHANNELS]; LLVMValueRef addr[LP_MAX_TGSI_ADDRS][NUM_CHANNELS]; + LLVMValueRef preds[LP_MAX_TGSI_PREDS][NUM_CHANNELS]; /* we allocate an array of temps if we have indirect * addressing and then the temps above is unused */ @@ -131,6 +143,9 @@ struct lp_build_tgsi_soa_context struct lp_build_mask_context *mask; struct lp_exec_mask exec_mask; + + struct tgsi_full_instruction *instructions; + uint max_instructions; }; static const unsigned char @@ -163,10 +178,11 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context mask->has_mask = FALSE; mask->cond_stack_size = 0; mask->loop_stack_size = 0; - mask->break_stack_size = 0; - mask->cont_stack_size = 0; + mask->call_stack_size = 0; mask->int_vec_type = lp_build_int_vec_type(mask->bld->type); + mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask = + LLVMConstAllOnes(mask->int_vec_type); } static void lp_exec_mask_update(struct lp_exec_mask *mask) @@ -186,34 +202,45 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask) } else mask->exec_mask = mask->cond_mask; + if (mask->call_stack_size) { + mask->exec_mask = LLVMBuildAnd(mask->bld->builder, + mask->exec_mask, + mask->ret_mask, + "callmask"); + } mask->has_mask = (mask->cond_stack_size > 0 || - mask->loop_stack_size > 0); + mask->loop_stack_size > 0 || + mask->call_stack_size > 0); } static void lp_exec_mask_cond_push(struct lp_exec_mask *mask, LLVMValueRef val) { assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING); + if (mask->cond_stack_size == 0) { + assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type)); + } mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask; - mask->cond_mask = LLVMBuildBitCast(mask->bld->builder, val, - mask->int_vec_type, ""); + assert(LLVMTypeOf(val) == mask->int_vec_type); + mask->cond_mask = val; lp_exec_mask_update(mask); } static void lp_exec_mask_cond_invert(struct lp_exec_mask *mask) { - LLVMValueRef prev_mask = mask->cond_stack[mask->cond_stack_size - 1]; - LLVMValueRef inv_mask = LLVMBuildNot(mask->bld->builder, - mask->cond_mask, ""); - - /* means that we didn't have any mask before and that - * we were fully enabled */ - if (mask->cond_stack_size <= 1) { - prev_mask = LLVMConstAllOnes(mask->int_vec_type); + LLVMValueRef prev_mask; + LLVMValueRef inv_mask; + + assert(mask->cond_stack_size); + prev_mask = mask->cond_stack[mask->cond_stack_size - 1]; + if (mask->cond_stack_size == 1) { + assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type)); } + inv_mask = LLVMBuildNot(mask->bld->builder, mask->cond_mask, ""); + mask->cond_mask = LLVMBuildAnd(mask->bld->builder, inv_mask, prev_mask, ""); @@ -222,31 +249,37 @@ static void lp_exec_mask_cond_invert(struct lp_exec_mask *mask) static void lp_exec_mask_cond_pop(struct lp_exec_mask *mask) { + assert(mask->cond_stack_size); mask->cond_mask = mask->cond_stack[--mask->cond_stack_size]; lp_exec_mask_update(mask); } static void lp_exec_bgnloop(struct lp_exec_mask *mask) { + if (mask->loop_stack_size == 0) { + assert(mask->loop_block == NULL); + assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type)); + assert(mask->break_mask == LLVMConstAllOnes(mask->int_vec_type)); + assert(mask->break_var == NULL); + } - if (mask->cont_stack_size == 0) - mask->cont_mask = LLVMConstAllOnes(mask->int_vec_type); - if (mask->break_stack_size == 0) - mask->break_mask = LLVMConstAllOnes(mask->int_vec_type); - if (mask->cond_stack_size == 0) - mask->cond_mask = LLVMConstAllOnes(mask->int_vec_type); + assert(mask->loop_stack_size < LP_MAX_TGSI_NESTING); - assert(mask->break_stack_size < LP_MAX_TGSI_NESTING); - assert(mask->cont_stack_size < LP_MAX_TGSI_NESTING); - assert(mask->break_stack_size < LP_MAX_TGSI_NESTING); + mask->loop_stack[mask->loop_stack_size].loop_block = mask->loop_block; + mask->loop_stack[mask->loop_stack_size].cont_mask = mask->cont_mask; + mask->loop_stack[mask->loop_stack_size].break_mask = mask->break_mask; + mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var; + ++mask->loop_stack_size; + + mask->break_var = lp_build_alloca(mask->bld->builder, mask->int_vec_type, ""); + LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var); - mask->break_stack[mask->break_stack_size++] = mask->break_mask; - mask->cont_stack[mask->cont_stack_size++] = mask->cont_mask; - mask->loop_stack[mask->loop_stack_size++] = mask->loop_block; mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop"); LLVMBuildBr(mask->bld->builder, mask->loop_block); LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block); + mask->break_mask = LLVMBuildLoad(mask->bld->builder, mask->break_var, ""); + lp_exec_mask_update(mask); } @@ -286,11 +319,24 @@ static void lp_exec_endloop(struct lp_exec_mask *mask) assert(mask->break_mask); + /* + * Restore the cont_mask, but don't pop + */ + assert(mask->loop_stack_size); + mask->cont_mask = mask->loop_stack[mask->loop_stack_size - 1].cont_mask; + lp_exec_mask_update(mask); + + /* + * Unlike the continue mask, the break_mask must be preserved across loop + * iterations + */ + LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var); + /* i1cond = (mask == 0) */ i1cond = LLVMBuildICmp( mask->bld->builder, LLVMIntNE, - LLVMBuildBitCast(mask->bld->builder, mask->break_mask, reg_type, ""), + LLVMBuildBitCast(mask->bld->builder, mask->exec_mask, reg_type, ""), LLVMConstNull(reg_type), ""); endloop = lp_build_insert_new_block(mask->bld->builder, "endloop"); @@ -300,15 +346,12 @@ static void lp_exec_endloop(struct lp_exec_mask *mask) LLVMPositionBuilderAtEnd(mask->bld->builder, endloop); - mask->loop_block = mask->loop_stack[--mask->loop_stack_size]; - /* pop the cont mask */ - if (mask->cont_stack_size) { - mask->cont_mask = mask->cont_stack[--mask->cont_stack_size]; - } - /* pop the break mask */ - if (mask->break_stack_size) { - mask->break_mask = mask->break_stack[--mask->break_stack_size]; - } + assert(mask->loop_stack_size); + --mask->loop_stack_size; + mask->loop_block = mask->loop_stack[mask->loop_stack_size].loop_block; + mask->cont_mask = mask->loop_stack[mask->loop_stack_size].cont_mask; + mask->break_mask = mask->loop_stack[mask->loop_stack_size].break_mask; + mask->break_var = mask->loop_stack[mask->loop_stack_size].break_var; lp_exec_mask_update(mask); } @@ -319,15 +362,25 @@ static void lp_exec_endloop(struct lp_exec_mask *mask) * (0 means don't store this bit, 1 means do store). */ static void lp_exec_mask_store(struct lp_exec_mask *mask, + LLVMValueRef pred, LLVMValueRef val, LLVMValueRef dst) { + /* Mix the predicate and execution mask */ if (mask->has_mask) { + if (pred) { + pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, ""); + } else { + pred = mask->exec_mask; + } + } + + if (pred) { LLVMValueRef real_val, dst_val; dst_val = LLVMBuildLoad(mask->bld->builder, dst, ""); real_val = lp_build_select(mask->bld, - mask->exec_mask, + pred, val, dst_val); LLVMBuildStore(mask->bld->builder, real_val, dst); @@ -335,6 +388,49 @@ static void lp_exec_mask_store(struct lp_exec_mask *mask, LLVMBuildStore(mask->bld->builder, val, dst); } +static void lp_exec_mask_call(struct lp_exec_mask *mask, + int func, + int *pc) +{ + assert(mask->call_stack_size < LP_MAX_TGSI_NESTING); + mask->call_stack[mask->call_stack_size].pc = *pc; + mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask; + mask->call_stack_size++; + *pc = func; +} + +static void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc) +{ + LLVMValueRef exec_mask; + + if (mask->call_stack_size == 0) { + /* returning from main() */ + *pc = -1; + return; + } + exec_mask = LLVMBuildNot(mask->bld->builder, + mask->exec_mask, + "ret"); + + mask->ret_mask = LLVMBuildAnd(mask->bld->builder, + mask->ret_mask, + exec_mask, "ret_full"); + + lp_exec_mask_update(mask); +} + +static void lp_exec_mask_bgnsub(struct lp_exec_mask *mask) +{ +} + +static void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc) +{ + assert(mask->call_stack_size); + mask->call_stack_size--; + *pc = mask->call_stack[mask->call_stack_size].pc; + mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask; + lp_exec_mask_update(mask); +} static LLVMValueRef emit_ddx(struct lp_build_tgsi_soa_context *bld, @@ -358,15 +454,16 @@ emit_ddy(struct lp_build_tgsi_soa_context *bld, static LLVMValueRef get_temp_ptr(struct lp_build_tgsi_soa_context *bld, unsigned index, - unsigned swizzle, + unsigned chan, boolean is_indirect, LLVMValueRef addr) { + assert(chan < 4); if (!bld->has_indirect_addressing) { - return bld->temps[index][swizzle]; + return bld->temps[index][chan]; } else { LLVMValueRef lindex = - LLVMConstInt(LLVMInt32Type(), index*4 + swizzle, 0); + LLVMConstInt(LLVMInt32Type(), index * 4 + chan, 0); if (is_indirect) lindex = lp_build_add(&bld->base, lindex, addr); return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, ""); @@ -384,34 +481,36 @@ emit_fetch( const unsigned chan_index ) { const struct tgsi_full_src_register *reg = &inst->Src[index]; - unsigned swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index ); + const unsigned swizzle = + tgsi_util_get_full_src_register_swizzle(reg, chan_index); LLVMValueRef res; - LLVMValueRef addr; - - switch (swizzle) { - case TGSI_SWIZZLE_X: - case TGSI_SWIZZLE_Y: - case TGSI_SWIZZLE_Z: - case TGSI_SWIZZLE_W: - - if (reg->Register.Indirect) { - LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type); - unsigned swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, chan_index ); - addr = LLVMBuildLoad(bld->base.builder, - bld->addr[reg->Indirect.Index][swizzle], - ""); - /* for indexing we want integers */ - addr = LLVMBuildFPToSI(bld->base.builder, addr, - int_vec_type, ""); - addr = LLVMBuildExtractElement(bld->base.builder, - addr, LLVMConstInt(LLVMInt32Type(), 0, 0), - ""); - addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0)); - } - - switch (reg->Register.File) { - case TGSI_FILE_CONSTANT: { - LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), reg->Register.Index*4 + swizzle, 0); + LLVMValueRef addr = NULL; + + if (swizzle > 3) { + assert(0 && "invalid swizzle in emit_fetch()"); + return bld->base.undef; + } + + if (reg->Register.Indirect) { + LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type); + unsigned swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, chan_index ); + addr = LLVMBuildLoad(bld->base.builder, + bld->addr[reg->Indirect.Index][swizzle], + ""); + /* for indexing we want integers */ + addr = LLVMBuildFPToSI(bld->base.builder, addr, + int_vec_type, ""); + addr = LLVMBuildExtractElement(bld->base.builder, + addr, LLVMConstInt(LLVMInt32Type(), 0, 0), + ""); + addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0)); + } + + switch (reg->Register.File) { + case TGSI_FILE_CONSTANT: + { + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), + reg->Register.Index*4 + swizzle, 0); LLVMValueRef scalar, scalar_ptr; if (reg->Register.Indirect) { @@ -419,24 +518,26 @@ emit_fetch( "\taddr = %d\n", addr);*/ index = lp_build_add(&bld->base, index, addr); } - scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr, &index, 1, ""); + scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr, + &index, 1, ""); scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, ""); res = lp_build_broadcast_scalar(&bld->base, scalar); - break; } + break; - case TGSI_FILE_IMMEDIATE: - res = bld->immediates[reg->Register.Index][swizzle]; - assert(res); - break; + case TGSI_FILE_IMMEDIATE: + res = bld->immediates[reg->Register.Index][swizzle]; + assert(res); + break; - case TGSI_FILE_INPUT: - res = bld->inputs[reg->Register.Index][swizzle]; - assert(res); - break; + case TGSI_FILE_INPUT: + res = bld->inputs[reg->Register.Index][swizzle]; + assert(res); + break; - case TGSI_FILE_TEMPORARY: { + case TGSI_FILE_TEMPORARY: + { LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle, reg->Register.Indirect, @@ -444,17 +545,11 @@ emit_fetch( res = LLVMBuildLoad(bld->base.builder, temp_ptr, ""); if(!res) return bld->base.undef; - break; - } - - default: - assert( 0 ); - return bld->base.undef; } break; default: - assert( 0 ); + assert(0 && "invalid src register in emit_fetch()"); return bld->base.undef; } @@ -512,6 +607,73 @@ emit_fetch_deriv( /** + * Predicate. + */ +static void +emit_fetch_predicate( + struct lp_build_tgsi_soa_context *bld, + const struct tgsi_full_instruction *inst, + LLVMValueRef *pred) +{ + unsigned index; + unsigned char swizzles[4]; + LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL}; + LLVMValueRef value; + unsigned chan; + + if (!inst->Instruction.Predicate) { + FOR_EACH_CHANNEL( chan ) { + pred[chan] = NULL; + } + return; + } + + swizzles[0] = inst->Predicate.SwizzleX; + swizzles[1] = inst->Predicate.SwizzleY; + swizzles[2] = inst->Predicate.SwizzleZ; + swizzles[3] = inst->Predicate.SwizzleW; + + index = inst->Predicate.Index; + assert(index < LP_MAX_TGSI_PREDS); + + FOR_EACH_CHANNEL( chan ) { + unsigned swizzle = swizzles[chan]; + + /* + * Only fetch the predicate register channels that are actually listed + * in the swizzles + */ + if (!unswizzled[swizzle]) { + value = LLVMBuildLoad(bld->base.builder, + bld->preds[index][swizzle], ""); + + /* + * Convert the value to an integer mask. + * + * TODO: Short-circuit this comparison -- a D3D setp_xx instructions + * is needlessly causing two comparisons due to storing the intermediate + * result as float vector instead of an integer mask vector. + */ + value = lp_build_compare(bld->base.builder, + bld->base.type, + PIPE_FUNC_NOTEQUAL, + value, + bld->base.zero); + if (inst->Predicate.Negate) { + value = LLVMBuildNot(bld->base.builder, value, ""); + } + + unswizzled[swizzle] = value; + } else { + value = unswizzled[swizzle]; + } + + pred[chan] = value; + } +} + + +/** * Register store. */ static void @@ -520,10 +682,11 @@ emit_store( const struct tgsi_full_instruction *inst, unsigned index, unsigned chan_index, + LLVMValueRef pred, LLVMValueRef value) { const struct tgsi_full_dst_register *reg = &inst->Dst[index]; - LLVMValueRef addr; + LLVMValueRef addr = NULL; switch( inst->Instruction.Saturate ) { case TGSI_SAT_NONE: @@ -560,7 +723,7 @@ emit_store( switch( reg->Register.File ) { case TGSI_FILE_OUTPUT: - lp_exec_mask_store(&bld->exec_mask, value, + lp_exec_mask_store(&bld->exec_mask, pred, value, bld->outputs[reg->Register.Index][chan_index]); break; @@ -569,17 +732,18 @@ emit_store( chan_index, reg->Register.Indirect, addr); - lp_exec_mask_store(&bld->exec_mask, value, temp_ptr); + lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr); break; } case TGSI_FILE_ADDRESS: - lp_exec_mask_store(&bld->exec_mask, value, + lp_exec_mask_store(&bld->exec_mask, pred, value, bld->addr[reg->Indirect.Index][chan_index]); break; case TGSI_FILE_PREDICATE: - /* FIXME */ + lp_exec_mask_store(&bld->exec_mask, pred, value, + bld->preds[index][chan_index]); break; default: @@ -789,10 +953,10 @@ emit_declaration( case TGSI_FILE_TEMPORARY: assert(idx < LP_MAX_TGSI_TEMPS); if (bld->has_indirect_addressing) { - LLVMValueRef val = LLVMConstInt(LLVMInt32Type(), - last*4 + 4, 0); + LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(), + last*4 + 4, 0); bld->temps_array = lp_build_array_alloca(bld->base.builder, - vec_type, val, ""); + vec_type, array_size, ""); } else { for (i = 0; i < NUM_CHANNELS; i++) bld->temps[idx][i] = lp_build_alloca(bld->base.builder, @@ -814,7 +978,10 @@ emit_declaration( break; case TGSI_FILE_PREDICATE: - _debug_printf("warning: predicate registers not yet implemented\n"); + assert(idx < LP_MAX_TGSI_PREDS); + for (i = 0; i < NUM_CHANNELS; i++) + bld->preds[idx][i] = lp_build_alloca(bld->base.builder, + vec_type, ""); break; default: @@ -833,7 +1000,8 @@ static boolean emit_instruction( struct lp_build_tgsi_soa_context *bld, const struct tgsi_full_instruction *inst, - const struct tgsi_opcode_info *info) + const struct tgsi_opcode_info *info, + int *pc) { unsigned chan_index; LLVMValueRef src0, src1, src2; @@ -857,8 +1025,10 @@ emit_instruction( * redundant code. */ + (*pc)++; + assert(info->num_dst <= 1); - if(info->num_dst) { + if (info->num_dst) { FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) { dst0[chan_index] = bld->base.undef; } @@ -1455,16 +1625,18 @@ emit_instruction( break; case TGSI_OPCODE_CAL: - /* FIXME */ - return FALSE; + lp_exec_mask_call(&bld->exec_mask, + inst->Label.Label, + pc); + break; case TGSI_OPCODE_RET: - /* FIXME */ - return FALSE; + lp_exec_mask_ret(&bld->exec_mask, pc); break; case TGSI_OPCODE_END: + *pc = -1; break; case TGSI_OPCODE_SSG: @@ -1630,6 +1802,10 @@ emit_instruction( lp_exec_bgnloop(&bld->exec_mask); break; + case TGSI_OPCODE_BGNSUB: + lp_exec_mask_bgnsub(&bld->exec_mask); + break; + case TGSI_OPCODE_ELSE: lp_exec_mask_cond_invert(&bld->exec_mask); break; @@ -1642,6 +1818,10 @@ emit_instruction( lp_exec_endloop(&bld->exec_mask); break; + case TGSI_OPCODE_ENDSUB: + lp_exec_mask_endsub(&bld->exec_mask, pc); + break; + case TGSI_OPCODE_PUSHA: /* deprecated? */ assert(0); @@ -1754,8 +1934,12 @@ emit_instruction( } if(info->num_dst) { + LLVMValueRef pred[NUM_CHANNELS]; + + emit_fetch_predicate( bld, inst, pred ); + FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) { - emit_store( bld, inst, 0, chan_index, dst0[chan_index]); + emit_store( bld, inst, 0, chan_index, pred[chan_index], dst0[chan_index]); } } @@ -1773,16 +1957,19 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, const LLVMValueRef (*inputs)[NUM_CHANNELS], LLVMValueRef (*outputs)[NUM_CHANNELS], struct lp_build_sampler_soa *sampler, - struct tgsi_shader_info *info) + const struct tgsi_shader_info *info) { struct lp_build_tgsi_soa_context bld; struct tgsi_parse_context parse; uint num_immediates = 0; + uint num_instructions = 0; unsigned i; + int pc = 0; /* Setup build context */ memset(&bld, 0, sizeof bld); lp_build_context_init(&bld.base, builder, type); + lp_build_context_init(&bld.int_bld, builder, lp_int_type(type)); bld.mask = mask; bld.pos = pos; bld.inputs = inputs; @@ -1791,6 +1978,13 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, bld.sampler = sampler; bld.has_indirect_addressing = info->opcode_count[TGSI_OPCODE_ARR] > 0 || info->opcode_count[TGSI_OPCODE_ARL] > 0; + bld.instructions = (struct tgsi_full_instruction *) + MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) ); + bld.max_instructions = LP_MAX_INSTRUCTIONS; + + if (!bld.instructions) { + return; + } lp_exec_mask_init(&bld.exec_mask, &bld.base); @@ -1807,11 +2001,21 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, case TGSI_TOKEN_TYPE_INSTRUCTION: { - unsigned opcode = parse.FullToken.FullInstruction.Instruction.Opcode; - const struct tgsi_opcode_info *opcode_info = tgsi_get_opcode_info(opcode); - if (!emit_instruction( &bld, &parse.FullToken.FullInstruction, opcode_info )) - _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n", - opcode_info->mnemonic); + /* save expanded instruction */ + if (num_instructions == bld.max_instructions) { + bld.instructions = REALLOC(bld.instructions, + bld.max_instructions + * sizeof(struct tgsi_full_instruction), + (bld.max_instructions + LP_MAX_INSTRUCTIONS) + * sizeof(struct tgsi_full_instruction)); + bld.max_instructions += LP_MAX_INSTRUCTIONS; + } + + memcpy(bld.instructions + num_instructions, + &parse.FullToken.FullInstruction, + sizeof(bld.instructions[0])); + + num_instructions++; } break; @@ -1838,14 +2042,33 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, assert( 0 ); } } + + while (pc != -1) { + struct tgsi_full_instruction *instr = bld.instructions + pc; + const struct tgsi_opcode_info *opcode_info = + tgsi_get_opcode_info(instr->Instruction.Opcode); + if (!emit_instruction( &bld, instr, opcode_info, &pc )) + _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n", + opcode_info->mnemonic); + } + if (0) { LLVMBasicBlockRef block = LLVMGetInsertBlock(builder); LLVMValueRef function = LLVMGetBasicBlockParent(block); debug_printf("11111111111111111111111111111 \n"); tgsi_dump(tokens, 0); - LLVMDumpValue(function); + lp_debug_dump_value(function); debug_printf("2222222222222222222222222222 \n"); } tgsi_parse_free( &parse ); + + if (0) { + LLVMModuleRef module = LLVMGetGlobalParent( + LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder))); + LLVMDumpModule(module); + + } + + FREE( bld.instructions ); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.c b/src/gallium/auxiliary/gallivm/lp_bld_type.c index 796af88caad..aac3a57bc73 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_type.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_type.c @@ -195,6 +195,7 @@ lp_uint_type(struct lp_type type) { struct lp_type res_type; + assert(type.length <= LP_MAX_VECTOR_LENGTH); memset(&res_type, 0, sizeof res_type); res_type.width = type.width; res_type.length = type.length; @@ -211,6 +212,7 @@ lp_int_type(struct lp_type type) { struct lp_type res_type; + assert(type.length <= LP_MAX_VECTOR_LENGTH); memset(&res_type, 0, sizeof res_type); res_type.width = type.width; res_type.length = type.length; @@ -238,6 +240,131 @@ lp_wider_type(struct lp_type type) } +/** + * Return the size of the LLVMType in bits. + * XXX this function doesn't necessarily handle all LLVM types. + */ +unsigned +lp_sizeof_llvm_type(LLVMTypeRef t) +{ + LLVMTypeKind k = LLVMGetTypeKind(t); + + switch (k) { + case LLVMIntegerTypeKind: + return LLVMGetIntTypeWidth(t); + case LLVMFloatTypeKind: + return 8 * sizeof(float); + case LLVMDoubleTypeKind: + return 8 * sizeof(double); + case LLVMVectorTypeKind: + { + LLVMTypeRef elem = LLVMGetElementType(t); + unsigned len = LLVMGetVectorSize(t); + return len * lp_sizeof_llvm_type(elem); + } + break; + case LLVMArrayTypeKind: + { + LLVMTypeRef elem = LLVMGetElementType(t); + unsigned len = LLVMGetArrayLength(t); + return len * lp_sizeof_llvm_type(elem); + } + break; + default: + assert(0 && "Unexpected type in lp_get_llvm_type_size()"); + return 0; + } +} + + +/** + * Return string name for a LLVMTypeKind. Useful for debugging. + */ +const char * +lp_typekind_name(LLVMTypeKind t) +{ + switch (t) { + case LLVMVoidTypeKind: + return "LLVMVoidTypeKind"; + case LLVMFloatTypeKind: + return "LLVMFloatTypeKind"; + case LLVMDoubleTypeKind: + return "LLVMDoubleTypeKind"; + case LLVMX86_FP80TypeKind: + return "LLVMX86_FP80TypeKind"; + case LLVMFP128TypeKind: + return "LLVMFP128TypeKind"; + case LLVMPPC_FP128TypeKind: + return "LLVMPPC_FP128TypeKind"; + case LLVMLabelTypeKind: + return "LLVMLabelTypeKind"; + case LLVMIntegerTypeKind: + return "LLVMIntegerTypeKind"; + case LLVMFunctionTypeKind: + return "LLVMFunctionTypeKind"; + case LLVMStructTypeKind: + return "LLVMStructTypeKind"; + case LLVMArrayTypeKind: + return "LLVMArrayTypeKind"; + case LLVMPointerTypeKind: + return "LLVMPointerTypeKind"; + case LLVMOpaqueTypeKind: + return "LLVMOpaqueTypeKind"; + case LLVMVectorTypeKind: + return "LLVMVectorTypeKind"; + case LLVMMetadataTypeKind: + return "LLVMMetadataTypeKind"; + /* Only in LLVM 2.7 and later??? + case LLVMUnionTypeKind: + return "LLVMUnionTypeKind"; + */ + default: + return "unknown LLVMTypeKind"; + } +} + + +/** + * Print an LLVMTypeRef. Like LLVMDumpValue(). For debugging. + */ +void +lp_dump_llvmtype(LLVMTypeRef t) +{ + LLVMTypeKind k = LLVMGetTypeKind(t); + + if (k == LLVMVectorTypeKind) { + LLVMTypeRef te = LLVMGetElementType(t); + LLVMTypeKind ke = LLVMGetTypeKind(te); + unsigned len = LLVMGetVectorSize(t); + if (ke == LLVMIntegerTypeKind) { + unsigned b = LLVMGetIntTypeWidth(te); + debug_printf("Vector [%u] of %u-bit Integer\n", len, b); + } + else { + debug_printf("Vector [%u] of %s\n", len, lp_typekind_name(ke)); + } + } + else if (k == LLVMArrayTypeKind) { + LLVMTypeRef te = LLVMGetElementType(t); + LLVMTypeKind ke = LLVMGetTypeKind(te); + unsigned len = LLVMGetArrayLength(t); + debug_printf("Array [%u] of %s\n", len, lp_typekind_name(ke)); + } + else if (k == LLVMIntegerTypeKind) { + unsigned b = LLVMGetIntTypeWidth(t); + debug_printf("%u-bit Integer\n", b); + } + else if (k == LLVMPointerTypeKind) { + LLVMTypeRef te = LLVMGetElementType(t); + debug_printf("Pointer to "); + lp_dump_llvmtype(te); + } + else { + debug_printf("%s\n", lp_typekind_name(k)); + } +} + + void lp_build_context_init(struct lp_build_context *bld, LLVMBuilderRef builder, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h index cd59d2faa66..17819d4d32a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_type.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h @@ -316,6 +316,18 @@ struct lp_type lp_wider_type(struct lp_type type); +unsigned +lp_sizeof_llvm_type(LLVMTypeRef t); + + +const char * +lp_typekind_name(LLVMTypeKind t); + + +void +lp_dump_llvmtype(LLVMTypeRef t); + + void lp_build_context_init(struct lp_build_context *bld, LLVMBuilderRef builder, diff --git a/src/gallium/auxiliary/indices/.gitignore b/src/gallium/auxiliary/indices/.gitignore new file mode 100644 index 00000000000..73740071451 --- /dev/null +++ b/src/gallium/auxiliary/indices/.gitignore @@ -0,0 +1,2 @@ +u_indices_gen.c +u_unfilled_gen.c diff --git a/src/gallium/auxiliary/indices/u_indices_gen.c b/src/gallium/auxiliary/indices/u_indices_gen.c deleted file mode 100644 index 3c981e5d7f4..00000000000 --- a/src/gallium/auxiliary/indices/u_indices_gen.c +++ /dev/null @@ -1,5129 +0,0 @@ -/* File automatically generated by indices.py */ - -/* - * Copyright 2009 VMware, Inc. - * 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 - * 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 - * VMWARE 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. - */ - - - -/** - * @file - * Functions to translate and generate index lists - */ - -#include "indices/u_indices.h" -#include "indices/u_indices_priv.h" -#include "pipe/p_compiler.h" -#include "util/u_debug.h" -#include "pipe/p_defines.h" -#include "util/u_memory.h" - - -static unsigned out_size_idx( unsigned index_size ) -{ - switch (index_size) { - case 4: return OUT_UINT; - case 2: return OUT_USHORT; - default: assert(0); return OUT_USHORT; - } -} - -static unsigned in_size_idx( unsigned index_size ) -{ - switch (index_size) { - case 4: return IN_UINT; - case 2: return IN_USHORT; - case 1: return IN_UBYTE; - default: assert(0); return IN_UBYTE; - } -} - - -static u_translate_func translate[IN_COUNT][OUT_COUNT][PV_COUNT][PV_COUNT][PRIM_COUNT]; -static u_generate_func generate[OUT_COUNT][PV_COUNT][PV_COUNT][PRIM_COUNT]; - - - -static void generate_points_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)(i); - } -} -static void generate_lines_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)(i); - (out+i)[1] = (ushort)(i+1); - } -} -static void generate_linestrip_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(i+1); - } -} -static void generate_lineloop_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(i+1); - } - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(0); -} -static void generate_tris_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)(i); - (out+i)[1] = (ushort)(i+1); - (out+i)[2] = (ushort)(i+2); - } -} -static void generate_tristrip_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(i+1+(i&1)); - (out+j)[2] = (ushort)(i+2-(i&1)); - } -} -static void generate_trifan_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(0); - (out+j)[1] = (ushort)(i+1); - (out+j)[2] = (ushort)(i+2); - } -} -static void generate_quads_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)(i+0); - (out+j+0)[1] = (ushort)(i+1); - (out+j+0)[2] = (ushort)(i+3); - (out+j+3)[0] = (ushort)(i+1); - (out+j+3)[1] = (ushort)(i+2); - (out+j+3)[2] = (ushort)(i+3); - } -} -static void generate_quadstrip_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)(i+2); - (out+j+0)[1] = (ushort)(i+0); - (out+j+0)[2] = (ushort)(i+3); - (out+j+3)[0] = (ushort)(i+0); - (out+j+3)[1] = (ushort)(i+1); - (out+j+3)[2] = (ushort)(i+3); - } -} -static void generate_polygon_ushort_first2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(0); - (out+j)[1] = (ushort)(i+1); - (out+j)[2] = (ushort)(i+2); - } -} -static void generate_points_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)(i); - } -} -static void generate_lines_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)(i+1); - (out+i)[1] = (ushort)(i); - } -} -static void generate_linestrip_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)(i+1); - (out+j)[1] = (ushort)(i); - } -} -static void generate_lineloop_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)(i+1); - (out+j)[1] = (ushort)(i); - } - (out+j)[0] = (ushort)(0); - (out+j)[1] = (ushort)(i); -} -static void generate_tris_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)(i+1); - (out+i)[1] = (ushort)(i+2); - (out+i)[2] = (ushort)(i); - } -} -static void generate_tristrip_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(i+1+(i&1)); - (out+j)[1] = (ushort)(i+2-(i&1)); - (out+j)[2] = (ushort)(i); - } -} -static void generate_trifan_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(i+1); - (out+j)[1] = (ushort)(i+2); - (out+j)[2] = (ushort)(0); - } -} -static void generate_quads_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)(i+1); - (out+j+0)[1] = (ushort)(i+3); - (out+j+0)[2] = (ushort)(i+0); - (out+j+3)[0] = (ushort)(i+2); - (out+j+3)[1] = (ushort)(i+3); - (out+j+3)[2] = (ushort)(i+1); - } -} -static void generate_quadstrip_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)(i+0); - (out+j+0)[1] = (ushort)(i+3); - (out+j+0)[2] = (ushort)(i+2); - (out+j+3)[0] = (ushort)(i+1); - (out+j+3)[1] = (ushort)(i+3); - (out+j+3)[2] = (ushort)(i+0); - } -} -static void generate_polygon_ushort_first2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(i+1); - (out+j)[1] = (ushort)(i+2); - (out+j)[2] = (ushort)(0); - } -} -static void generate_points_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)(i); - } -} -static void generate_lines_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)(i+1); - (out+i)[1] = (ushort)(i); - } -} -static void generate_linestrip_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)(i+1); - (out+j)[1] = (ushort)(i); - } -} -static void generate_lineloop_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)(i+1); - (out+j)[1] = (ushort)(i); - } - (out+j)[0] = (ushort)(0); - (out+j)[1] = (ushort)(i); -} -static void generate_tris_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)(i+2); - (out+i)[1] = (ushort)(i); - (out+i)[2] = (ushort)(i+1); - } -} -static void generate_tristrip_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(i+2); - (out+j)[1] = (ushort)(i+(i&1)); - (out+j)[2] = (ushort)(i+1-(i&1)); - } -} -static void generate_trifan_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(i+2); - (out+j)[1] = (ushort)(0); - (out+j)[2] = (ushort)(i+1); - } -} -static void generate_quads_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)(i+3); - (out+j+0)[1] = (ushort)(i+0); - (out+j+0)[2] = (ushort)(i+1); - (out+j+3)[0] = (ushort)(i+3); - (out+j+3)[1] = (ushort)(i+1); - (out+j+3)[2] = (ushort)(i+2); - } -} -static void generate_quadstrip_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)(i+3); - (out+j+0)[1] = (ushort)(i+2); - (out+j+0)[2] = (ushort)(i+0); - (out+j+3)[0] = (ushort)(i+3); - (out+j+3)[1] = (ushort)(i+0); - (out+j+3)[2] = (ushort)(i+1); - } -} -static void generate_polygon_ushort_last2first( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(0); - (out+j)[1] = (ushort)(i+1); - (out+j)[2] = (ushort)(i+2); - } -} -static void generate_points_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)(i); - } -} -static void generate_lines_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)(i); - (out+i)[1] = (ushort)(i+1); - } -} -static void generate_linestrip_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(i+1); - } -} -static void generate_lineloop_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(i+1); - } - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(0); -} -static void generate_tris_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)(i); - (out+i)[1] = (ushort)(i+1); - (out+i)[2] = (ushort)(i+2); - } -} -static void generate_tristrip_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(i+(i&1)); - (out+j)[1] = (ushort)(i+1-(i&1)); - (out+j)[2] = (ushort)(i+2); - } -} -static void generate_trifan_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(0); - (out+j)[1] = (ushort)(i+1); - (out+j)[2] = (ushort)(i+2); - } -} -static void generate_quads_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)(i+0); - (out+j+0)[1] = (ushort)(i+1); - (out+j+0)[2] = (ushort)(i+3); - (out+j+3)[0] = (ushort)(i+1); - (out+j+3)[1] = (ushort)(i+2); - (out+j+3)[2] = (ushort)(i+3); - } -} -static void generate_quadstrip_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)(i+2); - (out+j+0)[1] = (ushort)(i+0); - (out+j+0)[2] = (ushort)(i+3); - (out+j+3)[0] = (ushort)(i+0); - (out+j+3)[1] = (ushort)(i+1); - (out+j+3)[2] = (ushort)(i+3); - } -} -static void generate_polygon_ushort_last2last( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)(i+1); - (out+j)[1] = (ushort)(i+2); - (out+j)[2] = (ushort)(0); - } -} -static void generate_points_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)(i); - } -} -static void generate_lines_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)(i); - (out+i)[1] = (uint)(i+1); - } -} -static void generate_linestrip_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(i+1); - } -} -static void generate_lineloop_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(i+1); - } - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(0); -} -static void generate_tris_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)(i); - (out+i)[1] = (uint)(i+1); - (out+i)[2] = (uint)(i+2); - } -} -static void generate_tristrip_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(i+1+(i&1)); - (out+j)[2] = (uint)(i+2-(i&1)); - } -} -static void generate_trifan_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(0); - (out+j)[1] = (uint)(i+1); - (out+j)[2] = (uint)(i+2); - } -} -static void generate_quads_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)(i+0); - (out+j+0)[1] = (uint)(i+1); - (out+j+0)[2] = (uint)(i+3); - (out+j+3)[0] = (uint)(i+1); - (out+j+3)[1] = (uint)(i+2); - (out+j+3)[2] = (uint)(i+3); - } -} -static void generate_quadstrip_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)(i+2); - (out+j+0)[1] = (uint)(i+0); - (out+j+0)[2] = (uint)(i+3); - (out+j+3)[0] = (uint)(i+0); - (out+j+3)[1] = (uint)(i+1); - (out+j+3)[2] = (uint)(i+3); - } -} -static void generate_polygon_uint_first2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(0); - (out+j)[1] = (uint)(i+1); - (out+j)[2] = (uint)(i+2); - } -} -static void generate_points_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)(i); - } -} -static void generate_lines_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)(i+1); - (out+i)[1] = (uint)(i); - } -} -static void generate_linestrip_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)(i+1); - (out+j)[1] = (uint)(i); - } -} -static void generate_lineloop_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)(i+1); - (out+j)[1] = (uint)(i); - } - (out+j)[0] = (uint)(0); - (out+j)[1] = (uint)(i); -} -static void generate_tris_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)(i+1); - (out+i)[1] = (uint)(i+2); - (out+i)[2] = (uint)(i); - } -} -static void generate_tristrip_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(i+1+(i&1)); - (out+j)[1] = (uint)(i+2-(i&1)); - (out+j)[2] = (uint)(i); - } -} -static void generate_trifan_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(i+1); - (out+j)[1] = (uint)(i+2); - (out+j)[2] = (uint)(0); - } -} -static void generate_quads_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)(i+1); - (out+j+0)[1] = (uint)(i+3); - (out+j+0)[2] = (uint)(i+0); - (out+j+3)[0] = (uint)(i+2); - (out+j+3)[1] = (uint)(i+3); - (out+j+3)[2] = (uint)(i+1); - } -} -static void generate_quadstrip_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)(i+0); - (out+j+0)[1] = (uint)(i+3); - (out+j+0)[2] = (uint)(i+2); - (out+j+3)[0] = (uint)(i+1); - (out+j+3)[1] = (uint)(i+3); - (out+j+3)[2] = (uint)(i+0); - } -} -static void generate_polygon_uint_first2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(i+1); - (out+j)[1] = (uint)(i+2); - (out+j)[2] = (uint)(0); - } -} -static void generate_points_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)(i); - } -} -static void generate_lines_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)(i+1); - (out+i)[1] = (uint)(i); - } -} -static void generate_linestrip_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)(i+1); - (out+j)[1] = (uint)(i); - } -} -static void generate_lineloop_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)(i+1); - (out+j)[1] = (uint)(i); - } - (out+j)[0] = (uint)(0); - (out+j)[1] = (uint)(i); -} -static void generate_tris_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)(i+2); - (out+i)[1] = (uint)(i); - (out+i)[2] = (uint)(i+1); - } -} -static void generate_tristrip_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(i+2); - (out+j)[1] = (uint)(i+(i&1)); - (out+j)[2] = (uint)(i+1-(i&1)); - } -} -static void generate_trifan_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(i+2); - (out+j)[1] = (uint)(0); - (out+j)[2] = (uint)(i+1); - } -} -static void generate_quads_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)(i+3); - (out+j+0)[1] = (uint)(i+0); - (out+j+0)[2] = (uint)(i+1); - (out+j+3)[0] = (uint)(i+3); - (out+j+3)[1] = (uint)(i+1); - (out+j+3)[2] = (uint)(i+2); - } -} -static void generate_quadstrip_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)(i+3); - (out+j+0)[1] = (uint)(i+2); - (out+j+0)[2] = (uint)(i+0); - (out+j+3)[0] = (uint)(i+3); - (out+j+3)[1] = (uint)(i+0); - (out+j+3)[2] = (uint)(i+1); - } -} -static void generate_polygon_uint_last2first( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(0); - (out+j)[1] = (uint)(i+1); - (out+j)[2] = (uint)(i+2); - } -} -static void generate_points_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)(i); - } -} -static void generate_lines_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)(i); - (out+i)[1] = (uint)(i+1); - } -} -static void generate_linestrip_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(i+1); - } -} -static void generate_lineloop_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(i+1); - } - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(0); -} -static void generate_tris_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)(i); - (out+i)[1] = (uint)(i+1); - (out+i)[2] = (uint)(i+2); - } -} -static void generate_tristrip_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(i+(i&1)); - (out+j)[1] = (uint)(i+1-(i&1)); - (out+j)[2] = (uint)(i+2); - } -} -static void generate_trifan_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(0); - (out+j)[1] = (uint)(i+1); - (out+j)[2] = (uint)(i+2); - } -} -static void generate_quads_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)(i+0); - (out+j+0)[1] = (uint)(i+1); - (out+j+0)[2] = (uint)(i+3); - (out+j+3)[0] = (uint)(i+1); - (out+j+3)[1] = (uint)(i+2); - (out+j+3)[2] = (uint)(i+3); - } -} -static void generate_quadstrip_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)(i+2); - (out+j+0)[1] = (uint)(i+0); - (out+j+0)[2] = (uint)(i+3); - (out+j+3)[0] = (uint)(i+0); - (out+j+3)[1] = (uint)(i+1); - (out+j+3)[2] = (uint)(i+3); - } -} -static void generate_polygon_uint_last2last( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)(i+1); - (out+j)[1] = (uint)(i+2); - (out+j)[2] = (uint)(0); - } -} -static void translate_points_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - } -} -static void translate_linestrip_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } -} -static void translate_lineloop_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[0]; -} -static void translate_tris_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - (out+i)[2] = (ushort)in[i+2]; - } -} -static void translate_tristrip_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1+(i&1)]; - (out+j)[2] = (ushort)in[i+2-(i&1)]; - } -} -static void translate_trifan_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_quads_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+1]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+2]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_quadstrip_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+2]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+0]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_polygon_ubyte2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_points_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i]; - } -} -static void translate_linestrip_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } -} -static void translate_lineloop_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i]; -} -static void translate_tris_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i+2]; - (out+i)[2] = (ushort)in[i]; - } -} -static void translate_tristrip_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1+(i&1)]; - (out+j)[1] = (ushort)in[i+2-(i&1)]; - (out+j)[2] = (ushort)in[i]; - } -} -static void translate_trifan_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_quads_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+1]; - (out+j+0)[1] = (ushort)in[i+3]; - (out+j+0)[2] = (ushort)in[i+0]; - (out+j+3)[0] = (ushort)in[i+2]; - (out+j+3)[1] = (ushort)in[i+3]; - (out+j+3)[2] = (ushort)in[i+1]; - } -} -static void translate_quadstrip_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+3]; - (out+j+0)[2] = (ushort)in[i+2]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+3]; - (out+j+3)[2] = (ushort)in[i+0]; - } -} -static void translate_polygon_ubyte2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_points_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i]; - } -} -static void translate_linestrip_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } -} -static void translate_lineloop_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i]; -} -static void translate_tris_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i+2]; - (out+i)[1] = (ushort)in[i]; - (out+i)[2] = (ushort)in[i+1]; - } -} -static void translate_tristrip_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[i+(i&1)]; - (out+j)[2] = (ushort)in[i+1-(i&1)]; - } -} -static void translate_trifan_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[0]; - (out+j)[2] = (ushort)in[i+1]; - } -} -static void translate_quads_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+3]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+1]; - (out+j+3)[0] = (ushort)in[i+3]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+2]; - } -} -static void translate_quadstrip_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+3]; - (out+j+0)[1] = (ushort)in[i+2]; - (out+j+0)[2] = (ushort)in[i+0]; - (out+j+3)[0] = (ushort)in[i+3]; - (out+j+3)[1] = (ushort)in[i+0]; - (out+j+3)[2] = (ushort)in[i+1]; - } -} -static void translate_polygon_ubyte2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_points_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - } -} -static void translate_linestrip_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } -} -static void translate_lineloop_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[0]; -} -static void translate_tris_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - (out+i)[2] = (ushort)in[i+2]; - } -} -static void translate_tristrip_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+(i&1)]; - (out+j)[1] = (ushort)in[i+1-(i&1)]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_trifan_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_quads_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+1]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+2]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_quadstrip_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+2]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+0]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_polygon_ubyte2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_points_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - } -} -static void translate_linestrip_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } -} -static void translate_lineloop_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[0]; -} -static void translate_tris_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - (out+i)[2] = (uint)in[i+2]; - } -} -static void translate_tristrip_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1+(i&1)]; - (out+j)[2] = (uint)in[i+2-(i&1)]; - } -} -static void translate_trifan_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_quads_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+1]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+2]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_quadstrip_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+2]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+0]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_polygon_ubyte2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_points_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i]; - } -} -static void translate_linestrip_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } -} -static void translate_lineloop_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i]; -} -static void translate_tris_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i+2]; - (out+i)[2] = (uint)in[i]; - } -} -static void translate_tristrip_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1+(i&1)]; - (out+j)[1] = (uint)in[i+2-(i&1)]; - (out+j)[2] = (uint)in[i]; - } -} -static void translate_trifan_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -static void translate_quads_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+1]; - (out+j+0)[1] = (uint)in[i+3]; - (out+j+0)[2] = (uint)in[i+0]; - (out+j+3)[0] = (uint)in[i+2]; - (out+j+3)[1] = (uint)in[i+3]; - (out+j+3)[2] = (uint)in[i+1]; - } -} -static void translate_quadstrip_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+3]; - (out+j+0)[2] = (uint)in[i+2]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+3]; - (out+j+3)[2] = (uint)in[i+0]; - } -} -static void translate_polygon_ubyte2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -static void translate_points_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i]; - } -} -static void translate_linestrip_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } -} -static void translate_lineloop_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i]; -} -static void translate_tris_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i+2]; - (out+i)[1] = (uint)in[i]; - (out+i)[2] = (uint)in[i+1]; - } -} -static void translate_tristrip_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[i+(i&1)]; - (out+j)[2] = (uint)in[i+1-(i&1)]; - } -} -static void translate_trifan_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[0]; - (out+j)[2] = (uint)in[i+1]; - } -} -static void translate_quads_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+3]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+1]; - (out+j+3)[0] = (uint)in[i+3]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+2]; - } -} -static void translate_quadstrip_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+3]; - (out+j+0)[1] = (uint)in[i+2]; - (out+j+0)[2] = (uint)in[i+0]; - (out+j+3)[0] = (uint)in[i+3]; - (out+j+3)[1] = (uint)in[i+0]; - (out+j+3)[2] = (uint)in[i+1]; - } -} -static void translate_polygon_ubyte2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_points_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - } -} -static void translate_linestrip_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } -} -static void translate_lineloop_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[0]; -} -static void translate_tris_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - (out+i)[2] = (uint)in[i+2]; - } -} -static void translate_tristrip_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+(i&1)]; - (out+j)[1] = (uint)in[i+1-(i&1)]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_trifan_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_quads_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+1]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+2]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_quadstrip_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+2]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+0]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_polygon_ubyte2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -static void translate_points_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - } -} -static void translate_linestrip_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } -} -static void translate_lineloop_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[0]; -} -static void translate_tris_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - (out+i)[2] = (ushort)in[i+2]; - } -} -static void translate_tristrip_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1+(i&1)]; - (out+j)[2] = (ushort)in[i+2-(i&1)]; - } -} -static void translate_trifan_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_quads_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+1]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+2]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_quadstrip_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+2]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+0]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_polygon_ushort2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_points_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i]; - } -} -static void translate_linestrip_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } -} -static void translate_lineloop_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i]; -} -static void translate_tris_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i+2]; - (out+i)[2] = (ushort)in[i]; - } -} -static void translate_tristrip_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1+(i&1)]; - (out+j)[1] = (ushort)in[i+2-(i&1)]; - (out+j)[2] = (ushort)in[i]; - } -} -static void translate_trifan_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_quads_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+1]; - (out+j+0)[1] = (ushort)in[i+3]; - (out+j+0)[2] = (ushort)in[i+0]; - (out+j+3)[0] = (ushort)in[i+2]; - (out+j+3)[1] = (ushort)in[i+3]; - (out+j+3)[2] = (ushort)in[i+1]; - } -} -static void translate_quadstrip_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+3]; - (out+j+0)[2] = (ushort)in[i+2]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+3]; - (out+j+3)[2] = (ushort)in[i+0]; - } -} -static void translate_polygon_ushort2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_points_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i]; - } -} -static void translate_linestrip_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } -} -static void translate_lineloop_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i]; -} -static void translate_tris_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i+2]; - (out+i)[1] = (ushort)in[i]; - (out+i)[2] = (ushort)in[i+1]; - } -} -static void translate_tristrip_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[i+(i&1)]; - (out+j)[2] = (ushort)in[i+1-(i&1)]; - } -} -static void translate_trifan_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[0]; - (out+j)[2] = (ushort)in[i+1]; - } -} -static void translate_quads_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+3]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+1]; - (out+j+3)[0] = (ushort)in[i+3]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+2]; - } -} -static void translate_quadstrip_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+3]; - (out+j+0)[1] = (ushort)in[i+2]; - (out+j+0)[2] = (ushort)in[i+0]; - (out+j+3)[0] = (ushort)in[i+3]; - (out+j+3)[1] = (ushort)in[i+0]; - (out+j+3)[2] = (ushort)in[i+1]; - } -} -static void translate_polygon_ushort2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_points_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - } -} -static void translate_linestrip_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } -} -static void translate_lineloop_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[0]; -} -static void translate_tris_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - (out+i)[2] = (ushort)in[i+2]; - } -} -static void translate_tristrip_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+(i&1)]; - (out+j)[1] = (ushort)in[i+1-(i&1)]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_trifan_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_quads_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+1]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+2]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_quadstrip_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+2]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+0]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_polygon_ushort2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_points_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - } -} -static void translate_linestrip_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } -} -static void translate_lineloop_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[0]; -} -static void translate_tris_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - (out+i)[2] = (uint)in[i+2]; - } -} -static void translate_tristrip_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1+(i&1)]; - (out+j)[2] = (uint)in[i+2-(i&1)]; - } -} -static void translate_trifan_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_quads_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+1]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+2]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_quadstrip_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+2]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+0]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_polygon_ushort2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_points_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i]; - } -} -static void translate_linestrip_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } -} -static void translate_lineloop_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i]; -} -static void translate_tris_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i+2]; - (out+i)[2] = (uint)in[i]; - } -} -static void translate_tristrip_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1+(i&1)]; - (out+j)[1] = (uint)in[i+2-(i&1)]; - (out+j)[2] = (uint)in[i]; - } -} -static void translate_trifan_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -static void translate_quads_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+1]; - (out+j+0)[1] = (uint)in[i+3]; - (out+j+0)[2] = (uint)in[i+0]; - (out+j+3)[0] = (uint)in[i+2]; - (out+j+3)[1] = (uint)in[i+3]; - (out+j+3)[2] = (uint)in[i+1]; - } -} -static void translate_quadstrip_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+3]; - (out+j+0)[2] = (uint)in[i+2]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+3]; - (out+j+3)[2] = (uint)in[i+0]; - } -} -static void translate_polygon_ushort2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -static void translate_points_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i]; - } -} -static void translate_linestrip_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } -} -static void translate_lineloop_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i]; -} -static void translate_tris_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i+2]; - (out+i)[1] = (uint)in[i]; - (out+i)[2] = (uint)in[i+1]; - } -} -static void translate_tristrip_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[i+(i&1)]; - (out+j)[2] = (uint)in[i+1-(i&1)]; - } -} -static void translate_trifan_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[0]; - (out+j)[2] = (uint)in[i+1]; - } -} -static void translate_quads_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+3]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+1]; - (out+j+3)[0] = (uint)in[i+3]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+2]; - } -} -static void translate_quadstrip_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+3]; - (out+j+0)[1] = (uint)in[i+2]; - (out+j+0)[2] = (uint)in[i+0]; - (out+j+3)[0] = (uint)in[i+3]; - (out+j+3)[1] = (uint)in[i+0]; - (out+j+3)[2] = (uint)in[i+1]; - } -} -static void translate_polygon_ushort2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_points_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - } -} -static void translate_linestrip_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } -} -static void translate_lineloop_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[0]; -} -static void translate_tris_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - (out+i)[2] = (uint)in[i+2]; - } -} -static void translate_tristrip_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+(i&1)]; - (out+j)[1] = (uint)in[i+1-(i&1)]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_trifan_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_quads_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+1]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+2]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_quadstrip_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+2]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+0]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_polygon_ushort2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -static void translate_points_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - } -} -static void translate_linestrip_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } -} -static void translate_lineloop_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[0]; -} -static void translate_tris_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - (out+i)[2] = (ushort)in[i+2]; - } -} -static void translate_tristrip_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1+(i&1)]; - (out+j)[2] = (ushort)in[i+2-(i&1)]; - } -} -static void translate_trifan_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_quads_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+1]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+2]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_quadstrip_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+2]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+0]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_polygon_uint2ushort_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_points_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i]; - } -} -static void translate_linestrip_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } -} -static void translate_lineloop_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i]; -} -static void translate_tris_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i+2]; - (out+i)[2] = (ushort)in[i]; - } -} -static void translate_tristrip_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1+(i&1)]; - (out+j)[1] = (ushort)in[i+2-(i&1)]; - (out+j)[2] = (ushort)in[i]; - } -} -static void translate_trifan_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_quads_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+1]; - (out+j+0)[1] = (ushort)in[i+3]; - (out+j+0)[2] = (ushort)in[i+0]; - (out+j+3)[0] = (ushort)in[i+2]; - (out+j+3)[1] = (ushort)in[i+3]; - (out+j+3)[2] = (ushort)in[i+1]; - } -} -static void translate_quadstrip_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+3]; - (out+j+0)[2] = (ushort)in[i+2]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+3]; - (out+j+3)[2] = (ushort)in[i+0]; - } -} -static void translate_polygon_uint2ushort_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_points_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i+1]; - (out+i)[1] = (ushort)in[i]; - } -} -static void translate_linestrip_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } -} -static void translate_lineloop_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i]; - } - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i]; -} -static void translate_tris_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i+2]; - (out+i)[1] = (ushort)in[i]; - (out+i)[2] = (ushort)in[i+1]; - } -} -static void translate_tristrip_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[i+(i&1)]; - (out+j)[2] = (ushort)in[i+1-(i&1)]; - } -} -static void translate_trifan_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[0]; - (out+j)[2] = (ushort)in[i+1]; - } -} -static void translate_quads_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+3]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+1]; - (out+j+3)[0] = (ushort)in[i+3]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+2]; - } -} -static void translate_quadstrip_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+3]; - (out+j+0)[1] = (ushort)in[i+2]; - (out+j+0)[2] = (ushort)in[i+0]; - (out+j+3)[0] = (ushort)in[i+3]; - (out+j+3)[1] = (ushort)in[i+0]; - (out+j+3)[2] = (ushort)in[i+1]; - } -} -static void translate_polygon_uint2ushort_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_points_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (ushort)in[i]; - } -} -static void translate_lines_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - } -} -static void translate_linestrip_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } -} -static void translate_lineloop_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - } - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[0]; -} -static void translate_tris_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (ushort)in[i]; - (out+i)[1] = (ushort)in[i+1]; - (out+i)[2] = (ushort)in[i+2]; - } -} -static void translate_tristrip_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+(i&1)]; - (out+j)[1] = (ushort)in[i+1-(i&1)]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_trifan_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j)[2] = (ushort)in[i+2]; - } -} -static void translate_quads_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (ushort)in[i+0]; - (out+j+0)[1] = (ushort)in[i+1]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+1]; - (out+j+3)[1] = (ushort)in[i+2]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_quadstrip_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (ushort)in[i+2]; - (out+j+0)[1] = (ushort)in[i+0]; - (out+j+0)[2] = (ushort)in[i+3]; - (out+j+3)[0] = (ushort)in[i+0]; - (out+j+3)[1] = (ushort)in[i+1]; - (out+j+3)[2] = (ushort)in[i+3]; - } -} -static void translate_polygon_uint2ushort_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (ushort)in[i+1]; - (out+j)[1] = (ushort)in[i+2]; - (out+j)[2] = (ushort)in[0]; - } -} -static void translate_points_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - } -} -static void translate_linestrip_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } -} -static void translate_lineloop_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[0]; -} -static void translate_tris_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - (out+i)[2] = (uint)in[i+2]; - } -} -static void translate_tristrip_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1+(i&1)]; - (out+j)[2] = (uint)in[i+2-(i&1)]; - } -} -static void translate_trifan_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_quads_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+1]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+2]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_quadstrip_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+2]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+0]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_polygon_uint2uint_first2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_points_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i]; - } -} -static void translate_linestrip_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } -} -static void translate_lineloop_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i]; -} -static void translate_tris_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i+2]; - (out+i)[2] = (uint)in[i]; - } -} -static void translate_tristrip_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1+(i&1)]; - (out+j)[1] = (uint)in[i+2-(i&1)]; - (out+j)[2] = (uint)in[i]; - } -} -static void translate_trifan_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -static void translate_quads_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+1]; - (out+j+0)[1] = (uint)in[i+3]; - (out+j+0)[2] = (uint)in[i+0]; - (out+j+3)[0] = (uint)in[i+2]; - (out+j+3)[1] = (uint)in[i+3]; - (out+j+3)[2] = (uint)in[i+1]; - } -} -static void translate_quadstrip_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+3]; - (out+j+0)[2] = (uint)in[i+2]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+3]; - (out+j+3)[2] = (uint)in[i+0]; - } -} -static void translate_polygon_uint2uint_first2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -static void translate_points_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i+1]; - (out+i)[1] = (uint)in[i]; - } -} -static void translate_linestrip_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } -} -static void translate_lineloop_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i]; - } - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i]; -} -static void translate_tris_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i+2]; - (out+i)[1] = (uint)in[i]; - (out+i)[2] = (uint)in[i+1]; - } -} -static void translate_tristrip_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[i+(i&1)]; - (out+j)[2] = (uint)in[i+1-(i&1)]; - } -} -static void translate_trifan_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[0]; - (out+j)[2] = (uint)in[i+1]; - } -} -static void translate_quads_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+3]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+1]; - (out+j+3)[0] = (uint)in[i+3]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+2]; - } -} -static void translate_quadstrip_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+3]; - (out+j+0)[1] = (uint)in[i+2]; - (out+j+0)[2] = (uint)in[i+0]; - (out+j+3)[0] = (uint)in[i+3]; - (out+j+3)[1] = (uint)in[i+0]; - (out+j+3)[2] = (uint)in[i+1]; - } -} -static void translate_polygon_uint2uint_last2first( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_points_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i++) { - (out+i)[0] = (uint)in[i]; - } -} -static void translate_lines_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=2) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - } -} -static void translate_linestrip_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } -} -static void translate_lineloop_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr - 2; j+=2, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - } - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[0]; -} -static void translate_tris_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (i = 0; i < nr; i+=3) { - (out+i)[0] = (uint)in[i]; - (out+i)[1] = (uint)in[i+1]; - (out+i)[2] = (uint)in[i+2]; - } -} -static void translate_tristrip_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+(i&1)]; - (out+j)[1] = (uint)in[i+1-(i&1)]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_trifan_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j)[2] = (uint)in[i+2]; - } -} -static void translate_quads_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=4) { - (out+j+0)[0] = (uint)in[i+0]; - (out+j+0)[1] = (uint)in[i+1]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+1]; - (out+j+3)[1] = (uint)in[i+2]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_quadstrip_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=2) { - (out+j+0)[0] = (uint)in[i+2]; - (out+j+0)[1] = (uint)in[i+0]; - (out+j+0)[2] = (uint)in[i+3]; - (out+j+3)[0] = (uint)in[i+0]; - (out+j+3)[1] = (uint)in[i+1]; - (out+j+3)[2] = (uint)in[i+3]; - } -} -static void translate_polygon_uint2uint_last2last( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=3, i++) { - (out+j)[0] = (uint)in[i+1]; - (out+j)[1] = (uint)in[i+2]; - (out+j)[2] = (uint)in[0]; - } -} -void u_index_init( void ) -{ - static int firsttime = 1; - if (!firsttime) return; - firsttime = 0; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_POINTS] = generate_points_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINES] = generate_lines_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = generate_linestrip_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = generate_lineloop_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLES] = generate_tris_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUADS] = generate_quads_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_POLYGON] = generate_polygon_ushort_first2first; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_POINTS] = generate_points_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINES] = generate_lines_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_STRIP] = generate_linestrip_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_LOOP] = generate_lineloop_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLES] = generate_tris_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_QUADS] = generate_quads_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_ushort_first2last; -generate[OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_POLYGON] = generate_polygon_ushort_first2last; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_POINTS] = generate_points_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINES] = generate_lines_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = generate_linestrip_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = generate_lineloop_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLES] = generate_tris_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_QUADS] = generate_quads_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_POLYGON] = generate_polygon_ushort_last2first; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_POINTS] = generate_points_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINES] = generate_lines_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_STRIP] = generate_linestrip_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_LOOP] = generate_lineloop_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLES] = generate_tris_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_QUADS] = generate_quads_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_ushort_last2last; -generate[OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_POLYGON] = generate_polygon_ushort_last2last; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_POINTS] = generate_points_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINES] = generate_lines_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = generate_linestrip_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = generate_lineloop_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLES] = generate_tris_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUADS] = generate_quads_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_POLYGON] = generate_polygon_uint_first2first; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_POINTS] = generate_points_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINES] = generate_lines_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_STRIP] = generate_linestrip_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_LOOP] = generate_lineloop_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLES] = generate_tris_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_QUADS] = generate_quads_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_uint_first2last; -generate[OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_POLYGON] = generate_polygon_uint_first2last; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_POINTS] = generate_points_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINES] = generate_lines_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = generate_linestrip_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = generate_lineloop_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLES] = generate_tris_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_QUADS] = generate_quads_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_POLYGON] = generate_polygon_uint_last2first; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_POINTS] = generate_points_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINES] = generate_lines_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_STRIP] = generate_linestrip_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_LOOP] = generate_lineloop_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLES] = generate_tris_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_QUADS] = generate_quads_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_uint_last2last; -generate[OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_POLYGON] = generate_polygon_uint_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2ushort_first2first; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2ushort_first2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2ushort_last2first; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2ushort_last2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2uint_first2first; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2uint_first2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2uint_last2first; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2uint_last2last; -translate[IN_UBYTE][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2uint_last2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_ushort2ushort_first2first; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_ushort2ushort_first2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_ushort2ushort_last2first; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2ushort_last2last; -translate[IN_USHORT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_ushort2ushort_last2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_ushort2uint_first2first; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_ushort2uint_first2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_ushort2uint_last2first; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2uint_last2last; -translate[IN_USHORT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_ushort2uint_last2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_uint2ushort_first2first; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_FIRST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_uint2ushort_first2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_uint2ushort_last2first; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2ushort_last2last; -translate[IN_UINT][OUT_USHORT][PV_LAST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_uint2ushort_last2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_uint2uint_first2first; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_FIRST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_uint2uint_first2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_POINTS] = translate_points_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINES] = translate_lines_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLES] = translate_tris_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_QUADS] = translate_quads_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_FIRST][PIPE_PRIM_POLYGON] = translate_polygon_uint2uint_last2first; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_POINTS] = translate_points_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINES] = translate_lines_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_STRIP] = translate_linestrip_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_LINE_LOOP] = translate_lineloop_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLES] = translate_tris_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_QUADS] = translate_quads_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2uint_last2last; -translate[IN_UINT][OUT_UINT][PV_LAST][PV_LAST][PIPE_PRIM_POLYGON] = translate_polygon_uint2uint_last2last; -} -#include "indices/u_indices.c" diff --git a/src/gallium/auxiliary/indices/u_unfilled_gen.c b/src/gallium/auxiliary/indices/u_unfilled_gen.c deleted file mode 100644 index 93897c98deb..00000000000 --- a/src/gallium/auxiliary/indices/u_unfilled_gen.c +++ /dev/null @@ -1,992 +0,0 @@ -/* File automatically generated by u_unfilled_gen.py */ - -/* - * Copyright 2009 VMware, Inc. - * 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 - * 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 - * VMWARE 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. - */ - - - -/** - * @file - * Functions to translate and generate index lists - */ - -#include "indices/u_indices.h" -#include "indices/u_indices_priv.h" -#include "pipe/p_compiler.h" -#include "util/u_debug.h" -#include "pipe/p_defines.h" -#include "util/u_memory.h" - - -static unsigned out_size_idx( unsigned index_size ) -{ - switch (index_size) { - case 4: return OUT_UINT; - case 2: return OUT_USHORT; - default: assert(0); return OUT_USHORT; - } -} - -static unsigned in_size_idx( unsigned index_size ) -{ - switch (index_size) { - case 4: return IN_UINT; - case 2: return IN_USHORT; - case 1: return IN_UBYTE; - default: assert(0); return IN_UBYTE; - } -} - - -static u_generate_func generate_line[OUT_COUNT][PRIM_COUNT]; -static u_translate_func translate_line[IN_COUNT][OUT_COUNT][PRIM_COUNT]; - - -static void generate_tris_ushort( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=3) { - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(i+1); - (out+j+2)[0] = (ushort)(i+1); - (out+j+2)[1] = (ushort)(i+2); - (out+j+4)[0] = (ushort)(i+2); - (out+j+4)[1] = (ushort)(i); - } -} -static void generate_tristrip_ushort( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)(i); - (out+j)[1] = (ushort)(i+1/*+(i&1)*/); - (out+j+2)[0] = (ushort)(i+1/*+(i&1)*/); - (out+j+2)[1] = (ushort)(i+2/*-(i&1)*/); - (out+j+4)[0] = (ushort)(i+2/*-(i&1)*/); - (out+j+4)[1] = (ushort)(i); - } -} -static void generate_trifan_ushort( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)(0); - (out+j)[1] = (ushort)(i+1); - (out+j+2)[0] = (ushort)(i+1); - (out+j+2)[1] = (ushort)(i+2); - (out+j+4)[0] = (ushort)(i+2); - (out+j+4)[1] = (ushort)(0); - } -} -static void generate_quads_ushort( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=4) { - (out+j)[0] = (ushort)(i+0); - (out+j)[1] = (ushort)(i+1); - (out+j+2)[0] = (ushort)(i+1); - (out+j+2)[1] = (ushort)(i+2); - (out+j+4)[0] = (ushort)(i+2); - (out+j+4)[1] = (ushort)(i+3); - (out+j+6)[0] = (ushort)(i+3); - (out+j+6)[1] = (ushort)(i+0); - } -} -static void generate_quadstrip_ushort( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=2) { - (out+j)[0] = (ushort)(i+2); - (out+j)[1] = (ushort)(i+0); - (out+j+2)[0] = (ushort)(i+0); - (out+j+2)[1] = (ushort)(i+1); - (out+j+4)[0] = (ushort)(i+1); - (out+j+4)[1] = (ushort)(i+3); - (out+j+6)[0] = (ushort)(i+3); - (out+j+6)[1] = (ushort)(i+2); - } -} -static void generate_polygon_ushort( - unsigned nr, - void *_out ) -{ - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)(0); - (out+j)[1] = (ushort)(i+1); - (out+j+2)[0] = (ushort)(i+1); - (out+j+2)[1] = (ushort)(i+2); - (out+j+4)[0] = (ushort)(i+2); - (out+j+4)[1] = (ushort)(0); - } -} -static void generate_tris_uint( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=3) { - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(i+1); - (out+j+2)[0] = (uint)(i+1); - (out+j+2)[1] = (uint)(i+2); - (out+j+4)[0] = (uint)(i+2); - (out+j+4)[1] = (uint)(i); - } -} -static void generate_tristrip_uint( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)(i); - (out+j)[1] = (uint)(i+1/*+(i&1)*/); - (out+j+2)[0] = (uint)(i+1/*+(i&1)*/); - (out+j+2)[1] = (uint)(i+2/*-(i&1)*/); - (out+j+4)[0] = (uint)(i+2/*-(i&1)*/); - (out+j+4)[1] = (uint)(i); - } -} -static void generate_trifan_uint( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)(0); - (out+j)[1] = (uint)(i+1); - (out+j+2)[0] = (uint)(i+1); - (out+j+2)[1] = (uint)(i+2); - (out+j+4)[0] = (uint)(i+2); - (out+j+4)[1] = (uint)(0); - } -} -static void generate_quads_uint( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=4) { - (out+j)[0] = (uint)(i+0); - (out+j)[1] = (uint)(i+1); - (out+j+2)[0] = (uint)(i+1); - (out+j+2)[1] = (uint)(i+2); - (out+j+4)[0] = (uint)(i+2); - (out+j+4)[1] = (uint)(i+3); - (out+j+6)[0] = (uint)(i+3); - (out+j+6)[1] = (uint)(i+0); - } -} -static void generate_quadstrip_uint( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=2) { - (out+j)[0] = (uint)(i+2); - (out+j)[1] = (uint)(i+0); - (out+j+2)[0] = (uint)(i+0); - (out+j+2)[1] = (uint)(i+1); - (out+j+4)[0] = (uint)(i+1); - (out+j+4)[1] = (uint)(i+3); - (out+j+6)[0] = (uint)(i+3); - (out+j+6)[1] = (uint)(i+2); - } -} -static void generate_polygon_uint( - unsigned nr, - void *_out ) -{ - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)(0); - (out+j)[1] = (uint)(i+1); - (out+j+2)[0] = (uint)(i+1); - (out+j+2)[1] = (uint)(i+2); - (out+j+4)[0] = (uint)(i+2); - (out+j+4)[1] = (uint)(0); - } -} -static void translate_tris_ubyte2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=3) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[i]; - } -} -static void translate_tristrip_ubyte2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1/*+(i&1)*/]; - (out+j+2)[0] = (ushort)in[i+1/*+(i&1)*/]; - (out+j+2)[1] = (ushort)in[i+2/*-(i&1)*/]; - (out+j+4)[0] = (ushort)in[i+2/*-(i&1)*/]; - (out+j+4)[1] = (ushort)in[i]; - } -} -static void translate_trifan_ubyte2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[0]; - } -} -static void translate_quads_ubyte2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=4) { - (out+j)[0] = (ushort)in[i+0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[i+3]; - (out+j+6)[0] = (ushort)in[i+3]; - (out+j+6)[1] = (ushort)in[i+0]; - } -} -static void translate_quadstrip_ubyte2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=2) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[i+0]; - (out+j+2)[0] = (ushort)in[i+0]; - (out+j+2)[1] = (ushort)in[i+1]; - (out+j+4)[0] = (ushort)in[i+1]; - (out+j+4)[1] = (ushort)in[i+3]; - (out+j+6)[0] = (ushort)in[i+3]; - (out+j+6)[1] = (ushort)in[i+2]; - } -} -static void translate_polygon_ubyte2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[0]; - } -} -static void translate_tris_ubyte2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=3) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[i]; - } -} -static void translate_tristrip_ubyte2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1/*+(i&1)*/]; - (out+j+2)[0] = (uint)in[i+1/*+(i&1)*/]; - (out+j+2)[1] = (uint)in[i+2/*-(i&1)*/]; - (out+j+4)[0] = (uint)in[i+2/*-(i&1)*/]; - (out+j+4)[1] = (uint)in[i]; - } -} -static void translate_trifan_ubyte2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[0]; - } -} -static void translate_quads_ubyte2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=4) { - (out+j)[0] = (uint)in[i+0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[i+3]; - (out+j+6)[0] = (uint)in[i+3]; - (out+j+6)[1] = (uint)in[i+0]; - } -} -static void translate_quadstrip_ubyte2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=2) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[i+0]; - (out+j+2)[0] = (uint)in[i+0]; - (out+j+2)[1] = (uint)in[i+1]; - (out+j+4)[0] = (uint)in[i+1]; - (out+j+4)[1] = (uint)in[i+3]; - (out+j+6)[0] = (uint)in[i+3]; - (out+j+6)[1] = (uint)in[i+2]; - } -} -static void translate_polygon_ubyte2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ubyte*in = (const ubyte*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[0]; - } -} -static void translate_tris_ushort2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=3) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[i]; - } -} -static void translate_tristrip_ushort2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1/*+(i&1)*/]; - (out+j+2)[0] = (ushort)in[i+1/*+(i&1)*/]; - (out+j+2)[1] = (ushort)in[i+2/*-(i&1)*/]; - (out+j+4)[0] = (ushort)in[i+2/*-(i&1)*/]; - (out+j+4)[1] = (ushort)in[i]; - } -} -static void translate_trifan_ushort2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[0]; - } -} -static void translate_quads_ushort2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=4) { - (out+j)[0] = (ushort)in[i+0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[i+3]; - (out+j+6)[0] = (ushort)in[i+3]; - (out+j+6)[1] = (ushort)in[i+0]; - } -} -static void translate_quadstrip_ushort2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=2) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[i+0]; - (out+j+2)[0] = (ushort)in[i+0]; - (out+j+2)[1] = (ushort)in[i+1]; - (out+j+4)[0] = (ushort)in[i+1]; - (out+j+4)[1] = (ushort)in[i+3]; - (out+j+6)[0] = (ushort)in[i+3]; - (out+j+6)[1] = (ushort)in[i+2]; - } -} -static void translate_polygon_ushort2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[0]; - } -} -static void translate_tris_ushort2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=3) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[i]; - } -} -static void translate_tristrip_ushort2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1/*+(i&1)*/]; - (out+j+2)[0] = (uint)in[i+1/*+(i&1)*/]; - (out+j+2)[1] = (uint)in[i+2/*-(i&1)*/]; - (out+j+4)[0] = (uint)in[i+2/*-(i&1)*/]; - (out+j+4)[1] = (uint)in[i]; - } -} -static void translate_trifan_ushort2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[0]; - } -} -static void translate_quads_ushort2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=4) { - (out+j)[0] = (uint)in[i+0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[i+3]; - (out+j+6)[0] = (uint)in[i+3]; - (out+j+6)[1] = (uint)in[i+0]; - } -} -static void translate_quadstrip_ushort2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=2) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[i+0]; - (out+j+2)[0] = (uint)in[i+0]; - (out+j+2)[1] = (uint)in[i+1]; - (out+j+4)[0] = (uint)in[i+1]; - (out+j+4)[1] = (uint)in[i+3]; - (out+j+6)[0] = (uint)in[i+3]; - (out+j+6)[1] = (uint)in[i+2]; - } -} -static void translate_polygon_ushort2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const ushort*in = (const ushort*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[0]; - } -} -static void translate_tris_uint2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=3) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[i]; - } -} -static void translate_tristrip_uint2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[i]; - (out+j)[1] = (ushort)in[i+1/*+(i&1)*/]; - (out+j+2)[0] = (ushort)in[i+1/*+(i&1)*/]; - (out+j+2)[1] = (ushort)in[i+2/*-(i&1)*/]; - (out+j+4)[0] = (ushort)in[i+2/*-(i&1)*/]; - (out+j+4)[1] = (ushort)in[i]; - } -} -static void translate_trifan_uint2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[0]; - } -} -static void translate_quads_uint2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=4) { - (out+j)[0] = (ushort)in[i+0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[i+3]; - (out+j+6)[0] = (ushort)in[i+3]; - (out+j+6)[1] = (ushort)in[i+0]; - } -} -static void translate_quadstrip_uint2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=2) { - (out+j)[0] = (ushort)in[i+2]; - (out+j)[1] = (ushort)in[i+0]; - (out+j+2)[0] = (ushort)in[i+0]; - (out+j+2)[1] = (ushort)in[i+1]; - (out+j+4)[0] = (ushort)in[i+1]; - (out+j+4)[1] = (ushort)in[i+3]; - (out+j+6)[0] = (ushort)in[i+3]; - (out+j+6)[1] = (ushort)in[i+2]; - } -} -static void translate_polygon_uint2ushort( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - ushort *out = (ushort*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (ushort)in[0]; - (out+j)[1] = (ushort)in[i+1]; - (out+j+2)[0] = (ushort)in[i+1]; - (out+j+2)[1] = (ushort)in[i+2]; - (out+j+4)[0] = (ushort)in[i+2]; - (out+j+4)[1] = (ushort)in[0]; - } -} -static void translate_tris_uint2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i+=3) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[i]; - } -} -static void translate_tristrip_uint2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[i]; - (out+j)[1] = (uint)in[i+1/*+(i&1)*/]; - (out+j+2)[0] = (uint)in[i+1/*+(i&1)*/]; - (out+j+2)[1] = (uint)in[i+2/*-(i&1)*/]; - (out+j+4)[0] = (uint)in[i+2/*-(i&1)*/]; - (out+j+4)[1] = (uint)in[i]; - } -} -static void translate_trifan_uint2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[0]; - } -} -static void translate_quads_uint2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=4) { - (out+j)[0] = (uint)in[i+0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[i+3]; - (out+j+6)[0] = (uint)in[i+3]; - (out+j+6)[1] = (uint)in[i+0]; - } -} -static void translate_quadstrip_uint2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=8, i+=2) { - (out+j)[0] = (uint)in[i+2]; - (out+j)[1] = (uint)in[i+0]; - (out+j+2)[0] = (uint)in[i+0]; - (out+j+2)[1] = (uint)in[i+1]; - (out+j+4)[0] = (uint)in[i+1]; - (out+j+4)[1] = (uint)in[i+3]; - (out+j+6)[0] = (uint)in[i+3]; - (out+j+6)[1] = (uint)in[i+2]; - } -} -static void translate_polygon_uint2uint( - const void * _in, - unsigned nr, - void *_out ) -{ - const uint*in = (const uint*)_in; - uint *out = (uint*)_out; - unsigned i, j; - (void)j; - for (j = i = 0; j < nr; j+=6, i++) { - (out+j)[0] = (uint)in[0]; - (out+j)[1] = (uint)in[i+1]; - (out+j+2)[0] = (uint)in[i+1]; - (out+j+2)[1] = (uint)in[i+2]; - (out+j+4)[0] = (uint)in[i+2]; - (out+j+4)[1] = (uint)in[0]; - } -} -void u_unfilled_init( void ) -{ - static int firsttime = 1; - if (!firsttime) return; - firsttime = 0; -generate_line[OUT_USHORT][PIPE_PRIM_TRIANGLES] = generate_tris_ushort; -generate_line[OUT_USHORT][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_ushort; -generate_line[OUT_USHORT][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_ushort; -generate_line[OUT_USHORT][PIPE_PRIM_QUADS] = generate_quads_ushort; -generate_line[OUT_USHORT][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_ushort; -generate_line[OUT_USHORT][PIPE_PRIM_POLYGON] = generate_polygon_ushort; -generate_line[OUT_UINT][PIPE_PRIM_TRIANGLES] = generate_tris_uint; -generate_line[OUT_UINT][PIPE_PRIM_TRIANGLE_FAN] = generate_trifan_uint; -generate_line[OUT_UINT][PIPE_PRIM_TRIANGLE_STRIP] = generate_tristrip_uint; -generate_line[OUT_UINT][PIPE_PRIM_QUADS] = generate_quads_uint; -generate_line[OUT_UINT][PIPE_PRIM_QUAD_STRIP] = generate_quadstrip_uint; -generate_line[OUT_UINT][PIPE_PRIM_POLYGON] = generate_polygon_uint; -translate_line[IN_UBYTE][OUT_USHORT][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2ushort; -translate_line[IN_UBYTE][OUT_USHORT][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2ushort; -translate_line[IN_UBYTE][OUT_USHORT][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2ushort; -translate_line[IN_UBYTE][OUT_USHORT][PIPE_PRIM_QUADS] = translate_quads_ubyte2ushort; -translate_line[IN_UBYTE][OUT_USHORT][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2ushort; -translate_line[IN_UBYTE][OUT_USHORT][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2ushort; -translate_line[IN_UBYTE][OUT_UINT][PIPE_PRIM_TRIANGLES] = translate_tris_ubyte2uint; -translate_line[IN_UBYTE][OUT_UINT][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ubyte2uint; -translate_line[IN_UBYTE][OUT_UINT][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ubyte2uint; -translate_line[IN_UBYTE][OUT_UINT][PIPE_PRIM_QUADS] = translate_quads_ubyte2uint; -translate_line[IN_UBYTE][OUT_UINT][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ubyte2uint; -translate_line[IN_UBYTE][OUT_UINT][PIPE_PRIM_POLYGON] = translate_polygon_ubyte2uint; -translate_line[IN_USHORT][OUT_USHORT][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2ushort; -translate_line[IN_USHORT][OUT_USHORT][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2ushort; -translate_line[IN_USHORT][OUT_USHORT][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2ushort; -translate_line[IN_USHORT][OUT_USHORT][PIPE_PRIM_QUADS] = translate_quads_ushort2ushort; -translate_line[IN_USHORT][OUT_USHORT][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2ushort; -translate_line[IN_USHORT][OUT_USHORT][PIPE_PRIM_POLYGON] = translate_polygon_ushort2ushort; -translate_line[IN_USHORT][OUT_UINT][PIPE_PRIM_TRIANGLES] = translate_tris_ushort2uint; -translate_line[IN_USHORT][OUT_UINT][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_ushort2uint; -translate_line[IN_USHORT][OUT_UINT][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_ushort2uint; -translate_line[IN_USHORT][OUT_UINT][PIPE_PRIM_QUADS] = translate_quads_ushort2uint; -translate_line[IN_USHORT][OUT_UINT][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_ushort2uint; -translate_line[IN_USHORT][OUT_UINT][PIPE_PRIM_POLYGON] = translate_polygon_ushort2uint; -translate_line[IN_UINT][OUT_USHORT][PIPE_PRIM_TRIANGLES] = translate_tris_uint2ushort; -translate_line[IN_UINT][OUT_USHORT][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2ushort; -translate_line[IN_UINT][OUT_USHORT][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2ushort; -translate_line[IN_UINT][OUT_USHORT][PIPE_PRIM_QUADS] = translate_quads_uint2ushort; -translate_line[IN_UINT][OUT_USHORT][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2ushort; -translate_line[IN_UINT][OUT_USHORT][PIPE_PRIM_POLYGON] = translate_polygon_uint2ushort; -translate_line[IN_UINT][OUT_UINT][PIPE_PRIM_TRIANGLES] = translate_tris_uint2uint; -translate_line[IN_UINT][OUT_UINT][PIPE_PRIM_TRIANGLE_FAN] = translate_trifan_uint2uint; -translate_line[IN_UINT][OUT_UINT][PIPE_PRIM_TRIANGLE_STRIP] = translate_tristrip_uint2uint; -translate_line[IN_UINT][OUT_UINT][PIPE_PRIM_QUADS] = translate_quads_uint2uint; -translate_line[IN_UINT][OUT_UINT][PIPE_PRIM_QUAD_STRIP] = translate_quadstrip_uint2uint; -translate_line[IN_UINT][OUT_UINT][PIPE_PRIM_POLYGON] = translate_polygon_uint2uint; -} -#include "indices/u_unfilled_indices.c" diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h index c09e8a7a76f..0238308d20b 100644 --- a/src/gallium/auxiliary/os/os_thread.h +++ b/src/gallium/auxiliary/os/os_thread.h @@ -40,7 +40,7 @@ #include "util/u_debug.h" /* for assert */ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) #include <pthread.h> /* POSIX threads headers */ #include <stdio.h> /* for perror() */ @@ -405,7 +405,7 @@ pipe_semaphore_wait(pipe_semaphore *sema) */ typedef struct { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) pthread_key_t key; #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) DWORD key; @@ -420,7 +420,7 @@ typedef struct { static INLINE void pipe_tsd_init(pipe_tsd *tsd) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { perror("pthread_key_create(): failed to allocate key for thread specific data"); exit(-1); @@ -437,7 +437,7 @@ pipe_tsd_get(pipe_tsd *tsd) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) return pthread_getspecific(tsd->key); #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) assert(0); @@ -454,7 +454,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) if (pthread_setspecific(tsd->key, value) != 0) { perror("pthread_set_specific() failed"); exit(-1); diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c index 6259142bec0..84907215fe6 100644 --- a/src/gallium/auxiliary/os/os_time.c +++ b/src/gallium/auxiliary/os/os_time.c @@ -37,7 +37,7 @@ #if !defined(PIPE_OS_EMBEDDED) -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) # include <sys/time.h> /* timeval */ #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) # include <windows.h> diff --git a/src/gallium/auxiliary/rbug/README b/src/gallium/auxiliary/rbug/README index d984067893c..c5156438a1b 100644 --- a/src/gallium/auxiliary/rbug/README +++ b/src/gallium/auxiliary/rbug/README @@ -10,7 +10,7 @@ The code currently uses tcp and ip4v for connections. Information about driver integration can be found in: -src/gallium/drivers/trace/README +src/gallium/drivers/rbug/README for information about applications look in: diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 7595214bdf2..9f70b73698a 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -1743,20 +1743,35 @@ void x86_release_func( struct x86_function *p ) } -void (*x86_get_func( struct x86_function *p ))(void) +static INLINE x86_func +voidptr_to_x86_func(void *v) +{ + union { + void *v; + x86_func f; + } u; + assert(sizeof(u.v) == sizeof(u.f)); + u.v = v; + return u.f; +} + + +x86_func x86_get_func( struct x86_function *p ) { DUMP_END(); if (DISASSEM && p->store) debug_printf("disassemble %p %p\n", p->store, p->csr); if (p->store == p->error_overflow) - return (void (*)(void)) NULL; + return voidptr_to_x86_func(NULL); else - return (void (*)(void)) p->store; + return voidptr_to_x86_func(p->store); } #else +void x86sse_dummy( void ); + void x86sse_dummy( void ) { } diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 319b836ffb1..6208e8f707f 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -102,6 +102,11 @@ enum sse_cc { #define cc_Z cc_E #define cc_NZ cc_NE + +/** generic pointer to function */ +typedef void (*x86_func)(void); + + /* Begin/end/retrieve function creation: */ @@ -109,7 +114,7 @@ enum sse_cc { void x86_init_func( struct x86_function *p ); void x86_init_func_size( struct x86_function *p, unsigned code_size ); void x86_release_func( struct x86_function *p ); -void (*x86_get_func( struct x86_function *p ))( void ); +x86_func x86_get_func( struct x86_function *p ); /* Debugging: */ diff --git a/src/gallium/auxiliary/target-helpers/wrap_screen.c b/src/gallium/auxiliary/target-helpers/wrap_screen.c index eb475123198..df5d56a53c9 100644 --- a/src/gallium/auxiliary/target-helpers/wrap_screen.c +++ b/src/gallium/auxiliary/target-helpers/wrap_screen.c @@ -33,6 +33,7 @@ #include "target-helpers/wrap_screen.h" #include "trace/tr_public.h" +#include "rbug/rbug_public.h" #include "identity/id_public.h" #include "util/u_debug.h" @@ -56,6 +57,9 @@ gallium_wrap_screen( struct pipe_screen *screen ) /* Trace does its own checking if it should run */ screen = trace_screen_create(screen); + /* Rbug does its own checking if it should run */ + screen = rbug_screen_create(screen); + return screen; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 1ad183b8dd4..35480076edf 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -56,7 +56,7 @@ dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) va_list ap; (void)ctx; va_start(ap, format); - debug_vprintf(format, ap); + _debug_vprintf(format, ap); va_end(ap); } diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 9b1ca7fa851..c15d970b573 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -621,12 +621,10 @@ tgsi_exec_machine_bind_shader( { uint k; struct tgsi_parse_context parse; - struct tgsi_exec_labels *labels = &mach->Labels; struct tgsi_full_instruction *instructions; struct tgsi_full_declaration *declarations; uint maxInstructions = 10, numInstructions = 0; uint maxDeclarations = 10, numDeclarations = 0; - uint instno = 0; #if 0 tgsi_dump(tokens, 0); @@ -637,6 +635,23 @@ tgsi_exec_machine_bind_shader( mach->Tokens = tokens; mach->Samplers = samplers; + if (!tokens) { + /* unbind and free all */ + if (mach->Declarations) { + FREE( mach->Declarations ); + } + mach->Declarations = NULL; + mach->NumDeclarations = 0; + + if (mach->Instructions) { + FREE( mach->Instructions ); + } + mach->Instructions = NULL; + mach->NumInstructions = 0; + + return; + } + k = tgsi_parse_init (&parse, mach->Tokens); if (k != TGSI_PARSE_OK) { debug_printf( "Problem parsing!\n" ); @@ -645,7 +660,6 @@ tgsi_exec_machine_bind_shader( mach->Processor = parse.FullHeader.Processor.Processor; mach->ImmLimit = 0; - labels->count = 0; declarations = (struct tgsi_full_declaration *) MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) ); @@ -663,7 +677,6 @@ tgsi_exec_machine_bind_shader( } while( !tgsi_parse_end_of_tokens( &parse ) ) { - uint pointer = parse.Position; uint i; tgsi_parse_token( &parse ); @@ -707,11 +720,6 @@ tgsi_exec_machine_bind_shader( break; case TGSI_TOKEN_TYPE_INSTRUCTION: - assert( labels->count < MAX_LABELS ); - - labels->labels[labels->count][0] = instno; - labels->labels[labels->count][1] = pointer; - labels->count++; /* save expanded instruction */ if (numInstructions == maxInstructions) { @@ -801,7 +809,9 @@ void tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach) { if (mach) { - FREE(mach->Instructions); + if (mach->Instructions) + FREE(mach->Instructions); + if (mach->Declarations) FREE(mach->Declarations); } @@ -3126,7 +3136,7 @@ exec_instruction( break; case TGSI_OPCODE_DIV: - assert( 0 ); + exec_vector_binary(mach, inst, micro_div, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT); break; case TGSI_OPCODE_DP2: diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 11bbaf6722e..3caf820af67 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -37,8 +37,6 @@ extern "C" { #endif -#define MAX_LABELS (4 * 1024) /**< basically, max instructions */ - #define NUM_CHANNELS 4 /* R,G,B,A */ #define QUAD_SIZE 4 /* 4 pixel/quad */ @@ -93,16 +91,6 @@ struct tgsi_sampler float rgba[NUM_CHANNELS][QUAD_SIZE]); }; -/** - * For branching/calling subroutines. - */ -struct tgsi_exec_labels -{ - unsigned labels[MAX_LABELS][2]; - unsigned count; -}; - - #define TGSI_EXEC_NUM_TEMPS 128 #define TGSI_EXEC_NUM_IMMEDIATES 256 @@ -186,10 +174,11 @@ struct tgsi_exec_labels -#define TGSI_EXEC_MAX_COND_NESTING 32 -#define TGSI_EXEC_MAX_LOOP_NESTING 32 -#define TGSI_EXEC_MAX_SWITCH_NESTING 32 -#define TGSI_EXEC_MAX_CALL_NESTING 32 +#define TGSI_EXEC_MAX_NESTING 32 +#define TGSI_EXEC_MAX_COND_NESTING TGSI_EXEC_MAX_NESTING +#define TGSI_EXEC_MAX_LOOP_NESTING TGSI_EXEC_MAX_NESTING +#define TGSI_EXEC_MAX_SWITCH_NESTING TGSI_EXEC_MAX_NESTING +#define TGSI_EXEC_MAX_CALL_NESTING TGSI_EXEC_MAX_NESTING /* The maximum number of input attributes per vertex. For 2D * input register files, this is the stride between two 1D @@ -324,7 +313,6 @@ struct tgsi_exec_machine struct tgsi_full_declaration *Declarations; uint NumDeclarations; - struct tgsi_exec_labels Labels; }; struct tgsi_exec_machine * diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c index cfa2f631bd8..e59e964ffa7 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.c +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -205,3 +205,18 @@ tgsi_get_opcode_name( uint opcode ) return info->mnemonic; } + +const char * +tgsi_get_processor_name( uint processor ) +{ + switch (processor) { + case TGSI_PROCESSOR_VERTEX: + return "vertex shader"; + case TGSI_PROCESSOR_FRAGMENT: + return "fragment shader"; + case TGSI_PROCESSOR_GEOMETRY: + return "geometry shader"; + default: + return "unknown shader type!"; + } +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.h b/src/gallium/auxiliary/tgsi/tgsi_info.h index 74713c3b98a..50248884fd0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.h +++ b/src/gallium/auxiliary/tgsi/tgsi_info.h @@ -52,6 +52,9 @@ tgsi_get_opcode_info( uint opcode ); const char * tgsi_get_opcode_name( uint opcode ); +const char * +tgsi_get_processor_name( uint processor ); + #if defined __cplusplus } diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c index ad553c71a57..3521847b619 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c @@ -1366,4 +1366,12 @@ tgsi_emit_ppc(const struct tgsi_token *tokens, return ok; } +#else + +void ppc_dummy_func(void); + +void ppc_dummy_func(void) +{ +} + #endif /* PIPE_ARCH_PPC */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c index 232fc537c1d..e0c5d3d3d61 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -88,10 +88,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST); info->opcode_count[fullinst->Instruction.Opcode]++; - /* special case: scan fragment shaders for use of the fog - * input/attribute. The X component is fog, the Y component - * is the front/back-face flag. - */ + /* check if we read the frag shader FOG or FACE inputs */ if (procType == TGSI_PROCESSOR_FRAGMENT) { uint i; for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) { @@ -109,6 +106,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, } } } + + info->num_instructions++; } break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h index 741aa7d5c42..27de33f7990 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h @@ -54,6 +54,7 @@ struct tgsi_shader_info int file_max[TGSI_FILE_COUNT]; /**< highest index of declared registers */ uint immediate_count; /**< number of immediates declared */ + uint num_instructions; uint opcode_count[TGSI_OPCODE_LAST]; /**< opcode histogram */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 1071298b497..d5061f8b511 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -1929,20 +1929,32 @@ emit_instruction( break; case TGSI_OPCODE_MUL: + /* do all fetches and adds, storing results in temp regs */ FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_mul( func, 0, 1 ); - STORE( func, *inst, 0, 0, chan_index ); + int r = chan_index + 1; + FETCH( func, *inst, 0, 0, chan_index ); /* load xmm[0] */ + FETCH( func, *inst, r, 1, chan_index ); /* load xmm[r] */ + emit_mul( func, r, 0 ); /* xmm[r] = xmm[r] * xmm[0] */ + } + /* do all stores of the temp regs */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + int r = chan_index + 1; + STORE( func, *inst, r, 0, chan_index ); /* store xmm[r] */ } break; case TGSI_OPCODE_ADD: + /* do all fetches and adds, storing results in temp regs */ FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_add( func, 0, 1 ); - STORE( func, *inst, 0, 0, chan_index ); + int r = chan_index + 1; + FETCH( func, *inst, 0, 0, chan_index ); /* load xmm[0] */ + FETCH( func, *inst, r, 1, chan_index ); /* load xmm[r] */ + emit_add( func, r, 0 ); /* xmm[r] = xmm[r] + xmm[0] */ + } + /* do all stores of the temp regs */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + int r = chan_index + 1; + STORE( func, *inst, r, 0, chan_index ); /* store xmm[r] */ } break; @@ -2816,6 +2828,40 @@ static void soa_to_aos( struct x86_function *func, x86_pop( func, x86_make_reg( file_REG32, reg_BX ) ); } + +/** + * Check if the instructions dst register is the same as any src + * register and warn if there's a posible SOA dependency. + */ +static void +check_soa_dependencies(const struct tgsi_full_instruction *inst) +{ + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ADD: + case TGSI_OPCODE_MOV: + case TGSI_OPCODE_MUL: + case TGSI_OPCODE_XPD: + /* OK - these opcodes correctly handle SOA dependencies */ + break; + default: + if (tgsi_check_soa_dependencies(inst)) { + uint opcode = inst->Instruction.Opcode; + + /* XXX: we only handle src/dst aliasing in a few opcodes + * currently. Need to use an additional temporay to hold + * the result in the cases where the code is too opaque to + * fix. + */ + if (opcode != TGSI_OPCODE_MOV) { + debug_printf("Warning: src/dst aliasing in instruction" + " is not handled:\n"); + tgsi_dump_instruction(inst, 1); + } + } + } +} + + /** * Translate a TGSI vertex/fragment shader to SSE2 code. * Slightly different things are done for vertex vs. fragment shaders. @@ -2905,27 +2951,14 @@ tgsi_emit_sse2( if (!ok) { uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode; + uint proc = parse.FullHeader.Processor.Processor; debug_printf("failed to translate tgsi opcode %d (%s) to SSE (%s)\n", opcode, tgsi_get_opcode_name(opcode), - parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ? - "vertex shader" : "fragment shader"); + tgsi_get_processor_name(proc)); } - if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) { - uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode; - - /* XXX: we only handle src/dst aliasing in a few opcodes - * currently. Need to use an additional temporay to hold - * the result in the cases where the code is too opaque to - * fix. - */ - if (opcode != TGSI_OPCODE_MOV) { - debug_printf("Warning: src/dst aliasing in instruction" - " is not handled:\n"); - tgsi_dump_instruction(&parse.FullToken.FullInstruction, 1); - } - } + check_soa_dependencies(&parse.FullToken.FullInstruction); break; case TGSI_TOKEN_TYPE_IMMEDIATE: diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index 49b854b1234..5fda808dbef 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -1467,6 +1467,12 @@ const struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg, } +void ureg_free_tokens( const struct tgsi_token *tokens ) +{ + FREE((struct tgsi_token *)tokens); +} + + struct ureg_program *ureg_create( unsigned processor ) { struct ureg_program *ureg = CALLOC_STRUCT( ureg_program ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index f32420dd872..055545f3d2a 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -104,6 +104,10 @@ ureg_get_tokens( struct ureg_program *ureg, unsigned *nr_tokens ); +/* Free the tokens created by ureg_get_tokens() */ +void ureg_free_tokens( const struct tgsi_token *tokens ); + + void ureg_destroy( struct ureg_program * ); diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 9df5f9a9d26..d4fbd658f40 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -48,7 +48,6 @@ #include "util/u_sampler.h" #include "util/u_simple_shaders.h" #include "util/u_surface.h" -#include "util/u_rect.h" #include "cso_cache/cso_context.h" @@ -102,8 +101,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) /* rasterizer */ memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); - ctx->rasterizer.front_winding = PIPE_WINDING_CW; - ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; + ctx->rasterizer.cull_face = PIPE_FACE_NONE; ctx->rasterizer.gl_rasterization_rules = 1; /* samplers */ diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index d603c7ac06d..e0bd89154cb 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -44,7 +44,6 @@ #include "util/u_blitter.h" #include "util/u_draw_quad.h" #include "util/u_pack_color.h" -#include "util/u_rect.h" #include "util/u_sampler.h" #include "util/u_simple_shaders.h" #include "util/u_surface.h" @@ -70,8 +69,8 @@ struct blitter_context_priv void *vs_tex; /**< Vertex shader which passes {pos, texcoord} to the output.*/ /* Fragment shaders. */ - /* FS which outputs a color to multiple color buffers. */ - void *fs_col[PIPE_MAX_COLOR_BUFS]; + /* The shader at index i outputs color to color buffers 0,1,...,i-1. */ + void *fs_col[PIPE_MAX_COLOR_BUFS+1]; /* FS which outputs a color from a texture, where the index is PIPE_TEXTURE_* to be sampled. */ @@ -176,8 +175,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) /* rasterizer state */ memset(&rs_state, 0, sizeof(rs_state)); - rs_state.front_winding = PIPE_WINDING_CW; - rs_state.cull_mode = PIPE_WINDING_NONE; + rs_state.cull_face = PIPE_FACE_NONE; rs_state.gl_rasterization_rules = 1; rs_state.flatshade = 1; ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); @@ -249,7 +247,7 @@ void util_blitter_destroy(struct blitter_context *blitter) pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]); } - for (i = 0; i < PIPE_MAX_COLOR_BUFS && ctx->fs_col[i]; i++) + for (i = 0; i <= PIPE_MAX_COLOR_BUFS && ctx->fs_col[i]; i++) if (ctx->fs_col[i]) pipe->delete_fs_state(pipe, ctx->fs_col[i]); @@ -496,15 +494,14 @@ static INLINE void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs) { struct pipe_context *pipe = ctx->pipe; - unsigned index = num_cbufs ? num_cbufs - 1 : 0; assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); - if (!ctx->fs_col[index]) - ctx->fs_col[index] = + if (!ctx->fs_col[num_cbufs]) + ctx->fs_col[num_cbufs] = util_make_fragment_clonecolor_shader(pipe, num_cbufs); - return ctx->fs_col[index]; + return ctx->fs_col[num_cbufs]; } static INLINE diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 0de38e791d6..86db2c2e4b4 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -123,8 +123,12 @@ debug_get_bool_option(const char *name, boolean dfault) result = FALSE; else if(!util_strcmp(str, "f")) result = FALSE; + else if(!util_strcmp(str, "F")) + result = FALSE; else if(!util_strcmp(str, "false")) result = FALSE; + else if(!util_strcmp(str, "FALSE")) + result = FALSE; else result = TRUE; diff --git a/src/gallium/auxiliary/util/u_debug_symbol.c b/src/gallium/auxiliary/util/u_debug_symbol.c index 417d0cf04c9..6e250575d66 100644 --- a/src/gallium/auxiliary/util/u_debug_symbol.c +++ b/src/gallium/auxiliary/util/u_debug_symbol.c @@ -67,21 +67,6 @@ BOOL WINAPI j_SymInitialize(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadePr return FALSE; } -typedef BOOL (WINAPI *PFNSYMCLEANUP)(HANDLE); -static PFNSYMCLEANUP pfnSymCleanup = NULL; - -static -BOOL WINAPI j_SymCleanup(HANDLE hProcess) -{ - if( - (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && - (pfnSymCleanup || (pfnSymCleanup = (PFNSYMCLEANUP) GetProcAddress(hModule_Imagehlp, "SymCleanup"))) - ) - return pfnSymCleanup(hProcess); - else - return FALSE; -} - typedef DWORD (WINAPI *PFNSYMSETOPTIONS)(DWORD); static PFNSYMSETOPTIONS pfnSymSetOptions = NULL; @@ -97,36 +82,6 @@ DWORD WINAPI j_SymSetOptions(DWORD SymOptions) return FALSE; } -typedef BOOL (WINAPI *PFNSYMUNDNAME)(PIMAGEHLP_SYMBOL, PSTR, DWORD); -static PFNSYMUNDNAME pfnSymUnDName = NULL; - -static -BOOL WINAPI j_SymUnDName(PIMAGEHLP_SYMBOL Symbol, PSTR UnDecName, DWORD UnDecNameLength) -{ - if( - (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && - (pfnSymUnDName || (pfnSymUnDName = (PFNSYMUNDNAME) GetProcAddress(hModule_Imagehlp, "SymUnDName"))) - ) - return pfnSymUnDName(Symbol, UnDecName, UnDecNameLength); - else - return FALSE; -} - -typedef PFUNCTION_TABLE_ACCESS_ROUTINE PFNSYMFUNCTIONTABLEACCESS; -static PFNSYMFUNCTIONTABLEACCESS pfnSymFunctionTableAccess = NULL; - -static -PVOID WINAPI j_SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase) -{ - if( - (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && - (pfnSymFunctionTableAccess || (pfnSymFunctionTableAccess = (PFNSYMFUNCTIONTABLEACCESS) GetProcAddress(hModule_Imagehlp, "SymFunctionTableAccess"))) - ) - return pfnSymFunctionTableAccess(hProcess, AddrBase); - else - return NULL; -} - typedef PGET_MODULE_BASE_ROUTINE PFNSYMGETMODULEBASE; static PFNSYMGETMODULEBASE pfnSymGetModuleBase = NULL; @@ -142,41 +97,6 @@ DWORD WINAPI j_SymGetModuleBase(HANDLE hProcess, DWORD dwAddr) return 0; } -typedef BOOL (WINAPI *PFNSTACKWALK)(DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE); -static PFNSTACKWALK pfnStackWalk = NULL; - -static -BOOL WINAPI j_StackWalk( - DWORD MachineType, - HANDLE hProcess, - HANDLE hThread, - LPSTACKFRAME StackFrame, - PVOID ContextRecord, - PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, - PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, - PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, - PTRANSLATE_ADDRESS_ROUTINE TranslateAddress -) -{ - if( - (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && - (pfnStackWalk || (pfnStackWalk = (PFNSTACKWALK) GetProcAddress(hModule_Imagehlp, "StackWalk"))) - ) - return pfnStackWalk( - MachineType, - hProcess, - hThread, - StackFrame, - ContextRecord, - ReadMemoryRoutine, - FunctionTableAccessRoutine, - GetModuleBaseRoutine, - TranslateAddress - ); - else - return FALSE; -} - typedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_SYMBOL); static PFNSYMGETSYMFROMADDR pfnSymGetSymFromAddr = NULL; @@ -192,21 +112,6 @@ BOOL WINAPI j_SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacem return FALSE; } -typedef BOOL (WINAPI *PFNSYMGETLINEFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_LINE); -static PFNSYMGETLINEFROMADDR pfnSymGetLineFromAddr = NULL; - -static -BOOL WINAPI j_SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE Line) -{ - if( - (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && - (pfnSymGetLineFromAddr || (pfnSymGetLineFromAddr = (PFNSYMGETLINEFROMADDR) GetProcAddress(hModule_Imagehlp, "SymGetLineFromAddr"))) - ) - return pfnSymGetLineFromAddr(hProcess, dwAddr, pdwDisplacement, Line); - else - return FALSE; -} - static INLINE boolean debug_symbol_print_imagehlp(const void *addr) diff --git a/src/gallium/auxiliary/util/u_dump.h b/src/gallium/auxiliary/util/u_dump.h index bdc73ac47d2..49536c0d593 100644 --- a/src/gallium/auxiliary/util/u_dump.h +++ b/src/gallium/auxiliary/util/u_dump.h @@ -71,9 +71,15 @@ const char * util_dump_blend_func(unsigned value, boolean shortened); const char * +util_dump_logicop(unsigned value, boolean shortened); + +const char * util_dump_func(unsigned value, boolean shortened); const char * +util_dump_stencil_op(unsigned value, boolean shortened); + +const char * util_dump_tex_target(unsigned value, boolean shortened); const char * diff --git a/src/gallium/auxiliary/util/u_dump_defines.c b/src/gallium/auxiliary/util/u_dump_defines.c index 96a22563473..692d4447c66 100644 --- a/src/gallium/auxiliary/util/u_dump_defines.c +++ b/src/gallium/auxiliary/util/u_dump_defines.c @@ -160,6 +160,49 @@ DEFINE_UTIL_DUMP_CONTINUOUS(blend_func) static const char * +util_dump_logicop_names[] = { + "PIPE_LOGICOP_CLEAR", + "PIPE_LOGICOP_NOR", + "PIPE_LOGICOP_AND_INVERTED", + "PIPE_LOGICOP_COPY_INVERTED", + "PIPE_LOGICOP_AND_REVERSE", + "PIPE_LOGICOP_INVERT", + "PIPE_LOGICOP_XOR", + "PIPE_LOGICOP_NAND", + "PIPE_LOGICOP_AND", + "PIPE_LOGICOP_EQUIV", + "PIPE_LOGICOP_NOOP", + "PIPE_LOGICOP_OR_INVERTED", + "PIPE_LOGICOP_COPY", + "PIPE_LOGICOP_OR_REVERSE", + "PIPE_LOGICOP_OR", + "PIPE_LOGICOP_SET" +}; + +static const char * +util_dump_logicop_short_names[] = { + "clear", + "nor", + "and_inverted", + "copy_inverted", + "and_reverse", + "invert", + "xor", + "nand", + "and", + "equiv", + "noop", + "or_inverted", + "copy", + "or_reverse", + "or", + "set" +}; + +DEFINE_UTIL_DUMP_CONTINUOUS(logicop) + + +static const char * util_dump_func_names[] = { "PIPE_FUNC_NEVER", "PIPE_FUNC_LESS", @@ -187,7 +230,35 @@ DEFINE_UTIL_DUMP_CONTINUOUS(func) static const char * +util_dump_stencil_op_names[] = { + "PIPE_STENCIL_OP_KEEP", + "PIPE_STENCIL_OP_ZERO", + "PIPE_STENCIL_OP_REPLACE", + "PIPE_STENCIL_OP_INCR", + "PIPE_STENCIL_OP_DECR", + "PIPE_STENCIL_OP_INCR_WRAP", + "PIPE_STENCIL_OP_DECR_WRAP", + "PIPE_STENCIL_OP_INVERT" +}; + +static const char * +util_dump_stencil_op_short_names[] = { + "keep", + "zero", + "replace", + "incr", + "decr", + "incr_wrap", + "decr_wrap", + "invert" +}; + +DEFINE_UTIL_DUMP_CONTINUOUS(stencil_op) + + +static const char * util_dump_tex_target_names[] = { + "PIPE_BUFFER", "PIPE_TEXTURE_1D", "PIPE_TEXTURE_2D", "PIPE_TEXTURE_3D", @@ -196,6 +267,7 @@ util_dump_tex_target_names[] = { static const char * util_dump_tex_target_short_names[] = { + "buffer", "1d", "2d", "3d", diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c index 2ce643e90cd..cda5b8ba512 100644 --- a/src/gallium/auxiliary/util/u_dump_state.c +++ b/src/gallium/auxiliary/util/u_dump_state.c @@ -300,12 +300,13 @@ util_dump_rasterizer_state(struct os_stream *stream, const struct pipe_rasterize util_dump_member(stream, bool, state, flatshade); util_dump_member(stream, bool, state, light_twoside); - util_dump_member(stream, uint, state, front_winding); - util_dump_member(stream, uint, state, cull_mode); - util_dump_member(stream, uint, state, fill_cw); - util_dump_member(stream, uint, state, fill_ccw); - util_dump_member(stream, bool, state, offset_cw); - util_dump_member(stream, bool, state, offset_ccw); + util_dump_member(stream, uint, state, front_ccw); + util_dump_member(stream, uint, state, cull_face); + util_dump_member(stream, uint, state, fill_front); + util_dump_member(stream, uint, state, fill_back); + util_dump_member(stream, bool, state, offset_point); + util_dump_member(stream, bool, state, offset_line); + util_dump_member(stream, bool, state, offset_tri); util_dump_member(stream, bool, state, scissor); util_dump_member(stream, bool, state, poly_smooth); util_dump_member(stream, bool, state, poly_stipple_enable); diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index 8ba076949b6..fd95bea1a7b 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -367,6 +367,26 @@ util_format_is_plain(enum pipe_format format) } static INLINE boolean +util_format_is_compressed(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return FALSE; + } + + switch (desc->layout) { + case UTIL_FORMAT_LAYOUT_S3TC: + case UTIL_FORMAT_LAYOUT_RGTC: + /* XXX add other formats in the future */ + return TRUE; + default: + return FALSE; + } +} + +static INLINE boolean util_format_is_s3tc(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py index 0c1bbc84c17..6d0016c0ad8 100644 --- a/src/gallium/auxiliary/util/u_format_pack.py +++ b/src/gallium/auxiliary/util/u_format_pack.py @@ -37,9 +37,6 @@ ''' -import sys -import math - from u_format_parse import * diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py index 7076c676aaf..ddb9f2443d9 100755 --- a/src/gallium/auxiliary/util/u_format_parse.py +++ b/src/gallium/auxiliary/util/u_format_parse.py @@ -43,7 +43,7 @@ ZS = 'zs' def is_pot(x): - return (x & (x - 1)) == 0; + return (x & (x - 1)) == 0 VERY_LARGE = 99999999999999999999999 diff --git a/src/gallium/auxiliary/util/u_format_srgb.py b/src/gallium/auxiliary/util/u_format_srgb.py index a4c76dc00b3..3e8000f3687 100644 --- a/src/gallium/auxiliary/util/u_format_srgb.py +++ b/src/gallium/auxiliary/util/u_format_srgb.py @@ -39,7 +39,6 @@ ''' -import sys import math diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 48ee0427261..d19267be72f 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1295,8 +1295,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, /* rasterizer */ memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); - ctx->rasterizer.front_winding = PIPE_WINDING_CW; - ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; + ctx->rasterizer.cull_face = PIPE_FACE_NONE; ctx->rasterizer.gl_rasterization_rules = 1; /* sampler state */ diff --git a/src/gallium/auxiliary/util/u_half.py b/src/gallium/auxiliary/util/u_half.py index 8007482e971..915cf3b9273 100644 --- a/src/gallium/auxiliary/util/u_half.py +++ b/src/gallium/auxiliary/util/u_half.py @@ -83,11 +83,11 @@ for i in xrange(1, 1024): # normalize number while (m & 0x00800000) == 0: - e -= 0x00800000; - m <<= 1; + e -= 0x00800000 + m <<= 1 - m &= ~0x00800000; - e += 0x38800000; + m &= ~0x00800000 + e += 0x38800000 value(m | e) # normals diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index a48689ee8be..540305c1465 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -369,6 +369,24 @@ pipe_transfer_destroy( struct pipe_context *context, } +static INLINE boolean util_get_offset( + const struct pipe_rasterizer_state *templ, + unsigned fill_mode) +{ + switch(fill_mode) { + case PIPE_POLYGON_MODE_POINT: + return templ->offset_point; + case PIPE_POLYGON_MODE_LINE: + return templ->offset_line; + case PIPE_POLYGON_MODE_FILL: + return templ->offset_tri; + default: + assert(0); + return FALSE; + } +} + + #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 6f49a723557..9adf22c471e 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -38,7 +38,6 @@ #include "util/u_format.h" #include "util/u_inlines.h" -#include "util/u_memory.h" #include "util/u_rect.h" #include "util/u_surface.h" diff --git a/src/gallium/auxiliary/util/u_surfaces.c b/src/gallium/auxiliary/util/u_surfaces.c index 668da8c5c27..b5d21570d57 100644 --- a/src/gallium/auxiliary/util/u_surfaces.c +++ b/src/gallium/auxiliary/util/u_surfaces.c @@ -28,7 +28,7 @@ util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, str { /* or 2D array */ if(!us->u.table) us->u.table = util_hash_table_create(hash, compare); - key = (void *)(((zslice + face) << 8) | level); + key = (void *)(uintptr_t)(((zslice + face) << 8) | level); /* TODO: ouch, should have a get-reference function... * also, shouldn't allocate a two-pointer structure for each item... */ ps = util_hash_table_get(us->u.table, key); diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c index bedace3b1dc..69f6fab9504 100644 --- a/src/gallium/auxiliary/util/u_transfer.c +++ b/src/gallium/auxiliary/util/u_transfer.c @@ -35,12 +35,12 @@ void u_default_transfer_inline_write( struct pipe_context *pipe, util_copy_rect(map, resource->format, - transfer->stride, /* bytes? */ + transfer->stride, /* bytes */ 0, 0, box->width, box->height, data, - box->width, /* bytes? texels? */ + stride, /* bytes */ 0, 0); out: diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index ac3c3c7bdbd..89c02b1b703 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -201,9 +201,16 @@ returned). Otherwise, if the ``wait`` parameter is FALSE, the call will not block and the return value will be TRUE if the query has completed or FALSE otherwise. -A common type of query is the occlusion query which counts the number of -fragments/pixels which are written to the framebuffer (and not culled by -Z/stencil/alpha testing or shader KILL instructions). +The most common type of query is the occlusion query, +``PIPE_QUERY_OCCLUSION_COUNTER``, which counts the number of fragments which +are written to the framebuffer without being culled by +:ref:`Depth, Stencil, & Alpha` testing or shader KILL instructions. + +Another type of query, ``PIPE_QUERY_TIME_ELAPSED``, returns the amount of +time, in nanoseconds, the context takes to perform operations. + +Gallium does not guarantee the availability of any query types; one must +always check the capabilities of the :ref:`Screen` first. Conditional Rendering @@ -289,11 +296,6 @@ data to be written to the resource at this point. The returned map points to the start of the mapped range according to the box region, not the beginning of the resource. -.. _transfer_flush_region: -``transfer_flush_region`` If a transfer was created with TRANFER_FLUSH_EXPLICIT, -only the region specified is guaranteed to be written to. This is relative to -the mapped range, not the beginning of the resource. - ``transfer_unmap`` remove the memory mapping for the transfer object. Any pointers into the map should be considered invalid and discarded. @@ -301,6 +303,16 @@ Any pointers into the map should be considered invalid and discarded. Basically get_transfer, transfer_map, data write, transfer_unmap, and transfer_destroy all in one. +.. _transfer_flush_region: + +transfer_flush_region +%%%%%%%%%%%%%%%%%%%%% + +If a transfer was created with ``FLUSH_EXPLICIT``, it will not automatically +be flushed on write or unmap. Flushes must be requested with +``transfer_flush_region``. Flush ranges are relative to the mapped range, not +the beginning of the resource. + .. _pipe_transfer: PIPE_TRANSFER @@ -320,5 +332,4 @@ These flags control the behavior of a transfer object. operations pending on the resource are undefined. Cannot be used with ``READ``. * ``FLUSH_EXPLICIT``: Written ranges will be notified later with - :ref:`transfer_flush_region`. Cannot be used with - ``READ``. + :ref:`transfer_flush_region`. Cannot be used with ``READ``. diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst index 56a601a8d06..ad1612f93e3 100644 --- a/src/gallium/docs/source/cso/rasterizer.rst +++ b/src/gallium/docs/source/cso/rasterizer.rst @@ -46,6 +46,78 @@ There are several important exceptions to the specification of this rule. second vertex, not the first. This permits each segment of the fan to have a different color. +Polygons +-------- + +light_twoside +^^^^^^^^^^^^^ + +If set, there are per-vertex back-facing colors. The hardware +(perhaps assisted by :ref:`Draw`) should be set up to use this state +along with the front/back information to set the final vertex colors +prior to rasterization. + +The frontface vertex shader color output is marked with TGSI semantic +COLOR[0], and backface COLOR[1]. + +front_ccw + Indicates whether the window order of front-facing polygons is + counter-clockwise (TRUE) or clockwise (FALSE). + +cull_mode + Indicates which faces of polygons to cull, either PIPE_FACE_NONE + (cull no polygons), PIPE_FACE_FRONT (cull front-facing polygons), + PIPE_FACE_BACK (cull back-facing polygons), or + PIPE_FACE_FRONT_AND_BACK (cull all polygons). + +fill_front + Indicates how to fill front-facing polygons, either + PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or + PIPE_POLYGON_MODE_POINT. +fill_back + Indicates how to fill back-facing polygons, either + PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or + PIPE_POLYGON_MODE_POINT. + +poly_stipple_enable + Whether polygon stippling is enabled. +poly_smooth + Controls OpenGL-style polygon smoothing/antialiasing + +offset_point + If set, point-filled polygons will have polygon offset factors applied +offset_line + If set, line-filled polygons will have polygon offset factors applied +offset_tri + If set, filled polygons will have polygon offset factors applied + +offset_units + Specifies the polygon offset bias +offset_scale + Specifies the polygon offset scale + + + +Lines +----- + +line_width + The width of lines. +line_smooth + Whether lines should be smoothed. Line smoothing is simply anti-aliasing. +line_stipple_enable + Whether line stippling is enabled. +line_stipple_pattern + 16-bit bitfield of on/off flags, used to pattern the line stipple. +line_stipple_factor + When drawing a stippled line, each bit in the stipple pattern is + repeated N times, where N = line_stipple_factor + 1. +line_last_pixel + Controls whether the last pixel in a line is drawn or not. OpenGL + omits the last pixel to avoid double-drawing pixels at the ends of lines + when drawing connected lines. + + Points ------ @@ -89,68 +161,21 @@ coordinates are not generated. Some renderers always internally translate points into quads; this state still affects those renderers by overriding other rasterization state. -Other Members -^^^^^^^^^^^^^ - -light_twoside - If set, there are per-vertex back-facing colors. :ref:`Draw` - uses this state along with the front/back information to set the - final vertex colors prior to rasterization. - -front_winding - Indicates the window order of front-facing polygons, either - PIPE_WINDING_CW or PIPE_WINDING_CCW - -cull_mode - Indicates which polygons to cull, either PIPE_WINDING_NONE (cull no - polygons), PIPE_WINDING_CW (cull clockwise-winding polygons), - PIPE_WINDING_CCW (cull counter clockwise-winding polygons), or - PIPE_WINDING_BOTH (cull all polygons). - -fill_cw - Indicates how to fill clockwise polygons, either PIPE_POLYGON_MODE_FILL, - PIPE_POLYGON_MODE_LINE or PIPE_POLYGON_MODE_POINT. -fill_ccw - Indicates how to fill counter clockwise polygons, either - PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or PIPE_POLYGON_MODE_POINT. - -poly_stipple_enable - Whether polygon stippling is enabled. -poly_smooth - Controls OpenGL-style polygon smoothing/antialiasing -offset_cw - If set, clockwise polygons will have polygon offset factors applied -offset_ccw - If set, counter clockwise polygons will have polygon offset factors applied -offset_units - Specifies the polygon offset bias -offset_scale - Specifies the polygon offset scale - -line_width - The width of lines. -line_smooth - Whether lines should be smoothed. Line smoothing is simply anti-aliasing. -line_stipple_enable - Whether line stippling is enabled. -line_stipple_pattern - 16-bit bitfield of on/off flags, used to pattern the line stipple. -line_stipple_factor - When drawing a stippled line, each bit in the stipple pattern is - repeated N times, where N = line_stipple_factor + 1. -line_last_pixel - Controls whether the last pixel in a line is drawn or not. OpenGL - omits the last pixel to avoid double-drawing pixels at the ends of lines - when drawing connected lines. - point_smooth Whether points should be smoothed. Point smoothing turns rectangular points into circles or ovals. point_size_per_vertex - Whether vertices have a point size element. + Whether the vertex shader is expected to have a point size output. + Undefined behaviour is permitted if there is disagreement between + this flag and the actual bound shader. point_size The size of points, if not specified per-vertex. + + +Other Members +------------- + scissor Whether the scissor test is enabled. diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index 5a60ee00a69..48d9d570b6f 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -1,3 +1,5 @@ +.. _screen: + Screen ====== @@ -33,6 +35,7 @@ The integer capabilities: * ``MAX_RENDER_TARGETS``: The maximum number of render targets that may be bound. * ``OCCLUSION_QUERY``: Whether occlusion queries are available. +* ``TIMER_QUERY``: Whether timer queries are available. * ``TEXTURE_SHADOW_MAP``: XXX * ``MAX_TEXTURE_2D_LEVELS``: The maximum number of mipmap levels available for a 2D texture. @@ -101,6 +104,22 @@ The floating-point capabilities: * ``GUARD_BAND_LEFT``, ``GUARD_BAND_TOP``, ``GUARD_BAND_RIGHT``, ``GUARD_BAND_BOTTOM``: XXX +Fragment shader limits: + +* ``PIPE_CAP_MAX_FS_INSTRUCTIONS``: The maximum number of instructions. +* ``PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS``: The maximum number of arithmetic instructions. +* ``PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS``: The maximum number of texture instructions. +* ``PIPE_CAP_MAX_FS_TEX_INDIRECTIONS``: The maximum number of texture indirections. +* ``PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH``: The maximum nested control flow depth. +* ``PIPE_CAP_MAX_FS_INPUTS``: The maximum number of input registers. +* ``PIPE_CAP_MAX_FS_CONSTS``: The maximum number of constants. +* ``PIPE_CAP_MAX_FS_TEMPS``: The maximum number of temporary registers. +* ``PIPE_CAP_MAX_FS_ADDRS``: The maximum number of address registers. +* ``PIPE_CAP_MAX_FS_PREDS``: The maximum number of predicate registers. + +Vertex shader limits: + +* ``PIPE_CAP_MAX_VS_*``: Identical to ``PIPE_CAP_MAX_FS_*``. .. _pipe_bind: diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 49cece58b8f..411f204f15a 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -73,7 +73,7 @@ cell_destroy_context( struct pipe_context *pipe ) static struct draw_context * cell_draw_create(struct cell_context *cell) { - struct draw_context *draw = draw_create(); + struct draw_context *draw = draw_create(&cell->pipe); #if 0 /* broken */ if (getenv("GALLIUM_CELL_VS")) { diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index b50a30bee80..6a1e4d8a646 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -103,7 +103,7 @@ cell_draw_range_elements(struct pipe_context *pipe, draw_set_mapped_vertex_buffer(draw, i, NULL); } if (indexBuffer) { - draw_set_mapped_element_buffer(draw, 0, NULL); + draw_set_mapped_element_buffer(draw, 0, 0, NULL); } /* @@ -122,7 +122,7 @@ cell_draw_elements(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { cell_draw_range_elements( pipe, indexBuffer, - indexSize, indeBias, + indexSize, indexBias, 0, 0xffffffff, mode, start, count ); } diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c index eac798e8cf6..34ca864155b 100644 --- a/src/gallium/drivers/cell/ppu/cell_fence.c +++ b/src/gallium/drivers/cell/ppu/cell_fence.c @@ -123,7 +123,7 @@ cell_free_fenced_buffers(struct cell_context *cell, while (node) { struct cell_buffer_node *next = node->next; assert(node->buffer); - pipe_buffer_unmap(ps, node->buffer); + /* XXX need this? pipe_buffer_unmap(ps, node->buffer);*/ #if 0 printf("Unref buffer %p\n", node->buffer); if (node->buffer->reference.count == 1) diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index ecc9de4df66..03f84d295b5 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -204,7 +204,7 @@ cell_bind_rasterizer_state(struct pipe_context *pipe, void *rast) struct cell_context *cell = cell_context(pipe); /* pass-through to draw module */ - draw_set_rasterizer_state(cell->draw, rasterizer); + draw_set_rasterizer_state(cell->draw, rasterizer, rast); cell->rasterizer = rasterizer; diff --git a/src/gallium/drivers/cell/ppu/cell_render.c b/src/gallium/drivers/cell/ppu/cell_render.c index 79cb8df82fa..f648482c551 100644 --- a/src/gallium/drivers/cell/ppu/cell_render.c +++ b/src/gallium/drivers/cell/ppu/cell_render.c @@ -152,7 +152,7 @@ cell_flush_prim_buffer(struct cell_context *cell) struct cell_command_render *render = &cell_global.command[i].render; render->prim_type = PIPE_PRIM_TRIANGLES; render->num_verts = cell->prim_buffer.num_verts; - render->front_winding = cell->rasterizer->front_winding; + render->front_ccw = cell->rasterizer->front_ccw; render->vertex_size = cell->vertex_info->size * 4; render->xmin = cell->prim_buffer.xmin; render->ymin = cell->prim_buffer.ymin; diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 9bb3abfc9dd..0f12e0667eb 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -55,7 +55,7 @@ cell_get_name(struct pipe_screen *screen) static int -cell_get_param(struct pipe_screen *screen, int param) +cell_get_param(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: @@ -76,6 +76,8 @@ cell_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_OCCLUSION_QUERY: return 1; + case PIPE_CAP_TIMER_QUERY: + return 0; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 10; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: @@ -105,7 +107,7 @@ cell_get_param(struct pipe_screen *screen, int param) static float -cell_get_paramf(struct pipe_screen *screen, int param) +cell_get_paramf(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index d08334d892b..b3042df7792 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -34,7 +34,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" - +#include "util/u_transfer.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -42,7 +42,7 @@ #include "cell_context.h" #include "cell_screen.h" #include "cell_state.h" -#include "cell_resource.h" +#include "cell_texture.h" #include "state_tracker/sw_winsys.h" @@ -155,9 +155,9 @@ fail: static void -cell_resource_destroy(struct pipe_resource *pt) +cell_resource_destroy(struct pipe_screen *scrn, struct pipe_resource *pt) { - struct cell_screen *screen = cell_screen(pt->screen); + struct cell_screen *screen = cell_screen(scrn); struct sw_winsys *winsys = screen->winsys; struct cell_resource *ct = cell_resource(pt); @@ -365,10 +365,10 @@ cell_get_transfer(struct pipe_context *ctx, { struct cell_resource *ct = cell_resource(resource); struct cell_transfer *ctrans; - enum pipe_format *format = resource->format; + enum pipe_format format = resource->format; assert(resource); - assert(level <= resource->last_level); + assert(sr.level <= resource->last_level); /* make sure the requested region is in the image bounds */ assert(box->x + box->width <= u_minify(resource->width0, sr.level)); @@ -612,6 +612,24 @@ cell_user_buffer_create(struct pipe_screen *screen, } +static struct pipe_resource * +cell_resource_from_handle(struct pipe_screen *screen, + const struct pipe_resource *templat, + struct winsys_handle *handle) +{ + /* XXX todo */ + return NULL; +} + + +static boolean +cell_resource_get_handle(struct pipe_screen *scree, + struct pipe_resource *tex, + struct winsys_handle *handle) +{ + /* XXX todo */ + return FALSE; +} void @@ -630,7 +648,7 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen) } void -cell_init_transfer_funcs(struct cell_context *cell) +cell_init_texture_transfer_funcs(struct cell_context *cell) { cell->pipe.get_transfer = cell_get_transfer; cell->pipe.transfer_destroy = cell_transfer_destroy; diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c index cfaffb52a85..37b71956482 100644 --- a/src/gallium/drivers/cell/ppu/cell_vbuf.c +++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c @@ -165,9 +165,9 @@ cell_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) static void -cell_vbuf_draw(struct vbuf_render *vbr, - const ushort *indices, - uint nr_indices) +cell_vbuf_draw_elements(struct vbuf_render *vbr, + const ushort *indices, + uint nr_indices) { struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); struct cell_context *cell = cvbr->cell; @@ -319,7 +319,7 @@ cell_init_vbuf(struct cell_context *cell) cell->vbuf_render->base.map_vertices = cell_vbuf_map_vertices; cell->vbuf_render->base.unmap_vertices = cell_vbuf_unmap_vertices; cell->vbuf_render->base.set_primitive = cell_vbuf_set_primitive; - cell->vbuf_render->base.draw = cell_vbuf_draw; + cell->vbuf_render->base.draw_elements = cell_vbuf_draw_elements; cell->vbuf_render->base.release_vertices = cell_vbuf_release_vertices; cell->vbuf_render->base.destroy = cell_vbuf_destroy; diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index f619380d807..efeebca27bb 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -568,7 +568,7 @@ setup_sort_vertices(const qword vs) ASSERT(CELL_FACING_FRONT == 0); ASSERT(CELL_FACING_BACK == 1); setup.facing = (area * sign > 0.0f) - ^ (spu.rasterizer.front_winding == PIPE_WINDING_CW); + ^ (!spu.rasterizer.front_ccw); return TRUE; } diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c index df9e68af4fc..f8665acbe18 100644 --- a/src/gallium/drivers/i915/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915/i915_prim_vbuf.c @@ -544,9 +544,9 @@ draw_calc_nr_indices(uint nr_indices, unsigned type) } static void -i915_vbuf_render_draw(struct vbuf_render *render, - const ushort *indices, - uint nr_indices) +i915_vbuf_render_draw_elements(struct vbuf_render *render, + const ushort *indices, + uint nr_indices) { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; @@ -638,7 +638,7 @@ i915_vbuf_render_create(struct i915_context *i915) i915_render->base.map_vertices = i915_vbuf_render_map_vertices; i915_render->base.unmap_vertices = i915_vbuf_render_unmap_vertices; i915_render->base.set_primitive = i915_vbuf_render_set_primitive; - i915_render->base.draw = i915_vbuf_render_draw; + i915_render->base.draw_elements = i915_vbuf_render_draw_elements; i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays; i915_render->base.release_vertices = i915_vbuf_render_release_vertices; i915_render->base.destroy = i915_vbuf_render_destroy; diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index c10ba25d2d5..0897a863dbd 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -90,7 +90,7 @@ i915_get_name(struct pipe_screen *screen) } static int -i915_get_param(struct pipe_screen *screen, int param) +i915_get_param(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: @@ -113,6 +113,8 @@ i915_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_OCCLUSION_QUERY: return 0; + case PIPE_CAP_TIMER_QUERY: + return 0; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: @@ -133,7 +135,7 @@ i915_get_param(struct pipe_screen *screen, int param) } static float -i915_get_paramf(struct pipe_screen *screen, int param) +i915_get_paramf(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index e008195a910..e767aa9f8f0 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -686,17 +686,23 @@ i915_create_rasterizer_state(struct pipe_context *pipe, else cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT; - switch (rasterizer->cull_mode) { - case PIPE_WINDING_NONE: + switch (rasterizer->cull_face) { + case PIPE_FACE_NONE: cso->LIS4 |= S4_CULLMODE_NONE; break; - case PIPE_WINDING_CW: - cso->LIS4 |= S4_CULLMODE_CW; + case PIPE_FACE_FRONT: + if (rasterizer->front_ccw) + cso->LIS4 |= S4_CULLMODE_CCW; + else + cso->LIS4 |= S4_CULLMODE_CW; break; - case PIPE_WINDING_CCW: - cso->LIS4 |= S4_CULLMODE_CCW; + case PIPE_FACE_BACK: + if (rasterizer->front_ccw) + cso->LIS4 |= S4_CULLMODE_CW; + else + cso->LIS4 |= S4_CULLMODE_CCW; break; - case PIPE_WINDING_BOTH: + case PIPE_FACE_FRONT_AND_BACK: cso->LIS4 |= S4_CULLMODE_BOTH; break; } diff --git a/src/gallium/drivers/i965/SConscript b/src/gallium/drivers/i965/SConscript index 85c4d7ed22e..019af682f68 100644 --- a/src/gallium/drivers/i965/SConscript +++ b/src/gallium/drivers/i965/SConscript @@ -50,7 +50,7 @@ i965 = env.ConvenienceLibrary( 'brw_sf_state.c', 'brw_state_batch.c', 'brw_state_cache.c', -# 'brw_state_debug.c', + 'brw_state_debug.c', 'brw_state_upload.c', 'brw_swtnl.c', 'brw_urb.c', diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index 003b1fd5bf0..8b3f46f2c16 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -161,7 +161,7 @@ brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, int ret; if (batch->ptr - batch->map > batch->buf->size) { - debug_printf("bad relocation ptr %p map %p offset %d size %d\n", + debug_printf("bad relocation ptr %p map %p offset %li size %i\n", batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size); return PIPE_ERROR_OUT_OF_MEMORY; diff --git a/src/gallium/drivers/i965/brw_pipe_rast.c b/src/gallium/drivers/i965/brw_pipe_rast.c index 2117e91a9e4..4c1a6d7dcdf 100644 --- a/src/gallium/drivers/i965/brw_pipe_rast.c +++ b/src/gallium/drivers/i965/brw_pipe_rast.c @@ -42,7 +42,7 @@ calculate_clip_key_rast( const struct brw_context *brw, key->do_flat_shading = templ->flatshade; - if (templ->cull_mode == PIPE_WINDING_BOTH) { + if (templ->cull_face == PIPE_FACE_FRONT_AND_BACK) { key->clip_mode = BRW_CLIPMODE_REJECT_ALL; return; } @@ -50,12 +50,18 @@ calculate_clip_key_rast( const struct brw_context *brw, key->fill_ccw = CLIP_CULL; key->fill_cw = CLIP_CULL; - if (!(templ->cull_mode & PIPE_WINDING_CCW)) { - key->fill_ccw = translate_fill(templ->fill_ccw); + if (!(templ->cull_face & PIPE_FACE_FRONT)) { + if (templ->front_ccw) + key->fill_ccw = translate_fill(templ->fill_front); + else + key->fill_cw = translate_fill(templ->fill_front); } - if (!(templ->cull_mode & PIPE_WINDING_CW)) { - key->fill_cw = translate_fill(templ->fill_cw); + if (!(templ->cull_face & PIPE_FACE_BACK)) { + if (templ->front_ccw) + key->fill_cw = translate_fill(templ->fill_back); + else + key->fill_ccw = translate_fill(templ->fill_back); } if (key->fill_cw == CLIP_LINE || @@ -66,8 +72,29 @@ calculate_clip_key_rast( const struct brw_context *brw, key->clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED; } - key->offset_ccw = templ->offset_ccw; - key->offset_cw = templ->offset_cw; + switch (key->fill_cw) { + case CLIP_POINT: + key->offset_cw = templ->offset_point; + break; + case CLIP_LINE: + key->offset_cw = templ->offset_line; + break; + case CLIP_FILL: + key->offset_cw = templ->offset_tri; + break; + } + + switch (key->fill_ccw) { + case CLIP_POINT: + key->offset_ccw = templ->offset_point; + break; + case CLIP_LINE: + key->offset_ccw = templ->offset_line; + break; + case CLIP_FILL: + key->offset_ccw = templ->offset_tri; + break; + } if (templ->light_twoside && key->fill_cw != CLIP_CULL) key->copy_bfc_cw = 1; @@ -111,12 +138,12 @@ static void *brw_create_rasterizer_state( struct pipe_context *pipe, /* Caclculate lookup value for WM IZ table. */ if (templ->line_smooth) { - if (templ->fill_cw == PIPE_POLYGON_MODE_LINE && - templ->fill_ccw == PIPE_POLYGON_MODE_LINE) { + if (templ->fill_front == PIPE_POLYGON_MODE_LINE && + templ->fill_back == PIPE_POLYGON_MODE_LINE) { rast->unfilled_aa_line = AA_ALWAYS; } - else if (templ->fill_cw == PIPE_POLYGON_MODE_LINE || - templ->fill_ccw == PIPE_POLYGON_MODE_LINE) { + else if (templ->fill_front == PIPE_POLYGON_MODE_LINE || + templ->fill_back == PIPE_POLYGON_MODE_LINE) { rast->unfilled_aa_line = AA_SOMETIMES; } else { diff --git a/src/gallium/drivers/i965/brw_resource.c b/src/gallium/drivers/i965/brw_resource.c index 3b9854be588..1efdb1e0b4d 100644 --- a/src/gallium/drivers/i965/brw_resource.c +++ b/src/gallium/drivers/i965/brw_resource.c @@ -13,7 +13,7 @@ brw_resource_create(struct pipe_screen *screen, if (template->target == PIPE_BUFFER) return brw_buffer_create(screen, template); else - return brw_resource_create(screen, template); + return brw_texture_create(screen, template); } diff --git a/src/gallium/drivers/i965/brw_resource_texture.c b/src/gallium/drivers/i965/brw_resource_texture.c index 4fbb0c2484d..ffd0f38672c 100644 --- a/src/gallium/drivers/i965/brw_resource_texture.c +++ b/src/gallium/drivers/i965/brw_resource_texture.c @@ -210,7 +210,7 @@ brw_texture_get_handle(struct pipe_screen *screen, stride = tex->pitch * tex->cpp; - return bscreen->sws->bo_get_handle(tex->bo, whandle, stride); + return bscreen->sws->bo_get_handle(tex->bo, whandle, stride) == PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c index 172e222c057..7a7b9c1a5a9 100644 --- a/src/gallium/drivers/i965/brw_screen.c +++ b/src/gallium/drivers/i965/brw_screen.c @@ -149,7 +149,7 @@ brw_get_name(struct pipe_screen *screen) } static int -brw_get_param(struct pipe_screen *screen, int param) +brw_get_param(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: @@ -172,6 +172,8 @@ brw_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_OCCLUSION_QUERY: return 0; + case PIPE_CAP_TIMER_QUERY: + return 0; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: @@ -192,7 +194,7 @@ brw_get_param(struct pipe_screen *screen, int param) } static float -brw_get_paramf(struct pipe_screen *screen, int param) +brw_get_paramf(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c index 9cceb4dbe52..5abf3848ab4 100644 --- a/src/gallium/drivers/i965/brw_sf.c +++ b/src/gallium/drivers/i965/brw_sf.c @@ -166,8 +166,8 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw) case PIPE_PRIM_TRIANGLES: /* PIPE_NEW_RAST */ - if (rast->fill_cw != PIPE_POLYGON_MODE_FILL || - rast->fill_ccw != PIPE_POLYGON_MODE_FILL) + if (rast->fill_front != PIPE_POLYGON_MODE_FILL || + rast->fill_back != PIPE_POLYGON_MODE_FILL) key.primitive = SF_UNFILLED_TRIS; else key.primitive = SF_TRIANGLES; @@ -187,7 +187,7 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw) key.do_twoside_color = rast->light_twoside; if (key.do_twoside_color) { - key.frontface_ccw = (rast->front_winding == PIPE_WINDING_CCW); + key.frontface_ccw = rast->front_ccw; } if (brw_search_cache(&brw->cache, BRW_SF_PROG, diff --git a/src/gallium/drivers/i965/brw_sf_state.c b/src/gallium/drivers/i965/brw_sf_state.c index 0ad91e03072..6c299a86b49 100644 --- a/src/gallium/drivers/i965/brw_sf_state.c +++ b/src/gallium/drivers/i965/brw_sf_state.c @@ -89,8 +89,8 @@ struct brw_sf_unit_key { unsigned line_smooth:1; unsigned point_sprite:1; unsigned point_attenuated:1; - unsigned front_face:2; - unsigned cull_mode:2; + unsigned front_ccw:1; + unsigned cull_face:2; unsigned flatshade_first:1; unsigned gl_rasterization_rules:1; unsigned line_last_pixel_enable:1; @@ -115,8 +115,8 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key) /* PIPE_NEW_RAST */ key->scissor = rast->scissor; - key->front_face = rast->front_winding; - key->cull_mode = rast->cull_mode; + key->front_ccw = rast->front_ccw; + key->cull_face = rast->cull_face; key->line_smooth = rast->line_smooth; key->line_width = rast->line_width; key->flatshade_first = rast->flatshade_first; @@ -183,22 +183,22 @@ sf_unit_create_from_key(struct brw_context *brw, if (key->scissor) sf.sf6.scissor = 1; - if (key->front_face == PIPE_WINDING_CCW) + if (key->front_ccw) sf.sf5.front_winding = BRW_FRONTWINDING_CCW; else sf.sf5.front_winding = BRW_FRONTWINDING_CW; - switch (key->cull_mode) { - case PIPE_WINDING_CCW: - case PIPE_WINDING_CW: - sf.sf6.cull_mode = (key->front_face == key->cull_mode ? - BRW_CULLMODE_FRONT : - BRW_CULLMODE_BACK); + switch (key->cull_face) { + case PIPE_FACE_FRONT: + sf.sf6.cull_mode = BRW_CULLMODE_FRONT; break; - case PIPE_WINDING_BOTH: + case PIPE_FACE_BACK: + sf.sf6.cull_mode = BRW_CULLMODE_BACK; + break; + case PIPE_FACE_FRONT_AND_BACK: sf.sf6.cull_mode = BRW_CULLMODE_BOTH; break; - case PIPE_WINDING_NONE: + case PIPE_FACE_NONE: sf.sf6.cull_mode = BRW_CULLMODE_NONE; break; default: @@ -284,7 +284,7 @@ static enum pipe_error upload_sf_unit( struct brw_context *brw ) */ total_grf = (align(key.total_grf, 16) / 16 - 1); viewport_transform = 1; - front_winding = (key.front_face == PIPE_WINDING_CCW ? + front_winding = (key.front_ccw ? BRW_FRONTWINDING_CCW : BRW_FRONTWINDING_CW); diff --git a/src/gallium/drivers/i965/brw_wm_state.c b/src/gallium/drivers/i965/brw_wm_state.c index ee970ac75bc..efc2d96be13 100644 --- a/src/gallium/drivers/i965/brw_wm_state.c +++ b/src/gallium/drivers/i965/brw_wm_state.c @@ -128,8 +128,9 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) key->line_stipple = brw->curr.rast->templ.line_stipple_enable; - key->offset_enable = (brw->curr.rast->templ.offset_cw || - brw->curr.rast->templ.offset_ccw); + key->offset_enable = (brw->curr.rast->templ.offset_point || + brw->curr.rast->templ.offset_line || + brw->curr.rast->templ.offset_tri); key->offset_units = brw->curr.rast->templ.offset_units; key->offset_factor = brw->curr.rast->templ.offset_scale; diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 7082d60d1c9..f71585e06f8 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -67,7 +67,7 @@ identity_screen_get_vendor(struct pipe_screen *_screen) static int identity_screen_get_param(struct pipe_screen *_screen, - int param) + enum pipe_cap param) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; @@ -78,7 +78,7 @@ identity_screen_get_param(struct pipe_screen *_screen, static float identity_screen_get_paramf(struct pipe_screen *_screen, - int param) + enum pipe_cap param) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 4ea367597e1..526e85c82e1 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -59,7 +59,7 @@ lp_tile_soa.c: lp_tile_soa.py ../../auxiliary/util/u_format_parse.py ../../auxil python lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@ LDFLAGS += $(LLVM_LDFLAGS) -LIBS += $(GL_LIB_DEPS) -L../../auxiliary/ -lgallium libllvmpipe.a $(LLVM_LIBS) +LIBS += -L../../auxiliary/ -lgallium libllvmpipe.a $(LLVM_LIBS) $(GL_LIB_DEPS) LD=g++ $(PROGS): lp_test_main.o libllvmpipe.a diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README index 3c3fd386b52..9c874acdedc 100644 --- a/src/gallium/drivers/llvmpipe/README +++ b/src/gallium/drivers/llvmpipe/README @@ -69,7 +69,15 @@ Requirements http://people.freedesktop.org/~jrfonseca/llvm/ and set the LLVM environment variable to the extracted path. - The version of LLVM from SVN ("2.7svn") from mid-March 2010 seems pretty + For MSVC there are two set of binaries: llvm-x.x-msvc32mt.7z and + llvm-x.x-msvc32mtd.7z . + + You have to set the LLVM=/path/to/llvm-x.x-msvc32mtd env var when passing + debug=yes to scons, and LLVM=/path/to/llvm-x.x-msvc32mt when building with + debug=no. This is necessary as LLVM builds as static library so the chosen + MS CRT must match. + + The version of LLVM from SVN ("2.7svn") from mid-March 2010 is pretty stable and has some features not in version 2.6. - scons (optional) diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 2911cf2179a..c155558aa54 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -85,4 +85,4 @@ if env['platform'] != 'embedded': ) env.InstallProgram(target) - Export('llvmpipe') +Export('llvmpipe') diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.h b/src/gallium/drivers/llvmpipe/lp_bld_blend.h index ebbdb1a604c..5cecec3d7f9 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.h @@ -29,17 +29,6 @@ #define LP_BLD_BLEND_H -/** - * @file - * LLVM IR building helpers interfaces. - * - * We use LLVM-C bindings for now. They are not documented, but follow the C++ - * interfaces very closely, and appear to be complete enough for code - * genration. See - * http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html - * for a standalone example. - */ - #include "gallivm/lp_bld.h" #include "pipe/p_format.h" @@ -75,6 +64,7 @@ LLVMValueRef lp_build_blend_aos(LLVMBuilderRef builder, const struct pipe_blend_state *blend, struct lp_type type, + unsigned rt, LLVMValueRef src, LLVMValueRef dst, LLVMValueRef const_, @@ -85,6 +75,7 @@ void lp_build_blend_soa(LLVMBuilderRef builder, const struct pipe_blend_state *blend, struct lp_type type, + unsigned rt, LLVMValueRef src[4], LLVMValueRef dst[4], LLVMValueRef const_[4], diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c index 3fa5e51cac5..70d08e71f6e 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c @@ -243,6 +243,9 @@ lp_build_blend_factor(struct lp_build_blend_aos_context *bld, } +/** + * Is (a OP b) == (b OP a)? + */ boolean lp_build_blend_func_commutative(unsigned func) { @@ -305,6 +308,7 @@ LLVMValueRef lp_build_blend_aos(LLVMBuilderRef builder, const struct pipe_blend_state *blend, struct lp_type type, + unsigned rt, LLVMValueRef src, LLVMValueRef dst, LLVMValueRef const_, @@ -314,11 +318,10 @@ lp_build_blend_aos(LLVMBuilderRef builder, LLVMValueRef src_term; LLVMValueRef dst_term; - /* FIXME */ - assert(blend->independent_blend_enable == 0); - assert(blend->rt[0].colormask == 0xf); + /* FIXME: color masking not implemented yet */ + assert(blend->rt[rt].colormask == 0xf); - if(!blend->rt[0].blend_enable) + if(!blend->rt[rt].blend_enable) return src; /* It makes no sense to blend unless values are normalized */ @@ -335,16 +338,16 @@ lp_build_blend_aos(LLVMBuilderRef builder, * combinations it is possible to reorder the operations and therefore saving * some instructions. */ - src_term = lp_build_blend_factor(&bld, src, blend->rt[0].rgb_src_factor, - blend->rt[0].alpha_src_factor, alpha_swizzle); - dst_term = lp_build_blend_factor(&bld, dst, blend->rt[0].rgb_dst_factor, - blend->rt[0].alpha_dst_factor, alpha_swizzle); + src_term = lp_build_blend_factor(&bld, src, blend->rt[rt].rgb_src_factor, + blend->rt[rt].alpha_src_factor, alpha_swizzle); + dst_term = lp_build_blend_factor(&bld, dst, blend->rt[rt].rgb_dst_factor, + blend->rt[rt].alpha_dst_factor, alpha_swizzle); lp_build_name(src_term, "src_term"); lp_build_name(dst_term, "dst_term"); - if(blend->rt[0].rgb_func == blend->rt[0].alpha_func) { - return lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term); + if(blend->rt[rt].rgb_func == blend->rt[rt].alpha_func) { + return lp_build_blend_func(&bld.base, blend->rt[rt].rgb_func, src_term, dst_term); } else { /* Seperate RGB / A functions */ @@ -352,8 +355,8 @@ lp_build_blend_aos(LLVMBuilderRef builder, LLVMValueRef rgb; LLVMValueRef alpha; - rgb = lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term); - alpha = lp_build_blend_func(&bld.base, blend->rt[0].alpha_func, src_term, dst_term); + rgb = lp_build_blend_func(&bld.base, blend->rt[rt].rgb_func, src_term, dst_term); + alpha = lp_build_blend_func(&bld.base, blend->rt[rt].alpha_func, src_term, dst_term); return lp_build_blend_swizzle(&bld, rgb, alpha, LP_BUILD_BLEND_SWIZZLE_RGBA, alpha_swizzle); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c index b7523eb9c13..b9c7a6ceed6 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c @@ -33,8 +33,8 @@ * Blending in SoA is much faster than AoS, especially when separate rgb/alpha * factors/functions are used, since no channel masking/shuffling is necessary * and we can achieve the full throughput of the SIMD operations. Furthermore - * the fragment shader output is also in SoA, so it fits nicely with the rest of - * the fragment pipeline. + * the fragment shader output is also in SoA, so it fits nicely with the rest + * of the fragment pipeline. * * The drawback is that to be displayed the color buffer needs to be in AoS * layout, so we need to tile/untile the color buffer before/after rendering. @@ -77,7 +77,7 @@ /** - * We may the same values several times, so we keep them here to avoid + * We may use the same values several times, so we keep them here to avoid * recomputing them. Also reusing the values allows us to do simplifications * that LLVM optimization passes wouldn't normally be able to do. */ @@ -98,16 +98,22 @@ struct lp_build_blend_soa_context /** * We store all factors in a table in order to eliminate redundant * multiplications later. + * Indexes are: factor[src,dst][color,term][r,g,b,a] */ LLVMValueRef factor[2][2][4]; /** * Table with all terms. + * Indexes are: term[src,dst][r,g,b,a] */ LLVMValueRef term[2][4]; }; +/** + * Build a single SOA blend factor for a color channel. + * \param i the color channel in [0,3] + */ static LLVMValueRef lp_build_blend_soa_factor(struct lp_build_blend_soa_context *bld, unsigned factor, unsigned i) @@ -191,6 +197,7 @@ lp_build_blend_soa_factor(struct lp_build_blend_soa_context *bld, /** * Generate blend code in SOA mode. + * \param rt render target index (to index the blend / colormask state) * \param src src/fragment color * \param dst dst/framebuffer color * \param con constant blend color @@ -200,6 +207,7 @@ void lp_build_blend_soa(LLVMBuilderRef builder, const struct pipe_blend_state *blend, struct lp_type type, + unsigned rt, LLVMValueRef src[4], LLVMValueRef dst[4], LLVMValueRef con[4], @@ -208,6 +216,8 @@ lp_build_blend_soa(LLVMBuilderRef builder, struct lp_build_blend_soa_context bld; unsigned i, j, k; + assert(rt < PIPE_MAX_COLOR_BUFS); + /* Setup build context */ memset(&bld, 0, sizeof bld); lp_build_context_init(&bld.base, builder, type); @@ -218,7 +228,8 @@ lp_build_blend_soa(LLVMBuilderRef builder, } for (i = 0; i < 4; ++i) { - if (blend->rt[0].colormask & (1 << i)) { + /* only compute blending for the color channels enabled for writing */ + if (blend->rt[rt].colormask & (1 << i)) { if (blend->logicop_enable) { if(!type.floating) { res[i] = lp_build_logicop(builder, blend->logicop_func, src[i], dst[i]); @@ -226,10 +237,10 @@ lp_build_blend_soa(LLVMBuilderRef builder, else res[i] = dst[i]; } - else if (blend->rt[0].blend_enable) { - unsigned src_factor = i < 3 ? blend->rt[0].rgb_src_factor : blend->rt[0].alpha_src_factor; - unsigned dst_factor = i < 3 ? blend->rt[0].rgb_dst_factor : blend->rt[0].alpha_dst_factor; - unsigned func = i < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func; + else if (blend->rt[rt].blend_enable) { + unsigned src_factor = i < 3 ? blend->rt[rt].rgb_src_factor : blend->rt[rt].alpha_src_factor; + unsigned dst_factor = i < 3 ? blend->rt[rt].rgb_dst_factor : blend->rt[rt].alpha_dst_factor; + unsigned func = i < 3 ? blend->rt[rt].rgb_func : blend->rt[rt].alpha_func; boolean func_commutative = lp_build_blend_func_commutative(func); /* It makes no sense to blend unless values are normalized */ @@ -269,9 +280,9 @@ lp_build_blend_soa(LLVMBuilderRef builder, /* XXX special case these combos to work around an apparent * bug in LLVM. * This hack disables the check for multiplication by zero - * in lp_bld_mul(). When we optimize away the multiplication, - * something goes wrong during code generation and we segfault - * at runtime. + * in lp_bld_mul(). When we optimize away the + * multiplication, something goes wrong during code + * generation and we segfault at runtime. */ LLVMValueRef zeroSave = bld.base.zero; bld.base.zero = NULL; @@ -287,7 +298,7 @@ lp_build_blend_soa(LLVMBuilderRef builder, /* See if this function has been previously applied */ for(j = 0; j < i; ++j) { - unsigned prev_func = j < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func; + unsigned prev_func = j < 3 ? blend->rt[rt].rgb_func : blend->rt[rt].alpha_func; unsigned func_reverse = lp_build_blend_func_reverse(func, prev_func); if((!func_reverse && diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index 1b59a13c946..e05bbe5011a 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -72,6 +72,7 @@ #include "gallivm/lp_bld_const.h" #include "gallivm/lp_bld_logic.h" #include "gallivm/lp_bld_flow.h" +#include "gallivm/lp_bld_intr.h" #include "gallivm/lp_bld_debug.h" #include "gallivm/lp_bld_swizzle.h" @@ -445,6 +446,42 @@ get_s_shift_and_mask(const struct util_format_description *format_desc, } +/** + * Perform the occlusion test and increase the counter. + * Test the depth mask. Add the number of channel which has none zero mask + * into the occlusion counter. e.g. maskvalue is {-1, -1, -1, -1}. + * The counter will add 4. + * + * \param type holds element type of the mask vector. + * \param maskvalue is the depth test mask. + * \param counter is a pointer of the uint32 counter. + */ +static void +lp_build_occlusion_count(LLVMBuilderRef builder, + struct lp_type type, + LLVMValueRef maskvalue, + LLVMValueRef counter) +{ + LLVMValueRef countmask = lp_build_const_int_vec(type, 1); + LLVMValueRef countv = LLVMBuildAnd(builder, maskvalue, countmask, "countv"); + LLVMTypeRef i8v16 = LLVMVectorType(LLVMInt8Type(), 16); + LLVMValueRef counti = LLVMBuildBitCast(builder, countv, i8v16, "counti"); + LLVMValueRef maskarray[4] = { + LLVMConstInt(LLVMInt32Type(), 0, 0), + LLVMConstInt(LLVMInt32Type(), 4, 0), + LLVMConstInt(LLVMInt32Type(), 8, 0), + LLVMConstInt(LLVMInt32Type(), 12, 0), + }; + LLVMValueRef shufflemask = LLVMConstVector(maskarray, 4); + LLVMValueRef shufflev = LLVMBuildShuffleVector(builder, counti, LLVMGetUndef(i8v16), shufflemask, "shufflev"); + LLVMValueRef shuffle = LLVMBuildBitCast(builder, shufflev, LLVMInt32Type(), "shuffle"); + LLVMValueRef count = lp_build_intrinsic_unary(builder, "llvm.ctpop.i32", LLVMInt32Type(), shuffle); + LLVMValueRef orig = LLVMBuildLoad(builder, counter, "orig"); + LLVMValueRef incr = LLVMBuildAdd(builder, orig, count, "incr"); + LLVMBuildStore(builder, incr, counter); +} + + /** * Generate code for performing depth and/or stencil tests. @@ -470,7 +507,8 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder, LLVMValueRef stencil_refs[2], LLVMValueRef z_src, LLVMValueRef zs_dst_ptr, - LLVMValueRef face) + LLVMValueRef face, + LLVMValueRef counter) { struct lp_build_context bld; struct lp_build_context sbld; @@ -682,4 +720,7 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder, if (depth->enabled && stencil[0].enabled) lp_build_mask_update(mask, z_pass); + + if (counter) + lp_build_occlusion_count(builder, type, mask->value, counter); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.h b/src/gallium/drivers/llvmpipe/lp_bld_depth.h index 27dd46b625d..e257a5bd7d0 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.h @@ -60,7 +60,8 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder, LLVMValueRef stencil_refs[2], LLVMValueRef zs_src, LLVMValueRef zs_dst_ptr, - LLVMValueRef facing); + LLVMValueRef facing, + LLVMValueRef counter); #endif /* !LP_BLD_DEPTH_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 4e597b24796..de7fe7a1796 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -82,11 +82,7 @@ struct llvmpipe_context { unsigned dirty; /**< Mask of LP_NEW_x flags */ - /* Counter for occlusion queries. Note this supports overlapping - * queries. - */ - uint64_t occlusion_count; - unsigned active_query_count; + int active_query_count; /** Mapped vertex buffers */ ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/drivers/llvmpipe/lp_debug.h b/src/gallium/drivers/llvmpipe/lp_debug.h index ee818143610..92fb2b3ee5b 100644 --- a/src/gallium/drivers/llvmpipe/lp_debug.h +++ b/src/gallium/drivers/llvmpipe/lp_debug.h @@ -39,16 +39,13 @@ st_print_current(void); #define DEBUG_PIPE 0x1 #define DEBUG_TGSI 0x2 #define DEBUG_TEX 0x4 -#define DEBUG_ASM 0x8 #define DEBUG_SETUP 0x10 #define DEBUG_RAST 0x20 #define DEBUG_QUERY 0x40 #define DEBUG_SCREEN 0x80 -#define DEBUG_JIT 0x100 #define DEBUG_SHOW_TILES 0x200 #define DEBUG_SHOW_SUBTILES 0x400 #define DEBUG_COUNTERS 0x800 -#define DEBUG_NO_LLVM_OPT 0x1000 #ifdef DEBUG diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 644b821957a..e1425435e19 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -31,6 +31,7 @@ #include "pipe/p_defines.h" +#include "util/u_string.h" #include "draw/draw_context.h" #include "lp_flush.h" #include "lp_context.h" @@ -71,25 +72,25 @@ llvmpipe_flush( struct pipe_context *pipe, } /* Enable to dump BMPs of the color/depth buffers each frame */ -#if 0 - if (flags & PIPE_FLUSH_FRAME) { - static unsigned frame_no = 1; - char filename[256]; - unsigned i; - - for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { - util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no); - debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[0]); - } + if (0) { + if (flags & PIPE_FLUSH_FRAME) { + static unsigned frame_no = 1; + char filename[256]; + unsigned i; + + for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { + util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no); + debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[0]); + } - if (0) { - util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no); - debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf); - } + if (0) { + util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no); + debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf); + } - ++frame_no; + ++frame_no; + } } -#endif } diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 30e206a2b42..23aa34ddec1 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -38,7 +38,7 @@ #include "util/u_memory.h" #include "util/u_cpu_detect.h" #include "gallivm/lp_bld_init.h" -#include "lp_debug.h" +#include "gallivm/lp_bld_debug.h" #include "lp_screen.h" #include "gallivm/lp_bld_intr.h" #include "lp_jit.h" @@ -151,9 +151,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) screen->context_ptr_type = LLVMPointerType(context_type, 0); } -#ifdef DEBUG - LLVMDumpModule(screen->module); -#endif + if (gallivm_debug & GALLIVM_DEBUG_IR) { + LLVMDumpModule(screen->module); + } } @@ -181,7 +181,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) screen->pass = LLVMCreateFunctionPassManager(screen->provider); LLVMAddTargetData(screen->target, screen->pass); - if ((LP_DEBUG & DEBUG_NO_LLVM_OPT) == 0) { + if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) { /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, * but there are more on SVN. */ /* TODO: Add more passes */ @@ -196,6 +196,11 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) LLVMAddInstructionCombiningPass(screen->pass); } LLVMAddGVNPass(screen->pass); + } else { + /* We need at least this pass to prevent the backends to fail in + * unexpected ways. + */ + LLVMAddPromoteMemoryToRegisterPass(screen->pass); } lp_jit_init_globals(screen); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 5d0268c68c4..8dee0413019 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -146,13 +146,9 @@ enum { lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_BLEND_COLOR, "blend_color") #define lp_jit_context_textures(_builder, _ptr) \ - lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES, "textures") + lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CTX_TEXTURES, "textures") -/** Indexes into jit_function[] array */ -#define RAST_WHOLE 0 -#define RAST_EDGE_TEST 1 - typedef void (*lp_jit_frag_func)(const struct lp_jit_context *context, @@ -169,7 +165,38 @@ typedef void const int32_t c3, const int32_t *step1, const int32_t *step2, - const int32_t *step3); + const int32_t *step3, + uint32_t *counter); + + +/** cast wrapper to avoid compiler warnings */ +static INLINE lp_jit_frag_func +cast_voidptr_to_lp_jit_frag_func(void *v) +{ + union { + void *v; + lp_jit_frag_func f; + } u; + assert(sizeof(u.v) == sizeof(u.f)); + u.v = v; + return u.f; +} + + +/** cast wrapper */ +static INLINE void * +cast_lp_jit_frag_func_to_voidptr(lp_jit_frag_func f) +{ + union { + void *v; + lp_jit_frag_func f; + } u; + assert(sizeof(u.v) == sizeof(u.f)); + u.f = f; + return u.v; +} + + void diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c index 5554285425d..c23e9839063 100644 --- a/src/gallium/drivers/llvmpipe/lp_query.c +++ b/src/gallium/drivers/llvmpipe/lp_query.c @@ -1,6 +1,7 @@ /************************************************************************** * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,15 +19,15 @@ * 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 + * IN NO EVENT SHALL THE AUTHORS 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. * **************************************************************************/ -/* Author: - * Keith Whitwell <[email protected]> +/* Authors: + * Keith Whitwell, Qicheng Christopher Li, Brian Paul */ #include "draw/draw_context.h" @@ -34,12 +35,10 @@ #include "util/u_memory.h" #include "lp_context.h" #include "lp_query.h" +#include "lp_rast.h" +#include "lp_rast_priv.h" #include "lp_state.h" - -struct llvmpipe_query { - uint64_t start; - uint64_t end; -}; +#include "lp_setup_context.h" static struct llvmpipe_query *llvmpipe_query( struct pipe_query *p ) @@ -51,15 +50,46 @@ static struct pipe_query * llvmpipe_create_query(struct pipe_context *pipe, unsigned type) { + struct llvmpipe_query *pq; + assert(type == PIPE_QUERY_OCCLUSION_COUNTER); - return (struct pipe_query *)CALLOC_STRUCT( llvmpipe_query ); + + pq = CALLOC_STRUCT( llvmpipe_query ); + if (pq) { + pipe_mutex_init(pq->mutex); + } + + return (struct pipe_query *) pq; } static void llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q) { - FREE(q); + struct llvmpipe_query *pq = llvmpipe_query(q); + pipe_mutex_destroy(pq->mutex); + FREE(pq); +} + + +static boolean +llvmpipe_get_query_result(struct pipe_context *pipe, + struct pipe_query *q, + boolean wait, + uint64_t *result ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + struct llvmpipe_query *pq = llvmpipe_query(q); + + if (!pq->done) { + lp_setup_flush(llvmpipe->setup, TRUE); + } + + if (pq->done) { + *result = pq->result; + } + + return pq->done; } @@ -67,9 +97,23 @@ static void llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) { struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); - struct llvmpipe_query *sq = llvmpipe_query(q); - - sq->start = llvmpipe->occlusion_count; + struct llvmpipe_query *pq = llvmpipe_query(q); + + /* Check if the query is already in the scene. If so, we need to + * flush the scene now. Real apps shouldn't re-use a query in a + * frame of rendering. + */ + if (pq->binned) { + struct pipe_fence_handle *fence; + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &fence); + if (fence) { + pipe->screen->fence_finish(pipe->screen, fence, 0); + pipe->screen->fence_reference(pipe->screen, &fence, NULL); + } + } + + lp_setup_begin_query(llvmpipe->setup, pq); + llvmpipe->active_query_count++; llvmpipe->dirty |= LP_NEW_QUERY; } @@ -79,26 +123,16 @@ static void llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) { struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); - struct llvmpipe_query *sq = llvmpipe_query(q); + struct llvmpipe_query *pq = llvmpipe_query(q); + lp_setup_end_query(llvmpipe->setup, pq); + + assert(llvmpipe->active_query_count); llvmpipe->active_query_count--; - sq->end = llvmpipe->occlusion_count; llvmpipe->dirty |= LP_NEW_QUERY; } -static boolean -llvmpipe_get_query_result(struct pipe_context *pipe, - struct pipe_query *q, - boolean wait, - uint64_t *result ) -{ - struct llvmpipe_query *sq = llvmpipe_query(q); - *result = sq->end - sq->start; - return TRUE; -} - - void llvmpipe_init_query_funcs(struct llvmpipe_context *llvmpipe ) { llvmpipe->pipe.create_query = llvmpipe_create_query; diff --git a/src/gallium/drivers/llvmpipe/lp_query.h b/src/gallium/drivers/llvmpipe/lp_query.h index fa9fcd87139..721c41cb5c9 100644 --- a/src/gallium/drivers/llvmpipe/lp_query.h +++ b/src/gallium/drivers/llvmpipe/lp_query.h @@ -1,6 +1,7 @@ /************************************************************************** * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,14 +26,33 @@ * **************************************************************************/ -/* Author: - * Keith Whitwell +/* Authors: + * Keith Whitwell, Qicheng Christopher Li, Brian Paul */ #ifndef LP_QUERY_H #define LP_QUERY_H +#include <limits.h> +#include "os/os_thread.h" +#include "lp_limits.h" + + struct llvmpipe_context; + + +struct llvmpipe_query { + uint64_t count[LP_MAX_THREADS]; /**< a counter for each thread */ + uint64_t result; /**< total of all counters */ + + pipe_mutex mutex; + unsigned num_tiles, tile_count; + + boolean done; + boolean binned; /**< has this query been binned in the scene? */ +}; + + extern void llvmpipe_init_query_funcs(struct llvmpipe_context * ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index a00a592f2fe..6bb868bf1a9 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -34,6 +34,7 @@ #include "lp_debug.h" #include "lp_fence.h" #include "lp_perf.h" +#include "lp_query.h" #include "lp_rast.h" #include "lp_rast_priv.h" #include "lp_tile_soa.h" @@ -442,7 +443,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, color, depth, INT_MIN, INT_MIN, INT_MIN, - NULL, NULL, NULL ); + NULL, NULL, NULL, &task->vis_counter); } } } @@ -502,7 +503,8 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task, c1, c2, c3, inputs->step[0], inputs->step[1], - inputs->step[2]); + inputs->step[2], + &task->vis_counter); } @@ -602,6 +604,60 @@ lp_rast_fence(struct lp_rasterizer_task *task, } +/** + * Begin a new occlusion query. + * This is a bin command put in all bins. + * Called per thread. + */ +void +lp_rast_begin_query(struct lp_rasterizer_task *task, + const union lp_rast_cmd_arg arg) +{ + /* Reset the the per-task counter */ + task->vis_counter = 0; +} + + +/** + * End the current occlusion query. + * This is a bin command put in all bins. + * Called per thread. + */ +void +lp_rast_end_query(struct lp_rasterizer_task *task, + const union lp_rast_cmd_arg arg) +{ + struct llvmpipe_query *pq = arg.query_obj; + + pipe_mutex_lock(pq->mutex); + { + /* Accumulate the visible fragment counter from this tile in + * the query object. + */ + pq->count[task->thread_index] += task->vis_counter; + + /* check if this is the last tile in the scene */ + pq->tile_count++; + if (pq->tile_count == pq->num_tiles) { + uint i; + + /* sum the per-thread counters for the query */ + pq->result = 0; + for (i = 0; i < LP_MAX_THREADS; i++) { + pq->result += pq->count[i]; + } + + /* reset counters (in case this query is re-used in the scene) */ + memset(pq->count, 0, sizeof(pq->count)); + + pq->tile_count = 0; + pq->binned = FALSE; + pq->done = TRUE; + } + } + pipe_mutex_unlock(pq->mutex); +} + /** @@ -650,6 +706,8 @@ static struct { RAST(set_state), RAST(store_color), RAST(fence), + RAST(begin_query), + RAST(end_query), }; static void @@ -956,3 +1014,5 @@ lp_rast_get_num_threads( struct lp_rasterizer *rast ) { return rast->num_threads; } + + diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index e2f6f926779..881f475189e 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -157,6 +157,7 @@ union lp_rast_cmd_arg { uint8_t clear_color[4]; unsigned clear_zstencil; struct lp_fence *fence; + struct llvmpipe_query *query_obj; }; @@ -233,4 +234,11 @@ void lp_rast_store_color( struct lp_rasterizer_task *, const union lp_rast_cmd_arg ); +void lp_rast_begin_query(struct lp_rasterizer_task *, + const union lp_rast_cmd_arg ); + +void lp_rast_end_query(struct lp_rasterizer_task *, + const union lp_rast_cmd_arg ); + + #endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 5884d12721e..efc013ff3f0 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -33,6 +33,7 @@ #include "gallivm/lp_bld_debug.h" #include "lp_rast.h" #include "lp_scene.h" +#include "lp_state.h" #include "lp_texture.h" #include "lp_tile_soa.h" #include "lp_limits.h" @@ -59,6 +60,9 @@ struct lp_rasterizer_task /** "my" index */ unsigned thread_index; + /* occlude counter for visiable pixels */ + uint32_t vis_counter; + pipe_semaphore work_ready; pipe_semaphore work_done; }; @@ -221,7 +225,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, color, depth, INT_MIN, INT_MIN, INT_MIN, - NULL, NULL, NULL ); + NULL, NULL, NULL, &task->vis_counter ); } diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index 887f2dbad91..59e4c18ad05 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -30,7 +30,6 @@ #include "util/u_memory.h" #include "util/u_inlines.h" #include "util/u_simple_list.h" -#include "util/u_surface.h" #include "lp_scene.h" #include "lp_scene_queue.h" @@ -210,25 +209,31 @@ lp_scene_reset(struct lp_scene *scene ) -void +struct cmd_block * lp_bin_new_cmd_block( struct cmd_block_list *list ) { struct cmd_block *block = MALLOC_STRUCT(cmd_block); - list->tail->next = block; - list->tail = block; - block->next = NULL; - block->count = 0; + if (block) { + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->count = 0; + } + return block; } -void +struct data_block * lp_bin_new_data_block( struct data_block_list *list ) { struct data_block *block = MALLOC_STRUCT(data_block); - list->tail->next = block; - list->tail = block; - block->next = NULL; - block->used = 0; + if (block) { + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->used = 0; + } + return block; } diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index 9467cd6f16d..22d619fdbc3 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -158,9 +158,9 @@ boolean lp_scene_is_empty(struct lp_scene *scene ); void lp_scene_reset(struct lp_scene *scene ); -void lp_bin_new_data_block( struct data_block_list *list ); +struct data_block *lp_bin_new_data_block( struct data_block_list *list ); -void lp_bin_new_cmd_block( struct cmd_block_list *list ); +struct cmd_block *lp_bin_new_cmd_block( struct cmd_block_list *list ); unsigned lp_scene_data_size( const struct lp_scene *scene ); @@ -181,15 +181,19 @@ static INLINE void * lp_scene_alloc( struct lp_scene *scene, unsigned size) { struct data_block_list *list = &scene->data; - - if (list->tail->used + size > DATA_BLOCK_SIZE) { - lp_bin_new_data_block( list ); + struct data_block *tail = list->tail; + + if (tail->used + size > DATA_BLOCK_SIZE) { + tail = lp_bin_new_data_block( list ); + if (!tail) { + /* out of memory */ + return NULL; + } } scene->scene_size += size; { - struct data_block *tail = list->tail; ubyte *data = tail->data + tail->used; tail->used += size; return data; @@ -205,15 +209,17 @@ lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size, unsigned alignment ) { struct data_block_list *list = &scene->data; + struct data_block *tail = list->tail; - if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { - lp_bin_new_data_block( list ); + if (tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { + tail = lp_bin_new_data_block( list ); + if (!tail) + return NULL; } scene->scene_size += size; { - struct data_block *tail = list->tail; ubyte *data = tail->data + tail->used; unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; tail->used += offset + size; @@ -257,16 +263,21 @@ lp_scene_bin_command( struct lp_scene *scene, { struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); struct cmd_block_list *list = &bin->commands; + struct cmd_block *tail = list->tail; assert(x < scene->tiles_x); assert(y < scene->tiles_y); - if (list->tail->count == CMD_BLOCK_MAX) { - lp_bin_new_cmd_block( list ); + if (tail->count == CMD_BLOCK_MAX) { + tail = lp_bin_new_cmd_block( list ); + if (!tail) { + /* out of memory - simply ignore this command (for now) */ + return; + } + assert(tail->count == 0); } { - struct cmd_block *tail = list->tail; unsigned i = tail->count; tail->cmd[i] = cmd; tail->arg[i] = arg; diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 5f50446f846..cedc08e9292 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -34,6 +34,7 @@ #include "pipe/p_defines.h" #include "pipe/p_screen.h" +#include "gallivm/lp_bld_limits.h" #include "lp_texture.h" #include "lp_fence.h" #include "lp_jit.h" @@ -52,16 +53,13 @@ static const struct debug_named_value lp_debug_flags[] = { { "pipe", DEBUG_PIPE }, { "tgsi", DEBUG_TGSI }, { "tex", DEBUG_TEX }, - { "asm", DEBUG_ASM }, { "setup", DEBUG_SETUP }, { "rast", DEBUG_RAST }, { "query", DEBUG_QUERY }, { "screen", DEBUG_SCREEN }, - { "jit", DEBUG_JIT }, { "show_tiles", DEBUG_SHOW_TILES }, { "show_subtiles", DEBUG_SHOW_SUBTILES }, { "counters", DEBUG_COUNTERS }, - { "nopt", DEBUG_NO_LLVM_OPT }, {NULL, 0} }; #endif @@ -82,7 +80,7 @@ llvmpipe_get_name(struct pipe_screen *screen) static int -llvmpipe_get_param(struct pipe_screen *screen, int param) +llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: @@ -107,6 +105,8 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) return PIPE_MAX_COLOR_BUFS; case PIPE_CAP_OCCLUSION_QUERY: return 1; + case PIPE_CAP_TIMER_QUERY: + return 0; case PIPE_CAP_TEXTURE_MIRROR_CLAMP: return 1; case PIPE_CAP_TEXTURE_MIRROR_REPEAT: @@ -124,7 +124,7 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; case PIPE_CAP_INDEP_BLEND_ENABLE: - return 0; + return 1; case PIPE_CAP_INDEP_BLEND_FUNC: return 0; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: @@ -133,14 +133,44 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 0; + case PIPE_CAP_MAX_VS_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: + case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: + /* There is no limit in number of instructions beyond available memory */ + return 32768; + case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: + case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: + return LP_MAX_TGSI_NESTING; + case PIPE_CAP_MAX_VS_INPUTS: + case PIPE_CAP_MAX_FS_INPUTS: + return PIPE_MAX_ATTRIBS; + case PIPE_CAP_MAX_FS_CONSTS: + case PIPE_CAP_MAX_VS_CONSTS: + /* There is no limit in number of constants beyond available memory */ + return 32768; + case PIPE_CAP_MAX_VS_TEMPS: + case PIPE_CAP_MAX_FS_TEMPS: + return LP_MAX_TGSI_TEMPS; + case PIPE_CAP_MAX_VS_ADDRS: + case PIPE_CAP_MAX_FS_ADDRS: + return LP_MAX_TGSI_ADDRS; + case PIPE_CAP_MAX_VS_PREDS: + case PIPE_CAP_MAX_FS_PREDS: + return LP_MAX_TGSI_PREDS; default: + assert(0); return 0; } } static float -llvmpipe_get_paramf(struct pipe_screen *screen, int param) +llvmpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: @@ -155,7 +185,13 @@ llvmpipe_get_paramf(struct pipe_screen *screen, int param) return 16.0; /* not actually signficant at this time */ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0; /* arbitrary */ + case PIPE_CAP_GUARD_BAND_LEFT: + case PIPE_CAP_GUARD_BAND_TOP: + case PIPE_CAP_GUARD_BAND_RIGHT: + case PIPE_CAP_GUARD_BAND_BOTTOM: + return 0.0; default: + assert(0); return 0; } } @@ -270,7 +306,16 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen ) struct pipe_screen * llvmpipe_create_screen(struct sw_winsys *winsys) { - struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen); + struct llvmpipe_screen *screen; + +#ifdef PIPE_ARCH_X86 + /* require SSE2 due to LLVM PR6960. */ + util_cpu_detect(); + if (!util_cpu_caps.has_sse2) + return NULL; +#endif + + screen = CALLOC_STRUCT(llvmpipe_screen); #ifdef DEBUG LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 ); diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h index 4f394326103..eb40f6823f5 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.h +++ b/src/gallium/drivers/llvmpipe/lp_screen.h @@ -60,10 +60,9 @@ struct llvmpipe_screen unsigned num_threads; - /* Increments whenever textures are modified. Contexts can track - * this. + /* Increments whenever textures are modified. Contexts can track this. */ - unsigned timestamp; + unsigned timestamp; }; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 1a2cd55b164..656e6cc38a6 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -32,18 +32,20 @@ * lp_setup_flush(). */ +#include <limits.h> + #include "pipe/p_defines.h" #include "util/u_framebuffer.h" #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_pack_color.h" -#include "util/u_surface.h" #include "lp_context.h" #include "lp_scene.h" #include "lp_scene_queue.h" #include "lp_texture.h" #include "lp_debug.h" #include "lp_fence.h" +#include "lp_query.h" #include "lp_rast.h" #include "lp_setup_context.h" #include "lp_screen.h" @@ -418,7 +420,8 @@ lp_setup_set_fs_functions( struct lp_setup_context *setup, lp_jit_frag_func jit_function1, boolean opaque ) { - LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) jit_function0); + LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, + cast_lp_jit_frag_func_to_voidptr(jit_function0)); /* FIXME: reference count */ setup->fs.current.jit_function[0] = jit_function0; @@ -644,16 +647,19 @@ lp_setup_update_state( struct lp_setup_context *setup ) stored = lp_scene_alloc_aligned(scene, 4 * 16, 16); - /* smear each blend color component across 16 ubyte elements */ - for (i = 0; i < 4; ++i) { - uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]); - for (j = 0; j < 16; ++j) - stored[i*16 + j] = c; - } + if (stored) { + /* smear each blend color component across 16 ubyte elements */ + for (i = 0; i < 4; ++i) { + uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]); + for (j = 0; j < 16; ++j) + stored[i*16 + j] = c; + } - setup->blend_color.stored = stored; + setup->blend_color.stored = stored; + + setup->fs.current.jit_context.blend_color = setup->blend_color.stored; + } - setup->fs.current.jit_context.blend_color = setup->blend_color.stored; setup->dirty |= LP_SETUP_NEW_FS; } @@ -662,17 +668,19 @@ lp_setup_update_state( struct lp_setup_context *setup ) stored = lp_scene_alloc_aligned(scene, 4 * sizeof(int32_t), 16); - stored[0] = (float) setup->scissor.current.minx; - stored[1] = (float) setup->scissor.current.miny; - stored[2] = (float) setup->scissor.current.maxx; - stored[3] = (float) setup->scissor.current.maxy; + if (stored) { + stored[0] = (float) setup->scissor.current.minx; + stored[1] = (float) setup->scissor.current.miny; + stored[2] = (float) setup->scissor.current.maxx; + stored[3] = (float) setup->scissor.current.maxy; - setup->scissor.stored = stored; + setup->scissor.stored = stored; - setup->fs.current.jit_context.scissor_xmin = stored[0]; - setup->fs.current.jit_context.scissor_ymin = stored[1]; - setup->fs.current.jit_context.scissor_xmax = stored[2]; - setup->fs.current.jit_context.scissor_ymax = stored[3]; + setup->fs.current.jit_context.scissor_xmin = stored[0]; + setup->fs.current.jit_context.scissor_ymin = stored[1]; + setup->fs.current.jit_context.scissor_xmax = stored[2]; + setup->fs.current.jit_context.scissor_ymax = stored[3]; + } setup->dirty |= LP_SETUP_NEW_FS; } @@ -852,3 +860,40 @@ fail: return NULL; } + +/** + * Put a BeginQuery command into all bins. + */ +void +lp_setup_begin_query(struct lp_setup_context *setup, + struct llvmpipe_query *pq) +{ + struct lp_scene * scene = lp_setup_get_current_scene(setup); + union lp_rast_cmd_arg cmd_arg; + + /* init the query to its beginning state */ + pq->done = FALSE; + pq->tile_count = 0; + pq->num_tiles = scene->tiles_x * scene->tiles_y; + assert(pq->num_tiles > 0); + + memset(pq->count, 0, sizeof(pq->count)); /* reset all counters */ + + cmd_arg.query_obj = pq; + lp_scene_bin_everywhere(scene, lp_rast_begin_query, cmd_arg); + pq->binned = TRUE; +} + + +/** + * Put an EndQuery command into all bins. + */ +void +lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) +{ + struct lp_scene * scene = lp_setup_get_current_scene(setup); + union lp_rast_cmd_arg cmd_arg; + + cmd_arg.query_obj = pq; + lp_scene_bin_everywhere(scene, lp_rast_end_query, cmd_arg); +} diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index e10d37d8d04..10db03b9c69 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -53,12 +53,15 @@ struct lp_shader_input { }; struct pipe_resource; +struct pipe_query; struct pipe_surface; struct pipe_blend_color; struct pipe_screen; struct pipe_framebuffer_state; struct lp_fragment_shader; struct lp_jit_context; +struct llvmpipe_query; + struct lp_setup_context * lp_setup_create( struct pipe_context *pipe, @@ -140,5 +143,12 @@ void lp_setup_set_vertex_info( struct lp_setup_context *setup, struct vertex_info *info ); +void +lp_setup_begin_query(struct lp_setup_context *setup, + struct llvmpipe_query *pq); + +void +lp_setup_end_query(struct lp_setup_context *setup, + struct llvmpipe_query *pq); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index f8a58165733..306cb6e27d2 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -205,8 +205,14 @@ static void setup_tri_coefficients( struct lp_setup_context *setup, switch (setup->fs.input[slot].interp) { case LP_INTERP_CONSTANT: - for (i = 0; i < NUM_CHANNELS; i++) - constant_coef(setup, tri, slot+1, v3[vert_attr][i], i); + if (setup->flatshade_first) { + for (i = 0; i < NUM_CHANNELS; i++) + constant_coef(setup, tri, slot+1, v1[vert_attr][i], i); + } + else { + for (i = 0; i < NUM_CHANNELS; i++) + constant_coef(setup, tri, slot+1, v3[vert_attr][i], i); + } break; case LP_INTERP_LINEAR: @@ -665,14 +671,14 @@ void lp_setup_choose_triangle( struct lp_setup_context *setup ) { switch (setup->cullmode) { - case PIPE_WINDING_NONE: + case PIPE_FACE_NONE: setup->triangle = triangle_both; break; - case PIPE_WINDING_CCW: - setup->triangle = triangle_cw; + case PIPE_FACE_BACK: + setup->triangle = setup->ccw_is_frontface ? triangle_ccw : triangle_cw; break; - case PIPE_WINDING_CW: - setup->triangle = triangle_ccw; + case PIPE_FACE_FRONT: + setup->triangle = setup->ccw_is_frontface ? triangle_cw : triangle_ccw; break; default: setup->triangle = triangle_nop; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c index 5d3122e8ba2..f6a424f25a8 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c @@ -131,11 +131,12 @@ static INLINE const_float4_ptr get_vert( const void *vertex_buffer, * draw elements / indexed primitives */ static void -lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) +lp_setup_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr) { struct lp_setup_context *setup = lp_setup_context(vbr); const unsigned stride = setup->vertex_info->size * sizeof(float); const void *vertex_buffer = setup->vertex_buffer; + const boolean flatshade_first = setup->flatshade_first; unsigned i; lp_setup_update_state(setup); @@ -178,35 +179,28 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLES: - if (setup->flatshade_first) { - for (i = 2; i < nr; i += 3) { - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); } break; case PIPE_PRIM_TRIANGLE_STRIP: - if (setup->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { + /* emit first triangle vertex as first triangle vertex */ setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i+(i&1)-1], stride), - get_vert(vertex_buffer, indices[i-(i&1)], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); + get_vert(vertex_buffer, indices[i-(i&1)], stride) ); + } } else { for (i = 2; i < nr; i += 1) { + /* emit last triangle vertex as last triangle vertex */ setup->triangle( setup, get_vert(vertex_buffer, indices[i+(i&1)-2], stride), get_vert(vertex_buffer, indices[i-(i&1)-1], stride), @@ -216,16 +210,18 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLE_FAN: - if (setup->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { + /* emit first non-spoke vertex as first vertex */ setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[0], stride), - get_vert(vertex_buffer, indices[i-1], stride) ); + get_vert(vertex_buffer, indices[0], stride) ); } } else { for (i = 2; i < nr; i += 1) { + /* emit last non-spoke vertex as last vertex */ setup->triangle( setup, get_vert(vertex_buffer, indices[0], stride), get_vert(vertex_buffer, indices[i-1], stride), @@ -235,43 +231,88 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_QUADS: - for (i = 3; i < nr; i += 4) { - setup->triangle( setup, + /* GL quads don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-0], stride) ); - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 3; i < nr; i += 2) { - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); + /* GL quad strips don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_POLYGON: /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. + * shading color. */ - for (i = 2; i < nr; i += 1) { - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[0], stride) ); + if (flatshade_first) { + /* emit first polygon vertex as first triangle vertex */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + else { + /* emit first polygon vertex as last triangle vertex */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } } break; @@ -292,6 +333,7 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) const unsigned stride = setup->vertex_info->size * sizeof(float); const void *vertex_buffer = (void *) get_vert(setup->vertex_buffer, start, stride); + const boolean flatshade_first = setup->flatshade_first; unsigned i; lp_setup_update_state(setup); @@ -334,35 +376,27 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLES: - if (setup->flatshade_first) { - for (i = 2; i < nr; i += 3) { - setup->triangle( setup, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-2, stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - setup->triangle( setup, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_TRIANGLE_STRIP: - if (setup->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i++) { + /* emit first triangle vertex as first triangle vertex */ setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i+(i&1)-1, stride), - get_vert(vertex_buffer, i-(i&1), stride), - get_vert(vertex_buffer, i-2, stride) ); + get_vert(vertex_buffer, i-(i&1), stride) ); } } else { for (i = 2; i < nr; i++) { + /* emit last triangle vertex as last triangle vertex */ setup->triangle( setup, get_vert(vertex_buffer, i+(i&1)-2, stride), get_vert(vertex_buffer, i-(i&1)-1, stride), @@ -372,16 +406,18 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLE_FAN: - if (setup->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { + /* emit first non-spoke vertex as first vertex */ setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride), - get_vert(vertex_buffer, i-1, stride) ); + get_vert(vertex_buffer, 0, stride) ); } } else { for (i = 2; i < nr; i += 1) { + /* emit last non-spoke vertex as last vertex */ setup->triangle( setup, get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride), @@ -391,42 +427,86 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_QUADS: - for (i = 3; i < nr; i += 4) { - setup->triangle( setup, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - setup->triangle( setup, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); + /* GL quads don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 3; i < nr; i += 2) { - setup->triangle( setup, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - setup->triangle( setup, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-0, stride) ); + /* GL quad strips don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_POLYGON: /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. + * shading color. */ - for (i = 2; i < nr; i += 1) { - setup->triangle( setup, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride) ); + if (flatshade_first) { + /* emit first polygon vertex as first triangle vertex */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + else { + /* emit first polygon vertex as last triangle vertex */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride) ); + } } break; @@ -463,7 +543,7 @@ lp_setup_init_vbuf(struct lp_setup_context *setup) setup->base.map_vertices = lp_setup_map_vertices; setup->base.unmap_vertices = lp_setup_unmap_vertices; setup->base.set_primitive = lp_setup_set_primitive; - setup->base.draw = lp_setup_draw; + setup->base.draw_elements = lp_setup_draw_elements; setup->base.draw_arrays = lp_setup_draw_arrays; setup->base.release_vertices = lp_setup_release_vertices; setup->base.destroy = lp_setup_vbuf_destroy; diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 18143807c91..bae5de0cb35 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -63,6 +63,11 @@ struct llvmpipe_context; struct lp_fragment_shader; +/** Indexes into jit_function[] array */ +#define RAST_WHOLE 0 +#define RAST_EDGE_TEST 1 + + struct lp_fragment_shader_variant_key { struct pipe_depth_state depth; @@ -73,6 +78,7 @@ struct lp_fragment_shader_variant_key unsigned nr_cbufs:8; unsigned flatshade:1; unsigned scissor:1; + unsigned occlusion_count:1; struct { ubyte colormask; @@ -86,6 +92,8 @@ struct lp_fragment_shader_variant { struct lp_fragment_shader_variant_key key; + boolean opaque; + LLVMValueRef function[2]; lp_jit_frag_func jit_function[2]; diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 113d77ab788..2edfcb28ce6 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -163,7 +163,8 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) LP_NEW_DEPTH_STENCIL_ALPHA | LP_NEW_RASTERIZER | LP_NEW_SAMPLER | - LP_NEW_SAMPLER_VIEW)) + LP_NEW_SAMPLER_VIEW | + LP_NEW_QUERY)) llvmpipe_update_fs( llvmpipe ); if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 5f861d6ca4d..9ef78e6badf 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -87,7 +87,6 @@ #include "lp_bld_depth.h" #include "lp_bld_interp.h" #include "lp_context.h" -#include "lp_debug.h" #include "lp_perf.h" #include "lp_screen.h" #include "lp_setup.h" @@ -148,7 +147,8 @@ generate_depth_stencil(LLVMBuilderRef builder, LLVMValueRef stencil_refs[2], LLVMValueRef src, LLVMValueRef dst_ptr, - LLVMValueRef facing) + LLVMValueRef facing, + LLVMValueRef counter) { const struct util_format_description *format_desc; struct lp_type dst_type; @@ -195,7 +195,8 @@ generate_depth_stencil(LLVMBuilderRef builder, stencil_refs, src, dst_ptr, - facing); + facing, + counter); } @@ -400,7 +401,8 @@ generate_fs(struct llvmpipe_context *lp, LLVMValueRef c2, LLVMValueRef step0_ptr, LLVMValueRef step1_ptr, - LLVMValueRef step2_ptr) + LLVMValueRef step2_ptr, + LLVMValueRef counter) { const struct tgsi_token *tokens = shader->base.tokens; LLVMTypeRef vec_type; @@ -466,12 +468,13 @@ generate_fs(struct llvmpipe_context *lp, if (early_depth_stencil_test) generate_depth_stencil(builder, key, type, &mask, - stencil_refs, z, depth_ptr, facing); + stencil_refs, z, depth_ptr, facing, counter); lp_build_tgsi_soa(builder, tokens, type, &mask, consts_ptr, interp->pos, interp->inputs, outputs, sampler, &shader->info); + /* loop over fragment shader outputs/results */ for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) { for(chan = 0; chan < NUM_CHANNELS; ++chan) { if(outputs[attrib][chan]) { @@ -513,7 +516,7 @@ generate_fs(struct llvmpipe_context *lp, if (!early_depth_stencil_test) generate_depth_stencil(builder, key, type, &mask, - stencil_refs, z, depth_ptr, facing); + stencil_refs, z, depth_ptr, facing, counter); lp_build_mask_end(&mask); @@ -528,9 +531,16 @@ generate_fs(struct llvmpipe_context *lp, /** * Generate color blending and color output. + * \param rt the render target index (to index blend, colormask state) + * \param type the pixel color type + * \param context_ptr pointer to the runtime JIT context + * \param mask execution mask (active fragment/pixel mask) + * \param src colors from the fragment shader + * \param dst_ptr the destination color buffer pointer */ static void generate_blend(const struct pipe_blend_state *blend, + unsigned rt, LLVMBuilderRef builder, struct lp_type type, LLVMValueRef context_ptr, @@ -561,6 +571,7 @@ generate_blend(const struct pipe_blend_state *blend, const_ptr = LLVMBuildBitCast(builder, const_ptr, LLVMPointerType(vec_type, 0), ""); + /* load constant blend color and colors from the dest color buffer */ for(chan = 0; chan < 4; ++chan) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0); con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), ""); @@ -571,10 +582,12 @@ generate_blend(const struct pipe_blend_state *blend, lp_build_name(dst[chan], "dst.%c", "rgba"[chan]); } - lp_build_blend_soa(builder, blend, type, src, dst, con, res); + /* do blend */ + lp_build_blend_soa(builder, blend, type, rt, src, dst, con, res); + /* store results to color buffer */ for(chan = 0; chan < 4; ++chan) { - if(blend->rt[0].colormask & (1 << chan)) { + if(blend->rt[rt].colormask & (1 << chan)) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0); lp_build_name(res[chan], "res.%c", "rgba"[chan]); res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]); @@ -587,20 +600,6 @@ generate_blend(const struct pipe_blend_state *blend, } -/** casting function to avoid compiler warnings */ -static lp_jit_frag_func -cast_voidptr_to_lp_jit_frag_func(void *p) -{ - union { - void *v; - lp_jit_frag_func f; - } tmp; - assert(sizeof(tmp.v) == sizeof(tmp.f)); - tmp.v = p; - return tmp.f; -} - - /** * Generate the runtime callable function for the whole fragment pipeline. * Note that the function which we generate operates on a block of 16 @@ -620,7 +619,7 @@ generate_fragment(struct llvmpipe_context *lp, LLVMTypeRef fs_elem_type; LLVMTypeRef fs_int_vec_type; LLVMTypeRef blend_vec_type; - LLVMTypeRef arg_types[15]; + LLVMTypeRef arg_types[16]; LLVMTypeRef func_type; LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type(); LLVMValueRef context_ptr; @@ -631,7 +630,7 @@ generate_fragment(struct llvmpipe_context *lp, LLVMValueRef dady_ptr; LLVMValueRef color_ptr_ptr; LLVMValueRef depth_ptr; - LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr; + LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr, counter = NULL; LLVMBasicBlockRef block; LLVMBuilderRef builder; LLVMValueRef x0; @@ -641,7 +640,6 @@ generate_fragment(struct llvmpipe_context *lp, LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH]; LLVMValueRef fs_out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][LP_MAX_VECTOR_LENGTH]; LLVMValueRef blend_mask; - LLVMValueRef blend_in_color[NUM_CHANNELS]; LLVMValueRef function; LLVMValueRef facing; unsigned num_fs; @@ -696,6 +694,7 @@ generate_fragment(struct llvmpipe_context *lp, arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step0 */ arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step1 */ arg_types[14] = LLVMPointerType(int32_vec4_type, 0);/* step2 */ + arg_types[15] = LLVMPointerType(LLVMInt32Type(), 0);/* counter */ func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); @@ -734,7 +733,7 @@ generate_fragment(struct llvmpipe_context *lp, lp_build_name(a0_ptr, "a0"); lp_build_name(dadx_ptr, "dadx"); lp_build_name(dady_ptr, "dady"); - lp_build_name(color_ptr_ptr, "color_ptr"); + lp_build_name(color_ptr_ptr, "color_ptr_ptr"); lp_build_name(depth_ptr, "depth"); lp_build_name(c0, "c0"); lp_build_name(c1, "c1"); @@ -743,6 +742,11 @@ generate_fragment(struct llvmpipe_context *lp, lp_build_name(step1_ptr, "step1"); lp_build_name(step2_ptr, "step2"); + if (key->occlusion_count) { + counter = LLVMGetParam(function, 15); + lp_build_name(counter, "counter"); + } + /* * Function body */ @@ -787,7 +791,7 @@ generate_fragment(struct llvmpipe_context *lp, facing, do_tri_test, c0, c1, c2, - step0_ptr, step1_ptr, step2_ptr); + step0_ptr, step1_ptr, step2_ptr, counter); for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) for(chan = 0; chan < NUM_CHANNELS; ++chan) @@ -801,6 +805,8 @@ generate_fragment(struct llvmpipe_context *lp, for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) { LLVMValueRef color_ptr; LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), cbuf, 0); + LLVMValueRef blend_in_color[NUM_CHANNELS]; + unsigned rt; /* * Convert the fs's output color and mask to fit to the blending type. @@ -821,10 +827,14 @@ generate_fragment(struct llvmpipe_context *lp, ""); lp_build_name(color_ptr, "color_ptr%d", cbuf); + /* which blend/colormask state to use */ + rt = key->blend.independent_blend_enable ? cbuf : 0; + /* * Blending. */ generate_blend(&key->blend, + rt, builder, blend_type, context_ptr, @@ -842,7 +852,7 @@ generate_fragment(struct llvmpipe_context *lp, #ifdef DEBUG if(LLVMVerifyFunction(function, LLVMPrintMessageAction)) { if (1) - LLVMDumpValue(function); + lp_debug_dump_value(function); abort(); } #endif @@ -851,9 +861,9 @@ generate_fragment(struct llvmpipe_context *lp, if (1) LLVMRunFunctionPassManager(screen->pass, function); - if (LP_DEBUG & DEBUG_JIT) { + if (gallivm_debug & GALLIVM_DEBUG_IR) { /* Print the LLVM IR to stderr */ - LLVMDumpValue(function); + lp_debug_dump_value(function); debug_printf("\n"); } @@ -865,12 +875,84 @@ generate_fragment(struct llvmpipe_context *lp, variant->jit_function[do_tri_test] = cast_voidptr_to_lp_jit_frag_func(f); - if (LP_DEBUG & DEBUG_ASM) + if (gallivm_debug & GALLIVM_DEBUG_ASM) { lp_disassemble(f); + } } } +static void +dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key) +{ + unsigned i; + + debug_printf("fs variant %p:\n", (void *) key); + + if (key->depth.enabled) { + debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format)); + debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE)); + debug_printf("depth.writemask = %u\n", key->depth.writemask); + } + + for (i = 0; i < 2; ++i) { + if (key->stencil[i].enabled) { + debug_printf("stencil[%u].func = %s\n", i, util_dump_func(key->stencil[i].func, TRUE)); + debug_printf("stencil[%u].fail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].fail_op, TRUE)); + debug_printf("stencil[%u].zpass_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zpass_op, TRUE)); + debug_printf("stencil[%u].zfail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zfail_op, TRUE)); + debug_printf("stencil[%u].valuemask = 0x%x\n", i, key->stencil[i].valuemask); + debug_printf("stencil[%u].writemask = 0x%x\n", i, key->stencil[i].writemask); + } + } + + if (key->alpha.enabled) { + debug_printf("alpha.func = %s\n", util_dump_func(key->alpha.func, TRUE)); + debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); + } + + if (key->blend.logicop_enable) { + debug_printf("blend.logicop_func = %s\n", util_dump_logicop(key->blend.logicop_func, TRUE)); + } + else if (key->blend.rt[0].blend_enable) { + debug_printf("blend.rgb_func = %s\n", util_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); + debug_printf("blend.rgb_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); + debug_printf("blend.rgb_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); + debug_printf("blend.alpha_func = %s\n", util_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); + debug_printf("blend.alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); + debug_printf("blend.alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); + } + debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask); + for (i = 0; i < PIPE_MAX_SAMPLERS; ++i) { + if (key->sampler[i].format) { + debug_printf("sampler[%u] = \n", i); + debug_printf(" .format = %s\n", + util_format_name(key->sampler[i].format)); + debug_printf(" .target = %s\n", + util_dump_tex_target(key->sampler[i].target, TRUE)); + debug_printf(" .pot = %u %u %u\n", + key->sampler[i].pot_width, + key->sampler[i].pot_height, + key->sampler[i].pot_depth); + debug_printf(" .wrap = %s %s %s\n", + util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), + util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), + util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); + debug_printf(" .min_img_filter = %s\n", + util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); + debug_printf(" .min_mip_filter = %s\n", + util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); + debug_printf(" .mag_img_filter = %s\n", + util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); + if (key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE) + debug_printf(" .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE)); + debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords); + } + } +} + + + static struct lp_fragment_shader_variant * generate_variant(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, @@ -878,57 +960,9 @@ generate_variant(struct llvmpipe_context *lp, { struct lp_fragment_shader_variant *variant; - if (LP_DEBUG & DEBUG_JIT) { - unsigned i; - + if (gallivm_debug & GALLIVM_DEBUG_IR) { tgsi_dump(shader->base.tokens, 0); - if(key->depth.enabled) { - debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format)); - debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE)); - debug_printf("depth.writemask = %u\n", key->depth.writemask); - } - if(key->alpha.enabled) { - debug_printf("alpha.func = %s\n", util_dump_func(key->alpha.func, TRUE)); - debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); - } - if(key->blend.logicop_enable) { - debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func); - } - else if(key->blend.rt[0].blend_enable) { - debug_printf("blend.rgb_func = %s\n", util_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); - debug_printf("rgb_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); - debug_printf("rgb_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); - debug_printf("alpha_func = %s\n", util_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); - debug_printf("alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); - debug_printf("alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); - } - debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask); - for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { - if(key->sampler[i].format) { - debug_printf("sampler[%u] = \n", i); - debug_printf(" .format = %s\n", - util_format_name(key->sampler[i].format)); - debug_printf(" .target = %s\n", - util_dump_tex_target(key->sampler[i].target, TRUE)); - debug_printf(" .pot = %u %u %u\n", - key->sampler[i].pot_width, - key->sampler[i].pot_height, - key->sampler[i].pot_depth); - debug_printf(" .wrap = %s %s %s\n", - util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), - util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), - util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); - debug_printf(" .min_img_filter = %s\n", - util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); - debug_printf(" .min_mip_filter = %s\n", - util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); - debug_printf(" .mag_img_filter = %s\n", - util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); - if(key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE) - debug_printf(" .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE)); - debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords); - } - } + dump_fs_variant_key(key); } variant = CALLOC_STRUCT(lp_fragment_shader_variant); @@ -937,8 +971,20 @@ generate_variant(struct llvmpipe_context *lp, memcpy(&variant->key, key, sizeof *key); - generate_fragment(lp, shader, variant, 0); - generate_fragment(lp, shader, variant, 1); + generate_fragment(lp, shader, variant, RAST_WHOLE); + generate_fragment(lp, shader, variant, RAST_EDGE_TEST); + + /* TODO: most of these can be relaxed, in particular the colormask */ + variant->opaque = + !key->blend.logicop_enable && + !key->blend.rt[0].blend_enable && + key->blend.rt[0].colormask == 0xf && + !key->stencil[0].enabled && + !key->alpha.enabled && + !key->depth.enabled && + !key->scissor && + !shader->info.uses_kill + ? TRUE : FALSE; /* insert new variant into linked list */ variant->next = shader->variants; @@ -964,7 +1010,7 @@ llvmpipe_create_fs_state(struct pipe_context *pipe, /* we need to keep a local copy of the tokens */ shader->base.tokens = tgsi_dup_tokens(templ->tokens); - if (LP_DEBUG & DEBUG_TGSI) { + if (gallivm_debug & GALLIVM_DEBUG_TGSI) { debug_printf("llvmpipe: Create fragment shader %p:\n", (void *) shader); tgsi_dump(templ->tokens, 0); } @@ -1123,6 +1169,9 @@ make_variant_key(struct llvmpipe_context *lp, key->flatshade = lp->rasterizer->flatshade; key->scissor = lp->rasterizer->scissor; + if (lp->active_query_count) { + key->occlusion_count = TRUE; + } if (lp->framebuffer.nr_cbufs) { memcpy(&key->blend, lp->blend, sizeof key->blend); @@ -1187,7 +1236,6 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) struct lp_fragment_shader *shader = lp->fs; struct lp_fragment_shader_variant_key key; struct lp_fragment_shader_variant *variant; - boolean opaque; make_variant_key(lp, shader, &key); @@ -1212,22 +1260,10 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) LP_COUNT_ADD(nr_llvm_compiles, 2); /* emit vs. omit in/out test */ } - /* TODO: put this in the variant */ - /* TODO: most of these can be relaxed, in particular the colormask */ - opaque = !key.blend.logicop_enable && - !key.blend.rt[0].blend_enable && - key.blend.rt[0].colormask == 0xf && - !key.stencil[0].enabled && - !key.alpha.enabled && - !key.depth.enabled && - !key.scissor && - !shader->info.uses_kill - ? TRUE : FALSE; - lp_setup_set_fs_functions(lp->setup, variant->jit_function[RAST_WHOLE], variant->jit_function[RAST_EDGE_TEST], - opaque); + variant->opaque); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c index 622eb47ff45..afd3e0b21c9 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c +++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c @@ -67,8 +67,8 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle) */ if (llvmpipe->rasterizer) { lp_setup_set_triangle_state( llvmpipe->setup, - llvmpipe->rasterizer->cull_mode, - llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW, + llvmpipe->rasterizer->cull_face, + llvmpipe->rasterizer->front_ccw, llvmpipe->rasterizer->scissor, llvmpipe->rasterizer->gl_rasterization_rules); lp_setup_set_flatshade_first( llvmpipe->setup, diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c index fae7bf3fcf2..072d699666b 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c @@ -52,6 +52,19 @@ enum vector_mode typedef void (*blend_test_ptr_t)(const void *src, const void *dst, const void *con, void *res); +/** cast wrapper */ +static blend_test_ptr_t +voidptr_to_blend_test_ptr_t(void *p) +{ + union { + void *v; + blend_test_ptr_t f; + } u; + u.v = p; + return u.f; +} + + void write_tsv_header(FILE *fp) @@ -163,6 +176,7 @@ add_blend_test(LLVMModuleRef module, LLVMValueRef res_ptr; LLVMBasicBlockRef block; LLVMBuilderRef builder; + const unsigned rt = 0; vec_type = lp_build_vec_type(type); @@ -188,7 +202,7 @@ add_blend_test(LLVMModuleRef module, dst = LLVMBuildLoad(builder, dst_ptr, "dst"); con = LLVMBuildLoad(builder, const_ptr, "const"); - res = lp_build_blend_aos(builder, blend, type, src, dst, con, 3); + res = lp_build_blend_aos(builder, blend, type, rt, src, dst, con, 3); lp_build_name(res, "res"); @@ -212,7 +226,7 @@ add_blend_test(LLVMModuleRef module, lp_build_name(dst[i], "dst.%c", "rgba"[i]); } - lp_build_blend_soa(builder, blend, type, src, dst, con, res); + lp_build_blend_soa(builder, blend, type, rt, src, dst, con, res); for(i = 0; i < 4; ++i) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); @@ -481,6 +495,7 @@ test_one(unsigned verbose, int64_t cycles[LP_TEST_NUM_SAMPLES]; double cycles_avg = 0.0; unsigned i, j; + void *code; if(verbose >= 1) dump_blend_type(stdout, blend, mode, type); @@ -522,10 +537,11 @@ test_one(unsigned verbose, if(verbose >= 2) LLVMDumpModule(module); - blend_test_ptr = (blend_test_ptr_t)LLVMGetPointerToGlobal(engine, func); + code = LLVMGetPointerToGlobal(engine, func); + blend_test_ptr = voidptr_to_blend_test_ptr_t(code); if(verbose >= 2) - lp_disassemble(blend_test_ptr); + lp_disassemble(code); success = TRUE; for(i = 0; i < n && success; ++i) { diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c index 958cc40538e..254f0daea3b 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c @@ -43,6 +43,17 @@ typedef void (*conv_test_ptr_t)(const void *src, const void *dst); +/** cast wrapper */ +static conv_test_ptr_t +voidptr_to_conv_test_ptr_t(void *p) +{ + union { + void *v; + conv_test_ptr_t f; + } u; + u.v = p; + return u.f; +} void write_tsv_header(FILE *fp) @@ -164,6 +175,7 @@ test_one(unsigned verbose, unsigned num_dsts; double eps; unsigned i, j; + void *code; if(verbose >= 1) dump_conv_types(stdout, src_type, dst_type); @@ -221,10 +233,11 @@ test_one(unsigned verbose, if(verbose >= 2) LLVMDumpModule(module); - conv_test_ptr = (conv_test_ptr_t)LLVMGetPointerToGlobal(engine, func); + code = LLVMGetPointerToGlobal(engine, func); + conv_test_ptr = voidptr_to_conv_test_ptr_t(code); if(verbose >= 2) - lp_disassemble(conv_test_ptr); + lp_disassemble(code); success = TRUE; for(i = 0; i < n && success; ++i) { @@ -384,7 +397,7 @@ test_all(unsigned verbose, FILE *fp) { const struct lp_type *src_type; const struct lp_type *dst_type; - bool success = TRUE; + boolean success = TRUE; for(src_type = conv_types; src_type < &conv_types[num_types]; ++src_type) { for(dst_type = conv_types; dst_type < &conv_types[num_types]; ++dst_type) { @@ -411,7 +424,7 @@ test_some(unsigned verbose, FILE *fp, unsigned long n) const struct lp_type *src_type; const struct lp_type *dst_type; unsigned long i; - bool success = TRUE; + boolean success = TRUE; for(i = 0; i < n; ++i) { src_type = &conv_types[rand() % num_types]; diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c index fbac815d107..267f1487bb8 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_format.c +++ b/src/gallium/drivers/llvmpipe/lp_test_format.c @@ -73,6 +73,19 @@ typedef void (*fetch_ptr_t)(float *, const void *packed, unsigned i, unsigned j); +/** cast wrapper to avoid warnings */ +static fetch_ptr_t +void_to_fetch_ptr_t(void *p) +{ + union { + void *v; + fetch_ptr_t f; + } u; + u.v = p; + return u.f; +} + + static LLVMValueRef add_fetch_rgba_test(LLVMModuleRef lp_build_module, @@ -125,7 +138,7 @@ test_format(unsigned verbose, FILE *fp, fetch_ptr_t fetch_ptr; float unpacked[4]; boolean success; - unsigned i; + unsigned i, j, k; fetch = add_fetch_rgba_test(lp_build_module, desc); @@ -149,31 +162,39 @@ test_format(unsigned verbose, FILE *fp, (void)pass; #endif - fetch_ptr = (fetch_ptr_t) LLVMGetPointerToGlobal(lp_build_engine, fetch); + fetch_ptr = void_to_fetch_ptr_t(LLVMGetPointerToGlobal(lp_build_engine, fetch)); - memset(unpacked, 0, sizeof unpacked); + for (i = 0; i < desc->block.height; ++i) { + for (j = 0; j < desc->block.width; ++j) { - fetch_ptr(unpacked, test->packed, 0, 0); + memset(unpacked, 0, sizeof unpacked); - success = TRUE; - for(i = 0; i < 4; ++i) - if (fabs((float)test->unpacked[0][0][i] - unpacked[i]) > FLT_EPSILON) - success = FALSE; + fetch_ptr(unpacked, test->packed, j, i); - if (!success) { - printf("FAILED\n"); - printf(" Packed: %02x %02x %02x %02x\n", - test->packed[0], test->packed[1], test->packed[2], test->packed[3]); - printf(" Unpacked: %f %f %f %f obtained\n", - unpacked[0], unpacked[1], unpacked[2], unpacked[3]); - printf(" %f %f %f %f expected\n", - test->unpacked[0][0][0], - test->unpacked[0][0][1], - test->unpacked[0][0][2], - test->unpacked[0][0][3]); - LLVMDumpValue(fetch); + success = TRUE; + for(k = 0; k < 4; ++k) + if (fabs((float)test->unpacked[i][j][k] - unpacked[k]) > FLT_EPSILON) + success = FALSE; + + if (!success) { + printf("FAILED\n"); + printf(" Packed: %02x %02x %02x %02x\n", + test->packed[0], test->packed[1], test->packed[2], test->packed[3]); + printf(" Unpacked (%u,%u): %f %f %f %f obtained\n", + j, i, + unpacked[0], unpacked[1], unpacked[2], unpacked[3]); + printf(" %f %f %f %f expected\n", + test->unpacked[i][j][0], + test->unpacked[i][j][1], + test->unpacked[i][j][2], + test->unpacked[i][j][3]); + } + } } + if (!success) + LLVMDumpValue(fetch); + LLVMFreeMachineCodeForFunction(lp_build_engine, fetch); LLVMDeleteFunction(fetch); @@ -193,20 +214,23 @@ test_one(unsigned verbose, FILE *fp, const struct util_format_description *format_desc) { unsigned i; - bool success = TRUE; - - printf("Testing %s ...\n", - format_desc->name); + boolean first = TRUE; + boolean success = TRUE; for (i = 0; i < util_format_nr_test_cases; ++i) { const struct util_format_test_case *test = &util_format_test_cases[i]; if (test->format == format_desc->format) { + if (first) { + printf("Testing %s ...\n", + format_desc->name); + first = FALSE; + } + if (!test_format(verbose, fp, format_desc, test)) { success = FALSE; } - } } @@ -218,7 +242,7 @@ boolean test_all(unsigned verbose, FILE *fp) { enum pipe_format format; - bool success = TRUE; + boolean success = TRUE; for (format = 1; format < PIPE_FORMAT_COUNT; ++format) { const struct util_format_description *format_desc; @@ -232,9 +256,7 @@ test_all(unsigned verbose, FILE *fp) * TODO: test more */ - if (format_desc->block.width != 1 || - format_desc->block.height != 1 || - format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { + if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { continue; } diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c index e5e5925012a..13485c37748 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_printf.c +++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c @@ -41,6 +41,7 @@ struct printf_test_case { + int foo; }; void @@ -57,6 +58,19 @@ write_tsv_header(FILE *fp) typedef void (*test_printf_t)(int i); +/** cast wrapper */ +static test_printf_t +voidptr_to_test_printf_t(void *p) +{ + union { + void *v; + test_printf_t f; + } u; + u.v = p; + return u.f; +} + + static LLVMValueRef add_printf_test(LLVMModuleRef module) { @@ -91,6 +105,7 @@ test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase) float unpacked[4]; unsigned packed; boolean success = TRUE; + void *code; module = LLVMModuleCreateWithName("test"); @@ -124,7 +139,8 @@ test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase) (void)pass; #endif - test_printf = (test_printf_t)LLVMGetPointerToGlobal(engine, test); + code = LLVMGetPointerToGlobal(engine, test); + test_printf = voidptr_to_test_printf_t(code); memset(unpacked, 0, sizeof unpacked); packed = 0; @@ -147,7 +163,7 @@ test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase) boolean test_all(unsigned verbose, FILE *fp) { - bool success = TRUE; + boolean success = TRUE; test_printf(verbose, fp, NULL); diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index d3a9d39f616..65208dd5d5c 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -87,7 +87,7 @@ struct lp_llvm_sampler_soa * @sa http://llvm.org/docs/GetElementPtr.html */ static LLVMValueRef -lp_llvm_texture_member(struct lp_sampler_dynamic_state *base, +lp_llvm_texture_member(const struct lp_sampler_dynamic_state *base, LLVMBuilderRef builder, unsigned unit, unsigned member_index, @@ -135,7 +135,7 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base, */ #define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \ static LLVMValueRef \ - lp_llvm_texture_##_name( struct lp_sampler_dynamic_state *base, \ + lp_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \ LLVMBuilderRef builder, \ unsigned unit) \ { \ @@ -164,7 +164,7 @@ lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler) * The 'texel' parameter returns four vectors corresponding to R, G, B, A. */ static void -lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base, +lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base, LLVMBuilderRef builder, struct lp_type type, unsigned unit, diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 2f41d620c8a..4eed687ac71 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -39,6 +39,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_simple_list.h" #include "util/u_transfer.h" #include "lp_context.h" @@ -51,6 +52,11 @@ #include "state_tracker/sw_winsys.h" +#ifdef DEBUG +static struct llvmpipe_resource resource_list; +#endif + + static INLINE boolean resource_is_texture(const struct pipe_resource *resource) { @@ -107,32 +113,55 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS); for (level = 0; level <= pt->last_level; level++) { - const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE; - const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE; - unsigned nblocksx, num_slices; - - if (lpr->base.target == PIPE_TEXTURE_CUBE) - num_slices = 6; - else if (lpr->base.target == PIPE_TEXTURE_3D) - num_slices = depth; - else - num_slices = 1; - - /* Allocate storage for whole quads. This is particularly important - * for depth surfaces, which are currently stored in a swizzled format. - */ - nblocksx = util_format_get_nblocksx(pt->format, align(width, TILE_SIZE)); - lpr->row_stride[level] = - align(nblocksx * util_format_get_blocksize(pt->format), 16); + /* Row stride and image stride (for linear layout) */ + { + unsigned alignment, nblocksx, nblocksy, block_size; + + /* For non-compressed formats we need to align the texture size + * to the tile size to facilitate render-to-texture. + */ + if (util_format_is_compressed(pt->format)) + alignment = 1; + else + alignment = TILE_SIZE; + + nblocksx = util_format_get_nblocksx(pt->format, + align(width, alignment)); + nblocksy = util_format_get_nblocksy(pt->format, + align(height, alignment)); + block_size = util_format_get_blocksize(pt->format); - lpr->img_stride[level] = lpr->row_stride[level] * align(height, TILE_SIZE); + lpr->row_stride[level] = align(nblocksx * block_size, 16); - lpr->tiles_per_row[level] = width_t; - lpr->tiles_per_image[level] = width_t * height_t; - lpr->num_slices_faces[level] = num_slices; - lpr->layout[level] = alloc_layout_array(num_slices, width, height); + lpr->img_stride[level] = lpr->row_stride[level] * nblocksy; + } + /* Size of the image in tiles (for tiled layout) */ + { + const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE; + const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE; + lpr->tiles_per_row[level] = width_t; + lpr->tiles_per_image[level] = width_t * height_t; + } + + /* Number of 3D image slices or cube faces */ + { + unsigned num_slices; + + if (lpr->base.target == PIPE_TEXTURE_CUBE) + num_slices = 6; + else if (lpr->base.target == PIPE_TEXTURE_3D) + num_slices = depth; + else + num_slices = 1; + + lpr->num_slices_faces[level] = num_slices; + + lpr->layout[level] = alloc_layout_array(num_slices, width, height); + } + + /* Compute size of next mipmap level */ width = u_minify(width, 1); height = u_minify(height, 1); depth = u_minify(depth, 1); @@ -222,6 +251,10 @@ llvmpipe_resource_create(struct pipe_screen *_screen, lpr->id = id_counter++; +#ifdef DEBUG + insert_at_tail(&resource_list, lpr); +#endif + return &lpr->base; fail: @@ -280,6 +313,11 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen, align_free(lpr->data); } +#ifdef DEBUG + if (lpr->next) + remove_from_list(lpr); +#endif + FREE(lpr); } @@ -450,7 +488,7 @@ static struct pipe_surface * llvmpipe_get_tex_surface(struct pipe_screen *screen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, - enum lp_texture_usage usage) + unsigned usage) { struct pipe_surface *ps; @@ -698,11 +736,8 @@ tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level, return buffer_size; } else { - const enum pipe_format format = lpr->base.format; - const unsigned nblocksy = - util_format_get_nblocksy(format, align(height, TILE_SIZE)); - const unsigned buffer_size = nblocksy * lpr->row_stride[level]; - return buffer_size; + /* we already computed this */ + return lpr->img_stride[level]; } } @@ -1188,9 +1223,43 @@ llvmpipe_resource_size(const struct pipe_resource *resource) } +#ifdef DEBUG +void +llvmpipe_print_resources(void) +{ + struct llvmpipe_resource *lpr; + unsigned n = 0, total = 0; + + debug_printf("LLVMPIPE: current resources:\n"); + foreach(lpr, &resource_list) { + unsigned size = llvmpipe_resource_size(&lpr->base); + debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n", + lpr->id, (void *) lpr, + lpr->base.width0, lpr->base.height0, lpr->base.depth0, + size, lpr->base.reference.count); + total += size; + n++; + } + debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total); +} +#endif + + void llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen) { +#ifdef DEBUG + /* init linked list for tracking resources */ + { + static boolean first_call = TRUE; + if (first_call) { + memset(&resource_list, 0, sizeof(resource_list)); + make_empty_list(&resource_list); + first_call = FALSE; + } + } +#endif + screen->resource_create = llvmpipe_resource_create; screen->resource_destroy = llvmpipe_resource_destroy; screen->resource_from_handle = llvmpipe_resource_from_handle; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index a8d08d6247f..503b6a19a8d 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -119,6 +119,11 @@ struct llvmpipe_resource unsigned timestamp; unsigned id; /**< temporary, for debugging */ + +#ifdef DEBUG + /** for linked list */ + struct llvmpipe_resource *prev, *next; +#endif }; @@ -220,6 +225,10 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr, extern void +llvmpipe_print_resources(void); + + +extern void llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen); extern void diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 89d5ffa8aa3..60bdd7276aa 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -5,6 +5,7 @@ #include "util/u_memory.h" #include "util/u_inlines.h" #include "util/u_format.h" +#include "util/u_format_s3tc.h" #include <stdio.h> #include <errno.h> @@ -246,6 +247,8 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) pscreen->fence_signalled = nouveau_screen_fence_signalled; pscreen->fence_finish = nouveau_screen_fence_finish; + util_format_s3tc_init(); + return 0; } diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 0156ff95ff9..97f938e6980 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -4208,9 +4208,12 @@ static void nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) { struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_program_exec *e; uint32_t *up, i; boolean upload = FALSE; + unsigned offset; + int width; if (!p->bo) { nouveau_bo_new(chan->device, NOUVEAU_BO_VRAM, 0x100, @@ -4267,10 +4270,22 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) NOUVEAU_ERR("0x%08x\n", e->inst[1]); } #endif - nv50_upload_sifc(nv50, p->bo, 0, NOUVEAU_BO_VRAM, - NV50_2D_DST_FORMAT_R8_UNORM, 65536, 1, 262144, - up, NV50_2D_SIFC_FORMAT_R8_UNORM, 0, - 0, 0, p->exec_size * 4, 1, 1); + + /* SIFC_HEIGHT/SIFC_WIDTH of 65536 do not work, and are not reported + * as data error either. hw bug ? */ +#define SIFC_MAX_WIDTH (65536 - 256) + offset = 0; + width = p->exec_size * 4; + while (width > 0) { + nv50_upload_sifc(nv50, p->bo, offset, NOUVEAU_BO_VRAM, + NV50_2D_DST_FORMAT_R8_UNORM, 65536, 1, 262144, + &up[offset / 4], NV50_2D_SIFC_FORMAT_R8_UNORM, + 0, 0, 0, MIN2(SIFC_MAX_WIDTH, width), 1, 1); + width -= SIFC_MAX_WIDTH; + offset += SIFC_MAX_WIDTH; + } + BEGIN_RING(chan, tesla, NV50TCL_CODE_CB_FLUSH, 1); + OUT_RING (chan, 0); FREE(up); } diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 244242b8434..c3ac8041462 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -108,7 +108,7 @@ emit_vertex(struct push_context *ctx, unsigned n) int i; if (ctx->edgeflag_attr < 16) { - float *edgeflag = ctx->attr[ctx->edgeflag_attr].map + + float *edgeflag = (uint8_t *)ctx->attr[ctx->edgeflag_attr].map + ctx->attr[ctx->edgeflag_attr].stride * n; if (*edgeflag != ctx->edgeflag) { @@ -120,7 +120,8 @@ emit_vertex(struct push_context *ctx, unsigned n) BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, ctx->vtx_size); for (i = 0; i < ctx->attr_nr; i++) - ctx->attr[i].push(chan, ctx->attr[i].map + ctx->attr[i].stride * n); + ctx->attr[i].push(chan, + (uint8_t *)ctx->attr[i].map + ctx->attr[i].stride * n); } static void @@ -243,14 +244,14 @@ nv50_push_elements_instanced(struct pipe_context *pipe, assert(bo->map); return; } - ctx.attr[n].map = bo->map + vb->buffer_offset + ve->src_offset; + ctx.attr[n].map = (uint8_t *)bo->map + vb->buffer_offset + ve->src_offset; nouveau_bo_unmap(bo); ctx.attr[n].stride = vb->stride; ctx.attr[n].divisor = ve->instance_divisor; if (ctx.attr[n].divisor) { ctx.attr[n].step = i_start % ve->instance_divisor; - ctx.attr[n].map += i_start * vb->stride; + ctx.attr[n].map = (uint8_t *)ctx.attr[n].map + i_start * vb->stride; } size = util_format_get_component_bits(ve->src_format, @@ -331,7 +332,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe, ctx.attr[i].divisor != ++ctx.attr[i].step) continue; ctx.attr[i].step = 0; - ctx.attr[i].map += ctx.attr[i].stride; + ctx.attr[i].map = (uint8_t *)ctx.attr[i].map + ctx.attr[i].stride; } u_split_prim_init(&s, mode, start, count); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index a8cb1e25d81..2c0caada366 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -20,6 +20,7 @@ * SOFTWARE. */ +#include "util/u_format_s3tc.h" #include "pipe/p_screen.h" #include "nv50_context.h" @@ -64,6 +65,17 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, break; } } else { + if (tex_usage & PIPE_BIND_SAMPLER_VIEW) { + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + return util_format_s3tc_enabled; + default: + break; + } + } switch (format) { case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_B8G8R8X8_UNORM: @@ -76,10 +88,6 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8A8_UNORM: - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: case PIPE_FORMAT_S8_USCALED_Z24_UNORM: case PIPE_FORMAT_Z24_UNORM_S8_USCALED: case PIPE_FORMAT_Z32_FLOAT: @@ -98,7 +106,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, } static int -nv50_screen_get_param(struct pipe_screen *pscreen, int param) +nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: @@ -121,6 +129,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) return 8; case PIPE_CAP_OCCLUSION_QUERY: return 1; + case PIPE_CAP_TIMER_QUERY: + return 0; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: @@ -146,6 +156,34 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 0; + case PIPE_CAP_MAX_VS_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: + case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: /* arbitrary limit */ + return 16384; + case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: + case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: /* need stack bo */ + return 4; + case PIPE_CAP_MAX_VS_INPUTS: + return 16; + case PIPE_CAP_MAX_FS_INPUTS: /* 128 / 4 with GP */ + return 64 / 4; + case PIPE_CAP_MAX_VS_CONSTS: + case PIPE_CAP_MAX_FS_CONSTS: + return 65536 / 16; + case PIPE_CAP_MAX_VS_ADDRS: + case PIPE_CAP_MAX_FS_ADDRS: /* no spilling atm */ + return 1; + case PIPE_CAP_MAX_VS_PREDS: + case PIPE_CAP_MAX_FS_PREDS: /* not yet handled */ + return 0; + case PIPE_CAP_MAX_VS_TEMPS: + case PIPE_CAP_MAX_FS_TEMPS: /* no spilling atm */ + return 128 / 4; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; @@ -153,7 +191,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) } static float -nv50_screen_get_paramf(struct pipe_screen *pscreen, int param) +nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index cf4105bcb77..f8bff764f27 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -345,7 +345,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, CALLOC_STRUCT(nv50_rasterizer_stateobj); /*XXX: ignored - * - light_twosize + * - light_twoside * - point_smooth * - multisample * - point_sprite / sprite_coord_mode @@ -385,72 +385,44 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, so_data (so, cso->point_quad_rasterization ? 1 : 0); so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3); - if (cso->front_winding == PIPE_WINDING_CCW) { - so_data(so, nvgl_polygon_mode(cso->fill_ccw)); - so_data(so, nvgl_polygon_mode(cso->fill_cw)); - } else { - so_data(so, nvgl_polygon_mode(cso->fill_cw)); - so_data(so, nvgl_polygon_mode(cso->fill_ccw)); - } + so_data(so, nvgl_polygon_mode(cso->fill_front)); + so_data(so, nvgl_polygon_mode(cso->fill_back)); so_data(so, cso->poly_smooth ? 1 : 0); so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3); - so_data (so, cso->cull_mode != PIPE_WINDING_NONE); - if (cso->front_winding == PIPE_WINDING_CCW) { + so_data (so, cso->cull_face != PIPE_FACE_NONE); + if (cso->front_ccw) { so_data(so, NV50TCL_FRONT_FACE_CCW); - switch (cso->cull_mode) { - case PIPE_WINDING_CCW: - so_data(so, NV50TCL_CULL_FACE_FRONT); - break; - case PIPE_WINDING_CW: - so_data(so, NV50TCL_CULL_FACE_BACK); - break; - case PIPE_WINDING_BOTH: - so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); - break; - default: - so_data(so, NV50TCL_CULL_FACE_BACK); - break; - } - } else { + } + else { so_data(so, NV50TCL_FRONT_FACE_CW); - switch (cso->cull_mode) { - case PIPE_WINDING_CCW: - so_data(so, NV50TCL_CULL_FACE_BACK); - break; - case PIPE_WINDING_CW: - so_data(so, NV50TCL_CULL_FACE_FRONT); - break; - case PIPE_WINDING_BOTH: - so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); - break; - default: - so_data(so, NV50TCL_CULL_FACE_BACK); - break; - } + } + switch (cso->cull_face) { + case PIPE_FACE_FRONT: + so_data(so, NV50TCL_CULL_FACE_FRONT); + break; + case PIPE_FACE_BACK: + so_data(so, NV50TCL_CULL_FACE_BACK); + break; + case PIPE_FACE_FRONT_AND_BACK: + so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV50TCL_CULL_FACE_BACK); + break; } so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1); so_data (so, cso->poly_stipple_enable ? 1 : 0); so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3); - if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || - (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) - so_data(so, 1); - else - so_data(so, 0); - if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) || - (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE)) - so_data(so, 1); - else - so_data(so, 0); - if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) || - (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL)) - so_data(so, 1); - else - so_data(so, 0); + so_data(so, cso->offset_point); + so_data(so, cso->offset_line); + so_data(so, cso->offset_tri); - if (cso->offset_cw || cso->offset_ccw) { + if (cso->offset_point || + cso->offset_line || + cso->offset_tri) { so_method(so, tesla, NV50TCL_POLYGON_OFFSET_FACTOR, 1); so_data (so, fui(cso->offset_scale)); so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index c5581a6f9d0..f973cf24b98 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -274,7 +274,6 @@ nv50_upload_sifc(struct nv50_context *nv50, { struct nouveau_channel *chan = nv50->screen->base.channel; struct nouveau_grobj *eng2d = nv50->screen->eng2d; - struct nouveau_grobj *tesla = nv50->screen->tesla; unsigned line_dwords = (w * cpp + 3) / 4; reloc |= NOUVEAU_BO_WR; @@ -346,7 +345,4 @@ nv50_upload_sifc(struct nv50_context *nv50, src = (uint8_t *) src + src_pitch; } - - BEGIN_RING(chan, tesla, NV50TCL_CODE_CB_FLUSH, 1); - OUT_RING (chan, 0); } diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 1786af776aa..7e534a0c738 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -1,5 +1,6 @@ #include "pipe/p_screen.h" #include "pipe/p_state.h" +#include "util/u_format_s3tc.h" #include "util/u_simple_screen.h" #include "nouveau/nouveau_screen.h" @@ -29,7 +30,7 @@ struct nouveau_winsys { #define NV6X_GRCLASS4497_CHIPSETS 0x00000088 static int -nvfx_screen_get_param(struct pipe_screen *pscreen, int param) +nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) { struct nvfx_screen *screen = nvfx_screen(pscreen); @@ -51,6 +52,8 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, int param) return screen->is_nv4x ? 4 : 2; case PIPE_CAP_OCCLUSION_QUERY: return 1; + case PIPE_CAP_TIMER_QUERY: + return 0; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: @@ -83,6 +86,45 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 0; + case PIPE_CAP_MAX_FS_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: + return 4096; + case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: + /* FIXME: is it the dynamic (nv30:0/nv40:24) or the static + value (nv30:0/nv40:4) ? */ + return screen->is_nv4x ? 4 : 0; + case PIPE_CAP_MAX_FS_INPUTS: + return 10; + case PIPE_CAP_MAX_FS_CONSTS: + return screen->is_nv4x ? 224 : 32; + case PIPE_CAP_MAX_FS_TEMPS: + return 32; + case PIPE_CAP_MAX_FS_ADDRS: + return screen->is_nv4x ? 1 : 0; + case PIPE_CAP_MAX_FS_PREDS: + return screen->is_nv4x ? 1 : 0; + case PIPE_CAP_MAX_VS_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: + return screen->is_nv4x ? 512 : 256; + case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: + return screen->is_nv4x ? 512 : 0; + case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: + /* FIXME: is it the dynamic (nv30:24/nv40:24) or the static + value (nv30:1/nv40:4) ? */ + return screen->is_nv4x ? 4 : 1; + case PIPE_CAP_MAX_VS_INPUTS: + return 16; + case PIPE_CAP_MAX_VS_CONSTS: + return 256; + case PIPE_CAP_MAX_VS_TEMPS: + return screen->is_nv4x ? 32 : 13; + case PIPE_CAP_MAX_VS_ADDRS: + return 2; + case PIPE_CAP_MAX_VS_PREDS: + return screen->is_nv4x ? 1 : 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; @@ -90,7 +132,7 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, int param) } static float -nvfx_screen_get_paramf(struct pipe_screen *pscreen, int param) +nvfx_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param) { struct nvfx_screen *screen = nvfx_screen(pscreen); @@ -149,6 +191,17 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen, } } else { switch (format) { + if (tex_usage & PIPE_BIND_SAMPLER_VIEW) { + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + return util_format_s3tc_enabled; + default: + break; + } + } case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_B8G8R8X8_UNORM: case PIPE_FORMAT_B5G5R5A1_UNORM: @@ -160,10 +213,6 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_L8A8_UNORM: case PIPE_FORMAT_Z16_UNORM: case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: return TRUE; /* TODO: does nv30 support this? */ case PIPE_FORMAT_R16_SNORM: diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c index 3c566808d03..30322d46d93 100644 --- a/src/gallium/drivers/nvfx/nvfx_state.c +++ b/src/gallium/drivers/nvfx/nvfx_state.c @@ -216,66 +216,39 @@ nvfx_rasterizer_state_create(struct pipe_context *pipe, sb_data(sb, fui(cso->point_size)); sb_method(sb, NV34TCL_POLYGON_MODE_FRONT, 6); - if (cso->front_winding == PIPE_WINDING_CCW) { - sb_data(sb, nvgl_polygon_mode(cso->fill_ccw)); - sb_data(sb, nvgl_polygon_mode(cso->fill_cw)); - switch (cso->cull_mode) { - case PIPE_WINDING_CCW: - sb_data(sb, NV34TCL_CULL_FACE_FRONT); - break; - case PIPE_WINDING_CW: - sb_data(sb, NV34TCL_CULL_FACE_BACK); - break; - case PIPE_WINDING_BOTH: - sb_data(sb, NV34TCL_CULL_FACE_FRONT_AND_BACK); - break; - default: - sb_data(sb, NV34TCL_CULL_FACE_BACK); - break; - } + sb_data(sb, nvgl_polygon_mode(cso->fill_front)); + sb_data(sb, nvgl_polygon_mode(cso->fill_back)); + switch (cso->cull_face) { + case PIPE_FACE_FRONT: + sb_data(sb, NV34TCL_CULL_FACE_FRONT); + break; + case PIPE_FACE_BACK: + sb_data(sb, NV34TCL_CULL_FACE_BACK); + break; + case PIPE_FACE_FRONT_AND_BACK: + sb_data(sb, NV34TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + sb_data(sb, NV34TCL_CULL_FACE_BACK); + break; + } + if (cso->front_ccw) { sb_data(sb, NV34TCL_FRONT_FACE_CCW); } else { - sb_data(sb, nvgl_polygon_mode(cso->fill_cw)); - sb_data(sb, nvgl_polygon_mode(cso->fill_ccw)); - switch (cso->cull_mode) { - case PIPE_WINDING_CCW: - sb_data(sb, NV34TCL_CULL_FACE_BACK); - break; - case PIPE_WINDING_CW: - sb_data(sb, NV34TCL_CULL_FACE_FRONT); - break; - case PIPE_WINDING_BOTH: - sb_data(sb, NV34TCL_CULL_FACE_FRONT_AND_BACK); - break; - default: - sb_data(sb, NV34TCL_CULL_FACE_BACK); - break; - } sb_data(sb, NV34TCL_FRONT_FACE_CW); } sb_data(sb, cso->poly_smooth ? 1 : 0); - sb_data(sb, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0); + sb_data(sb, (cso->cull_face != PIPE_FACE_NONE) ? 1 : 0); sb_method(sb, NV34TCL_POLYGON_STIPPLE_ENABLE, 1); sb_data(sb, cso->poly_stipple_enable ? 1 : 0); sb_method(sb, NV34TCL_POLYGON_OFFSET_POINT_ENABLE, 3); - if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || - (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) - sb_data(sb, 1); - else - sb_data(sb, 0); - if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) || - (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE)) - sb_data(sb, 1); - else - sb_data(sb, 0); - if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) || - (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL)) - sb_data(sb, 1); - else - sb_data(sb, 0); - if (cso->offset_cw || cso->offset_ccw) { + sb_data(sb, cso->offset_point); + sb_data(sb, cso->offset_line); + sb_data(sb, cso->offset_tri); + + if (cso->offset_point || cso->offset_line || cso->offset_tri) { sb_method(sb, NV34TCL_POLYGON_OFFSET_FACTOR, 2); sb_data(sb, fui(cso->offset_scale)); sb_data(sb, fui(cso->offset_units * 2)); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index b3ef97fa52b..f771e10c64e 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -80,6 +80,9 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->ztop_state.state); FREE(r300->fs_constants.state); FREE(r300->vs_constants.state); + if (!r300->screen->caps.has_tcl) { + FREE(r300->vertex_stream_state.state); + } FREE(r300); } @@ -151,6 +154,16 @@ static void r300_setup_atoms(struct r300_context* r300) r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer); r300->vs_constants.state = CALLOC_STRUCT(r300_constant_buffer); + if (!r300->screen->caps.has_tcl) { + r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state); + } + + /* Some non-CSO atoms don't use the state pointer. */ + r300->invariant_state.allow_null_state = TRUE; + r300->fs_rc_constant_state.allow_null_state = TRUE; + r300->pvs_flush.allow_null_state = TRUE; + r300->query_start.allow_null_state = TRUE; + r300->texture_cache_inval.allow_null_state = TRUE; } struct pipe_context* r300_create_context(struct pipe_screen* screen, @@ -201,9 +214,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); /* Enable Draw's clipping. */ draw_set_driver_clipping(r300->draw, FALSE); - /* Force Draw to never do viewport transform, since we can do - * transform in hardware, always. */ - draw_set_viewport_state(r300->draw, &r300_viewport_identity); + /* Disable converting points/lines to triangles. */ + draw_wide_line_threshold(r300->draw, 10000000.f); + draw_wide_point_threshold(r300->draw, 10000000.f); } r300_setup_atoms(r300); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index e9c8fcdc157..e44906d0099 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -55,6 +55,8 @@ struct r300_atom { unsigned size; /* Whether this atom should be emitted. */ boolean dirty; + /* Whether this atom may be emitted with state == NULL. */ + boolean allow_null_state; }; struct r300_blend_state { @@ -88,12 +90,15 @@ struct r300_dsa_state { }; struct r300_rs_state { - /* Draw-specific rasterizer state */ + /* Original rasterizer state. */ struct pipe_rasterizer_state rs; + /* Draw-specific rasterizer state. */ + struct pipe_rasterizer_state rs_draw; uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */ uint32_t antialiasing_config; /* R300_GB_AA_CONFIG: 0x4020 */ uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */ + uint32_t point_minmax; /* R300_GA_POINT_MINMAX: 0x4230 */ uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */ float depth_scale; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ @@ -151,6 +156,10 @@ struct r300_texture_format_state { struct r300_sampler_view { struct pipe_sampler_view base; + /* Swizzles in the UTIL_FORMAT_SWIZZLE_* representation, + * derived from base. */ + unsigned char swizzle[4]; + /* Copy of r300_texture::texture_format_state with format-specific bits * added. */ struct r300_texture_format_state format; @@ -166,6 +175,13 @@ struct r300_texture_fb_state { uint32_t zb_format; /* R300_ZB_FORMAT */ }; +struct r300_texture_sampler_state { + struct r300_texture_format_state format; + uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */ + uint32_t filter1; /* R300_TX_FILTER1: 0x4440 */ + uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */ +}; + struct r300_textures_state { /* Textures. */ struct r300_sampler_view *sampler_views[16]; @@ -177,12 +193,7 @@ struct r300_textures_state { /* This is the merge of the texture and sampler states. */ unsigned count; uint32_t tx_enable; /* R300_TX_ENABLE: 0x4101 */ - struct r300_texture_sampler_state { - struct r300_texture_format_state format; - uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */ - uint32_t filter1; /* R300_TX_FILTER1: 0x4440 */ - uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */ - } regs[16]; + struct r300_texture_sampler_state regs[16]; }; struct r300_vertex_stream_state { @@ -228,10 +239,6 @@ struct r300_constant_buffer { struct r300_query { /* The kind of query. Currently only OQ is supported. */ unsigned type; - /* Whether this query is currently active. Only active queries will - * get emitted into the command stream, and only active queries get - * tallied. */ - boolean active; /* The current count of this query. Required to be at least 32 bits. */ unsigned int count; /* The offset of this query into the query buffer, in bytes. */ @@ -297,16 +304,6 @@ struct r300_texture { enum r300_buffer_tiling microtile, macrotile; }; -struct r300_vertex_info { - /* Parent class */ - struct vertex_info vinfo; - - /* R300_VAP_PROG_STREAK_CNTL_[0-7] */ - uint32_t vap_prog_stream_cntl[8]; - /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */ - uint32_t vap_prog_stream_cntl_ext[8]; -}; - struct r300_vertex_element_state { unsigned count; struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS]; @@ -314,8 +311,6 @@ struct r300_vertex_element_state { struct r300_vertex_stream_state vertex_stream; }; -extern struct pipe_viewport_state r300_viewport_identity; - struct r300_context { /* Parent class */ struct pipe_context context; @@ -331,8 +326,7 @@ struct r300_context { void (*emit_draw_elements)( struct r300_context *r300, struct pipe_resource* indexBuffer, - unsigned indexSize, int indexBias, - unsigned minIndex, unsigned maxIndex, + unsigned indexSize, unsigned minIndex, unsigned maxIndex, unsigned mode, unsigned start, unsigned count); @@ -436,6 +430,8 @@ struct r300_context { boolean stencil_ref_bf_fallback; /* Point sprites texcoord index, 1 bit per texcoord */ int sprite_coord_enable; + /* Whether two-sided color selection is enabled (AKA light_twoside). */ + boolean two_sided_color; /* upload managers */ struct u_upload_mgr *upload_vb; diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 8eb321fa08a..85a1aa7b06e 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -40,6 +40,7 @@ static struct debug_option debug_options[] = { { "texalloc", DBG_TEXALLOC, "Texture allocation (for debugging)" }, { "fall", DBG_FALL, "Fallbacks (for debugging)" }, { "rs", DBG_RS, "Rasterizer (for debugging)" }, + { "fb", DBG_FB, "Framebuffer (for debugging)" }, { "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking)" }, { "notiling", DBG_NO_TILING, "Disable tiling (for benchmarking)" }, { "noimmd", DBG_NO_IMMD, "Disable immediate mode (for benchmarking)" }, @@ -97,3 +98,84 @@ void r300_init_debug(struct r300_screen * screen) } } } + +void r500_dump_rs_block(struct r300_rs_block *rs) +{ + unsigned count, ip, it_count, ic_count, i, j; + unsigned tex_ptr; + unsigned col_ptr, col_fmt; + + count = rs->inst_count & 0xf; + count++; + + it_count = rs->count & 0x7f; + ic_count = (rs->count >> 7) & 0xf; + + fprintf(stderr, "RS Block: %d texcoords (linear), %d colors (perspective)\n", + it_count, ic_count); + fprintf(stderr, "%d instructions\n", count); + + for (i = 0; i < count; i++) { + if (rs->inst[i] & 0x10) { + ip = rs->inst[i] & 0xf; + fprintf(stderr, "texture: ip %d to psf %d\n", + ip, (rs->inst[i] >> 5) & 0x7f); + + tex_ptr = rs->ip[ip] & 0xffffff; + fprintf(stderr, " : "); + + j = 3; + do { + if (tex_ptr & 0x3f == 63) { + fprintf(stderr, "1.0"); + } else if (tex_ptr & 0x3f == 62) { + fprintf(stderr, "0.0"); + } else { + fprintf(stderr, "[%d]", tex_ptr & 0x3f); + } + } while (j-- && fprintf(stderr, "/")); + fprintf(stderr, "\n"); + } + + if (rs->inst[i] & 0x10000) { + ip = (rs->inst[i] >> 12) & 0xf; + fprintf(stderr, "color: ip %d to psf %d\n", + ip, (rs->inst[i] >> 18) & 0x7f); + + col_ptr = (rs->ip[ip] >> 24) & 0x7; + col_fmt = (rs->ip[ip] >> 27) & 0xf; + fprintf(stderr, " : offset %d ", col_ptr); + + switch (col_fmt) { + case 0: + fprintf(stderr, "(R/G/B/A)"); + break; + case 1: + fprintf(stderr, "(R/G/B/0)"); + break; + case 2: + fprintf(stderr, "(R/G/B/1)"); + break; + case 4: + fprintf(stderr, "(0/0/0/A)"); + break; + case 5: + fprintf(stderr, "(0/0/0/0)"); + break; + case 6: + fprintf(stderr, "(0/0/0/1)"); + break; + case 8: + fprintf(stderr, "(1/1/1/A)"); + break; + case 9: + fprintf(stderr, "(1/1/1/0)"); + break; + case 10: + fprintf(stderr, "(1/1/1/1)"); + break; + } + fprintf(stderr, "\n"); + } + } +} diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 23bbc6a99c8..7f7f2929cc3 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -525,8 +525,6 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS(((fb->width + 1440-1) << R300_SCISSORS_X_SHIFT) | ((fb->height + 1440-1) << R300_SCISSORS_Y_SHIFT)); } - OUT_CS_REG(R300_GA_POINT_MINMAX, - (MAX2(fb->width, fb->height) * 6) << R300_GA_POINT_MINMAX_MAX_SHIFT); END_CS; } @@ -550,8 +548,8 @@ void r300_emit_query_start(struct r300_context *r300, unsigned size, void*state) } -static void r300_emit_query_finish(struct r300_context *r300, - struct r300_query *query) +static void r300_emit_query_end_frag_pipes(struct r300_context *r300, + struct r300_query *query) { struct r300_capabilities* caps = &r300->screen->caps; CS_LOCALS(r300); @@ -606,8 +604,8 @@ static void r300_emit_query_finish(struct r300_context *r300, END_CS; } -static void rv530_emit_query_single(struct r300_context *r300, - struct r300_query *query) +static void rv530_emit_query_end_single_z(struct r300_context *r300, + struct r300_query *query) { CS_LOCALS(r300); @@ -619,8 +617,8 @@ static void rv530_emit_query_single(struct r300_context *r300, END_CS; } -static void rv530_emit_query_double(struct r300_context *r300, - struct r300_query *query) +static void rv530_emit_query_end_double_z(struct r300_context *r300, + struct r300_query *query) { CS_LOCALS(r300); @@ -648,11 +646,13 @@ void r300_emit_query_end(struct r300_context* r300) if (caps->family == CHIP_FAMILY_RV530) { if (caps->num_z_pipes == 2) - rv530_emit_query_double(r300, query); + rv530_emit_query_end_double_z(r300, query); else - rv530_emit_query_single(r300, query); + rv530_emit_query_end_single_z(r300, query); } else - r300_emit_query_finish(r300, query); + r300_emit_query_end_frag_pipes(r300, query); + + query->begin_emitted = FALSE; } void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state) @@ -667,7 +667,9 @@ void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config); OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size); - OUT_CS_REG(R300_GA_LINE_CNTL, rs->line_control); + OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2); + OUT_CS(rs->point_minmax); + OUT_CS(rs->line_control); if (rs->polygon_offset_enable) { scale = rs->depth_scale * 12; @@ -714,6 +716,10 @@ void r300_emit_rs_block_state(struct r300_context* r300, unsigned count = (rs->inst_count & R300_RS_INST_COUNT_MASK) + 1; CS_LOCALS(r300); + if (SCREEN_DBG_ON(r300->screen, DBG_DRAW)) { + r500_dump_rs_block(rs); + } + DBG(r300, DBG_DRAW, "r300: RS emit:\n"); BEGIN_CS(size); @@ -1003,16 +1009,16 @@ void r300_emit_viewport_state(struct r300_context* r300, struct r300_viewport_state* viewport = (struct r300_viewport_state*)state; CS_LOCALS(r300); - BEGIN_CS(size); - OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); - OUT_CS_32F(viewport->xscale); - OUT_CS_32F(viewport->xoffset); - OUT_CS_32F(viewport->yscale); - OUT_CS_32F(viewport->yoffset); - OUT_CS_32F(viewport->zscale); - OUT_CS_32F(viewport->zoffset); - OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); - END_CS; + BEGIN_CS(size); + OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); + OUT_CS_32F(viewport->xscale); + OUT_CS_32F(viewport->xoffset); + OUT_CS_32F(viewport->yscale); + OUT_CS_32F(viewport->yoffset); + OUT_CS_32F(viewport->zscale); + OUT_CS_32F(viewport->zoffset); + OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); + END_CS; } void r300_emit_ztop_state(struct r300_context* r300, @@ -1094,7 +1100,8 @@ validate: } } /* ...occlusion query buffer... */ - if (r300->query_start.dirty) { + if (r300->query_start.dirty || + (r300->query_current && r300->query_current->begin_emitted)) { if (!r300_add_buffer(r300->rws, r300->oqbo, 0, RADEON_GEM_DOMAIN_GTT)) { r300->context.flush(&r300->context, 0, NULL); @@ -1152,8 +1159,6 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300) } } - /* emit_query_end is not atomized. */ - dwords += 26; /* let's reserve some more, just in case */ dwords += 32; diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index e78c6a3624f..d6876c1903f 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson <[email protected]> + * Copyright 2010 Marek Olšák <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -37,6 +38,8 @@ static void r300_flush(struct pipe_context* pipe, struct r300_context *r300 = r300_context(pipe); struct r300_query *query; struct r300_atom *atom; + struct pipe_framebuffer_state *fb; + unsigned i; CS_LOCALS(r300); (void) cs_count; @@ -48,15 +51,15 @@ static void r300_flush(struct pipe_context* pipe, draw_flush(r300->draw); } - r300_emit_query_end(r300); - if (r300->dirty_hw) { + r300_emit_query_end(r300); + FLUSH_CS; r300->dirty_hw = 0; /* New kitchen sink, baby. */ foreach(atom, &r300->atom_list) { - if (atom->state) { + if (atom->state || atom->allow_null_state) { atom->dirty = TRUE; } } @@ -72,6 +75,39 @@ static void r300_flush(struct pipe_context* pipe, foreach(query, &r300->query_list) { query->flushed = TRUE; } + + /* XXX + * + * This is a preliminary implementation of glFinish. Note that st/mesa + * uses a non-null fence when glFinish is called and then waits for + * the fence. Instead of returning the actual fence, we do the sync + * directly. + * + * The ideal implementation should use something like EmitIrqLocked and + * WaitIrq, or better, real fences. + * + * This feature degrades performance to the level of r300c for games that + * use glFinish a lot, even openarena does. Ideally we wouldn't need + * glFinish at all if we had proper throttling in swapbuffers so that + * the CPU wouldn't outrun the GPU by several frames, so this is basically + * a temporary fix for the input lag. Once swap&sync works with DRI2, + * I'll be happy to remove this code. + * + * - M. */ + if (fence && r300->fb_state.state) { + fb = r300->fb_state.state; + + for (i = 0; i < fb->nr_cbufs; i++) { + if (fb->cbufs[i]->texture) { + r300->rws->buffer_wait(r300->rws, + r300_texture(fb->cbufs[i]->texture)->buffer); + } + if (fb->zsbuf) { + r300->rws->buffer_wait(r300->rws, + r300_texture(fb->zsbuf->texture)->buffer); + } + } + } } void r300_init_flush_functions(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 88303f074cd..30aa0651399 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -137,6 +137,7 @@ static void get_external_state( { struct r300_textures_state *texstate = r300->textures_state.state; unsigned i; + unsigned char *swizzle; for (i = 0; i < texstate->sampler_state_count; i++) { struct r300_sampler_state* s = texstate->sampler_states[i]; @@ -146,9 +147,18 @@ static void get_external_state( } if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - /* XXX Gallium doesn't provide us with any information regarding - * this mode, so we are screwed. I'm setting 0 = LUMINANCE. */ - state->unit[i].depth_texture_mode = 0; + state->unit[i].compare_mode_enabled = 1; + + /* Pass depth texture swizzling to the compiler. */ + if (texstate->sampler_views[i]) { + swizzle = texstate->sampler_views[i]->swizzle; + + state->unit[i].depth_texture_swizzle = + RC_MAKE_SWIZZLE(swizzle[0], swizzle[1], + swizzle[2], swizzle[3]); + } else { + state->unit[i].depth_texture_swizzle = RC_SWIZZLE_XYZW; + } /* Fortunately, no need to translate this. */ state->unit[i].texture_compare_func = s->state.compare_func; diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c index 5c27796e894..6acbac22196 100644 --- a/src/gallium/drivers/r300/r300_query.c +++ b/src/gallium/drivers/r300/r300_query.c @@ -43,8 +43,6 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe, q->type = query_type; assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); - q->active = FALSE; - if (r300screen->caps.family == CHIP_FAMILY_RV530) query_size = r300screen->caps.num_z_pipes * sizeof(uint32_t); else @@ -59,6 +57,7 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe, /* XXX */ if (q->offset >= 4096) { q->offset = 0; + fprintf(stderr, "r300: Rewinding OQBO...\n"); } return (struct pipe_query*)q; @@ -80,7 +79,12 @@ static void r300_begin_query(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); struct r300_query* q = (struct r300_query*)query; - assert(r300->query_current == NULL); + if (r300->query_current != NULL) { + fprintf(stderr, "r300: begin_query: " + "Some other query has already been started.\n"); + assert(0); + return; + } pipe_buffer_write(pipe, r300->oqbo, @@ -97,10 +101,14 @@ static void r300_end_query(struct pipe_context* pipe, struct pipe_query* query) { struct r300_context* r300 = r300_context(pipe); - struct r300_query* q = (struct r300_query*)query; + + if ((struct r300_query*)query != r300->query_current) { + fprintf(stderr, "r300: end_query: Got invalid query.\n"); + assert(0); + return; + } r300_emit_query_end(r300); - q->begin_emitted = false; r300->query_current = NULL; } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 7c3a7902a49..e1f61982be2 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -114,16 +114,79 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, return color_control; } +static void r500_emit_index_offset(struct r300_context *r300, int index_bias) +{ + CS_LOCALS(r300); + + if (r300->screen->caps.is_r500 && + r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) { + BEGIN_CS(2); + OUT_CS_REG(R500_VAP_INDEX_OFFSET, + (index_bias & 0xFFFFFF) | (index_bias < 0 ? 1<<24 : 0)); + END_CS; + } else { + if (index_bias) { + fprintf(stderr, "r300: Non-zero index bias is unsupported " + "on this hardware.\n"); + assert(0); + } + } +} + +enum r300_prepare_flags { + PREP_FIRST_DRAW = (1 << 0), + PREP_VALIDATE_VBOS = (1 << 1), + PREP_EMIT_AOS = (1 << 2), + PREP_INDEXED = (1 << 3) +}; + /* Check if the requested number of dwords is available in the CS and - * if not, flush. Return TRUE if the flush occured. */ -static boolean r300_reserve_cs_space(struct r300_context *r300, - unsigned dwords) + * if not, flush. Then validate buffers and emit dirty state. + * Return TRUE if flush occured. */ +static void r300_prepare_for_rendering(struct r300_context *r300, + enum r300_prepare_flags flags, + struct pipe_resource *index_buffer, + unsigned cs_dwords, + unsigned aos_offset, + int index_bias) { - if (!r300->rws->check_cs(r300->rws, dwords)) { + boolean flushed = FALSE; + boolean first_draw = flags & PREP_FIRST_DRAW; + boolean emit_aos = flags & PREP_EMIT_AOS; + + /* Stencil ref fallback. */ + if (r300->stencil_ref_bf_fallback) { + cs_dwords = cs_dwords * 2 + 10; + } + + /* Add dirty state, index offset, and AOS. */ + if (first_draw) { + cs_dwords += r300_get_num_dirty_dwords(r300); + + if (r300->screen->caps.is_r500) + cs_dwords += 2; /* emit_index_offset */ + + if (emit_aos) + cs_dwords += 55; /* emit_aos */ + } + + /* Emitted in flush. */ + cs_dwords += 26; /* emit_query_end */ + + /* Reserve requested CS space. */ + if (!r300->rws->check_cs(r300->rws, cs_dwords)) { r300->context.flush(&r300->context, 0, NULL); - return TRUE; + flushed = TRUE; + } + + /* Validate buffers and emit dirty state if needed. */ + if (first_draw || flushed) { + r300_emit_buffer_validate(r300, flags & PREP_VALIDATE_VBOS, index_buffer); + r300_emit_dirty_state(r300); + r500_emit_index_offset(r300, index_bias); + if (emit_aos) + r300_emit_aos(r300, aos_offset, flags & PREP_INDEXED); } - return FALSE; } static boolean immd_is_good_idea(struct r300_context *r300, @@ -135,7 +198,15 @@ static boolean immd_is_good_idea(struct r300_context *r300, unsigned vertex_element_count = r300->velems->count; unsigned i, vbi; - if (count > 10 || DBG_ON(r300, DBG_NO_IMMD)) { + if (DBG_ON(r300, DBG_NO_IMMD)) { + return FALSE; + } + + if (r300->draw) { + return FALSE; + } + + if (count > 10) { return FALSE; } @@ -166,24 +237,6 @@ static boolean immd_is_good_idea(struct r300_context *r300, * after resolving fallback issues (e.g. stencil ref two-sided). * ****************************************************************************/ -static boolean r500_emit_index_offset(struct r300_context *r300, int indexBias) -{ - CS_LOCALS(r300); - - if (r300->screen->caps.is_r500 && - r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) { - BEGIN_CS(2); - OUT_CS_REG(R500_VAP_INDEX_OFFSET, - (indexBias & 0xFFFFFF) | (indexBias < 0 ? 1<<24 : 0)); - END_CS; - } else { - if (indexBias) - return FALSE; /* Can't do anything :( */ - } - - return TRUE; -} - void r500_emit_draw_arrays_immediate(struct r300_context *r300, unsigned mode, unsigned start, @@ -235,11 +288,7 @@ void r500_emit_draw_arrays_immediate(struct r300_context *r300, dwords = 9 + count * vertex_size; - r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2 + dwords); - r300_emit_buffer_validate(r300, FALSE, NULL); - r300_emit_dirty_state(r300); - - r500_emit_index_offset(r300, 0); + r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0); BEGIN_CS(dwords); OUT_CS_REG(R300_GA_COLOR_CONTROL, @@ -291,8 +340,6 @@ void r500_emit_draw_arrays(struct r300_context *r300, return; } - r500_emit_index_offset(r300, 0); - BEGIN_CS(7 + (alt_num_verts ? 2 : 0)); if (alt_num_verts) { OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); @@ -312,7 +359,6 @@ void r500_emit_draw_arrays(struct r300_context *r300, void r500_emit_draw_elements(struct r300_context *r300, struct pipe_resource* indexBuffer, unsigned indexSize, - int indexBias, unsigned minIndex, unsigned maxIndex, unsigned mode, @@ -335,12 +381,6 @@ void r500_emit_draw_elements(struct r300_context *r300, DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", count, minIndex, maxIndex); - if (!r500_emit_index_offset(r300, indexBias)) { - fprintf(stderr, "r300: Got a non-zero index bias, " - "refusing to render.\n"); - return; - } - BEGIN_CS(13 + (alt_num_verts ? 2 : 0)); if (alt_num_verts) { OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); @@ -457,7 +497,6 @@ void r300_emit_draw_arrays(struct r300_context *r300, void r300_emit_draw_elements(struct r300_context *r300, struct pipe_resource* indexBuffer, unsigned indexSize, - int indexBias, unsigned minIndex, unsigned maxIndex, unsigned mode, @@ -465,14 +504,14 @@ void r300_emit_draw_elements(struct r300_context *r300, unsigned count) { if (!r300->stencil_ref_bf_fallback) { - r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias, + r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count); } else { r300_begin_stencil_ref_fallback(r300); - r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias, + r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count); r300_switch_stencil_ref_side(r300); - r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias, + r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count); r300_end_stencil_ref_fallback(r300); } @@ -576,36 +615,33 @@ void r300_draw_range_elements(struct pipe_context* pipe, } r300_update_derived_state(r300); - r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count); - /* 128 dwords for emit_aos and emit_draw_elements */ - r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); - r300_emit_buffer_validate(r300, TRUE, indexBuffer); - r300_emit_dirty_state(r300); - r300_emit_aos(r300, 0, TRUE); + /* 15 dwords for emit_draw_elements */ + r300_prepare_for_rendering(r300, + PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, + indexBuffer, 15, 0, indexBias); u_upload_flush(r300->upload_vb); u_upload_flush(r300->upload_ib); if (alt_num_verts || count <= 65535) { - r300->emit_draw_elements(r300, indexBuffer, indexSize, indexBias, + r300->emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count); } else { do { short_count = MIN2(count, 65534); - r300->emit_draw_elements(r300, indexBuffer, indexSize, indexBias, + r300->emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, mode, start, short_count); start += short_count; count -= short_count; - /* 16 spare dwords are enough for emit_draw_elements. - * Also reserve some space for emit_query_end. */ - if (count && r300_reserve_cs_space(r300, 74)) { - r300_emit_buffer_validate(r300, TRUE, indexBuffer); - r300_emit_dirty_state(r300); - r300_emit_aos(r300, 0, TRUE); + /* 15 dwords for emit_draw_elements */ + if (count) { + r300_prepare_for_rendering(r300, + PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, + indexBuffer, 15, 0, indexBias); } } while (count); } @@ -650,30 +686,25 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, if (immd_is_good_idea(r300, count)) { r300->emit_draw_arrays_immediate(r300, mode, start, count); } else { - /* Make sure there are at least 128 spare dwords in the command buffer. - * (most of it being consumed by emit_aos) */ - r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); - r300_emit_buffer_validate(r300, TRUE, NULL); - r300_emit_dirty_state(r300); + /* 9 spare dwords for emit_draw_arrays. */ + r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, + NULL, 9, start, 0); if (alt_num_verts || count <= 65535) { - r300_emit_aos(r300, start, FALSE); r300->emit_draw_arrays(r300, mode, count); } else { do { short_count = MIN2(count, 65535); - r300_emit_aos(r300, start, FALSE); r300->emit_draw_arrays(r300, mode, short_count); start += short_count; count -= short_count; - /* Again, we emit both AOS and draw_arrays so there should be - * at least 128 spare dwords. - * Also reserve some space for emit_query_end. */ - if (count && r300_reserve_cs_space(r300, 186)) { - r300_emit_buffer_validate(r300, TRUE, NULL); - r300_emit_dirty_state(r300); + /* 9 spare dwords for emit_draw_arrays. */ + if (count) { + r300_prepare_for_rendering(r300, + PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, + start, 0); } } while (count); } @@ -704,6 +735,8 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe, return; } + r300_update_derived_state(r300); + for (i = 0; i < r300->vertex_buffer_count; i++) { void* buf = pipe_buffer_map(pipe, r300->vertex_buffer[i].buffer, @@ -716,6 +749,10 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe, draw_arrays(r300->draw, mode, start, count); + /* XXX Not sure whether this is the best fix. + * It prevents CS from being rejected and weird assertion failures. */ + draw_flush(r300->draw); + for (i = 0; i < r300->vertex_buffer_count; i++) { pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, vb_transfer[i]); @@ -748,6 +785,8 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe, return; } + r300_update_derived_state(r300); + for (i = 0; i < r300->vertex_buffer_count; i++) { void* buf = pipe_buffer_map(pipe, r300->vertex_buffer[i].buffer, @@ -763,6 +802,10 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe, draw_arrays(r300->draw, mode, start, count); + /* XXX Not sure whether this is the best fix. + * It prevents CS from being rejected and weird assertion failures. */ + draw_flush(r300->draw); + for (i = 0; i < r300->vertex_buffer_count; i++) { pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, vb_transfer[i]); @@ -796,7 +839,7 @@ struct r300_render { size_t vbo_max_used; void * vbo_ptr; - struct pipe_transfer *vbo_transfer; + struct pipe_transfer *vbo_transfer; }; static INLINE struct r300_render* @@ -811,8 +854,6 @@ r300_render_get_vertex_info(struct vbuf_render* render) struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; - r300_update_derived_state(r300); - return &r300->vertex_info; } @@ -860,10 +901,6 @@ static void r300_render_unmap_vertices(struct vbuf_render* render, { struct r300_render* r300render = r300_render(render); struct pipe_context* context = &r300render->r300->context; - CS_LOCALS(r300render->r300); - BEGIN_CS(2); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max); - END_CS; r300render->vbo_max_used = MAX2(r300render->vbo_max_used, r300render->vertex_size * (max + 1)); @@ -895,42 +932,64 @@ static void r500_render_draw_arrays(struct vbuf_render* render, { struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; + uint8_t* ptr; + unsigned i; + unsigned dwords = 6; CS_LOCALS(r300); - r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2); - r300_emit_buffer_validate(r300, FALSE, NULL); - r300_emit_dirty_state(r300); + (void) i; (void) ptr; + + r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0); DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count); - r500_emit_index_offset(r300, 0); + /* Uncomment to dump all VBOs rendered through this interface. + * Slow and noisy! + ptr = pipe_buffer_map(&r300render->r300->context, + r300render->vbo, PIPE_TRANSFER_READ, + &r300render->vbo_transfer); - BEGIN_CS(2); + for (i = 0; i < count; i++) { + printf("r300: Vertex %d\n", i); + draw_dump_emitted_vertex(&r300->vertex_info, ptr); + ptr += r300->vertex_info.size * 4; + printf("\n"); + } + + pipe_buffer_unmap(&r300render->r300->context, r300render->vbo, + r300render->vbo_transfer); + */ + + BEGIN_CS(dwords); + OUT_CS_REG(R300_GA_COLOR_CONTROL, + r300_provoking_vertex_fixes(r300, r300render->prim)); + OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | r300render->hwprim); END_CS; } -static void r500_render_draw(struct vbuf_render* render, - const ushort* indices, - uint count) +static void r500_render_draw_elements(struct vbuf_render* render, + const ushort* indices, + uint count) { struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; int i; - unsigned dwords = 2 + (count+1)/2; + unsigned dwords = 6 + (count+1)/2; + unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) / + (r300render->r300->vertex_info.size * 4) - 1; CS_LOCALS(r300); - r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); - r300_emit_buffer_validate(r300, FALSE, NULL); - r300_emit_dirty_state(r300); - - r500_emit_index_offset(r300, 0); + r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0); BEGIN_CS(dwords); + OUT_CS_REG(R300_GA_COLOR_CONTROL, + r300_provoking_vertex_fixes(r300, r300render->prim)); + OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | r300render->hwprim); @@ -960,19 +1019,19 @@ static void r300_render_draw_arrays(struct vbuf_render* render, } } -static void r300_render_draw(struct vbuf_render* render, - const ushort* indices, - uint count) +static void r300_render_draw_elements(struct vbuf_render* render, + const ushort* indices, + uint count) { struct r300_context* r300 = r300_render(render)->r300; if (!r300->stencil_ref_bf_fallback) { - r500_render_draw(render, indices, count); + r500_render_draw_elements(render, indices, count); } else { r300_begin_stencil_ref_fallback(r300); - r500_render_draw(render, indices, count); + r500_render_draw_elements(render, indices, count); r300_switch_stencil_ref_side(r300); - r500_render_draw(render, indices, count); + r500_render_draw_elements(render, indices, count); r300_end_stencil_ref_fallback(r300); } } @@ -998,10 +1057,10 @@ static struct vbuf_render* r300_render_create(struct r300_context* r300) r300render->base.unmap_vertices = r300_render_unmap_vertices; r300render->base.set_primitive = r300_render_set_primitive; if (r300->screen->caps.is_r500) { - r300render->base.draw = r500_render_draw; + r300render->base.draw_elements = r500_render_draw_elements; r300render->base.draw_arrays = r500_render_draw_arrays; } else { - r300render->base.draw = r300_render_draw; + r300render->base.draw_elements = r300_render_draw_elements; r300render->base.draw_arrays = r300_render_draw_arrays; } r300render->base.release_vertices = r300_render_release_vertices; diff --git a/src/gallium/drivers/r300/r300_render.h b/src/gallium/drivers/r300/r300_render.h index 4e78914c1ba..71dea218be6 100644 --- a/src/gallium/drivers/r300/r300_render.h +++ b/src/gallium/drivers/r300/r300_render.h @@ -35,7 +35,6 @@ void r500_emit_draw_arrays(struct r300_context *r300, void r500_emit_draw_elements(struct r300_context *r300, struct pipe_resource* indexBuffer, unsigned indexSize, - int indexBias, unsigned minIndex, unsigned maxIndex, unsigned mode, @@ -54,7 +53,6 @@ void r300_emit_draw_arrays(struct r300_context *r300, void r300_emit_draw_elements(struct r300_context *r300, struct pipe_resource* indexBuffer, unsigned indexSize, - int indexBias, unsigned minIndex, unsigned maxIndex, unsigned mode, diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index b7f1c617f03..ef0255066b7 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -76,20 +76,19 @@ static const char* r300_get_name(struct pipe_screen* pscreen) return chip_families[r300screen->caps.family]; } -static int r300_get_param(struct pipe_screen* pscreen, int param) +static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) { struct r300_screen* r300screen = r300_screen(pscreen); + boolean is_r400 = r300screen->caps.is_r400; + boolean is_r500 = r300screen->caps.is_r500; + + /* XXX extended shader capabilities of r400 unimplemented */ + is_r400 = FALSE; switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - case PIPE_CAP_MAX_COMBINED_SAMPLERS: - return r300screen->caps.num_tex_units; + /* Supported features (boolean caps). */ case PIPE_CAP_NPOT_TEXTURES: - /* XXX enable now to get GL2.1 API, - * figure out later how to emulate this */ - return 1; case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; case PIPE_CAP_GLSL: /* I'll be frank. This is a lie. * @@ -106,59 +105,103 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) * * ~ C. */ - return 1; - case PIPE_CAP_DUAL_SOURCE_BLEND: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; case PIPE_CAP_POINT_SPRITE: - return 1; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 4; case PIPE_CAP_OCCLUSION_QUERY: - return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - if (r300screen->caps.is_r500) { - /* 13 == 4096 */ - return 13; - } else { - /* 12 == 2048 */ - return 12; - } case PIPE_CAP_TEXTURE_MIRROR_CLAMP: - return 1; case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; + + /* Unsupported features (boolean caps). */ + case PIPE_CAP_TIMER_QUERY: + case PIPE_CAP_DUAL_SOURCE_BLEND: case PIPE_CAP_TGSI_CONT_SUPPORTED: + case PIPE_CAP_INDEP_BLEND_ENABLE: + case PIPE_CAP_INDEP_BLEND_FUNC: return 0; - case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 1; + + /* Texturing. */ + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return r300screen->caps.num_tex_units; + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + return 0; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + /* 13 == 4096, 12 == 2048 */ + return is_r500 ? 13 : 12; + + /* Render targets. */ + case PIPE_CAP_MAX_RENDER_TARGETS: + return 4; + + /* General shader limits and features. */ case PIPE_CAP_SM3: - if (r300screen->caps.is_r500) { - return 1; - } else { - return 0; - } + return is_r500 ? 1 : 0; case PIPE_CAP_MAX_CONST_BUFFERS: return 1; case PIPE_CAP_MAX_CONST_BUFFER_SIZE: return 256; - case PIPE_CAP_INDEP_BLEND_ENABLE: - return 0; - case PIPE_CAP_INDEP_BLEND_FUNC: - return 0; + + /* Fragment coordinate conventions. */ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 0; + + /* Fragment shader limits. */ + case PIPE_CAP_MAX_FS_INSTRUCTIONS: + return is_r500 || is_r400 ? 512 : 96; + case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: + return is_r500 || is_r400 ? 512 : 64; + case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: + return is_r500 || is_r400 ? 512 : 32; + case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: + return is_r500 ? 511 : 4; + case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: + return is_r500 ? 64 : 0; /* Actually unlimited on r500. */ + case PIPE_CAP_MAX_FS_INPUTS: + /* 2 colors + 8 texcoords are always supported + * (minus fog and wpos). + * + * R500 has the ability to turn 3rd and 4th color into + * additional texcoords but there is no two-sided color + * selection then. However the facing bit can be used instead. */ + return 10; + case PIPE_CAP_MAX_FS_CONSTS: + return is_r500 ? 256 : 32; + case PIPE_CAP_MAX_FS_TEMPS: + return is_r500 ? 128 : is_r400 ? 64 : 32; + case PIPE_CAP_MAX_FS_ADDRS: + return 0; + case PIPE_CAP_MAX_FS_PREDS: + return is_r500 ? 1 : 0; + + /* Vertex shader limits. */ + case PIPE_CAP_MAX_VS_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: + return is_r500 ? 1024 : 256; + case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: + return 0; + case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: + return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */ + case PIPE_CAP_MAX_VS_INPUTS: + return 16; + case PIPE_CAP_MAX_VS_CONSTS: + return 256; + case PIPE_CAP_MAX_VS_TEMPS: + return 32; + case PIPE_CAP_MAX_VS_ADDRS: + return 1; /* XXX guessed */ + case PIPE_CAP_MAX_VS_PREDS: + return is_r500 ? 4 : 0; /* XXX guessed. */ + default: fprintf(stderr, "r300: Implementation error: Bad param %d\n", param); @@ -166,7 +209,7 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) } } -static float r300_get_paramf(struct pipe_screen* pscreen, int param) +static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param) { struct r300_screen* r300screen = r300_screen(pscreen); diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index d58aa138a70..29492024fe3 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -61,19 +61,23 @@ static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) { * those changes. */ /*@{*/ -#define DBG_HELP 0x0000001 -#define DBG_FP 0x0000002 -#define DBG_VP 0x0000004 -#define DBG_CS 0x0000008 -#define DBG_DRAW 0x0000010 -#define DBG_TEX 0x0000020 -#define DBG_FALL 0x0000040 -#define DBG_ANISOHQ 0x0000080 -#define DBG_NO_TILING 0x0000100 -#define DBG_NO_IMMD 0x0000200 -#define DBG_STATS 0x0000400 -#define DBG_RS 0x0000800 -#define DBG_TEXALLOC 0x0001000 +#define DBG_HELP (1 << 0) +/* Logging. */ +#define DBG_FP (1 << 1) +#define DBG_VP (1 << 2) +#define DBG_CS (1 << 3) +#define DBG_DRAW (1 << 4) +#define DBG_TEX (1 << 5) +#define DBG_TEXALLOC (1 << 6) +#define DBG_RS (1 << 7) +#define DBG_FALL (1 << 8) +#define DBG_FB (1 << 9) +/* Features. */ +#define DBG_ANISOHQ (1 << 16) +#define DBG_NO_TILING (1 << 17) +#define DBG_NO_IMMD (1 << 18) +/* Statistics. */ +#define DBG_STATS (1 << 24) /*@}*/ static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 4f41530c16a..67e09362d8e 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -395,13 +395,13 @@ static void r300_set_clip_state(struct pipe_context* pipe, if (r300->screen->caps.has_tcl) { memcpy(r300->clip_state.state, state, sizeof(struct pipe_clip_state)); r300->clip_state.size = 29; + + r300->clip_state.dirty = TRUE; } else { draw_flush(r300->draw); draw_set_clip_state(r300->draw, state); r300->clip_state.size = 2; } - - r300->clip_state.dirty = TRUE; } static void @@ -573,13 +573,35 @@ static void r300_fb_set_tiling_flags(struct r300_context *r300, } } +static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index, + const char *binding) +{ + struct pipe_resource *tex = surf->texture; + struct r300_texture *rtex = r300_texture(tex); + + fprintf(stderr, + "r300: %s[%i] Dim: %ix%i, Offset: %i, ZSlice: %i, " + "Face: %i, Level: %i, Format: %s\n" + + "r300: TEX: Macro: %s, Micro: %s, Pitch: %i, " + "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n", + + binding, index, surf->width, surf->height, surf->offset, + surf->zslice, surf->face, surf->level, + util_format_short_name(surf->format), + + rtex->macrotile ? "YES" : " NO", rtex->microtile ? "YES" : " NO", + rtex->hwpitch[0], tex->width0, tex->height0, tex->depth0, + tex->last_level, util_format_short_name(tex->format)); +} + static void r300_set_framebuffer_state(struct pipe_context* pipe, const struct pipe_framebuffer_state* state) { struct r300_context* r300 = r300_context(pipe); struct pipe_framebuffer_state *old_state = r300->fb_state.state; - unsigned max_width, max_height; + unsigned max_width, max_height, i; uint32_t zbuffer_bpp = 0; if (state->nr_cbufs > 4) { @@ -623,7 +645,7 @@ static void memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) + - (state->zsbuf ? 10 : 0) + 11; + (state->zsbuf ? 10 : 0) + 9; /* Polygon offset depends on the zbuffer bit depth. */ if (state->zsbuf && r300->polygon_offset_enabled) { @@ -641,6 +663,16 @@ static void r300->rs_state.dirty = TRUE; } } + + if (DBG_ON(r300, DBG_FB)) { + fprintf(stderr, "r300: set_framebuffer_state:\n"); + for (i = 0; i < state->nr_cbufs; i++) { + r300_print_fb_surf_info(state->cbufs[i], i, "CB"); + } + if (state->zsbuf) { + r300_print_fb_surf_info(state->zsbuf, 0, "ZB"); + } + } } /* Create fragment shader state. */ @@ -729,9 +761,14 @@ static void* r300_create_rs_state(struct pipe_context* pipe, { struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); int i; + float psiz; - /* Copy rasterizer state for Draw. */ + /* Copy rasterizer state. */ rs->rs = *state; + rs->rs_draw = *state; + + /* Override some states for Draw. */ + rs->rs_draw.sprite_coord_enable = 0; /* We can do this in HW. */ #ifdef PIPE_ARCH_LITTLE_ENDIAN rs->vap_control_status = R300_VC_NO_SWAP; @@ -744,60 +781,64 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->vap_control_status |= R300_VAP_TCL_BYPASS; } - rs->point_size = pack_float_16_6x(state->point_size) | + /* Point size width and height. */ + rs->point_size = + pack_float_16_6x(state->point_size) | (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); + /* Point size clamping. */ + if (state->point_size_per_vertex) { + /* Per-vertex point size. + * Clamp to [0, max FB size] */ + psiz = pipe->screen->get_paramf(pipe->screen, + PIPE_CAP_MAX_POINT_WIDTH); + rs->point_minmax = + pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT; + } else { + /* We cannot disable the point-size vertex output, + * so clamp it. */ + psiz = state->point_size; + rs->point_minmax = + (pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MIN_SHIFT) | + (pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT); + } + + /* Line control. */ rs->line_control = pack_float_16_6x(state->line_width) | R300_GA_LINE_CNTL_END_TYPE_COMP; /* Enable polygon mode */ - if (state->fill_cw != PIPE_POLYGON_MODE_FILL || - state->fill_ccw != PIPE_POLYGON_MODE_FILL) { + if (state->fill_front != PIPE_POLYGON_MODE_FILL || + state->fill_back != PIPE_POLYGON_MODE_FILL) { rs->polygon_mode = R300_GA_POLY_MODE_DUAL; } - /* Radeons don't think in "CW/CCW", they think in "front/back". */ - if (state->front_winding == PIPE_WINDING_CW) { - rs->cull_mode = R300_FRONT_FACE_CW; - - /* Polygon offset */ - if (state->offset_cw) { - rs->polygon_offset_enable |= R300_FRONT_ENABLE; - } - if (state->offset_ccw) { - rs->polygon_offset_enable |= R300_BACK_ENABLE; - } - - /* Polygon mode */ - if (rs->polygon_mode) { - rs->polygon_mode |= - r300_translate_polygon_mode_front(state->fill_cw); - rs->polygon_mode |= - r300_translate_polygon_mode_back(state->fill_ccw); - } - } else { + /* Front face */ + if (state->front_ccw) rs->cull_mode = R300_FRONT_FACE_CCW; + else + rs->cull_mode = R300_FRONT_FACE_CW; - /* Polygon offset */ - if (state->offset_ccw) { - rs->polygon_offset_enable |= R300_FRONT_ENABLE; - } - if (state->offset_cw) { - rs->polygon_offset_enable |= R300_BACK_ENABLE; - } + /* Polygon offset */ + if (util_get_offset(state, state->fill_front)) { + rs->polygon_offset_enable |= R300_FRONT_ENABLE; + } + if (util_get_offset(state, state->fill_back)) { + rs->polygon_offset_enable |= R300_BACK_ENABLE; + } - /* Polygon mode */ - if (rs->polygon_mode) { - rs->polygon_mode |= - r300_translate_polygon_mode_front(state->fill_ccw); - rs->polygon_mode |= - r300_translate_polygon_mode_back(state->fill_cw); - } + /* Polygon mode */ + if (rs->polygon_mode) { + rs->polygon_mode |= + r300_translate_polygon_mode_front(state->fill_front); + rs->polygon_mode |= + r300_translate_polygon_mode_back(state->fill_back); } - if (state->front_winding & state->cull_mode) { + + if (state->cull_face & PIPE_FACE_FRONT) { rs->cull_mode |= R300_CULL_FRONT; } - if (~(state->front_winding) & state->cull_mode) { + if (state->cull_face & PIPE_FACE_BACK) { rs->cull_mode |= R300_CULL_BACK; } @@ -856,24 +897,30 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) struct r300_context* r300 = r300_context(pipe); struct r300_rs_state* rs = (struct r300_rs_state*)state; int last_sprite_coord_enable = r300->sprite_coord_enable; + boolean last_two_sided_color = r300->two_sided_color; - if (r300->draw) { + if (r300->draw && rs) { draw_flush(r300->draw); - draw_set_rasterizer_state(r300->draw, &rs->rs, state); + draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state); } if (rs) { - r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; + r300->polygon_offset_enabled = (rs->rs.offset_point || + rs->rs.offset_line || + rs->rs.offset_tri); r300->sprite_coord_enable = rs->rs.sprite_coord_enable; + r300->two_sided_color = rs->rs.light_twoside; } else { r300->polygon_offset_enabled = FALSE; r300->sprite_coord_enable = 0; + r300->two_sided_color = FALSE; } UPDATE_STATE(state, r300->rs_state); - r300->rs_state.size = 26 + (r300->polygon_offset_enabled ? 5 : 0); + r300->rs_state.size = 27 + (r300->polygon_offset_enabled ? 5 : 0); - if (last_sprite_coord_enable != r300->sprite_coord_enable) { + if (last_sprite_coord_enable != r300->sprite_coord_enable || + last_two_sided_color != r300->two_sided_color) { r300->rs_block_state.dirty = TRUE; } } @@ -913,7 +960,7 @@ static void* sampler->min_lod = MAX2((unsigned)state->min_lod, 0); sampler->max_lod = MAX2((unsigned)ceilf(state->max_lod), 0); - lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1); + lod_bias = CLAMP((int)(state->lod_bias * 32 + 1), -(1 << 9), (1 << 9) - 1); sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT; @@ -1028,7 +1075,6 @@ r300_create_sampler_view(struct pipe_context *pipe, { struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view); struct r300_texture *tex = r300_texture(texture); - unsigned char swizzle[4]; if (view) { view->base = *templ; @@ -1037,14 +1083,14 @@ r300_create_sampler_view(struct pipe_context *pipe, view->base.texture = NULL; pipe_resource_reference(&view->base.texture, texture); - swizzle[0] = templ->swizzle_r; - swizzle[1] = templ->swizzle_g; - swizzle[2] = templ->swizzle_b; - swizzle[3] = templ->swizzle_a; + view->swizzle[0] = templ->swizzle_r; + view->swizzle[1] = templ->swizzle_g; + view->swizzle[2] = templ->swizzle_b; + view->swizzle[3] = templ->swizzle_a; view->format = tex->tx_format; view->format.format1 |= r300_translate_texformat(templ->format, - swizzle); + view->swizzle); if (r300_screen(pipe->screen)->caps.is_r500) { view->format.format2 |= r500_tx_format_msb_bit(templ->format); } @@ -1081,6 +1127,13 @@ static void r300_set_viewport_state(struct pipe_context* pipe, r300->viewport = *state; + if (r300->draw) { + draw_flush(r300->draw); + draw_set_viewport_state(r300->draw, state); + viewport->vte_control = R300_VTX_XY_FMT | R300_VTX_Z_FMT; + return; + } + /* Do the transform in HW. */ viewport->vte_control = R300_VTX_W0_FMT; @@ -1190,7 +1243,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, } } -/* Update the PSC tables. */ +/* Initialize the PSC tables. */ static void r300_vertex_psc(struct r300_vertex_element_state *velems) { struct r300_vertex_stream_state *vstream = &velems->vertex_stream; @@ -1329,7 +1382,6 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe, abort(); } } - } } return velems; @@ -1350,6 +1402,7 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe, if (r300->draw) { draw_flush(r300->draw); draw_set_vertex_elements(r300->draw, velems->count, velems->velem); + return; } UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state); @@ -1372,8 +1425,10 @@ static void* r300_create_vs_state(struct pipe_context* pipe, vs->state = *shader; vs->state.tokens = tgsi_dup_tokens(shader->tokens); + r300_init_vs_outputs(vs); + if (r300->screen->caps.has_tcl) { - r300_translate_vertex_shader(r300, vs, vs->state.tokens); + r300_translate_vertex_shader(r300, vs); } else { vs->draw_vs = draw_create_vertex_shader(r300->draw, shader); } @@ -1443,7 +1498,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, struct r300_constant_buffer *cbuf; struct pipe_transfer *tr; void *mapped; - int max_size = 0; + int max_size = 0, max_size_bytes = 0, clamped_size = 0; switch (shader) { case PIPE_SHADER_VERTEX: @@ -1462,6 +1517,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, assert(0); return; } + max_size_bytes = max_size * 4 * sizeof(float); if (buf == NULL || buf->width0 == 0 || (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL) @@ -1470,19 +1526,21 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, return; } - assert((buf->width0 % 4 * sizeof(float)) == 0); + if (shader == PIPE_SHADER_FRAGMENT || + (shader == PIPE_SHADER_VERTEX && r300->screen->caps.has_tcl)) { + assert((buf->width0 % (4 * sizeof(float))) == 0); - /* Check the size of the constant buffer. */ - /* XXX Subtract immediates and RC_STATE_* variables. */ - if (buf->width0 > (sizeof(float) * 4 * max_size)) { - fprintf(stderr, "r300: Max size of the constant buffer is " - "%i*4 floats.\n", max_size); - abort(); - } + /* Check the size of the constant buffer. */ + /* XXX Subtract immediates and RC_STATE_* variables. */ + if (buf->width0 > max_size_bytes) { + fprintf(stderr, "r300: Max size of the constant buffer is " + "%i*4 floats.\n", max_size); + } + clamped_size = MIN2(buf->width0, max_size_bytes); - memcpy(cbuf->constants, mapped, buf->width0); - cbuf->count = buf->width0 / (4 * sizeof(float)); - pipe_buffer_unmap(pipe, buf, tr); + memcpy(cbuf->constants, mapped, clamped_size); + cbuf->count = clamped_size / (4 * sizeof(float)); + } if (shader == PIPE_SHADER_VERTEX) { if (r300->screen->caps.has_tcl) { @@ -1492,12 +1550,13 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, r300->pvs_flush.dirty = TRUE; } else if (r300->draw) { draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX, - 0, cbuf->constants, - buf->width0); + 0, mapped, buf->width0); } } else if (shader == PIPE_SHADER_FRAGMENT) { r300->fs_constants.dirty = TRUE; } + + pipe_buffer_unmap(pipe, buf, tr); } void r300_init_state_functions(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index e3adace0faa..7583862a1a4 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -34,6 +34,7 @@ #include "r300_state.h" #include "r300_state_derived.h" #include "r300_state_inlines.h" +#include "r300_texture.h" #include "r300_vs.h" /* r300_state_derived: Various bits of state which are dependent upon @@ -115,13 +116,12 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) static void r300_swtcl_vertex_psc(struct r300_context *r300) { struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state; - struct vertex_info* vinfo = &r300->vertex_info; + struct vertex_info *vinfo = &r300->vertex_info; uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; int* vs_output_tab = r300->stream_loc_notcl; - /* XXX hax */ memset(vstream, 0, sizeof(struct r300_vertex_stream_state)); /* For each Draw attribute, route it to the fragment shader according @@ -354,10 +354,26 @@ static void r300_update_rs_block(struct r300_context *r300) /* Set up back-face colors. The rasterizer will do the color selection * automatically. */ if (any_bcolor_used) { - for (i = 0; i < ATTR_COLOR_COUNT; i++) { - rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; - rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i); - stream_loc_notcl[loc++] = 4 + i; + if (r300->two_sided_color) { + /* Rasterize as back-face colors. */ + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; + rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i); + stream_loc_notcl[loc++] = 4 + i; + } + } else { + /* Rasterize two fake texcoords to prevent from the two-sided color + * selection. */ + /* XXX Consider recompiling the vertex shader to save 2 RS units. */ + for (i = 0; i < 2; i++) { + rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); + rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); + stream_loc_notcl[loc++] = 6 + tex_count; + + /* Rasterize it. */ + rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); + tex_count++; + } } } @@ -493,6 +509,12 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) unsigned min_level, max_level, i, size; unsigned count = MIN2(state->sampler_view_count, state->sampler_state_count); + unsigned char depth_swizzle[4] = { + UTIL_FORMAT_SWIZZLE_X, + UTIL_FORMAT_SWIZZLE_X, + UTIL_FORMAT_SWIZZLE_X, + UTIL_FORMAT_SWIZZLE_X + }; state->tx_enable = 0; state->count = 0; @@ -512,6 +534,20 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) texstate->filter1 = sampler->filter1; texstate->border_color = sampler->border_color; + /* If compare mode is disabled, the sampler view swizzles + * are stored in the format. + * Otherwise, swizzles must be applied after the compare mode + * in the fragment shader. */ + if (util_format_is_depth_or_stencil(tex->b.b.format)) { + if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) { + texstate->format.format1 |= + r300_get_swizzle_combined(depth_swizzle, view->swizzle); + } else { + texstate->format.format1 |= + r300_get_swizzle_combined(depth_swizzle, 0); + } + } + /* to emulate 1D textures through 2D ones correctly */ if (tex->b.b.target == PIPE_TEXTURE_1D) { texstate->filter0 &= ~R300_TX_WRAP_T_MASK; @@ -578,13 +614,13 @@ void r300_update_derived_state(struct r300_context* r300) if (r300->rs_block_state.dirty) { r300_update_rs_block(r300); - } - if (r300->draw) { - memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); - r300_draw_emit_all_attribs(r300); - draw_compute_vertex_size(&r300->vertex_info); - r300_swtcl_vertex_psc(r300); + if (r300->draw) { + memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); + r300_draw_emit_all_attribs(r300); + draw_compute_vertex_size(&r300->vertex_info); + r300_swtcl_vertex_psc(r300); + } } r300_update_hyperz_state(r300); diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index cd9443fa260..34d3a169d57 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -27,11 +27,6 @@ #include "r300_screen.h" #include "r300_state_invariant.h" -struct pipe_viewport_state r300_viewport_identity = { - .scale = {1.0, 1.0, 1.0, 1.0}, - .translate = {0.0, 0.0, 0.0, 0.0}, -}; - /* Calculate and emit invariant state. This is data that the 3D engine * will probably want at the beginning of every CS, but it's not currently * handled by any CSO setup, and in addition it doesn't really change much. diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index d6f629cf9c6..4a5c932b7e8 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -24,6 +24,7 @@ #include "pipe/p_screen.h" #include "util/u_format.h" +#include "util/u_format_s3tc.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -46,6 +47,60 @@ static const unsigned microblock_table[5][3][2] = { {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ }; +unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, + const unsigned char *swizzle_view) +{ + unsigned i; + unsigned char swizzle[4]; + unsigned result = 0; + const uint32_t swizzle_shift[4] = { + R300_TX_FORMAT_R_SHIFT, + R300_TX_FORMAT_G_SHIFT, + R300_TX_FORMAT_B_SHIFT, + R300_TX_FORMAT_A_SHIFT + }; + const uint32_t swizzle_bit[4] = { + R300_TX_FORMAT_X, + R300_TX_FORMAT_Y, + R300_TX_FORMAT_Z, + R300_TX_FORMAT_W + }; + + if (swizzle_view) { + /* Combine two sets of swizzles. */ + for (i = 0; i < 4; i++) { + swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ? + swizzle_format[swizzle_view[i]] : swizzle_view[i]; + } + } else { + memcpy(swizzle, swizzle_format, 4); + } + + /* Get swizzle. */ + for (i = 0; i < 4; i++) { + switch (swizzle[i]) { + case UTIL_FORMAT_SWIZZLE_Y: + result |= swizzle_bit[1] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_Z: + result |= swizzle_bit[2] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_W: + result |= swizzle_bit[3] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_0: + result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_1: + result |= R300_TX_FORMAT_ONE << swizzle_shift[i]; + break; + default: /* UTIL_FORMAT_SWIZZLE_X */ + result |= swizzle_bit[0] << swizzle_shift[i]; + } + } + return result; +} + /* Translate a pipe_format into a useful texture format for sampling. * * Some special formats are translated directly using R300_EASY_TX_FORMAT, @@ -65,38 +120,26 @@ uint32_t r300_translate_texformat(enum pipe_format format, const struct util_format_description *desc; unsigned i; boolean uniform = TRUE; - const uint32_t swizzle_shift[4] = { - R300_TX_FORMAT_R_SHIFT, - R300_TX_FORMAT_G_SHIFT, - R300_TX_FORMAT_B_SHIFT, - R300_TX_FORMAT_A_SHIFT - }; - const uint32_t swizzle_bit[4] = { - R300_TX_FORMAT_X, - R300_TX_FORMAT_Y, - R300_TX_FORMAT_Z, - R300_TX_FORMAT_W - }; const uint32_t sign_bit[4] = { R300_TX_FORMAT_SIGNED_X, R300_TX_FORMAT_SIGNED_Y, R300_TX_FORMAT_SIGNED_Z, R300_TX_FORMAT_SIGNED_W, }; - unsigned char swizzle[4]; desc = util_format_description(format); /* Colorspace (return non-RGB formats directly). */ switch (desc->colorspace) { - /* Depth stencil formats. */ + /* Depth stencil formats. + * Swizzles are added in r300_merge_textures_and_samplers. */ case UTIL_FORMAT_COLORSPACE_ZS: switch (format) { case PIPE_FORMAT_Z16_UNORM: - return R300_EASY_TX_FORMAT(X, X, X, X, X16); + return R300_TX_FORMAT_X16; case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); + return R300_TX_FORMAT_W24_FP; default: return ~0; /* Unsupported. */ } @@ -130,46 +173,14 @@ uint32_t r300_translate_texformat(enum pipe_format format, } } - /* Get swizzle. */ - if (swizzle_view) { - /* Compose two sets of swizzles. */ - for (i = 0; i < 4; i++) { - swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ? - desc->swizzle[swizzle_view[i]] : swizzle_view[i]; - } - } else { - memcpy(swizzle, desc->swizzle, sizeof(swizzle)); - } - - /* Add swizzle. */ - for (i = 0; i < 4; i++) { - switch (swizzle[i]) { - case UTIL_FORMAT_SWIZZLE_X: - case UTIL_FORMAT_SWIZZLE_NONE: - result |= swizzle_bit[0] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Y: - result |= swizzle_bit[1] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Z: - result |= swizzle_bit[2] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_W: - result |= swizzle_bit[3] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_0: - result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_1: - result |= R300_TX_FORMAT_ONE << swizzle_shift[i]; - break; - default: - return ~0; /* Unsupported. */ - } - } + result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view); /* S3TC formats. */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { + if (!util_format_s3tc_enabled) { + return ~0; /* Unsupported. */ + } + switch (format) { case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: @@ -920,6 +931,7 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, fprintf(stderr, "r300: texture_create: " "Got invalid texture dimensions: %ix%ix%i\n", base->width0, base->height0, base->depth0); + FREE(tex); return NULL; } @@ -948,7 +960,7 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, util_format_short_name(base->format)); tex->buffer = rws->buffer_create(rws, 2048, - PIPE_BIND_SAMPLER_VIEW, /* XXX */ + base->bind, tex->size); rws->buffer_set_tiling(rws, tex->buffer, tex->pitch[0], diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index ba79ec068a1..2d8f0e14393 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -27,6 +27,9 @@ struct r300_texture; +unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, + const unsigned char *swizzle_view); + uint32_t r300_translate_texformat(enum pipe_format format, const unsigned char *swizzle_view); diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index f0f87c5e2bc..beb321cb238 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -108,6 +108,12 @@ r300_texture_get_transfer(struct pipe_context *ctx, struct r300_transfer *trans; struct pipe_resource base; + /* XXX Why aren't flushes taken care of by winsys automatically? + * Winsys seems to sometimes return a cached buffer instead of + * a mapped hardware buffer if this flush is commented out. */ + if (ctx->is_resource_referenced(ctx, texture, sr.face, sr.level)) + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + trans = CALLOC_STRUCT(r300_transfer); if (trans) { /* Initialize the transfer object. */ diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index f3186431e1d..59f89b3482a 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -181,21 +181,23 @@ static void r300_dummy_vertex_shader( state.tokens = ureg_finalize(ureg); shader->dummy = TRUE; - r300_translate_vertex_shader(r300, shader, state.tokens); + r300_translate_vertex_shader(r300, shader); ureg_destroy(ureg); } -void r300_translate_vertex_shader(struct r300_context* r300, - struct r300_vertex_shader* vs, - const struct tgsi_token *tokens) +void r300_init_vs_outputs(struct r300_vertex_shader *vs) +{ + tgsi_scan_shader(vs->state.tokens, &vs->info); + r300_shader_read_vs_outputs(&vs->info, &vs->outputs); +} + +void r300_translate_vertex_shader(struct r300_context *r300, + struct r300_vertex_shader *vs) { struct r300_vertex_program_compiler compiler; struct tgsi_to_rc ttr; - tgsi_scan_shader(tokens, &vs->info); - r300_shader_read_vs_outputs(&vs->info, &vs->outputs); - /* Setup the compiler */ rc_init(&compiler.Base); @@ -205,7 +207,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, if (compiler.Base.Debug) { debug_printf("r300: Initial vertex program\n"); - tgsi_dump(tokens, 0); + tgsi_dump(vs->state.tokens, 0); } /* Translate TGSI to our internal representation */ @@ -213,7 +215,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, ttr.info = &vs->info; ttr.use_half_swizzles = FALSE; - r300_tgsi_to_rc(&ttr, tokens); + r300_tgsi_to_rc(&ttr, vs->state.tokens); compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1)); compiler.SetHwInputOutput = &set_vertex_inputs_outputs; diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h index 57b3fbca0bb..31890d78caf 100644 --- a/src/gallium/drivers/r300/r300_vs.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -56,8 +56,8 @@ struct r300_vertex_shader { void *draw_vs; }; -void r300_translate_vertex_shader(struct r300_context* r300, - struct r300_vertex_shader* vs, - const struct tgsi_token *tokens); +void r300_init_vs_outputs(struct r300_vertex_shader *vs); +void r300_translate_vertex_shader(struct r300_context *r300, + struct r300_vertex_shader *vs); #endif /* R300_VS_H */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 1642981eaa8..3d0413f90af 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -87,13 +87,8 @@ struct r300_winsys_screen { struct r300_winsys_buffer **pdst, struct r300_winsys_buffer *src); - boolean (*buffer_references)(struct r300_winsys_buffer *a, - struct r300_winsys_buffer *b); - - void (*buffer_flush_range)(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, - unsigned offset, - unsigned length); + void (*buffer_wait)(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf); /* Add a pipe_resource to the list of buffer objects to validate. */ boolean (*add_buffer)(struct r300_winsys_screen *winsys, diff --git a/src/gallium/drivers/rbug/Makefile b/src/gallium/drivers/rbug/Makefile new file mode 100644 index 00000000000..64e172fe5c1 --- /dev/null +++ b/src/gallium/drivers/rbug/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = rbug + +C_SOURCES = \ + rbug_core.c \ + rbug_context.c \ + rbug_objects.c \ + rbug_screen.c + +include ../../Makefile.template diff --git a/src/gallium/drivers/rbug/README b/src/gallium/drivers/rbug/README new file mode 100644 index 00000000000..b6d3a5cf351 --- /dev/null +++ b/src/gallium/drivers/rbug/README @@ -0,0 +1,58 @@ + RBUG PIPE DRIVER + + += About = + +This directory contains a Gallium3D remote debugger pipe driver. +It provides remote debugging functionality. + + += Build Instructions = + +To build, invoke scons on the top dir as + + scons dri=no statetrackers=mesa winsys=xlib + + += Usage = + +To use do + + export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib + +ensure the right libGL.so is being picked by doing + + ldd progs/trivial/tri + + export XMESA_TRACE=y + GALLIUM_RBUG=true progs/trivial/tri + +which should open gallium remote debugging session. While the program is running +you can launch the small remote debugging application from progs/rbug. More +information is in that directory. Also for a gui see: + + http://cgit.freedesktop.org/mesa/rbug-gui + + += Integrating = + +You can integrate the rbug pipe driver either inside the state tracker or the +target. The procedure on both cases is the same. Let's assume you have a +pipe_screen obtained by the usual means (variable and function names are just +for illustration purposes): + + real_screen = real_screen_create(...); + +The rbug screen is then created by doing + + rbug_screen = rbug_screen_create(real_screen); + +You can then simply use rbug_screen instead of real_screen. + +You can create as many contexts you wish from rbug_screen::context_create they +are automatically wrapped by rbug_screen. + + +-- +Jose Fonseca <[email protected]> +Jakob Bornecrantz <[email protected]> diff --git a/src/gallium/drivers/rbug/SConscript b/src/gallium/drivers/rbug/SConscript new file mode 100644 index 00000000000..3da6ac104a4 --- /dev/null +++ b/src/gallium/drivers/rbug/SConscript @@ -0,0 +1,14 @@ +Import('*') + +env = env.Clone() + +rbug = env.ConvenienceLibrary( + target = 'rbug', + source = [ + 'rbug_context.c', + 'rbug_core.c', + 'rbug_objects.c', + 'rbug_screen.c', + ]) + +Export('rbug') diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c new file mode 100644 index 00000000000..59f005ec16c --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -0,0 +1,1072 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 VMWARE 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_context.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "util/u_simple_list.h" + +#include "rbug/rbug_context.h" + +#include "rbug_context.h" +#include "rbug_objects.h" + + +static void +rbug_destroy(struct pipe_context *_pipe) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->destroy(pipe); + + FREE(rb_pipe); +} + +static void +rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag) +{ + + if (rb_pipe->draw_blocker & flag) { + rb_pipe->draw_blocked |= flag; + } else if ((rb_pipe->draw_rule.blocker & flag) && + (rb_pipe->draw_blocker & RBUG_BLOCK_RULE)) { + int k; + boolean block = FALSE; + debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__, + (void *) rb_pipe->draw_rule.fs, (void *) rb_pipe->curr.fs, + (void *) rb_pipe->draw_rule.vs, (void *) rb_pipe->curr.vs, + (void *) rb_pipe->draw_rule.surf, 0, + (void *) rb_pipe->draw_rule.texture, 0); + if (rb_pipe->draw_rule.fs && + rb_pipe->draw_rule.fs == rb_pipe->curr.fs) + block = TRUE; + if (rb_pipe->draw_rule.vs && + rb_pipe->draw_rule.vs == rb_pipe->curr.vs) + block = TRUE; + if (rb_pipe->draw_rule.surf && + rb_pipe->draw_rule.surf == rb_pipe->curr.zsbuf) + block = TRUE; + if (rb_pipe->draw_rule.surf) + for (k = 0; k < rb_pipe->curr.nr_cbufs; k++) + if (rb_pipe->draw_rule.surf == rb_pipe->curr.cbufs[k]) + block = TRUE; + if (rb_pipe->draw_rule.texture) { + for (k = 0; k < rb_pipe->curr.num_fs_views; k++) + if (rb_pipe->draw_rule.texture == rb_pipe->curr.fs_texs[k]) + block = TRUE; + for (k = 0; k < rb_pipe->curr.num_vs_views; k++) { + if (rb_pipe->draw_rule.texture == rb_pipe->curr.vs_texs[k]) { + block = TRUE; + } + } + } + + if (block) + rb_pipe->draw_blocked |= (flag | RBUG_BLOCK_RULE); + } + + if (rb_pipe->draw_blocked) + rbug_notify_draw_blocked(rb_pipe); + + /* wait for rbug to clear the blocked flag */ + while (rb_pipe->draw_blocked & flag) { + rb_pipe->draw_blocked |= flag; +#ifdef PIPE_THREAD_HAVE_CONDVAR + pipe_condvar_wait(rb_pipe->draw_cond, rb_pipe->draw_mutex); +#else + pipe_mutex_unlock(rb_pipe->draw_mutex); +#ifdef PIPE_SUBSYSTEM_WINDOWS_USER + Sleep(1); +#endif + pipe_mutex_lock(rb_pipe->draw_mutex); +#endif + } + +} + +static void +rbug_draw_arrays(struct pipe_context *_pipe, + unsigned prim, + unsigned start, + unsigned count) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe_mutex_lock(rb_pipe->draw_mutex); + rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); + + pipe->draw_arrays(pipe, + prim, + start, + count); + + rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); + pipe_mutex_unlock(rb_pipe->draw_mutex); +} + +static void +rbug_draw_elements(struct pipe_context *_pipe, + struct pipe_resource *_indexResource, + unsigned indexSize, + int indexBias, + unsigned prim, + unsigned start, + unsigned count) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource = rbug_resource(_indexResource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *indexResource = rb_resource->resource; + + pipe_mutex_lock(rb_pipe->draw_mutex); + rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); + + pipe->draw_elements(pipe, + indexResource, + indexSize, + indexBias, + prim, + start, + count); + + rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); + pipe_mutex_unlock(rb_pipe->draw_mutex); +} + +static void +rbug_draw_range_elements(struct pipe_context *_pipe, + struct pipe_resource *_indexResource, + unsigned indexSize, + int indexBias, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource = rbug_resource(_indexResource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *indexResource = rb_resource->resource; + + pipe_mutex_lock(rb_pipe->draw_mutex); + rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); + + pipe->draw_range_elements(pipe, + indexResource, + indexSize, + indexBias, + minIndex, + maxIndex, + mode, + start, + count); + + rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); + pipe_mutex_unlock(rb_pipe->draw_mutex); +} + +static struct pipe_query * +rbug_create_query(struct pipe_context *_pipe, + unsigned query_type) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_query(pipe, + query_type); +} + +static void +rbug_destroy_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->destroy_query(pipe, + query); +} + +static void +rbug_begin_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->begin_query(pipe, + query); +} + +static void +rbug_end_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->end_query(pipe, + query); +} + +static boolean +rbug_get_query_result(struct pipe_context *_pipe, + struct pipe_query *query, + boolean wait, + uint64_t *result) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->get_query_result(pipe, + query, + wait, + result); +} + +static void * +rbug_create_blend_state(struct pipe_context *_pipe, + const struct pipe_blend_state *blend) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_blend_state(pipe, + blend); +} + +static void +rbug_bind_blend_state(struct pipe_context *_pipe, + void *blend) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_blend_state(pipe, + blend); +} + +static void +rbug_delete_blend_state(struct pipe_context *_pipe, + void *blend) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_blend_state(pipe, + blend); +} + +static void * +rbug_create_sampler_state(struct pipe_context *_pipe, + const struct pipe_sampler_state *sampler) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_sampler_state(pipe, + sampler); +} + +static void +rbug_bind_fragment_sampler_states(struct pipe_context *_pipe, + unsigned num_samplers, + void **samplers) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_fragment_sampler_states(pipe, + num_samplers, + samplers); +} + +static void +rbug_bind_vertex_sampler_states(struct pipe_context *_pipe, + unsigned num_samplers, + void **samplers) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_vertex_sampler_states(pipe, + num_samplers, + samplers); +} + +static void +rbug_delete_sampler_state(struct pipe_context *_pipe, + void *sampler) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_sampler_state(pipe, + sampler); +} + +static void * +rbug_create_rasterizer_state(struct pipe_context *_pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_rasterizer_state(pipe, + rasterizer); +} + +static void +rbug_bind_rasterizer_state(struct pipe_context *_pipe, + void *rasterizer) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_rasterizer_state(pipe, + rasterizer); +} + +static void +rbug_delete_rasterizer_state(struct pipe_context *_pipe, + void *rasterizer) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_rasterizer_state(pipe, + rasterizer); +} + +static void * +rbug_create_depth_stencil_alpha_state(struct pipe_context *_pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void +rbug_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *depth_stencil_alpha) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void +rbug_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *depth_stencil_alpha) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void * +rbug_create_fs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *result; + + result = pipe->create_fs_state(pipe, state); + if (!result) + return NULL; + + return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_FRAGMENT); +} + +static void +rbug_bind_fs_state(struct pipe_context *_pipe, + void *_fs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *fs; + + fs = rbug_shader_unwrap(_fs); + rb_pipe->curr.fs = rbug_shader(_fs); + pipe->bind_fs_state(pipe, + fs); +} + +static void +rbug_delete_fs_state(struct pipe_context *_pipe, + void *_fs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_shader *rb_shader = rbug_shader(_fs); + + rbug_shader_destroy(rb_pipe, rb_shader); +} + +static void * +rbug_create_vs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *result; + + result = pipe->create_vs_state(pipe, state); + if (!result) + return NULL; + + return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_VERTEX); +} + +static void +rbug_bind_vs_state(struct pipe_context *_pipe, + void *_vs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *vs; + + vs = rbug_shader_unwrap(_vs); + rb_pipe->curr.vs = rbug_shader(_vs); + pipe->bind_vs_state(pipe, + vs); +} + +static void +rbug_delete_vs_state(struct pipe_context *_pipe, + void *_vs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_shader *rb_shader = rbug_shader(_vs); + + rbug_shader_destroy(rb_pipe, rb_shader); +} + +static void * +rbug_create_gs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *result; + + result = pipe->create_gs_state(pipe, state); + if (!result) + return NULL; + + return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_GEOM); +} + +static void +rbug_bind_gs_state(struct pipe_context *_pipe, + void *_gs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *gs; + + gs = rbug_shader_unwrap(_gs); + rb_pipe->curr.gs = rbug_shader(_gs); + pipe->bind_gs_state(pipe, + gs); +} + +static void +rbug_delete_gs_state(struct pipe_context *_pipe, + void *_gs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_shader *rb_shader = rbug_shader(_gs); + + rbug_shader_destroy(rb_pipe, rb_shader); +} + +static void * +rbug_create_vertex_elements_state(struct pipe_context *_pipe, + unsigned num_elements, + const struct pipe_vertex_element *vertex_elements) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_vertex_elements_state(pipe, + num_elements, + vertex_elements); +} + +static void +rbug_bind_vertex_elements_state(struct pipe_context *_pipe, + void *velems) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_vertex_elements_state(pipe, + velems); +} + +static void +rbug_delete_vertex_elements_state(struct pipe_context *_pipe, + void *velems) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_vertex_elements_state(pipe, + velems); +} + +static void +rbug_set_blend_color(struct pipe_context *_pipe, + const struct pipe_blend_color *blend_color) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_blend_color(pipe, + blend_color); +} + +static void +rbug_set_stencil_ref(struct pipe_context *_pipe, + const struct pipe_stencil_ref *stencil_ref) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_stencil_ref(pipe, + stencil_ref); +} + +static void +rbug_set_clip_state(struct pipe_context *_pipe, + const struct pipe_clip_state *clip) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_clip_state(pipe, + clip); +} + +static void +rbug_set_constant_buffer(struct pipe_context *_pipe, + uint shader, + uint index, + struct pipe_resource *_resource) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *unwrapped_resource; + struct pipe_resource *resource = NULL; + + /* XXX hmm? unwrap the input state */ + if (_resource) { + unwrapped_resource = rbug_resource_unwrap(_resource); + resource = unwrapped_resource; + } + + pipe->set_constant_buffer(pipe, + shader, + index, + resource); +} + +static void +rbug_set_framebuffer_state(struct pipe_context *_pipe, + const struct pipe_framebuffer_state *_state) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_framebuffer_state unwrapped_state; + struct pipe_framebuffer_state *state = NULL; + unsigned i; + + rb_pipe->curr.nr_cbufs = 0; + memset(rb_pipe->curr.cbufs, 0, sizeof(rb_pipe->curr.cbufs)); + + /* unwrap the input state */ + if (_state) { + memcpy(&unwrapped_state, _state, sizeof(unwrapped_state)); + + rb_pipe->curr.nr_cbufs = _state->nr_cbufs; + for(i = 0; i < _state->nr_cbufs; i++) { + unwrapped_state.cbufs[i] = rbug_surface_unwrap(_state->cbufs[i]); + if (_state->cbufs[i]) + rb_pipe->curr.cbufs[i] = rbug_resource(_state->cbufs[i]->texture); + } + unwrapped_state.zsbuf = rbug_surface_unwrap(_state->zsbuf); + state = &unwrapped_state; + } + + pipe->set_framebuffer_state(pipe, + state); +} + +static void +rbug_set_polygon_stipple(struct pipe_context *_pipe, + const struct pipe_poly_stipple *poly_stipple) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_polygon_stipple(pipe, + poly_stipple); +} + +static void +rbug_set_scissor_state(struct pipe_context *_pipe, + const struct pipe_scissor_state *scissor) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_scissor_state(pipe, + scissor); +} + +static void +rbug_set_viewport_state(struct pipe_context *_pipe, + const struct pipe_viewport_state *viewport) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_viewport_state(pipe, + viewport); +} + +static void +rbug_set_fragment_sampler_views(struct pipe_context *_pipe, + unsigned num, + struct pipe_sampler_view **_views) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view **views = NULL; + unsigned i; + + rb_pipe->curr.num_fs_views = 0; + memset(rb_pipe->curr.fs_views, 0, sizeof(rb_pipe->curr.fs_views)); + memset(rb_pipe->curr.fs_texs, 0, sizeof(rb_pipe->curr.fs_texs)); + memset(unwrapped_views, 0, sizeof(unwrapped_views)); + + if (_views) { + rb_pipe->curr.num_fs_views = num; + for (i = 0; i < num; i++) { + rb_pipe->curr.fs_views[i] = rbug_sampler_view(_views[i]); + rb_pipe->curr.fs_texs[i] = rbug_resource(_views[i] ? _views[i]->texture : NULL); + unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]); + } + views = unwrapped_views; + } + + pipe->set_fragment_sampler_views(pipe, num, views); +} + +static void +rbug_set_vertex_sampler_views(struct pipe_context *_pipe, + unsigned num, + struct pipe_sampler_view **_views) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_sampler_view **views = NULL; + unsigned i; + + rb_pipe->curr.num_vs_views = 0; + memset(rb_pipe->curr.vs_views, 0, sizeof(rb_pipe->curr.vs_views)); + memset(rb_pipe->curr.vs_texs, 0, sizeof(rb_pipe->curr.vs_texs)); + memset(unwrapped_views, 0, sizeof(unwrapped_views)); + + if (_views) { + rb_pipe->curr.num_vs_views = num; + for (i = 0; i < num; i++) { + rb_pipe->curr.vs_views[i] = rbug_sampler_view(_views[i]); + rb_pipe->curr.vs_texs[i] = rbug_resource(_views[i]->texture); + unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]); + } + views = unwrapped_views; + } + + pipe->set_vertex_sampler_views(pipe, num, views); +} + +static void +rbug_set_vertex_buffers(struct pipe_context *_pipe, + unsigned num_buffers, + const struct pipe_vertex_buffer *_buffers) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS]; + struct pipe_vertex_buffer *buffers = NULL; + unsigned i; + + if (num_buffers) { + memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); + for (i = 0; i < num_buffers; i++) + unwrapped_buffers[i].buffer = rbug_resource_unwrap(_buffers[i].buffer); + buffers = unwrapped_buffers; + } + + pipe->set_vertex_buffers(pipe, + num_buffers, + buffers); +} +static void +rbug_surface_copy(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned dstx, + unsigned dsty, + struct pipe_surface *_src, + unsigned srcx, + unsigned srcy, + unsigned width, + unsigned height) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_surface *rb_surface_dst = rbug_surface(_dst); + struct rbug_surface *rb_surface_src = rbug_surface(_src); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_surface *dst = rb_surface_dst->surface; + struct pipe_surface *src = rb_surface_src->surface; + + pipe->surface_copy(pipe, + dst, + dstx, + dsty, + src, + srcx, + srcy, + width, + height); +} + +static void +rbug_surface_fill(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned dstx, + unsigned dsty, + unsigned width, + unsigned height, + unsigned value) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_surface *rb_surface_dst = rbug_surface(_dst); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_surface *dst = rb_surface_dst->surface; + + pipe->surface_fill(pipe, + dst, + dstx, + dsty, + width, + height, + value); +} + +static void +rbug_clear(struct pipe_context *_pipe, + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->clear(pipe, + buffers, + rgba, + depth, + stencil); +} + +static void +rbug_flush(struct pipe_context *_pipe, + unsigned flags, + struct pipe_fence_handle **fence) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->flush(pipe, + flags, + fence); +} + +static unsigned int +rbug_is_resource_referenced(struct pipe_context *_pipe, + struct pipe_resource *_resource, + unsigned face, + unsigned level) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *resource = rb_resource->resource; + + return pipe->is_resource_referenced(pipe, + resource, + face, + level); +} + +static struct pipe_sampler_view * +rbug_context_create_sampler_view(struct pipe_context *_pipe, + struct pipe_resource *_resource, + const struct pipe_sampler_view *templ) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *resource = rb_resource->resource; + struct pipe_sampler_view *result; + + result = pipe->create_sampler_view(pipe, + resource, + templ); + + if (result) + return rbug_sampler_view_create(rb_pipe, rb_resource, result); + return NULL; +} + +static void +rbug_context_sampler_view_destroy(struct pipe_context *_pipe, + struct pipe_sampler_view *_view) +{ + rbug_sampler_view_destroy(rbug_context(_pipe), + rbug_sampler_view(_view)); +} + +static struct pipe_transfer * +rbug_context_get_transfer(struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_resource *resource = rb_resource->resource; + struct pipe_transfer *result; + + result = context->get_transfer(context, + resource, + sr, + usage, + box); + + if (result) + return rbug_transfer_create(rb_pipe, rb_resource, result); + return NULL; +} + +static void +rbug_context_transfer_destroy(struct pipe_context *_pipe, + struct pipe_transfer *_transfer) +{ + rbug_transfer_destroy(rbug_context(_pipe), + rbug_transfer(_transfer)); +} + +static void * +rbug_context_transfer_map(struct pipe_context *_context, + struct pipe_transfer *_transfer) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_transfer *rb_transfer = rbug_transfer(_transfer); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_transfer *transfer = rb_transfer->transfer; + + return context->transfer_map(context, + transfer); +} + + + +static void +rbug_context_transfer_flush_region(struct pipe_context *_context, + struct pipe_transfer *_transfer, + const struct pipe_box *box) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_transfer *rb_transfer = rbug_transfer(_transfer); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_transfer *transfer = rb_transfer->transfer; + + context->transfer_flush_region(context, + transfer, + box); +} + + +static void +rbug_context_transfer_unmap(struct pipe_context *_context, + struct pipe_transfer *_transfer) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_transfer *rb_transfer = rbug_transfer(_transfer); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_transfer *transfer = rb_transfer->transfer; + + context->transfer_unmap(context, + transfer); +} + + +static void +rbug_context_transfer_inline_write(struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned slice_stride) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_resource *resource = rb_resource->resource; + + context->transfer_inline_write(context, + resource, + sr, + usage, + box, + data, + stride, + slice_stride); +} + + +struct pipe_context * +rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) +{ + struct rbug_context *rb_pipe; + struct rbug_screen *rb_screen = rbug_screen(_screen); + + if (!rb_screen) + return NULL; + + rb_pipe = CALLOC_STRUCT(rbug_context); + if (!rb_pipe) + return NULL; + + pipe_mutex_init(rb_pipe->draw_mutex); + pipe_condvar_init(rb_pipe->draw_cond); + pipe_mutex_init(rb_pipe->call_mutex); + pipe_mutex_init(rb_pipe->list_mutex); + make_empty_list(&rb_pipe->shaders); + + rb_pipe->base.winsys = NULL; + rb_pipe->base.screen = _screen; + rb_pipe->base.priv = pipe->priv; /* expose wrapped data */ + rb_pipe->base.draw = NULL; + + rb_pipe->base.destroy = rbug_destroy; + rb_pipe->base.draw_arrays = rbug_draw_arrays; + rb_pipe->base.draw_elements = rbug_draw_elements; + rb_pipe->base.draw_range_elements = rbug_draw_range_elements; + rb_pipe->base.create_query = rbug_create_query; + rb_pipe->base.destroy_query = rbug_destroy_query; + rb_pipe->base.begin_query = rbug_begin_query; + rb_pipe->base.end_query = rbug_end_query; + rb_pipe->base.get_query_result = rbug_get_query_result; + rb_pipe->base.create_blend_state = rbug_create_blend_state; + rb_pipe->base.bind_blend_state = rbug_bind_blend_state; + rb_pipe->base.delete_blend_state = rbug_delete_blend_state; + rb_pipe->base.create_sampler_state = rbug_create_sampler_state; + rb_pipe->base.bind_fragment_sampler_states = rbug_bind_fragment_sampler_states; + rb_pipe->base.bind_vertex_sampler_states = rbug_bind_vertex_sampler_states; + rb_pipe->base.delete_sampler_state = rbug_delete_sampler_state; + rb_pipe->base.create_rasterizer_state = rbug_create_rasterizer_state; + rb_pipe->base.bind_rasterizer_state = rbug_bind_rasterizer_state; + rb_pipe->base.delete_rasterizer_state = rbug_delete_rasterizer_state; + rb_pipe->base.create_depth_stencil_alpha_state = rbug_create_depth_stencil_alpha_state; + rb_pipe->base.bind_depth_stencil_alpha_state = rbug_bind_depth_stencil_alpha_state; + rb_pipe->base.delete_depth_stencil_alpha_state = rbug_delete_depth_stencil_alpha_state; + rb_pipe->base.create_fs_state = rbug_create_fs_state; + rb_pipe->base.bind_fs_state = rbug_bind_fs_state; + rb_pipe->base.delete_fs_state = rbug_delete_fs_state; + rb_pipe->base.create_vs_state = rbug_create_vs_state; + rb_pipe->base.bind_vs_state = rbug_bind_vs_state; + rb_pipe->base.delete_vs_state = rbug_delete_vs_state; + rb_pipe->base.create_gs_state = rbug_create_gs_state; + rb_pipe->base.bind_gs_state = rbug_bind_gs_state; + rb_pipe->base.delete_gs_state = rbug_delete_gs_state; + rb_pipe->base.create_vertex_elements_state = rbug_create_vertex_elements_state; + rb_pipe->base.bind_vertex_elements_state = rbug_bind_vertex_elements_state; + rb_pipe->base.delete_vertex_elements_state = rbug_delete_vertex_elements_state; + rb_pipe->base.set_blend_color = rbug_set_blend_color; + rb_pipe->base.set_stencil_ref = rbug_set_stencil_ref; + rb_pipe->base.set_clip_state = rbug_set_clip_state; + rb_pipe->base.set_constant_buffer = rbug_set_constant_buffer; + rb_pipe->base.set_framebuffer_state = rbug_set_framebuffer_state; + rb_pipe->base.set_polygon_stipple = rbug_set_polygon_stipple; + rb_pipe->base.set_scissor_state = rbug_set_scissor_state; + rb_pipe->base.set_viewport_state = rbug_set_viewport_state; + rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views; + rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views; + rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers; + rb_pipe->base.surface_copy = rbug_surface_copy; + rb_pipe->base.surface_fill = rbug_surface_fill; + rb_pipe->base.clear = rbug_clear; + rb_pipe->base.flush = rbug_flush; + rb_pipe->base.is_resource_referenced = rbug_is_resource_referenced; + rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view; + rb_pipe->base.sampler_view_destroy = rbug_context_sampler_view_destroy; + rb_pipe->base.get_transfer = rbug_context_get_transfer; + rb_pipe->base.transfer_destroy = rbug_context_transfer_destroy; + rb_pipe->base.transfer_map = rbug_context_transfer_map; + rb_pipe->base.transfer_unmap = rbug_context_transfer_unmap; + rb_pipe->base.transfer_flush_region = rbug_context_transfer_flush_region; + rb_pipe->base.transfer_inline_write = rbug_context_transfer_inline_write; + + rb_pipe->pipe = pipe; + + rbug_screen_add_to_list(rb_screen, contexts, rb_pipe); + + return &rb_pipe->base; +} diff --git a/src/gallium/drivers/rbug/rbug_context.h b/src/gallium/drivers/rbug/rbug_context.h new file mode 100644 index 00000000000..80c803da83f --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_context.h @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 VMWARE 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. + * + **************************************************************************/ + +#ifndef RBUG_CONTEXT_H +#define RBUG_CONTEXT_H + +#include "pipe/p_state.h" +#include "pipe/p_context.h" + +#include "rbug_screen.h" + + +struct rbug_context { + struct pipe_context base; /**< base class */ + + struct pipe_context *pipe; + + struct rbug_list list; + + /* call locking */ + pipe_mutex call_mutex; + + /* current state */ + struct { + struct rbug_shader *fs; + struct rbug_shader *vs; + struct rbug_shader *gs; + + struct rbug_sampler_view *fs_views[PIPE_MAX_SAMPLERS]; + struct rbug_resource *fs_texs[PIPE_MAX_SAMPLERS]; + unsigned num_fs_views; + + struct rbug_sampler_view *vs_views[PIPE_MAX_VERTEX_SAMPLERS]; + struct rbug_resource *vs_texs[PIPE_MAX_VERTEX_SAMPLERS]; + unsigned num_vs_views; + + unsigned nr_cbufs; + struct rbug_resource *cbufs[PIPE_MAX_COLOR_BUFS]; + struct rbug_resource *zsbuf; + } curr; + + /* draw locking */ + pipe_mutex draw_mutex; + pipe_condvar draw_cond; + unsigned draw_num_rules; + int draw_blocker; + int draw_blocked; + + struct { + struct rbug_shader *fs; + struct rbug_shader *vs; + + struct rbug_resource *texture; + struct rbug_resource *surf; + + int blocker; + } draw_rule; + + /* list of state objects */ + pipe_mutex list_mutex; + unsigned num_shaders; + struct rbug_list shaders; +}; + +static INLINE struct rbug_context * +rbug_context(struct pipe_context *pipe) +{ + return (struct rbug_context *)pipe; +} + + +/********************************************************** + * rbug_context.c + */ + +struct pipe_context * +rbug_context_create(struct pipe_screen *screen, struct pipe_context *pipe); + + +/********************************************************** + * rbug_core.c + */ + +void rbug_notify_draw_blocked(struct rbug_context *rb_context); + + +#endif /* RBUG_CONTEXT_H */ diff --git a/src/gallium/drivers/rbug/rbug_core.c b/src/gallium/drivers/rbug/rbug_core.c new file mode 100644 index 00000000000..f1aab3869b5 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_core.c @@ -0,0 +1,890 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 VMWARE 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 "os/os_thread.h" +#include "util/u_format.h" +#include "util/u_string.h" +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_simple_list.h" +#include "util/u_network.h" +#include "os/os_time.h" + +#include "tgsi/tgsi_parse.h" + +#include "rbug_context.h" +#include "rbug_objects.h" + +#include "rbug/rbug.h" + +#include <errno.h> + +#define U642VOID(x) ((void *)(unsigned long)(x)) +#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) + +#define container_of(ptr, type, field) \ + (type*)((char*)ptr - offsetof(type, field)) + +struct rbug_rbug +{ + struct rbug_screen *rb_screen; + struct rbug_connection *con; + pipe_thread thread; + boolean running; +}; + +PIPE_THREAD_ROUTINE(rbug_thread, void_rbug); + + +/********************************************************** + * Helper functions + */ + + +static struct rbug_context * +rbug_get_context_locked(struct rbug_screen *rb_screen, rbug_context_t ctx) +{ + struct rbug_context *rb_context = NULL; + struct rbug_list *ptr; + + foreach(ptr, &rb_screen->contexts) { + rb_context = container_of(ptr, struct rbug_context, list); + if (ctx == VOID2U64(rb_context)) + break; + rb_context = NULL; + } + + return rb_context; +} + +static struct rbug_shader * +rbug_get_shader_locked(struct rbug_context *rb_context, rbug_shader_t shdr) +{ + struct rbug_shader *tr_shdr = NULL; + struct rbug_list *ptr; + + foreach(ptr, &rb_context->shaders) { + tr_shdr = container_of(ptr, struct rbug_shader, list); + if (shdr == VOID2U64(tr_shdr)) + break; + tr_shdr = NULL; + } + + return tr_shdr; +} + +static void * +rbug_shader_create_locked(struct pipe_context *pipe, + struct rbug_shader *rb_shader, + struct tgsi_token *tokens) +{ + void *state = NULL; + struct pipe_shader_state pss = { 0 }; + pss.tokens = tokens; + + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: + state = pipe->create_fs_state(pipe, &pss); + break; + case RBUG_SHADER_VERTEX: + state = pipe->create_vs_state(pipe, &pss); + break; + case RBUG_SHADER_GEOM: + state = pipe->create_gs_state(pipe, &pss); + break; + default: + assert(0); + break; + } + + return state; +} + +static void +rbug_shader_bind_locked(struct pipe_context *pipe, + struct rbug_shader *rb_shader, + void *state) +{ + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: + pipe->bind_fs_state(pipe, state); + break; + case RBUG_SHADER_VERTEX: + pipe->bind_vs_state(pipe, state); + break; + case RBUG_SHADER_GEOM: + pipe->bind_gs_state(pipe, state); + break; + default: + assert(0); + break; + } +} + +static void +rbug_shader_delete_locked(struct pipe_context *pipe, + struct rbug_shader *rb_shader, + void *state) +{ + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: + pipe->delete_fs_state(pipe, state); + break; + case RBUG_SHADER_VERTEX: + pipe->delete_vs_state(pipe, state); + break; + case RBUG_SHADER_GEOM: + pipe->delete_gs_state(pipe, state); + break; + default: + assert(0); + break; + } +} + +/************************************************ + * Request handler functions + */ + + +static int +rbug_texture_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_resource *tr_tex = NULL; + struct rbug_list *ptr; + rbug_texture_t *texs; + int i = 0; + + pipe_mutex_lock(rb_screen->list_mutex); + texs = MALLOC(rb_screen->num_resources * sizeof(rbug_texture_t)); + foreach(ptr, &rb_screen->resources) { + tr_tex = container_of(ptr, struct rbug_resource, list); + texs[i++] = VOID2U64(tr_tex); + } + pipe_mutex_unlock(rb_screen->list_mutex); + + rbug_send_texture_list_reply(tr_rbug->con, serial, texs, i, NULL); + FREE(texs); + + return 0; +} + +static int +rbug_texture_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_resource *tr_tex = NULL; + struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header; + struct rbug_list *ptr; + struct pipe_resource *t; + + pipe_mutex_lock(rb_screen->list_mutex); + foreach(ptr, &rb_screen->resources) { + tr_tex = container_of(ptr, struct rbug_resource, list); + if (gpti->texture == VOID2U64(tr_tex)) + break; + tr_tex = NULL; + } + + if (!tr_tex) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + t = tr_tex->resource; + rbug_send_texture_info_reply(tr_rbug->con, serial, + t->target, t->format, + &t->width0, 1, + &t->height0, 1, + &t->depth0, 1, + util_format_get_blockwidth(t->format), + util_format_get_blockheight(t->format), + util_format_get_blocksize(t->format), + t->last_level, + t->nr_samples, + t->bind, + NULL); + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_texture_read(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_resource *tr_tex = NULL; + struct rbug_list *ptr; + + struct pipe_context *context = rb_screen->private_context; + struct pipe_resource *tex; + struct pipe_transfer *t; + + void *map; + + pipe_mutex_lock(rb_screen->list_mutex); + foreach(ptr, &rb_screen->resources) { + tr_tex = container_of(ptr, struct rbug_resource, list); + if (gptr->texture == VOID2U64(tr_tex)) + break; + tr_tex = NULL; + } + + if (!tr_tex) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + tex = tr_tex->resource; + t = pipe_get_transfer(context, tex, + gptr->face, gptr->level, gptr->zslice, + PIPE_TRANSFER_READ, + gptr->x, gptr->y, gptr->w, gptr->h); + + map = context->transfer_map(context, t); + + rbug_send_texture_read_reply(tr_rbug->con, serial, + t->resource->format, + util_format_get_blockwidth(t->resource->format), + util_format_get_blockheight(t->resource->format), + util_format_get_blocksize(t->resource->format), + (uint8_t*)map, + t->stride * util_format_get_nblocksy(t->resource->format, + t->box.height), + t->stride, + NULL); + + context->transfer_unmap(context, t); + context->transfer_destroy(context, t); + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_list *ptr; + struct rbug_context *rb_context = NULL; + rbug_context_t *ctxs; + int i = 0; + + pipe_mutex_lock(rb_screen->list_mutex); + ctxs = MALLOC(rb_screen->num_contexts * sizeof(rbug_context_t)); + foreach(ptr, &rb_screen->contexts) { + rb_context = container_of(ptr, struct rbug_context, list); + ctxs[i++] = VOID2U64(rb_context); + } + pipe_mutex_unlock(rb_screen->list_mutex); + + rbug_send_context_list_reply(tr_rbug->con, serial, ctxs, i, NULL); + FREE(ctxs); + + return 0; +} + +static int +rbug_context_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS]; + rbug_texture_t texs[PIPE_MAX_SAMPLERS]; + int i; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, info->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + pipe_mutex_lock(rb_context->draw_mutex); + pipe_mutex_lock(rb_context->call_mutex); + + for (i = 0; i < rb_context->curr.nr_cbufs; i++) + cbufs[i] = VOID2U64(rb_context->curr.cbufs[i]); + + for (i = 0; i < rb_context->curr.num_fs_views; i++) + texs[i] = VOID2U64(rb_context->curr.fs_texs[i]); + + rbug_send_context_info_reply(tr_rbug->con, serial, + VOID2U64(rb_context->curr.vs), VOID2U64(rb_context->curr.fs), + texs, rb_context->curr.num_fs_views, + cbufs, rb_context->curr.nr_cbufs, + VOID2U64(rb_context->curr.zsbuf), + rb_context->draw_blocker, rb_context->draw_blocked, NULL); + + pipe_mutex_unlock(rb_context->call_mutex); + pipe_mutex_unlock(rb_context->draw_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_draw_block(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, block->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->draw_mutex); + rb_context->draw_blocker |= block->block; + pipe_mutex_unlock(rb_context->draw_mutex); + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_draw_step(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, step->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->draw_mutex); + if (rb_context->draw_blocked & RBUG_BLOCK_RULE) { + if (step->step & RBUG_BLOCK_RULE) + rb_context->draw_blocked &= ~RBUG_BLOCK_MASK; + } else { + rb_context->draw_blocked &= ~step->step; + } + pipe_mutex_unlock(rb_context->draw_mutex); + +#ifdef PIPE_THREAD_HAVE_CONDVAR + pipe_condvar_broadcast(rb_context->draw_cond); +#endif + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_draw_unblock(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, unblock->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->draw_mutex); + if (rb_context->draw_blocked & RBUG_BLOCK_RULE) { + if (unblock->unblock & RBUG_BLOCK_RULE) + rb_context->draw_blocked &= ~RBUG_BLOCK_MASK; + } else { + rb_context->draw_blocked &= ~unblock->unblock; + } + rb_context->draw_blocker &= ~unblock->unblock; + pipe_mutex_unlock(rb_context->draw_mutex); + +#ifdef PIPE_THREAD_HAVE_CONDVAR + pipe_condvar_broadcast(rb_context->draw_cond); +#endif + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_draw_rule(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, rule->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->draw_mutex); + rb_context->draw_rule.vs = U642VOID(rule->vertex); + rb_context->draw_rule.fs = U642VOID(rule->fragment); + rb_context->draw_rule.texture = U642VOID(rule->texture); + rb_context->draw_rule.surf = U642VOID(rule->surface); + rb_context->draw_rule.blocker = rule->block; + rb_context->draw_blocker |= RBUG_BLOCK_RULE; + pipe_mutex_unlock(rb_context->draw_mutex); + +#ifdef PIPE_THREAD_HAVE_CONDVAR + pipe_condvar_broadcast(rb_context->draw_cond); +#endif + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, flush->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + pipe_mutex_lock(rb_context->call_mutex); + + rb_context->pipe->flush(rb_context->pipe, flush->flags, NULL); + + pipe_mutex_unlock(rb_context->call_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_shader_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + struct rbug_shader *tr_shdr = NULL; + struct rbug_list *ptr; + rbug_shader_t *shdrs; + int i = 0; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, list->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->list_mutex); + shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t)); + foreach(ptr, &rb_context->shaders) { + tr_shdr = container_of(ptr, struct rbug_shader, list); + shdrs[i++] = VOID2U64(tr_shdr); + } + + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL); + FREE(shdrs); + + return 0; +} + +static int +rbug_shader_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + struct rbug_shader *tr_shdr = NULL; + unsigned original_len; + unsigned replaced_len; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, info->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, info->shader); + + if (!tr_shdr) { + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + /* just in case */ + assert(sizeof(struct tgsi_token) == 4); + + original_len = tgsi_num_tokens(tr_shdr->tokens); + if (tr_shdr->replaced_tokens) + replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens); + else + replaced_len = 0; + + rbug_send_shader_info_reply(tr_rbug->con, serial, + (uint32_t*)tr_shdr->tokens, original_len, + (uint32_t*)tr_shdr->replaced_tokens, replaced_len, + tr_shdr->disabled, + NULL); + + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_shader_disable(struct rbug_rbug *tr_rbug, struct rbug_header *header) +{ + struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + struct rbug_shader *tr_shdr = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, dis->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, dis->shader); + + if (!tr_shdr) { + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + tr_shdr->disabled = dis->disable; + + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_shader_replace(struct rbug_rbug *tr_rbug, struct rbug_header *header) +{ + struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + struct rbug_shader *tr_shdr = NULL; + struct pipe_context *pipe = NULL; + void *state; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, rep->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, rep->shader); + + if (!tr_shdr) { + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + pipe_mutex_lock(rb_context->call_mutex); + + pipe = rb_context->pipe; + + /* remove old replaced shader */ + if (tr_shdr->replaced_shader) { + /* if this shader is bound rebind the original shader */ + if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr) + rbug_shader_bind_locked(pipe, tr_shdr, tr_shdr->shader); + + FREE(tr_shdr->replaced_tokens); + rbug_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced_shader); + tr_shdr->replaced_shader = NULL; + tr_shdr->replaced_tokens = NULL; + } + + /* empty inputs means restore old which we did above */ + if (rep->tokens_len == 0) + goto out; + + tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens); + if (!tr_shdr->replaced_tokens) + goto err; + + state = rbug_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens); + if (!state) + goto err; + + /* bind new shader if the shader is currently a bound */ + if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr) + rbug_shader_bind_locked(pipe, tr_shdr, state); + + /* save state */ + tr_shdr->replaced_shader = state; + +out: + pipe_mutex_unlock(rb_context->call_mutex); + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; + +err: + FREE(tr_shdr->replaced_tokens); + tr_shdr->replaced_shader = NULL; + tr_shdr->replaced_tokens = NULL; + + pipe_mutex_unlock(rb_context->call_mutex); + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + return -EINVAL; +} + +static boolean +rbug_header(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + int ret = 0; + + switch(header->opcode) { + case RBUG_OP_PING: + rbug_send_ping_reply(tr_rbug->con, serial, NULL); + break; + case RBUG_OP_TEXTURE_LIST: + ret = rbug_texture_list(tr_rbug, header, serial); + break; + case RBUG_OP_TEXTURE_INFO: + ret = rbug_texture_info(tr_rbug, header, serial); + break; + case RBUG_OP_TEXTURE_READ: + ret = rbug_texture_read(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_LIST: + ret = rbug_context_list(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_INFO: + ret = rbug_context_info(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_BLOCK: + ret = rbug_context_draw_block(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_STEP: + ret = rbug_context_draw_step(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_UNBLOCK: + ret = rbug_context_draw_unblock(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_RULE: + ret = rbug_context_draw_rule(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_FLUSH: + ret = rbug_context_flush(tr_rbug, header, serial); + break; + case RBUG_OP_SHADER_LIST: + ret = rbug_shader_list(tr_rbug, header, serial); + break; + case RBUG_OP_SHADER_INFO: + ret = rbug_shader_info(tr_rbug, header, serial); + break; + case RBUG_OP_SHADER_DISABLE: + ret = rbug_shader_disable(tr_rbug, header); + break; + case RBUG_OP_SHADER_REPLACE: + ret = rbug_shader_replace(tr_rbug, header); + break; + default: + debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode); + ret = -ENOSYS; + break; + } + rbug_free_header(header); + + if (ret) + rbug_send_error_reply(tr_rbug->con, serial, ret, NULL); + + return TRUE; +} + +static void +rbug_con(struct rbug_rbug *tr_rbug) +{ + struct rbug_header *header; + uint32_t serial; + + debug_printf("%s - connection received\n", __FUNCTION__); + + while(tr_rbug->running) { + header = rbug_get_message(tr_rbug->con, &serial); + if (!header) + break; + + if (!rbug_header(tr_rbug, header, serial)) + break; + } + + debug_printf("%s - connection closed\n", __FUNCTION__); + + rbug_disconnect(tr_rbug->con); + tr_rbug->con = NULL; +} + +PIPE_THREAD_ROUTINE(rbug_thread, void_tr_rbug) +{ + struct rbug_rbug *tr_rbug = void_tr_rbug; + uint16_t port = 13370; + int s = -1; + int c; + + u_socket_init(); + + for (;port <= 13379 && s < 0; port++) + s = u_socket_listen_on_port(port); + + if (s < 0) { + debug_printf("rbug_rbug - failed to listen\n"); + return NULL; + } + + u_socket_block(s, false); + + debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port); + + while(tr_rbug->running) { + os_time_sleep(1); + + c = u_socket_accept(s); + if (c < 0) + continue; + + u_socket_block(c, true); + tr_rbug->con = rbug_from_socket(c); + + rbug_con(tr_rbug); + + u_socket_close(c); + } + + u_socket_close(s); + + u_socket_stop(); + + return NULL; +} + +/********************************************************** + * + */ + +struct rbug_rbug * +rbug_start(struct rbug_screen *rb_screen) +{ + struct rbug_rbug *tr_rbug = CALLOC_STRUCT(rbug_rbug); + if (!tr_rbug) + return NULL; + + tr_rbug->rb_screen = rb_screen; + tr_rbug->running = TRUE; + tr_rbug->thread = pipe_thread_create(rbug_thread, tr_rbug); + + return tr_rbug; +} + +void +rbug_stop(struct rbug_rbug *tr_rbug) +{ + if (!tr_rbug) + return; + + tr_rbug->running = false; + pipe_thread_wait(tr_rbug->thread); + + FREE(tr_rbug); + + return; +} + +void +rbug_notify_draw_blocked(struct rbug_context *rb_context) +{ + struct rbug_screen *rb_screen = rbug_screen(rb_context->base.screen); + struct rbug_rbug *tr_rbug = rb_screen->rbug; + + if (tr_rbug && tr_rbug->con) + rbug_send_context_draw_blocked(tr_rbug->con, + VOID2U64(rb_context), rb_context->draw_blocked, NULL); +} diff --git a/src/gallium/drivers/rbug/rbug_objects.c b/src/gallium/drivers/rbug/rbug_objects.c new file mode 100644 index 00000000000..0979fcff957 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_objects.c @@ -0,0 +1,247 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 VMWARE 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 "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_simple_list.h" + +#include "tgsi/tgsi_parse.h" + +#include "rbug_screen.h" +#include "rbug_objects.h" +#include "rbug_context.h" + + + +struct pipe_resource * +rbug_resource_create(struct rbug_screen *rb_screen, + struct pipe_resource *resource) +{ + struct rbug_resource *rb_resource; + + if(!resource) + goto error; + + assert(resource->screen == rb_screen->screen); + + rb_resource = CALLOC_STRUCT(rbug_resource); + if(!rb_resource) + goto error; + + memcpy(&rb_resource->base, resource, sizeof(struct pipe_resource)); + + pipe_reference_init(&rb_resource->base.reference, 1); + rb_resource->base.screen = &rb_screen->base; + rb_resource->resource = resource; + + rbug_screen_add_to_list(rb_screen, resources, rb_resource); + + return &rb_resource->base; + +error: + pipe_resource_reference(&resource, NULL); + return NULL; +} + +void +rbug_resource_destroy(struct rbug_resource *rb_resource) +{ + struct rbug_screen *rb_screen = rbug_screen(rb_resource->base.screen); + rbug_screen_remove_from_list(rb_screen, resources, rb_resource); + + pipe_resource_reference(&rb_resource->resource, NULL); + FREE(rb_resource); +} + + +struct pipe_surface * +rbug_surface_create(struct rbug_resource *rb_resource, + struct pipe_surface *surface) +{ + struct rbug_surface *rb_surface; + + if(!surface) + goto error; + + assert(surface->texture == rb_resource->resource); + + rb_surface = CALLOC_STRUCT(rbug_surface); + if(!rb_surface) + goto error; + + memcpy(&rb_surface->base, surface, sizeof(struct pipe_surface)); + + pipe_reference_init(&rb_surface->base.reference, 1); + rb_surface->base.texture = NULL; + pipe_resource_reference(&rb_surface->base.texture, &rb_resource->base); + rb_surface->surface = surface; + + return &rb_surface->base; + +error: + pipe_surface_reference(&surface, NULL); + return NULL; +} + +void +rbug_surface_destroy(struct rbug_surface *rb_surface) +{ + pipe_resource_reference(&rb_surface->base.texture, NULL); + pipe_surface_reference(&rb_surface->surface, NULL); + FREE(rb_surface); +} + + +struct pipe_sampler_view * +rbug_sampler_view_create(struct rbug_context *rb_context, + struct rbug_resource *rb_resource, + struct pipe_sampler_view *view) +{ + struct rbug_sampler_view *rb_view; + + if (!view) + goto error; + + assert(view->texture == rb_resource->resource); + + rb_view = MALLOC(sizeof(struct rbug_sampler_view)); + + rb_view->base = *view; + rb_view->base.reference.count = 1; + rb_view->base.texture = NULL; + pipe_resource_reference(&rb_view->base.texture, &rb_resource->base); + rb_view->base.context = rb_context->pipe; + rb_view->sampler_view = view; + + return &rb_view->base; +error: + return NULL; +} + +void +rbug_sampler_view_destroy(struct rbug_context *rb_context, + struct rbug_sampler_view *rb_view) +{ + pipe_resource_reference(&rb_view->base.texture, NULL); + rb_context->pipe->sampler_view_destroy(rb_context->pipe, + rb_view->sampler_view); + FREE(rb_view); +} + + +struct pipe_transfer * +rbug_transfer_create(struct rbug_context *rb_context, + struct rbug_resource *rb_resource, + struct pipe_transfer *transfer) +{ + struct rbug_transfer *rb_transfer; + + if(!transfer) + goto error; + + assert(transfer->resource == rb_resource->resource); + + rb_transfer = CALLOC_STRUCT(rbug_transfer); + if(!rb_transfer) + goto error; + + memcpy(&rb_transfer->base, transfer, sizeof(struct pipe_transfer)); + + rb_transfer->base.resource = NULL; + rb_transfer->transfer = transfer; + rb_transfer->pipe = rb_context->pipe; + + pipe_resource_reference(&rb_transfer->base.resource, &rb_resource->base); + assert(rb_transfer->base.resource == &rb_resource->base); + + return &rb_transfer->base; + +error: + rb_context->pipe->transfer_destroy(rb_context->pipe, transfer); + return NULL; +} + +void +rbug_transfer_destroy(struct rbug_context *rb_context, + struct rbug_transfer *rb_transfer) +{ + pipe_resource_reference(&rb_transfer->base.resource, NULL); + rb_transfer->pipe->transfer_destroy(rb_context->pipe, + rb_transfer->transfer); + FREE(rb_transfer); +} + +void * +rbug_shader_create(struct rbug_context *rb_context, + const struct pipe_shader_state *state, + void *result, enum rbug_shader_type type) +{ + struct rbug_shader *rb_shader = CALLOC_STRUCT(rbug_shader); + + rb_shader->type = type; + rb_shader->shader = result; + rb_shader->tokens = tgsi_dup_tokens(state->tokens); + + /* works on context as well since its just a macro */ + rbug_screen_add_to_list(rb_context, shaders, rb_shader); + + return rb_shader; +} + +void +rbug_shader_destroy(struct rbug_context *rb_context, + struct rbug_shader *rb_shader) +{ + struct pipe_context *pipe = rb_context->pipe; + + /* works on context as well since its just a macro */ + rbug_screen_remove_from_list(rb_context, shaders, rb_shader); + + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: + if (rb_shader->replaced_shader) + pipe->delete_fs_state(pipe, rb_shader->replaced_shader); + pipe->delete_fs_state(pipe, rb_shader->shader); + break; + case RBUG_SHADER_VERTEX: + if (rb_shader->replaced_shader) + pipe->delete_vs_state(pipe, rb_shader->replaced_shader); + pipe->delete_vs_state(pipe, rb_shader->shader); + break; + case RBUG_SHADER_GEOM: + if (rb_shader->replaced_shader) + pipe->delete_gs_state(pipe, rb_shader->replaced_shader); + pipe->delete_gs_state(pipe, rb_shader->shader); + break; + default: + assert(0); + } + + FREE(rb_shader->replaced_tokens); + FREE(rb_shader->tokens); + FREE(rb_shader); +} diff --git a/src/gallium/drivers/rbug/rbug_objects.h b/src/gallium/drivers/rbug/rbug_objects.h new file mode 100644 index 00000000000..49c128d3d1a --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_objects.h @@ -0,0 +1,226 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 VMWARE 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. + * + **************************************************************************/ + +#ifndef RBUG_OBJECTS_H +#define RBUG_OBJECTS_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "rbug_screen.h" + +struct rbug_context; + + +struct rbug_resource +{ + struct pipe_resource base; + + struct pipe_resource *resource; + + struct rbug_list list; +}; + + +enum rbug_shader_type +{ + RBUG_SHADER_GEOM, + RBUG_SHADER_VERTEX, + RBUG_SHADER_FRAGMENT, +}; + +struct rbug_shader +{ + struct rbug_list list; + + void *shader; + void *tokens; + void *replaced_shader; + void *replaced_tokens; + + enum rbug_shader_type type; + boolean disabled; +}; + + +struct rbug_sampler_view +{ + struct pipe_sampler_view base; + + struct pipe_sampler_view *sampler_view; +}; + + +struct rbug_surface +{ + struct pipe_surface base; + + struct pipe_surface *surface; +}; + + +struct rbug_transfer +{ + struct pipe_transfer base; + + struct pipe_context *pipe; + struct pipe_transfer *transfer; +}; + + +static INLINE struct rbug_resource * +rbug_resource(struct pipe_resource *_resource) +{ + if (!_resource) + return NULL; + (void)rbug_screen(_resource->screen); + return (struct rbug_resource *)_resource; +} + +static INLINE struct rbug_sampler_view * +rbug_sampler_view(struct pipe_sampler_view *_sampler_view) +{ + if (!_sampler_view) + return NULL; + (void)rbug_resource(_sampler_view->texture); + return (struct rbug_sampler_view *)_sampler_view; +} + +static INLINE struct rbug_surface * +rbug_surface(struct pipe_surface *_surface) +{ + if (!_surface) + return NULL; + (void)rbug_resource(_surface->texture); + return (struct rbug_surface *)_surface; +} + +static INLINE struct rbug_transfer * +rbug_transfer(struct pipe_transfer *_transfer) +{ + if (!_transfer) + return NULL; + (void)rbug_resource(_transfer->resource); + return (struct rbug_transfer *)_transfer; +} + +static INLINE struct rbug_shader * +rbug_shader(void *_state) +{ + if (!_state) + return NULL; + return (struct rbug_shader *)_state; +} + +static INLINE struct pipe_resource * +rbug_resource_unwrap(struct pipe_resource *_resource) +{ + if (!_resource) + return NULL; + return rbug_resource(_resource)->resource; +} + +static INLINE struct pipe_sampler_view * +rbug_sampler_view_unwrap(struct pipe_sampler_view *_sampler_view) +{ + if (!_sampler_view) + return NULL; + return rbug_sampler_view(_sampler_view)->sampler_view; +} + +static INLINE struct pipe_surface * +rbug_surface_unwrap(struct pipe_surface *_surface) +{ + if (!_surface) + return NULL; + return rbug_surface(_surface)->surface; +} + +static INLINE struct pipe_transfer * +rbug_transfer_unwrap(struct pipe_transfer *_transfer) +{ + if (!_transfer) + return NULL; + return rbug_transfer(_transfer)->transfer; +} + +static INLINE void * +rbug_shader_unwrap(void *_state) +{ + struct rbug_shader *shader; + if (!_state) + return NULL; + + shader = rbug_shader(_state); + return shader->replaced_shader ? shader->replaced_shader : shader->shader; +} + + +struct pipe_resource * +rbug_resource_create(struct rbug_screen *rb_screen, + struct pipe_resource *resource); + +void +rbug_resource_destroy(struct rbug_resource *rb_resource); + +struct pipe_surface * +rbug_surface_create(struct rbug_resource *rb_resource, + struct pipe_surface *surface); + +void +rbug_surface_destroy(struct rbug_surface *rb_surface); + +struct pipe_sampler_view * +rbug_sampler_view_create(struct rbug_context *rb_context, + struct rbug_resource *rb_resource, + struct pipe_sampler_view *view); + +void +rbug_sampler_view_destroy(struct rbug_context *rb_context, + struct rbug_sampler_view *rb_sampler_view); + +struct pipe_transfer * +rbug_transfer_create(struct rbug_context *rb_context, + struct rbug_resource *rb_resource, + struct pipe_transfer *transfer); + +void +rbug_transfer_destroy(struct rbug_context *rb_context, + struct rbug_transfer *rb_transfer); + +void * +rbug_shader_create(struct rbug_context *rb_context, + const struct pipe_shader_state *state, + void *result, enum rbug_shader_type type); + +void +rbug_shader_destroy(struct rbug_context *rb_context, + struct rbug_shader *rb_shader); + + +#endif /* RBUG_OBJECTS_H */ diff --git a/src/gallium/drivers/rbug/rbug_public.h b/src/gallium/drivers/rbug/rbug_public.h new file mode 100644 index 00000000000..b66740b49cd --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_public.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 VMWARE 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. + * + **************************************************************************/ + +#ifndef RBUG_PUBLIC_H +#define RBUG_PUBLIC_H + +struct pipe_screen; +struct pipe_context; + +struct pipe_screen * +rbug_screen_create(struct pipe_screen *screen); + +boolean +rbug_enabled(void); + +#endif /* RBUG_PUBLIC_H */ diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c new file mode 100644 index 00000000000..2b60af2302a --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_screen.c @@ -0,0 +1,351 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 VMWARE 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_screen.h" +#include "pipe/p_state.h" +#include "util/u_memory.h" +#include "util/u_debug.h" +#include "util/u_simple_list.h" + +#include "rbug_public.h" +#include "rbug_screen.h" +#include "rbug_context.h" +#include "rbug_objects.h" + +DEBUG_GET_ONCE_BOOL_OPTION(rbug, "GALLIUM_RBUG", FALSE) + +static void +rbug_screen_destroy(struct pipe_screen *_screen) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + screen->destroy(screen); + + FREE(rb_screen); +} + +static const char * +rbug_screen_get_name(struct pipe_screen *_screen) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_name(screen); +} + +static const char * +rbug_screen_get_vendor(struct pipe_screen *_screen) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_vendor(screen); +} + +static int +rbug_screen_get_param(struct pipe_screen *_screen, + enum pipe_cap param) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_param(screen, + param); +} + +static float +rbug_screen_get_paramf(struct pipe_screen *_screen, + enum pipe_cap param) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_paramf(screen, + param); +} + +static boolean +rbug_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->is_format_supported(screen, + format, + target, + tex_usage, + geom_flags); +} + +static struct pipe_context * +rbug_screen_context_create(struct pipe_screen *_screen, + void *priv) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_context *result; + + result = screen->context_create(screen, priv); + if (result) + return rbug_context_create(_screen, result); + return NULL; +} + +static struct pipe_resource * +rbug_screen_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *result; + + result = screen->resource_create(screen, + templat); + + if (result) + return rbug_resource_create(rb_screen, result); + return NULL; +} + +static struct pipe_resource * +rbug_screen_resource_from_handle(struct pipe_screen *_screen, + const struct pipe_resource *templ, + struct winsys_handle *handle) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *result; + + result = screen->resource_from_handle(screen, templ, handle); + + result = rbug_resource_create(rbug_screen(_screen), result); + + return result; +} + +static boolean +rbug_screen_resource_get_handle(struct pipe_screen *_screen, + struct pipe_resource *_resource, + struct winsys_handle *handle) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *resource = rb_resource->resource; + + return screen->resource_get_handle(screen, resource, handle); +} + + + +static void +rbug_screen_resource_destroy(struct pipe_screen *screen, + struct pipe_resource *_resource) +{ + rbug_resource_destroy(rbug_resource(_resource)); +} + +static struct pipe_surface * +rbug_screen_get_tex_surface(struct pipe_screen *_screen, + struct pipe_resource *_resource, + unsigned face, + unsigned level, + unsigned zslice, + unsigned usage) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *resource = rb_resource->resource; + struct pipe_surface *result; + + result = screen->get_tex_surface(screen, + resource, + face, + level, + zslice, + usage); + + if (result) + return rbug_surface_create(rb_resource, result); + return NULL; +} + +static void +rbug_screen_tex_surface_destroy(struct pipe_surface *_surface) +{ + rbug_surface_destroy(rbug_surface(_surface)); +} + + + +static struct pipe_resource * +rbug_screen_user_buffer_create(struct pipe_screen *_screen, + void *ptr, + unsigned bytes, + unsigned usage) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *result; + + result = screen->user_buffer_create(screen, + ptr, + bytes, + usage); + + if (result) + return rbug_resource_create(rb_screen, result); + return NULL; +} + + + +static void +rbug_screen_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_surface *_surface, + void *context_private) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct rbug_surface *rb_surface = rbug_surface(_surface); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_surface *surface = rb_surface->surface; + + screen->flush_frontbuffer(screen, + surface, + context_private); +} + +static void +rbug_screen_fence_reference(struct pipe_screen *_screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + screen->fence_reference(screen, + ptr, + fence); +} + +static int +rbug_screen_fence_signalled(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->fence_signalled(screen, + fence, + flags); +} + +static int +rbug_screen_fence_finish(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->fence_finish(screen, + fence, + flags); +} + +boolean +rbug_enabled() +{ + return debug_get_option_rbug(); +} + +struct pipe_screen * +rbug_screen_create(struct pipe_screen *screen) +{ + struct rbug_screen *rb_screen; + + if (!debug_get_option_rbug()) + return screen; + + rb_screen = CALLOC_STRUCT(rbug_screen); + if (!rb_screen) + return screen; + + pipe_mutex_init(rb_screen->list_mutex); + make_empty_list(&rb_screen->contexts); + make_empty_list(&rb_screen->resources); + make_empty_list(&rb_screen->surfaces); + make_empty_list(&rb_screen->transfers); + + rb_screen->base.winsys = NULL; + + rb_screen->base.destroy = rbug_screen_destroy; + rb_screen->base.get_name = rbug_screen_get_name; + rb_screen->base.get_vendor = rbug_screen_get_vendor; + rb_screen->base.get_param = rbug_screen_get_param; + rb_screen->base.get_paramf = rbug_screen_get_paramf; + rb_screen->base.is_format_supported = rbug_screen_is_format_supported; + rb_screen->base.context_create = rbug_screen_context_create; + rb_screen->base.resource_create = rbug_screen_resource_create; + rb_screen->base.resource_from_handle = rbug_screen_resource_from_handle; + rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle; + rb_screen->base.resource_destroy = rbug_screen_resource_destroy; + rb_screen->base.get_tex_surface = rbug_screen_get_tex_surface; + rb_screen->base.tex_surface_destroy = rbug_screen_tex_surface_destroy; + rb_screen->base.user_buffer_create = rbug_screen_user_buffer_create; + rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer; + rb_screen->base.fence_reference = rbug_screen_fence_reference; + rb_screen->base.fence_signalled = rbug_screen_fence_signalled; + rb_screen->base.fence_finish = rbug_screen_fence_finish; + + rb_screen->screen = screen; + + rb_screen->private_context = screen->context_create(screen, NULL); + if (!rb_screen->private_context) + goto err_free; + + rb_screen->rbug = rbug_start(rb_screen); + + if (!rb_screen->rbug) + goto err_context; + + return &rb_screen->base; + +err_context: + rb_screen->private_context->destroy(rb_screen->private_context); +err_free: + FREE(rb_screen); + return screen; +} diff --git a/src/gallium/drivers/rbug/rbug_screen.h b/src/gallium/drivers/rbug/rbug_screen.h new file mode 100644 index 00000000000..a53afac05e9 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_screen.h @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 VMWARE 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. + * + **************************************************************************/ + +#ifndef RBUG_SCREEN_H +#define RBUG_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + +#include "os/os_thread.h" + +struct rbug_list { + struct rbug_list *next; + struct rbug_list *prev; +}; + + +struct rbug_screen +{ + struct pipe_screen base; + + struct pipe_screen *screen; + struct pipe_context *private_context; + + /* remote debugger */ + struct rbug_rbug *rbug; + + pipe_mutex list_mutex; + int num_contexts; + int num_resources; + int num_surfaces; + int num_transfers; + struct rbug_list contexts; + struct rbug_list resources; + struct rbug_list surfaces; + struct rbug_list transfers; +}; + +static INLINE struct rbug_screen * +rbug_screen(struct pipe_screen *screen) +{ + return (struct rbug_screen *)screen; +} + +#define rbug_screen_add_to_list(scr, name, obj) \ + do { \ + pipe_mutex_lock(scr->list_mutex); \ + insert_at_head(&scr->name, &obj->list); \ + scr->num_##name++; \ + pipe_mutex_unlock(scr->list_mutex); \ + } while (0) + +#define rbug_screen_remove_from_list(scr, name, obj) \ + do { \ + pipe_mutex_lock(scr->list_mutex); \ + remove_from_list(&obj->list); \ + scr->num_##name--; \ + pipe_mutex_unlock(scr->list_mutex); \ + } while (0) + + + +/********************************************************** + * rbug_core.c + */ + +struct rbug_rbug; + +struct rbug_rbug * +rbug_start(struct rbug_screen *rb_screen); + +void +rbug_stop(struct rbug_rbug *rbug); + + +#endif /* RBUG_SCREEN_H */ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 0f1bcc21bd6..2f10b46e989 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -36,6 +36,7 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_inlines.h" +#include "tgsi/tgsi_exec.h" #include "sp_clear.h" #include "sp_context.h" #include "sp_flush.h" @@ -123,6 +124,8 @@ softpipe_destroy( struct pipe_context *pipe ) } } + tgsi_exec_machine_destroy(softpipe->fs_machine); + FREE( softpipe ); } @@ -294,6 +297,8 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); } + softpipe->fs_machine = tgsi_exec_machine_create(); + /* setup quad rendering stages */ softpipe->quad.shade = sp_quad_shade_stage(softpipe); softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 92607874b60..b3d3fe620fd 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -109,6 +109,9 @@ struct softpipe_context { /** The reduced version of the primitive supplied by the state tracker */ unsigned reduced_api_prim; + /** Derived information about which winding orders to cull */ + unsigned cull_mode; + /** * The reduced primitive after unfilled triangles, wide-line decomposition, * etc, are taken into account. This is the primitive type that's actually @@ -140,6 +143,8 @@ struct softpipe_context { struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS]; } tgsi; + struct tgsi_exec_machine *fs_machine; + /** The primitive drawing context */ struct draw_context *draw; diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index a58bc107c0a..db0d1755103 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -158,26 +158,27 @@ static INLINE cptrf4 get_vert( const void *vertex_buffer, * draw elements / indexed primitives */ static void -sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) +sp_vbuf_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float); const void *vertex_buffer = cvbr->vertex_buffer; - struct setup_context *setup_ctx = cvbr->setup; + struct setup_context *setup = cvbr->setup; + const boolean flatshade_first = softpipe->rasterizer->flatshade_first; unsigned i; switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { - sp_setup_point( setup_ctx, + sp_setup_point( setup, get_vert(vertex_buffer, indices[i-0], stride) ); } break; case PIPE_PRIM_LINES: for (i = 1; i < nr; i += 2) { - sp_setup_line( setup_ctx, + sp_setup_line( setup, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); } @@ -185,7 +186,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_LINE_STRIP: for (i = 1; i < nr; i ++) { - sp_setup_line( setup_ctx, + sp_setup_line( setup, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); } @@ -193,48 +194,41 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_LINE_LOOP: for (i = 1; i < nr; i ++) { - sp_setup_line( setup_ctx, + sp_setup_line( setup, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); } if (nr) { - sp_setup_line( setup_ctx, + sp_setup_line( setup, get_vert(vertex_buffer, indices[nr-1], stride), get_vert(vertex_buffer, indices[0], stride) ); } break; case PIPE_PRIM_TRIANGLES: - if (softpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 3) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } + for (i = 2; i < nr; i += 3) { + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); } break; case PIPE_PRIM_TRIANGLE_STRIP: - if (softpipe->rasterizer->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { - sp_setup_tri( setup_ctx, + /* emit first triangle vertex as first triangle vertex */ + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i+(i&1)-1], stride), - get_vert(vertex_buffer, indices[i-(i&1)], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); + get_vert(vertex_buffer, indices[i-(i&1)], stride) ); + } } else { for (i = 2; i < nr; i += 1) { - sp_setup_tri( setup_ctx, + /* emit last triangle vertex as last triangle vertex */ + sp_setup_tri( setup, get_vert(vertex_buffer, indices[i+(i&1)-2], stride), get_vert(vertex_buffer, indices[i-(i&1)-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); @@ -243,17 +237,19 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLE_FAN: - if (softpipe->rasterizer->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { - sp_setup_tri( setup_ctx, + /* emit first non-spoke vertex as first vertex */ + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[0], stride), - get_vert(vertex_buffer, indices[i-1], stride) ); + get_vert(vertex_buffer, indices[0], stride) ); } } else { for (i = 2; i < nr; i += 1) { - sp_setup_tri( setup_ctx, + /* emit last non-spoke vertex as last vertex */ + sp_setup_tri( setup, get_vert(vertex_buffer, indices[0], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); @@ -262,43 +258,88 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_QUADS: - for (i = 3; i < nr; i += 4) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); + /* GL quads don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 4) { + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 4) { + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 3; i < nr; i += 2) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); + /* GL quad strips don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 2) { + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 2) { + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_POLYGON: /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. + * shading color. */ - for (i = 2; i < nr; i += 1) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[0], stride) ); + if (flatshade_first) { + /* emit first polygon vertex as first triangle vertex */ + for (i = 2; i < nr; i += 1) { + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + else { + /* emit first polygon vertex as last triangle vertex */ + for (i = 2; i < nr; i += 1) { + sp_setup_tri( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } } break; @@ -317,23 +358,24 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; - struct setup_context *setup_ctx = cvbr->setup; + struct setup_context *setup = cvbr->setup; const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float); const void *vertex_buffer = (void *) get_vert(cvbr->vertex_buffer, start, stride); + const boolean flatshade_first = softpipe->rasterizer->flatshade_first; unsigned i; switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { - sp_setup_point( setup_ctx, + sp_setup_point( setup, get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_LINES: for (i = 1; i < nr; i += 2) { - sp_setup_line( setup_ctx, + sp_setup_line( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } @@ -341,7 +383,7 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_LINE_STRIP: for (i = 1; i < nr; i ++) { - sp_setup_line( setup_ctx, + sp_setup_line( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } @@ -349,48 +391,40 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_LINE_LOOP: for (i = 1; i < nr; i ++) { - sp_setup_line( setup_ctx, + sp_setup_line( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } if (nr) { - sp_setup_line( setup_ctx, + sp_setup_line( setup, get_vert(vertex_buffer, nr-1, stride), get_vert(vertex_buffer, 0, stride) ); } break; case PIPE_PRIM_TRIANGLES: - if (softpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 3) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-2, stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } + for (i = 2; i < nr; i += 3) { + sp_setup_tri( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_TRIANGLE_STRIP: - if (softpipe->rasterizer->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i++) { - sp_setup_tri( setup_ctx, + /* emit first triangle vertex as first triangle vertex */ + sp_setup_tri( setup, + get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i+(i&1)-1, stride), - get_vert(vertex_buffer, i-(i&1), stride), - get_vert(vertex_buffer, i-2, stride) ); + get_vert(vertex_buffer, i-(i&1), stride) ); } } else { for (i = 2; i < nr; i++) { - sp_setup_tri( setup_ctx, + /* emit last triangle vertex as last triangle vertex */ + sp_setup_tri( setup, get_vert(vertex_buffer, i+(i&1)-2, stride), get_vert(vertex_buffer, i-(i&1)-1, stride), get_vert(vertex_buffer, i-0, stride) ); @@ -399,17 +433,19 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLE_FAN: - if (softpipe->rasterizer->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { - sp_setup_tri( setup_ctx, + /* emit first non-spoke vertex as first vertex */ + sp_setup_tri( setup, + get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride), - get_vert(vertex_buffer, i-1, stride) ); + get_vert(vertex_buffer, 0, stride) ); } } else { for (i = 2; i < nr; i += 1) { - sp_setup_tri( setup_ctx, + /* emit last non-spoke vertex as last vertex */ + sp_setup_tri( setup, get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); @@ -418,42 +454,86 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_QUADS: - for (i = 3; i < nr; i += 4) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); + /* GL quads don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 4) { + sp_setup_tri( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride) ); + sp_setup_tri( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 4) { + sp_setup_tri( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + sp_setup_tri( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 3; i < nr; i += 2) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-0, stride) ); + /* GL quad strips don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 2) { + sp_setup_tri( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride) ); + sp_setup_tri( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 2) { + sp_setup_tri( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + sp_setup_tri( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_POLYGON: /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. + * shading color. */ - for (i = 2; i < nr; i += 1) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride) ); + if (flatshade_first) { + /* emit first polygon vertex as first triangle vertex */ + for (i = 2; i < nr; i += 1) { + sp_setup_tri( setup, + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + else { + /* emit first polygon vertex as last triangle vertex */ + for (i = 2; i < nr; i += 1) { + sp_setup_tri( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride) ); + } } break; @@ -492,7 +572,7 @@ sp_create_vbuf_backend(struct softpipe_context *sp) cvbr->base.map_vertices = sp_vbuf_map_vertices; cvbr->base.unmap_vertices = sp_vbuf_unmap_vertices; cvbr->base.set_primitive = sp_vbuf_set_primitive; - cvbr->base.draw = sp_vbuf_draw; + cvbr->base.draw_elements = sp_vbuf_draw_elements; cvbr->base.draw_arrays = sp_vbuf_draw_arrays; cvbr->base.release_vertices = sp_vbuf_release_vertices; cvbr->base.destroy = sp_vbuf_destroy; diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 8ae5a7f028b..907e94b59b9 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -50,8 +50,8 @@ struct quad_shade_stage { struct quad_stage stage; /**< base class */ - struct tgsi_exec_machine *machine; - struct tgsi_exec_vector *inputs, *outputs; + + /* no other fields at this time */ }; @@ -70,9 +70,8 @@ quad_shade_stage(struct quad_stage *qs) static INLINE boolean shade_quad(struct quad_stage *qs, struct quad_header *quad) { - struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; - struct tgsi_exec_machine *machine = qss->machine; + struct tgsi_exec_machine *machine = softpipe->fs_machine; /* run shader */ return softpipe->fs->run( softpipe->fs, machine, quad ); @@ -108,9 +107,8 @@ shade_quads(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { - struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; - struct tgsi_exec_machine *machine = qss->machine; + struct tgsi_exec_machine *machine = softpipe->fs_machine; unsigned i, pass = 0; for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { @@ -139,11 +137,10 @@ shade_quads(struct quad_stage *qs, static void shade_begin(struct quad_stage *qs) { - struct quad_shade_stage *qss = quad_shade_stage(qs); struct softpipe_context *softpipe = qs->softpipe; softpipe->fs->prepare( softpipe->fs, - qss->machine, + softpipe->fs_machine, (struct tgsi_sampler **) softpipe->tgsi.frag_samplers_list ); @@ -154,10 +151,6 @@ shade_begin(struct quad_stage *qs) static void shade_destroy(struct quad_stage *qs) { - struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; - - tgsi_exec_machine_destroy(qss->machine); - FREE( qs ); } @@ -174,16 +167,9 @@ sp_quad_shade_stage( struct softpipe_context *softpipe ) qss->stage.run = shade_quads; qss->stage.destroy = shade_destroy; - qss->machine = tgsi_exec_machine_create(); - if (!qss->machine) - goto fail; - return &qss->stage; fail: - if (qss && qss->machine) - tgsi_exec_machine_destroy(qss->machine); - FREE(qss); return NULL; } diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index 4ef5d9f7b1d..b959af63aff 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -30,6 +30,7 @@ */ #include "draw/draw_context.h" +#include "os/os_time.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "sp_context.h" @@ -37,6 +38,7 @@ #include "sp_state.h" struct softpipe_query { + unsigned type; uint64_t start; uint64_t end; }; @@ -51,8 +53,13 @@ static struct pipe_query * softpipe_create_query(struct pipe_context *pipe, unsigned type) { - assert(type == PIPE_QUERY_OCCLUSION_COUNTER); - return (struct pipe_query *)CALLOC_STRUCT( softpipe_query ); + struct softpipe_query* sq; + + assert(type == PIPE_QUERY_OCCLUSION_COUNTER || type == PIPE_QUERY_TIME_ELAPSED); + sq = CALLOC_STRUCT( softpipe_query ); + sq->type = type; + + return (struct pipe_query *)sq; } @@ -69,7 +76,17 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) struct softpipe_context *softpipe = softpipe_context( pipe ); struct softpipe_query *sq = softpipe_query(q); - sq->start = softpipe->occlusion_count; + switch (sq->type) { + case PIPE_QUERY_OCCLUSION_COUNTER: + sq->start = softpipe->occlusion_count; + break; + case PIPE_QUERY_TIME_ELAPSED: + sq->start = 1000*os_time_get(); + break; + default: + assert(0); + break; + } softpipe->active_query_count++; softpipe->dirty |= SP_NEW_QUERY; } @@ -82,7 +99,17 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) struct softpipe_query *sq = softpipe_query(q); softpipe->active_query_count--; - sq->end = softpipe->occlusion_count; + switch (sq->type) { + case PIPE_QUERY_OCCLUSION_COUNTER: + sq->end = softpipe->occlusion_count; + break; + case PIPE_QUERY_TIME_ELAPSED: + sq->end = 1000*os_time_get(); + break; + default: + assert(0); + break; + } softpipe->dirty |= SP_NEW_QUERY; } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index ad59ee90936..73987c913e5 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -33,6 +33,7 @@ #include "pipe/p_screen.h" #include "state_tracker/sw_winsys.h" +#include "tgsi/tgsi_exec.h" #include "sp_texture.h" #include "sp_screen.h" @@ -56,7 +57,7 @@ softpipe_get_name(struct pipe_screen *screen) static int -softpipe_get_param(struct pipe_screen *screen, int param) +softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: @@ -81,6 +82,8 @@ softpipe_get_param(struct pipe_screen *screen, int param) return PIPE_MAX_COLOR_BUFS; case PIPE_CAP_OCCLUSION_QUERY: return 1; + case PIPE_CAP_TIMER_QUERY: + return 1; case PIPE_CAP_TEXTURE_MIRROR_CLAMP: return 1; case PIPE_CAP_TEXTURE_MIRROR_REPEAT: @@ -110,6 +113,36 @@ softpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 1; + + case PIPE_CAP_MAX_VS_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: + case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: + /* There is no limit in number of instructions beyond available memory */ + return 32768; + case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: + case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: + return TGSI_EXEC_MAX_NESTING; + case PIPE_CAP_MAX_VS_INPUTS: + case PIPE_CAP_MAX_FS_INPUTS: + return TGSI_EXEC_MAX_INPUT_ATTRIBS; + case PIPE_CAP_MAX_FS_CONSTS: + case PIPE_CAP_MAX_VS_CONSTS: + return TGSI_EXEC_MAX_CONST_BUFFER; + case PIPE_CAP_MAX_VS_TEMPS: + case PIPE_CAP_MAX_FS_TEMPS: + return TGSI_EXEC_NUM_TEMPS; + case PIPE_CAP_MAX_VS_ADDRS: + case PIPE_CAP_MAX_FS_ADDRS: + return TGSI_EXEC_NUM_ADDRS; + case PIPE_CAP_MAX_VS_PREDS: + case PIPE_CAP_MAX_FS_PREDS: + return TGSI_EXEC_NUM_PREDS; + default: return 0; } @@ -117,7 +150,7 @@ softpipe_get_param(struct pipe_screen *screen, int param) static float -softpipe_get_paramf(struct pipe_screen *screen, int param) +softpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 86354664e4b..5d727dc00df 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -111,34 +111,13 @@ struct setup_context { uint numFragsWritten; /**< per primitive */ #endif - unsigned winding; /* which winding to cull */ + unsigned cull_face; /* which faces cull */ unsigned nr_vertex_attrs; }; -/** - * Do triangle cull test using tri determinant (sign indicates orientation) - * \return true if triangle is to be culled. - */ -static INLINE boolean -cull_tri(const struct setup_context *setup, float det) -{ - if (det != 0) { - /* if (det < 0 then Z points toward camera and triangle is - * counter-clockwise winding. - */ - unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; - - if ((winding & setup->winding) == 0) - return FALSE; - } - - /* Culled: - */ - return TRUE; -} @@ -304,7 +283,10 @@ setup_sort_vertices(struct setup_context *setup, const float (*v1)[4], const float (*v2)[4]) { - setup->vprovoke = v2; + if (setup->softpipe->rasterizer->flatshade_first) + setup->vprovoke = v0; + else + setup->vprovoke = v2; /* determine bottom to top order of vertices */ { @@ -390,8 +372,16 @@ setup_sort_vertices(struct setup_context *setup, * 0 = front-facing, 1 = back-facing */ setup->facing = - ((det > 0.0) ^ - (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW)); + ((det < 0.0) ^ + (setup->softpipe->rasterizer->front_ccw)); + + { + unsigned face = setup->facing == 0 ? PIPE_FACE_FRONT : PIPE_FACE_BACK; + + if (face & setup->cull_face) + return FALSE; + } + /* Prepare pixel offset for rasterisation: * - pixel center (0.5, 0.5) for GL, or @@ -829,11 +819,9 @@ sp_setup_tri(struct setup_context *setup, setup->numFragsWritten = 0; #endif - if (cull_tri( setup, det )) - return; - if (!setup_sort_vertices( setup, det, v0, v1, v2 )) return; + setup_tri_coefficients( setup ); setup_tri_edges( setup ); @@ -1417,14 +1405,14 @@ sp_setup_prepare(struct setup_context *setup) sp->quad.first->begin( sp->quad.first ); if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && - sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && - sp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { + sp->rasterizer->fill_front == PIPE_POLYGON_MODE_FILL && + sp->rasterizer->fill_back == PIPE_POLYGON_MODE_FILL) { /* we'll do culling */ - setup->winding = sp->rasterizer->cull_mode; + setup->cull_face = sp->rasterizer->cull_face; } else { /* 'draw' will do culling */ - setup->winding = PIPE_WINDING_NONE; + setup->cull_face = PIPE_FACE_NONE; } } diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 7f072f5a269..816e0c18bd2 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -36,6 +36,7 @@ #include "draw/draw_context.h" #include "draw/draw_vs.h" #include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_parse.h" @@ -95,10 +96,18 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { + struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; assert(fs != softpipe_context(pipe)->fs); - + + if (softpipe->fs_machine->Tokens == state->shader.tokens) { + /* unbind the shader from the tgsi executor if we're + * deleting it. + */ + tgsi_exec_machine_bind_shader(softpipe->fs_machine, NULL, 0, NULL); + } + state->delete( state ); } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 7aa85559b23..4e6123fbd07 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -343,11 +343,15 @@ softpipe_get_transfer(struct pipe_context *pipe, if (spt) { struct pipe_transfer *pt = &spt->base; enum pipe_format format = resource->format; + const unsigned hgt = u_minify(spr->base.height0, sr.level); + const unsigned nblocksy = util_format_get_nblocksy(format, hgt); + pipe_resource_reference(&pt->resource, resource); pt->sr = sr; pt->usage = usage; pt->box = *box; pt->stride = spr->stride[sr.level]; + pt->slice_stride = pt->stride * nblocksy; spt->offset = sp_get_tex_image_offset(spr, sr.level, sr.face, box->z); diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c index 5253c45cb20..660eb0757a6 100644 --- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c +++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c @@ -36,16 +36,17 @@ /* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW. */ static SVGA3dFace svga_translate_cullmode( unsigned mode, - unsigned front_winding ) + unsigned front_ccw ) { + const int hw_front_ccw = 0; /* hardware is always CW */ switch (mode) { - case PIPE_WINDING_NONE: + case PIPE_FACE_NONE: return SVGA3D_FACE_NONE; - case PIPE_WINDING_CCW: - return SVGA3D_FACE_BACK; - case PIPE_WINDING_CW: - return SVGA3D_FACE_FRONT; - case PIPE_WINDING_BOTH: + case PIPE_FACE_FRONT: + return front_ccw == hw_front_ccw ? SVGA3D_FACE_FRONT : SVGA3D_FACE_BACK; + case PIPE_FACE_BACK: + return front_ccw == hw_front_ccw ? SVGA3D_FACE_BACK : SVGA3D_FACE_FRONT; + case PIPE_FACE_FRONT_AND_BACK: return SVGA3D_FACE_FRONT_BACK; default: assert(0); @@ -81,8 +82,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe, /* fill_cw, fill_ccw - draw module or index translation */ rast->shademode = svga_translate_flatshade( templ->flatshade ); - rast->cullmode = svga_translate_cullmode( templ->cull_mode, - templ->front_winding ); + rast->cullmode = svga_translate_cullmode( templ->cull_face, + templ->front_ccw ); rast->scissortestenable = templ->scissor; rast->multisampleantialias = templ->multisample; rast->antialiasedlineenable = templ->line_smooth; @@ -117,31 +118,31 @@ svga_create_rasterizer_state(struct pipe_context *pipe, rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS; { - boolean offset_cw = templ->offset_cw; - boolean offset_ccw = templ->offset_ccw; - boolean offset = 0; - int fill_cw = templ->fill_cw; - int fill_ccw = templ->fill_ccw; + int fill_front = templ->fill_front; + int fill_back = templ->fill_back; int fill = PIPE_POLYGON_MODE_FILL; + boolean offset_front = util_get_offset(templ, fill_front); + boolean offset_back = util_get_offset(templ, fill_back); + boolean offset = 0; - switch (templ->cull_mode) { - case PIPE_WINDING_BOTH: + switch (templ->cull_face) { + case PIPE_FACE_FRONT_AND_BACK: offset = 0; fill = PIPE_POLYGON_MODE_FILL; break; - case PIPE_WINDING_CW: - offset = offset_ccw; - fill = fill_ccw; + case PIPE_FACE_FRONT: + offset = offset_front; + fill = fill_front; break; - case PIPE_WINDING_CCW: - offset = offset_cw; - fill = fill_cw; + case PIPE_FACE_BACK: + offset = offset_back; + fill = fill_back; break; - case PIPE_WINDING_NONE: - if (fill_cw != fill_ccw || offset_cw != offset_ccw) + case PIPE_FACE_NONE: + if (fill_front != fill_back || offset_front != offset_back) { /* Always need the draw module to work out different * front/back fill modes: @@ -149,8 +150,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe, rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; } else { - offset = offset_ccw; - fill = fill_ccw; + offset = offset_front; + fill = fill_front; } break; @@ -167,7 +168,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe, (templ->flatshade || templ->light_twoside || offset || - templ->cull_mode != PIPE_WINDING_NONE)) + templ->cull_face != PIPE_FACE_NONE)) { fill = PIPE_POLYGON_MODE_FILL; rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; diff --git a/src/gallium/drivers/svga/svga_resource.c b/src/gallium/drivers/svga/svga_resource.c index ba630582e59..ef2a0c40f03 100644 --- a/src/gallium/drivers/svga/svga_resource.c +++ b/src/gallium/drivers/svga/svga_resource.c @@ -33,6 +33,7 @@ svga_resource_from_handle(struct pipe_screen * screen, void svga_init_resource_functions(struct svga_context *svga) { + svga->pipe.is_resource_referenced = u_is_resource_referenced_vtbl; svga->pipe.get_transfer = u_get_transfer_vtbl; svga->pipe.transfer_map = u_transfer_map_vtbl; svga->pipe.transfer_flush_region = u_transfer_flush_region_vtbl; diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index b24af329218..99b419178b0 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -84,7 +84,7 @@ svga_get_name( struct pipe_screen *pscreen ) static float -svga_get_paramf(struct pipe_screen *screen, int param) +svga_get_paramf(struct pipe_screen *screen, enum pipe_cap param) { struct svga_screen *svgascreen = svga_screen(screen); struct svga_winsys_screen *sws = svgascreen->sws; @@ -134,6 +134,8 @@ svga_get_paramf(struct pipe_screen *screen, int param) return MIN2(result.u, PIPE_MAX_COLOR_BUFS); case PIPE_CAP_OCCLUSION_QUERY: return 1; + case PIPE_CAP_TIMER_QUERY: + return 0; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; @@ -177,6 +179,57 @@ svga_get_paramf(struct pipe_screen *screen, int param) case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 0; + /* + * Fragment shader limits + */ + + case PIPE_CAP_MAX_FS_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: + return svgascreen->use_ps30 ? 512 : 96; + case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: + return SVGA3D_MAX_NESTING_LEVEL; + case PIPE_CAP_MAX_FS_INPUTS: + return 10; + case PIPE_CAP_MAX_FS_CONSTS: + return svgascreen->use_vs30 ? 224 : 16; + case PIPE_CAP_MAX_FS_TEMPS: + if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result)) + return svgascreen->use_ps30 ? 32 : 12; + return result.u; + case PIPE_CAP_MAX_FS_ADDRS: + return svgascreen->use_ps30 ? 1 : 0; + case PIPE_CAP_MAX_FS_PREDS: + return svgascreen->use_ps30 ? 1 : 0; + + /* + * Vertex shader limits + */ + case PIPE_CAP_MAX_VS_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: + if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result)) + return svgascreen->use_vs30 ? 512 : 256; + return result.u; + case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: + /* XXX: until we have vertex texture support */ + return 0; + case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: + return SVGA3D_MAX_NESTING_LEVEL; + case PIPE_CAP_MAX_VS_INPUTS: + return 16; + case PIPE_CAP_MAX_VS_CONSTS: + return 256; + case PIPE_CAP_MAX_VS_TEMPS: + if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result)) + return svgascreen->use_vs30 ? 32 : 12; + return result.u; + case PIPE_CAP_MAX_VS_ADDRS: + return svgascreen->use_vs30 ? 1 : 0; + case PIPE_CAP_MAX_VS_PREDS: + return svgascreen->use_vs30 ? 1 : 0; + default: return 0; } @@ -186,7 +239,7 @@ svga_get_paramf(struct pipe_screen *screen, int param) /* This is a fairly pointless interface */ static int -svga_get_param(struct pipe_screen *screen, int param) +svga_get_param(struct pipe_screen *screen, enum pipe_cap param) { return (int) svga_get_paramf( screen, param ); } diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c index 1310fd9825f..ad6f2947137 100644 --- a/src/gallium/drivers/svga/svga_state_fs.c +++ b/src/gallium/drivers/svga/svga_state_fs.c @@ -131,8 +131,7 @@ static int make_fs_key( const struct svga_context *svga, /* SVGA_NEW_RAST */ key->light_twoside = svga->curr.rast->templ.light_twoside; - key->front_cw = (svga->curr.rast->templ.front_winding == - PIPE_WINDING_CW); + key->front_ccw = svga->curr.rast->templ.front_ccw; } /* The blend workaround for simulating logicop xor behaviour diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c index b7195d246bc..ab13f3fdf19 100644 --- a/src/gallium/drivers/svga/svga_state_rss.c +++ b/src/gallium/drivers/svga/svga_state_rss.c @@ -146,13 +146,13 @@ static int emit_rss( struct svga_context *svga, * then our definition of front face agrees with hardware. * Otherwise need to flip. */ - if (rast->templ.front_winding == PIPE_WINDING_CW) { - cw = 0; - ccw = 1; + if (rast->templ.front_ccw) { + ccw = 0; + cw = 1; } else { - cw = 1; - ccw = 0; + ccw = 1; + cw = 0; } /* Twoside stencil diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c index bd2cc380048..b21dc5fd9af 100644 --- a/src/gallium/drivers/svga/svga_surface.c +++ b/src/gallium/drivers/svga/svga_surface.c @@ -37,7 +37,6 @@ #include "svga_context.h" #include "svga_resource_texture.h" #include "svga_surface.h" -#include "svga_winsys.h" #include "svga_debug.h" diff --git a/src/gallium/drivers/svga/svga_swtnl.h b/src/gallium/drivers/svga/svga_swtnl.h index 8724690f7e1..65c675f99c9 100644 --- a/src/gallium/drivers/svga/svga_swtnl.h +++ b/src/gallium/drivers/svga/svga_swtnl.h @@ -30,7 +30,6 @@ struct svga_context; struct pipe_context; -struct pipe_buffer; struct vbuf_render; diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c index b0cbead8a5c..ff3da842729 100644 --- a/src/gallium/drivers/svga/svga_swtnl_backend.c +++ b/src/gallium/drivers/svga/svga_swtnl_backend.c @@ -240,9 +240,9 @@ svga_vbuf_render_draw_arrays( struct vbuf_render *render, static void -svga_vbuf_render_draw( struct vbuf_render *render, - const ushort *indices, - uint nr_indices) +svga_vbuf_render_draw_elements( struct vbuf_render *render, + const ushort *indices, + uint nr_indices) { struct svga_vbuf_render *svga_render = svga_vbuf_render(render); struct svga_context *svga = svga_render->svga; @@ -341,7 +341,7 @@ svga_vbuf_render_create( struct svga_context *svga ) svga_render->base.map_vertices = svga_vbuf_render_map_vertices; svga_render->base.unmap_vertices = svga_vbuf_render_unmap_vertices; svga_render->base.set_primitive = svga_vbuf_render_set_primitive; - svga_render->base.draw = svga_vbuf_render_draw; + svga_render->base.draw_elements = svga_vbuf_render_draw_elements; svga_render->base.draw_arrays = svga_vbuf_render_draw_arrays; svga_render->base.release_vertices = svga_vbuf_render_release_vertices; svga_render->base.destroy = svga_vbuf_render_destroy; diff --git a/src/gallium/drivers/svga/svga_tgsi.h b/src/gallium/drivers/svga/svga_tgsi.h index 063c9cf4221..7ea909c37bf 100644 --- a/src/gallium/drivers/svga/svga_tgsi.h +++ b/src/gallium/drivers/svga/svga_tgsi.h @@ -48,7 +48,7 @@ struct svga_vs_compile_key struct svga_fs_compile_key { unsigned light_twoside:1; - unsigned front_cw:1; + unsigned front_ccw:1; unsigned white_fragments:1; unsigned num_textures:8; unsigned num_unnormalized_coords:8; diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c index 7d7024c4a7d..67e1f22a701 100644 --- a/src/gallium/drivers/svga/svga_tgsi_insn.c +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c @@ -2588,10 +2588,10 @@ static boolean emit_light_twoside( struct svga_shader_emitter *emit ) if_token = inst_token( SVGA3DOP_IFC ); - if (emit->key.fkey.front_cw) - if_token.control = SVGA3DOPCOMP_GT; - else + if (emit->key.fkey.front_ccw) if_token.control = SVGA3DOPCOMP_LT; + else + if_token.control = SVGA3DOPCOMP_GT; zero = scalar(zero, TGSI_SWIZZLE_X); @@ -2639,12 +2639,12 @@ static boolean emit_frontface( struct svga_shader_emitter *emit ) temp = dst_register( SVGA3DREG_TEMP, emit->nr_hw_temp++ ); - if (emit->key.fkey.front_cw) { - pass = scalar( zero, TGSI_SWIZZLE_W ); - fail = scalar( zero, TGSI_SWIZZLE_X ); - } else { + if (emit->key.fkey.front_ccw) { pass = scalar( zero, TGSI_SWIZZLE_X ); fail = scalar( zero, TGSI_SWIZZLE_W ); + } else { + pass = scalar( zero, TGSI_SWIZZLE_W ); + fail = scalar( zero, TGSI_SWIZZLE_X ); } if (!emit_conditional(emit, PIPE_FUNC_GREATER, diff --git a/src/gallium/drivers/trace/Makefile b/src/gallium/drivers/trace/Makefile index 78f6347dc72..1b0c087a2a4 100644 --- a/src/gallium/drivers/trace/Makefile +++ b/src/gallium/drivers/trace/Makefile @@ -8,8 +8,6 @@ C_SOURCES = \ tr_dump.c \ tr_dump_state.c \ tr_screen.c \ - tr_state.c \ - tr_rbug.c \ tr_drm.c \ tr_texture.c diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index 203c3851bc3..cdcd8d2b4be 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -3,15 +3,15 @@ = About = -This directory contains a Gallium3D debugger pipe driver. -It can traces all incoming calls and/or provide remote debugging functionality. +This directory contains a Gallium3D trace debugger pipe driver. +It can traces all incoming calls. = Build Instructions = To build, invoke scons on the top dir as - scons dri=no statetrackers=mesa drivers=softpipe,i965simple,trace winsys=xlib + scons dri=no statetrackers=mesa winsys=xlib = Usage = @@ -36,40 +36,27 @@ Firefox or Internet Explorer. == Remote debugging == -For remote debugging +For remote debugging see: - export XMESA_TRACE=y - GALLIUM_RBUG=true progs/trivial/tri - -which should open gallium remote debugging session. While the program is running -you can launch the small remote debugging application from progs/rbug. More -information is in that directory. + src/gallium/drivers/rbug/README = Integrating = You can integrate the trace pipe driver either inside the state tracker or the -winsys. The procedure on both cases is the same. Let's assume you have a -pipe_screen and a pipe_context pair obtained by the usual means (variable and -function names are just for illustration purposes): +target. The procedure on both cases is the same. Let's assume you have a +pipe_screen obtained by the usual means (variable and function names are just +for illustration purposes): real_screen = real_screen_create(...); - real_context = real_context_create(...); - -The trace screen and pipe_context is then created by doing +The trace screen is then created by doing trace_screen = trace_screen_create(real_screen); - - trace_context = trace_context_create(trace_screen, real_context); - -You can then simply use trace_screen and trace_context instead of real_screen -and real_context. -Do not call trace_winsys_create. Simply pass trace_screen->winsys or -trace_context->winsys in places you would pass winsys. +You can then simply use trace_screen instead of real_screen. -You can create as many contexts you wish. Just ensure that you don't mistake -trace_screen with real_screen when creating them. +You can create as many contexts you wish from trace_screen::context_create they +are automatically wrapped by trace_screen. -- diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index 5f1fb17966a..0dc43a9ec41 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -10,8 +10,6 @@ trace = env.ConvenienceLibrary( 'tr_dump.c', 'tr_dump_state.c', 'tr_screen.c', - 'tr_state.c', - 'tr_rbug.c', 'tr_texture.c', ]) diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 64a4316984b..5cc244d4b77 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -28,16 +28,16 @@ #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_simple_list.h" -#include "util/u_format.h" #include "pipe/p_format.h" #include "pipe/p_screen.h" #include "tr_dump.h" #include "tr_dump_state.h" -#include "tr_state.h" +#include "tr_public.h" #include "tr_screen.h" #include "tr_texture.h" +#include "tr_context.h" @@ -83,82 +83,12 @@ trace_surface_unwrap(struct trace_context *tr_ctx, static INLINE void -trace_context_draw_block(struct trace_context *tr_ctx, int flag) -{ - int k; - - pipe_mutex_lock(tr_ctx->draw_mutex); - - if (tr_ctx->draw_blocker & flag) { - tr_ctx->draw_blocked |= flag; - } else if ((tr_ctx->draw_rule.blocker & flag) && - (tr_ctx->draw_blocker & 4)) { - boolean block = FALSE; - debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__, - (void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs, - (void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs, - (void *) tr_ctx->draw_rule.surf, 0, - (void *) tr_ctx->draw_rule.sampler_view, 0); - if (tr_ctx->draw_rule.fs && - tr_ctx->draw_rule.fs == tr_ctx->curr.fs) - block = TRUE; - if (tr_ctx->draw_rule.vs && - tr_ctx->draw_rule.vs == tr_ctx->curr.vs) - block = TRUE; - if (tr_ctx->draw_rule.surf && - tr_ctx->draw_rule.surf == tr_ctx->curr.zsbuf) - block = TRUE; - if (tr_ctx->draw_rule.surf) - for (k = 0; k < tr_ctx->curr.nr_cbufs; k++) - if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k]) - block = TRUE; - if (tr_ctx->draw_rule.sampler_view) { - for (k = 0; k < tr_ctx->curr.num_sampler_views; k++) - if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.sampler_views[k]) - block = TRUE; - for (k = 0; k < tr_ctx->curr.num_vert_sampler_views; k++) { - if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.vert_sampler_views[k]) { - block = TRUE; - } - } - } - - if (block) - tr_ctx->draw_blocked |= (flag | 4); - } - - if (tr_ctx->draw_blocked) - trace_rbug_notify_draw_blocked(tr_ctx); - - /* wait for rbug to clear the blocked flag */ - while (tr_ctx->draw_blocked & flag) { - tr_ctx->draw_blocked |= flag; -#ifdef PIPE_THREAD_HAVE_CONDVAR - pipe_condvar_wait(tr_ctx->draw_cond, tr_ctx->draw_mutex); -#else - pipe_mutex_unlock(tr_ctx->draw_mutex); -#ifdef PIPE_SUBSYSTEM_WINDOWS_USER - Sleep(1); -#endif - pipe_mutex_lock(tr_ctx->draw_mutex); -#endif - } - - pipe_mutex_unlock(tr_ctx->draw_mutex); -} - -static INLINE void trace_context_draw_arrays(struct pipe_context *_pipe, unsigned mode, unsigned start, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) - return; - - trace_context_draw_block(tr_ctx, 1); - trace_dump_call_begin("pipe_context", "draw_arrays"); trace_dump_arg(ptr, pipe); @@ -169,8 +99,6 @@ trace_context_draw_arrays(struct pipe_context *_pipe, pipe->draw_arrays(pipe, mode, start, count); trace_dump_call_end(); - - trace_context_draw_block(tr_ctx, 2); } @@ -185,11 +113,6 @@ trace_context_draw_elements(struct pipe_context *_pipe, struct pipe_context *pipe = tr_ctx->pipe; struct pipe_resource *indexBuffer = tr_buf->resource; - if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) - return; - - trace_context_draw_block(tr_ctx, 1); - trace_dump_call_begin("pipe_context", "draw_elements"); trace_dump_arg(ptr, pipe); @@ -204,8 +127,6 @@ trace_context_draw_elements(struct pipe_context *_pipe, mode, start, count); trace_dump_call_end(); - - trace_context_draw_block(tr_ctx, 2); } @@ -225,11 +146,6 @@ trace_context_draw_range_elements(struct pipe_context *_pipe, struct pipe_context *pipe = tr_ctx->pipe; struct pipe_resource *indexBuffer = tr_buf->resource; - if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) - return; - - trace_context_draw_block(tr_ctx, 1); - trace_dump_call_begin("pipe_context", "draw_range_elements"); trace_dump_arg(ptr, pipe); @@ -248,8 +164,6 @@ trace_context_draw_range_elements(struct pipe_context *_pipe, mode, start, count); trace_dump_call_end(); - - trace_context_draw_block(tr_ctx, 2); } @@ -634,31 +548,22 @@ trace_context_create_fs_state(struct pipe_context *_pipe, trace_dump_call_end(); - result = trace_shader_create(tr_ctx, state, result, TRACE_SHADER_FRAGMENT); - return result; } static INLINE void trace_context_bind_fs_state(struct pipe_context *_pipe, - void *_state) + void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_shader *tr_shdr = trace_shader(_state); struct pipe_context *pipe = tr_ctx->pipe; - void *state = tr_shdr ? tr_shdr->state : NULL; trace_dump_call_begin("pipe_context", "bind_fs_state"); trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - tr_ctx->curr.fs = tr_shdr; - - if (tr_shdr && tr_shdr->replaced) - state = tr_shdr->replaced; - pipe->bind_fs_state(pipe, state); trace_dump_call_end(); @@ -667,12 +572,10 @@ trace_context_bind_fs_state(struct pipe_context *_pipe, static INLINE void trace_context_delete_fs_state(struct pipe_context *_pipe, - void *_state) + void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_shader *tr_shdr = trace_shader(_state); struct pipe_context *pipe = tr_ctx->pipe; - void *state = tr_shdr->state; trace_dump_call_begin("pipe_context", "delete_fs_state"); @@ -682,8 +585,6 @@ trace_context_delete_fs_state(struct pipe_context *_pipe, pipe->delete_fs_state(pipe, state); trace_dump_call_end(); - - trace_shader_destroy(tr_ctx, tr_shdr); } @@ -706,31 +607,22 @@ trace_context_create_vs_state(struct pipe_context *_pipe, trace_dump_call_end(); - result = trace_shader_create(tr_ctx, state, result, TRACE_SHADER_VERTEX); - return result; } static INLINE void trace_context_bind_vs_state(struct pipe_context *_pipe, - void *_state) + void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_shader *tr_shdr = trace_shader(_state); struct pipe_context *pipe = tr_ctx->pipe; - void *state = tr_shdr ? tr_shdr->state : NULL; trace_dump_call_begin("pipe_context", "bind_vs_state"); trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - tr_ctx->curr.vs = tr_shdr; - - if (tr_shdr && tr_shdr->replaced) - state = tr_shdr->replaced; - pipe->bind_vs_state(pipe, state); trace_dump_call_end(); @@ -739,12 +631,10 @@ trace_context_bind_vs_state(struct pipe_context *_pipe, static INLINE void trace_context_delete_vs_state(struct pipe_context *_pipe, - void *_state) + void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_shader *tr_shdr = trace_shader(_state); struct pipe_context *pipe = tr_ctx->pipe; - void *state = tr_shdr->state; trace_dump_call_begin("pipe_context", "delete_vs_state"); @@ -754,8 +644,6 @@ trace_context_delete_vs_state(struct pipe_context *_pipe, pipe->delete_vs_state(pipe, state); trace_dump_call_end(); - - trace_shader_destroy(tr_ctx, tr_shdr); } @@ -927,18 +815,6 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe, struct pipe_framebuffer_state unwrapped_state; unsigned i; - { - tr_ctx->curr.nr_cbufs = state->nr_cbufs; - for (i = 0; i < state->nr_cbufs; i++) - if (state->cbufs[i]) - tr_ctx->curr.cbufs[i] = trace_resource(state->cbufs[i]->texture); - else - tr_ctx->curr.cbufs[i] = NULL; - if (state->zsbuf) - tr_ctx->curr.zsbuf = trace_resource(state->zsbuf->texture); - else - tr_ctx->curr.zsbuf = NULL; - } /* Unwrap the input state */ memcpy(&unwrapped_state, state, sizeof(unwrapped_state)); @@ -1088,10 +964,8 @@ trace_context_set_fragment_sampler_views(struct pipe_context *_pipe, struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS]; unsigned i; - tr_ctx->curr.num_sampler_views = num; for(i = 0; i < num; ++i) { tr_view = trace_sampler_view(views[i]); - tr_ctx->curr.sampler_views[i] = tr_view; unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL; } views = unwrapped_views; @@ -1119,10 +993,8 @@ trace_context_set_vertex_sampler_views(struct pipe_context *_pipe, struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS]; unsigned i; - tr_ctx->curr.num_vert_sampler_views = num; for(i = 0; i < num; ++i) { tr_view = trace_sampler_view(views[i]); - tr_ctx->curr.vert_sampler_views[i] = tr_view; unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL; } views = unwrapped_views; @@ -1293,7 +1165,6 @@ trace_context_flush(struct pipe_context *_pipe, static INLINE void trace_context_destroy(struct pipe_context *_pipe) { - struct trace_screen *tr_scr = trace_screen(_pipe->screen); struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; @@ -1301,8 +1172,6 @@ trace_context_destroy(struct pipe_context *_pipe) trace_dump_arg(ptr, pipe); trace_dump_call_end(); - trace_screen_remove_from_list(tr_scr, contexts, tr_ctx); - pipe->destroy(pipe); FREE(tr_ctx); @@ -1535,13 +1404,6 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.winsys = NULL; tr_ctx->base.priv = pipe->priv; /* expose wrapped priv data */ tr_ctx->base.screen = &tr_scr->base; - tr_ctx->draw_blocker = debug_get_flags_option("RBUG_BLOCK", - rbug_blocker_flags, - 0); - pipe_mutex_init(tr_ctx->draw_mutex); - pipe_condvar_init(tr_ctx->draw_cond); - pipe_mutex_init(tr_ctx->list_mutex); - make_empty_list(&tr_ctx->shaders); tr_ctx->base.destroy = trace_context_destroy; tr_ctx->base.draw_arrays = trace_context_draw_arrays; @@ -1603,8 +1465,6 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->pipe = pipe; - trace_screen_add_to_list(tr_scr, contexts, tr_ctx); - return &tr_ctx->base; error1: diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 1b4121d80a9..dadbe561180 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -47,45 +47,6 @@ struct trace_context struct pipe_context base; struct pipe_context *pipe; - - /* current state */ - struct { - struct trace_shader *fs; - struct trace_shader *vs; - - struct trace_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; - unsigned num_sampler_views; - - struct trace_sampler_view *vert_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; - unsigned num_vert_sampler_views; - - unsigned nr_cbufs; - struct trace_resource *cbufs[PIPE_MAX_COLOR_BUFS]; - struct trace_resource *zsbuf; - } curr; - - struct { - struct trace_shader *fs; - struct trace_shader *vs; - - struct trace_sampler_view *sampler_view; - struct trace_resource *surf; - - int blocker; - } draw_rule; - unsigned draw_num_rules; - pipe_condvar draw_cond; - pipe_mutex draw_mutex; - int draw_blocker; - int draw_blocked; - - /* for list on screen */ - struct tr_list list; - - /* list of state objects */ - pipe_mutex list_mutex; - unsigned num_shaders; - struct tr_list shaders; }; @@ -101,9 +62,6 @@ struct pipe_context * trace_context_create(struct trace_screen *tr_scr, struct pipe_context *pipe); -void -trace_rbug_notify_draw_blocked(struct trace_context *tr_ctx); - #ifdef __cplusplus } diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c index 0dc8cca2648..9c7d39201a9 100644 --- a/src/gallium/drivers/trace/tr_drm.c +++ b/src/gallium/drivers/trace/tr_drm.c @@ -28,6 +28,7 @@ #include "state_tracker/drm_api.h" #include "util/u_memory.h" +#include "rbug/rbug_public.h" #include "tr_drm.h" #include "tr_screen.h" #include "tr_public.h" @@ -61,7 +62,7 @@ trace_drm_create_screen(struct drm_api *_api, int fd, screen = api->create_screen(api, fd, arg); - return trace_screen_create(screen); + return trace_screen_create(rbug_screen_create(screen)); } static void @@ -84,7 +85,7 @@ trace_drm_create(struct drm_api *api) if (!api) goto error; - if (!trace_enabled()) + if (!trace_enabled() && !rbug_enabled()) goto error; tr_api = CALLOC_STRUCT(trace_drm_api); diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index f21f72b0c79..74c5e83e9e1 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -37,7 +37,6 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" -struct pipe_buffer; struct pipe_resource; struct pipe_surface; struct pipe_transfer; diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index f148a859ff3..1727c2a0206 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -136,12 +136,13 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) trace_dump_member(bool, state, flatshade); trace_dump_member(bool, state, light_twoside); - trace_dump_member(uint, state, front_winding); - trace_dump_member(uint, state, cull_mode); - trace_dump_member(uint, state, fill_cw); - trace_dump_member(uint, state, fill_ccw); - trace_dump_member(bool, state, offset_cw); - trace_dump_member(bool, state, offset_ccw); + trace_dump_member(uint, state, front_ccw); + trace_dump_member(uint, state, cull_face); + trace_dump_member(uint, state, fill_front); + trace_dump_member(uint, state, fill_back); + trace_dump_member(bool, state, offset_point); + trace_dump_member(bool, state, offset_line); + trace_dump_member(bool, state, offset_tri); trace_dump_member(bool, state, scissor); trace_dump_member(bool, state, poly_smooth); trace_dump_member(bool, state, poly_stipple_enable); diff --git a/src/gallium/drivers/trace/tr_public.h b/src/gallium/drivers/trace/tr_public.h index 62e217097d0..aee4937dd4f 100644 --- a/src/gallium/drivers/trace/tr_public.h +++ b/src/gallium/drivers/trace/tr_public.h @@ -38,6 +38,9 @@ struct pipe_context; struct pipe_screen * trace_screen_create(struct pipe_screen *screen); +boolean +trace_enabled(void); + #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c deleted file mode 100644 index 3ce1b85854b..00000000000 --- a/src/gallium/drivers/trace/tr_rbug.c +++ /dev/null @@ -1,864 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * 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 "os/os_thread.h" -#include "util/u_format.h" -#include "util/u_string.h" -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_simple_list.h" -#include "util/u_network.h" -#include "os/os_time.h" - -#include "tgsi/tgsi_parse.h" - -#include "tr_dump.h" -#include "tr_state.h" -#include "tr_texture.h" - -#include "rbug/rbug.h" - -#include <errno.h> - -#define U642VOID(x) ((void *)(unsigned long)(x)) -#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) - -struct trace_rbug -{ - struct trace_screen *tr_scr; - struct rbug_connection *con; - pipe_thread thread; - boolean running; -}; - -PIPE_THREAD_ROUTINE(trace_rbug_thread, void_tr_rbug); - - -/********************************************************** - * Helper functions - */ - - -static struct trace_context * -trace_rbug_get_context_locked(struct trace_screen *tr_scr, rbug_context_t ctx) -{ - struct trace_context *tr_ctx = NULL; - struct tr_list *ptr; - - foreach(ptr, &tr_scr->contexts) { - tr_ctx = (struct trace_context *)((char*)ptr - offsetof(struct trace_context, list)); - if (ctx == VOID2U64(tr_ctx)) - break; - tr_ctx = NULL; - } - - return tr_ctx; -} - -static struct trace_shader * -trace_rbug_get_shader_locked(struct trace_context *tr_ctx, rbug_shader_t shdr) -{ - struct trace_shader *tr_shdr = NULL; - struct tr_list *ptr; - - foreach(ptr, &tr_ctx->shaders) { - tr_shdr = (struct trace_shader *)((char*)ptr - offsetof(struct trace_shader, list)); - if (shdr == VOID2U64(tr_shdr)) - break; - tr_shdr = NULL; - } - - return tr_shdr; -} - -static void * -trace_shader_create_locked(struct pipe_context *pipe, - struct trace_shader *tr_shdr, - struct tgsi_token *tokens) -{ - void *state = NULL; - struct pipe_shader_state pss = { 0 }; - pss.tokens = tokens; - - if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { - state = pipe->create_fs_state(pipe, &pss); - } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { - state = pipe->create_vs_state(pipe, &pss); - } else - assert(0); - - return state; -} - -static void -trace_shader_bind_locked(struct pipe_context *pipe, - struct trace_shader *tr_shdr, - void *state) -{ - if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { - pipe->bind_fs_state(pipe, state); - } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { - pipe->bind_vs_state(pipe, state); - } else - assert(0); -} - -static void -trace_shader_delete_locked(struct pipe_context *pipe, - struct trace_shader *tr_shdr, - void *state) -{ - if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { - pipe->delete_fs_state(pipe, state); - } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { - pipe->delete_vs_state(pipe, state); - } else - assert(0); -} - -/************************************************ - * Request handler functions - */ - - -static int -trace_rbug_texture_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_resource *tr_tex = NULL; - struct tr_list *ptr; - rbug_texture_t *texs; - int i = 0; - - pipe_mutex_lock(tr_scr->list_mutex); - texs = MALLOC(tr_scr->num_textures * sizeof(rbug_texture_t)); - foreach(ptr, &tr_scr->textures) { - tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list)); - texs[i++] = VOID2U64(tr_tex); - } - pipe_mutex_unlock(tr_scr->list_mutex); - - rbug_send_texture_list_reply(tr_rbug->con, serial, texs, i, NULL); - FREE(texs); - - return 0; -} - -static int -trace_rbug_texture_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_resource *tr_tex = NULL; - struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header; - struct tr_list *ptr; - struct pipe_resource *t; - - pipe_mutex_lock(tr_scr->list_mutex); - foreach(ptr, &tr_scr->textures) { - tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list)); - if (gpti->texture == VOID2U64(tr_tex)) - break; - tr_tex = NULL; - } - - if (!tr_tex) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - t = tr_tex->resource; - rbug_send_texture_info_reply(tr_rbug->con, serial, - t->target, t->format, - &t->width0, 1, - &t->height0, 1, - &t->depth0, 1, - util_format_get_blockwidth(t->format), - util_format_get_blockheight(t->format), - util_format_get_blocksize(t->format), - t->last_level, - t->nr_samples, - t->bind, - NULL); - - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_resource *tr_tex = NULL; - struct tr_list *ptr; - - struct pipe_context *context = tr_scr->private_context; - struct pipe_resource *tex; - struct pipe_transfer *t; - - void *map; - - pipe_mutex_lock(tr_scr->list_mutex); - foreach(ptr, &tr_scr->textures) { - tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list)); - if (gptr->texture == VOID2U64(tr_tex)) - break; - tr_tex = NULL; - } - - if (!tr_tex) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - tex = tr_tex->resource; - t = pipe_get_transfer(context, tex, - gptr->face, gptr->level, gptr->zslice, - PIPE_TRANSFER_READ, - gptr->x, gptr->y, gptr->w, gptr->h); - - map = context->transfer_map(context, t); - - rbug_send_texture_read_reply(tr_rbug->con, serial, - t->resource->format, - util_format_get_blockwidth(t->resource->format), - util_format_get_blockheight(t->resource->format), - util_format_get_blocksize(t->resource->format), - (uint8_t*)map, - t->stride * util_format_get_nblocksy(t->resource->format, - t->box.height), - t->stride, - NULL); - - context->transfer_unmap(context, t); - context->transfer_destroy(context, t); - - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_context_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct tr_list *ptr; - struct trace_context *tr_ctx = NULL; - rbug_context_t *ctxs; - int i = 0; - - pipe_mutex_lock(tr_scr->list_mutex); - ctxs = MALLOC(tr_scr->num_contexts * sizeof(rbug_context_t)); - foreach(ptr, &tr_scr->contexts) { - tr_ctx = (struct trace_context *)((char*)ptr - offsetof(struct trace_context, list)); - ctxs[i++] = VOID2U64(tr_ctx); - } - pipe_mutex_unlock(tr_scr->list_mutex); - - rbug_send_context_list_reply(tr_rbug->con, serial, ctxs, i, NULL); - FREE(ctxs); - - return 0; -} - -static int -trace_rbug_context_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS]; - rbug_texture_t texs[PIPE_MAX_SAMPLERS]; - int i; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, info->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - /* protect the pipe context */ - pipe_mutex_lock(tr_ctx->draw_mutex); - trace_dump_call_lock(); - - for (i = 0; i < tr_ctx->curr.nr_cbufs; i++) - cbufs[i] = VOID2U64(tr_ctx->curr.cbufs[i]); - - for (i = 0; i < tr_ctx->curr.num_sampler_views; i++) - texs[i] = VOID2U64(tr_ctx->curr.sampler_views[i]); - - rbug_send_context_info_reply(tr_rbug->con, serial, - VOID2U64(tr_ctx->curr.vs), VOID2U64(tr_ctx->curr.fs), - texs, tr_ctx->curr.num_sampler_views, - cbufs, tr_ctx->curr.nr_cbufs, - VOID2U64(tr_ctx->curr.zsbuf), - tr_ctx->draw_blocker, tr_ctx->draw_blocked, NULL); - - trace_dump_call_unlock(); - pipe_mutex_unlock(tr_ctx->draw_mutex); - - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_context_draw_block(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, block->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - pipe_mutex_lock(tr_ctx->draw_mutex); - tr_ctx->draw_blocker |= block->block; - pipe_mutex_unlock(tr_ctx->draw_mutex); - - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_context_draw_step(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, step->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - pipe_mutex_lock(tr_ctx->draw_mutex); - if (tr_ctx->draw_blocked & RBUG_BLOCK_RULE) { - if (step->step & RBUG_BLOCK_RULE) - tr_ctx->draw_blocked &= ~RBUG_BLOCK_MASK; - } else { - tr_ctx->draw_blocked &= ~step->step; - } - pipe_mutex_unlock(tr_ctx->draw_mutex); - -#ifdef PIPE_THREAD_HAVE_CONDVAR - pipe_condvar_broadcast(tr_ctx->draw_cond); -#endif - - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_context_draw_unblock(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, unblock->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - pipe_mutex_lock(tr_ctx->draw_mutex); - if (tr_ctx->draw_blocked & RBUG_BLOCK_RULE) { - if (unblock->unblock & RBUG_BLOCK_RULE) - tr_ctx->draw_blocked &= ~RBUG_BLOCK_MASK; - } else { - tr_ctx->draw_blocked &= ~unblock->unblock; - } - tr_ctx->draw_blocker &= ~unblock->unblock; - pipe_mutex_unlock(tr_ctx->draw_mutex); - -#ifdef PIPE_THREAD_HAVE_CONDVAR - pipe_condvar_broadcast(tr_ctx->draw_cond); -#endif - - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_context_draw_rule(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, rule->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - pipe_mutex_lock(tr_ctx->draw_mutex); - tr_ctx->draw_rule.vs = U642VOID(rule->vertex); - tr_ctx->draw_rule.fs = U642VOID(rule->fragment); - tr_ctx->draw_rule.sampler_view = U642VOID(rule->texture); - tr_ctx->draw_rule.surf = U642VOID(rule->surface); - tr_ctx->draw_rule.blocker = rule->block; - tr_ctx->draw_blocker |= RBUG_BLOCK_RULE; - pipe_mutex_unlock(tr_ctx->draw_mutex); - -#ifdef PIPE_THREAD_HAVE_CONDVAR - pipe_condvar_broadcast(tr_ctx->draw_cond); -#endif - - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_context_flush(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, flush->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - /* protect the pipe context */ - trace_dump_call_lock(); - - tr_ctx->pipe->flush(tr_ctx->pipe, flush->flags, NULL); - - trace_dump_call_unlock(); - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_shader_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - struct trace_shader *tr_shdr = NULL; - struct tr_list *ptr; - rbug_shader_t *shdrs; - int i = 0; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, list->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - pipe_mutex_lock(tr_ctx->list_mutex); - shdrs = MALLOC(tr_ctx->num_shaders * sizeof(rbug_shader_t)); - foreach(ptr, &tr_ctx->shaders) { - tr_shdr = (struct trace_shader *)((char*)ptr - offsetof(struct trace_shader, list)); - shdrs[i++] = VOID2U64(tr_shdr); - } - - pipe_mutex_unlock(tr_ctx->list_mutex); - pipe_mutex_unlock(tr_scr->list_mutex); - - rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL); - FREE(shdrs); - - return 0; -} - -static int -trace_rbug_shader_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - struct trace_shader *tr_shdr = NULL; - unsigned original_len; - unsigned replaced_len; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, info->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - pipe_mutex_lock(tr_ctx->list_mutex); - - tr_shdr = trace_rbug_get_shader_locked(tr_ctx, info->shader); - - if (!tr_shdr) { - pipe_mutex_unlock(tr_ctx->list_mutex); - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - /* just in case */ - assert(sizeof(struct tgsi_token) == 4); - - original_len = tgsi_num_tokens(tr_shdr->tokens); - if (tr_shdr->replaced_tokens) - replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens); - else - replaced_len = 0; - - rbug_send_shader_info_reply(tr_rbug->con, serial, - (uint32_t*)tr_shdr->tokens, original_len, - (uint32_t*)tr_shdr->replaced_tokens, replaced_len, - tr_shdr->disabled, - NULL); - - pipe_mutex_unlock(tr_ctx->list_mutex); - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_shader_disable(struct trace_rbug *tr_rbug, struct rbug_header *header) -{ - struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - struct trace_shader *tr_shdr = NULL; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, dis->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - pipe_mutex_lock(tr_ctx->list_mutex); - - tr_shdr = trace_rbug_get_shader_locked(tr_ctx, dis->shader); - - if (!tr_shdr) { - pipe_mutex_unlock(tr_ctx->list_mutex); - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - tr_shdr->disabled = dis->disable; - - pipe_mutex_unlock(tr_ctx->list_mutex); - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; -} - -static int -trace_rbug_shader_replace(struct trace_rbug *tr_rbug, struct rbug_header *header) -{ - struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header; - - struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_context *tr_ctx = NULL; - struct trace_shader *tr_shdr = NULL; - struct pipe_context *pipe = NULL; - void *state; - - pipe_mutex_lock(tr_scr->list_mutex); - tr_ctx = trace_rbug_get_context_locked(tr_scr, rep->context); - - if (!tr_ctx) { - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - pipe_mutex_lock(tr_ctx->list_mutex); - - tr_shdr = trace_rbug_get_shader_locked(tr_ctx, rep->shader); - - if (!tr_shdr) { - pipe_mutex_unlock(tr_ctx->list_mutex); - pipe_mutex_unlock(tr_scr->list_mutex); - return -ESRCH; - } - - /* protect the pipe context */ - trace_dump_call_lock(); - - pipe = tr_ctx->pipe; - - /* remove old replaced shader */ - if (tr_shdr->replaced) { - if (tr_ctx->curr.fs == tr_shdr || tr_ctx->curr.vs == tr_shdr) - trace_shader_bind_locked(pipe, tr_shdr, tr_shdr->state); - - FREE(tr_shdr->replaced_tokens); - trace_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced); - tr_shdr->replaced = NULL; - tr_shdr->replaced_tokens = NULL; - } - - /* empty inputs means restore old which we did above */ - if (rep->tokens_len == 0) - goto out; - - tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens); - if (!tr_shdr->replaced_tokens) - goto err; - - state = trace_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens); - if (!state) - goto err; - - /* bind new shader if the shader is currently a bound */ - if (tr_ctx->curr.fs == tr_shdr || tr_ctx->curr.vs == tr_shdr) - trace_shader_bind_locked(pipe, tr_shdr, state); - - /* save state */ - tr_shdr->replaced = state; - -out: - trace_dump_call_unlock(); - pipe_mutex_unlock(tr_ctx->list_mutex); - pipe_mutex_unlock(tr_scr->list_mutex); - - return 0; - -err: - FREE(tr_shdr->replaced_tokens); - tr_shdr->replaced = NULL; - tr_shdr->replaced_tokens = NULL; - - trace_dump_call_unlock(); - pipe_mutex_unlock(tr_ctx->list_mutex); - pipe_mutex_unlock(tr_scr->list_mutex); - return -EINVAL; -} - -static boolean -trace_rbug_header(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) -{ - int ret = 0; - - switch(header->opcode) { - case RBUG_OP_PING: - rbug_send_ping_reply(tr_rbug->con, serial, NULL); - break; - case RBUG_OP_TEXTURE_LIST: - ret = trace_rbug_texture_list(tr_rbug, header, serial); - break; - case RBUG_OP_TEXTURE_INFO: - ret = trace_rbug_texture_info(tr_rbug, header, serial); - break; - case RBUG_OP_TEXTURE_READ: - ret = trace_rbug_texture_read(tr_rbug, header, serial); - break; - case RBUG_OP_CONTEXT_LIST: - ret = trace_rbug_context_list(tr_rbug, header, serial); - break; - case RBUG_OP_CONTEXT_INFO: - ret = trace_rbug_context_info(tr_rbug, header, serial); - break; - case RBUG_OP_CONTEXT_DRAW_BLOCK: - ret = trace_rbug_context_draw_block(tr_rbug, header, serial); - break; - case RBUG_OP_CONTEXT_DRAW_STEP: - ret = trace_rbug_context_draw_step(tr_rbug, header, serial); - break; - case RBUG_OP_CONTEXT_DRAW_UNBLOCK: - ret = trace_rbug_context_draw_unblock(tr_rbug, header, serial); - break; - case RBUG_OP_CONTEXT_DRAW_RULE: - ret = trace_rbug_context_draw_rule(tr_rbug, header, serial); - break; - case RBUG_OP_CONTEXT_FLUSH: - ret = trace_rbug_context_flush(tr_rbug, header, serial); - break; - case RBUG_OP_SHADER_LIST: - ret = trace_rbug_shader_list(tr_rbug, header, serial); - break; - case RBUG_OP_SHADER_INFO: - ret = trace_rbug_shader_info(tr_rbug, header, serial); - break; - case RBUG_OP_SHADER_DISABLE: - ret = trace_rbug_shader_disable(tr_rbug, header); - break; - case RBUG_OP_SHADER_REPLACE: - ret = trace_rbug_shader_replace(tr_rbug, header); - break; - default: - debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode); - ret = -ENOSYS; - break; - } - rbug_free_header(header); - - if (ret) - rbug_send_error_reply(tr_rbug->con, serial, ret, NULL); - - return TRUE; -} - -static void -trace_rbug_con(struct trace_rbug *tr_rbug) -{ - struct rbug_header *header; - uint32_t serial; - - debug_printf("%s - connection received\n", __FUNCTION__); - - while(tr_rbug->running) { - header = rbug_get_message(tr_rbug->con, &serial); - if (!header) - break; - - if (!trace_rbug_header(tr_rbug, header, serial)) - break; - } - - debug_printf("%s - connection closed\n", __FUNCTION__); - - rbug_disconnect(tr_rbug->con); - tr_rbug->con = NULL; -} - -PIPE_THREAD_ROUTINE(trace_rbug_thread, void_tr_rbug) -{ - struct trace_rbug *tr_rbug = void_tr_rbug; - uint16_t port = 13370; - int s = -1; - int c; - - u_socket_init(); - - for (;port <= 13379 && s < 0; port++) - s = u_socket_listen_on_port(port); - - if (s < 0) { - debug_printf("trace_rbug - failed to listen\n"); - return NULL; - } - - u_socket_block(s, false); - - debug_printf("trace_rbug - remote debugging listening on port %u\n", --port); - - while(tr_rbug->running) { - os_time_sleep(1); - - c = u_socket_accept(s); - if (c < 0) - continue; - - u_socket_block(c, true); - tr_rbug->con = rbug_from_socket(c); - - trace_rbug_con(tr_rbug); - - u_socket_close(c); - } - - u_socket_close(s); - - u_socket_stop(); - - return NULL; -} - -/********************************************************** - * - */ - -struct trace_rbug * -trace_rbug_start(struct trace_screen *tr_scr) -{ - struct trace_rbug *tr_rbug = CALLOC_STRUCT(trace_rbug); - if (!tr_rbug) - return NULL; - - tr_rbug->tr_scr = tr_scr; - tr_rbug->running = TRUE; - tr_rbug->thread = pipe_thread_create(trace_rbug_thread, tr_rbug); - - return tr_rbug; -} - -void -trace_rbug_stop(struct trace_rbug *tr_rbug) -{ - if (!tr_rbug) - return; - - tr_rbug->running = false; - pipe_thread_wait(tr_rbug->thread); - - FREE(tr_rbug); - - return; -} - -void -trace_rbug_notify_draw_blocked(struct trace_context *tr_ctx) -{ - struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); - struct trace_rbug *tr_rbug = tr_scr->rbug; - - if (tr_rbug && tr_rbug->con) - rbug_send_context_draw_blocked(tr_rbug->con, - VOID2U64(tr_ctx), tr_ctx->draw_blocked, NULL); -} diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index ffae6e94d11..32e519a68a0 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -40,7 +40,6 @@ static boolean trace = FALSE; -static boolean rbug = FALSE; static const char * trace_screen_get_name(struct pipe_screen *_screen) @@ -86,7 +85,7 @@ trace_screen_get_vendor(struct pipe_screen *_screen) static int trace_screen_get_param(struct pipe_screen *_screen, - int param) + enum pipe_cap param) { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; @@ -109,7 +108,7 @@ trace_screen_get_param(struct pipe_screen *_screen, static float trace_screen_get_paramf(struct pipe_screen *_screen, - int param) + enum pipe_cap param) { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; @@ -494,9 +493,6 @@ trace_screen_destroy(struct pipe_screen *_screen) trace_dump_call_end(); trace_dump_trace_end(); - if (tr_scr->rbug) - trace_rbug_stop(tr_scr->rbug); - screen->destroy(screen); FREE(tr_scr); @@ -518,11 +514,6 @@ trace_enabled(void) trace = TRUE; } - if (debug_get_bool_option("GALLIUM_RBUG", FALSE)) { - trace = TRUE; - rbug = TRUE; - } - return trace; } @@ -551,13 +542,6 @@ trace_screen_create(struct pipe_screen *screen) #else winsys = screen->winsys; #endif - pipe_mutex_init(tr_scr->list_mutex); - make_empty_list(&tr_scr->buffers); - make_empty_list(&tr_scr->contexts); - make_empty_list(&tr_scr->textures); - make_empty_list(&tr_scr->surfaces); - make_empty_list(&tr_scr->transfers); - tr_scr->base.winsys = winsys; tr_scr->base.destroy = trace_screen_destroy; tr_scr->base.get_name = trace_screen_get_name; @@ -580,20 +564,12 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer; tr_scr->screen = screen; - tr_scr->private_context = screen->context_create(screen, NULL); - if (tr_scr->private_context == NULL) - goto error3; trace_dump_ret(ptr, screen); trace_dump_call_end(); - if (rbug) - tr_scr->rbug = trace_rbug_start(tr_scr); - return &tr_scr->base; -error3: - FREE(tr_scr); error2: trace_dump_ret(ptr, screen); trace_dump_call_end(); diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index 05ff9ef61f1..3598ceaa20f 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -56,67 +56,17 @@ struct trace_screen struct pipe_screen base; struct pipe_screen *screen; - struct pipe_context *private_context; - - /* remote debugger */ - struct trace_rbug *rbug; - - pipe_mutex list_mutex; - int num_buffers; - int num_contexts; - int num_textures; - int num_surfaces; - int num_transfers; - struct tr_list buffers; - struct tr_list contexts; - struct tr_list textures; - struct tr_list surfaces; - struct tr_list transfers; }; /* - * tr_rbug.c - */ - - -struct trace_rbug; - -struct trace_rbug * -trace_rbug_start(struct trace_screen *tr_scr); - -void -trace_rbug_stop(struct trace_rbug *tr_rbug); - - -/* * tr_screen.c */ -boolean -trace_enabled(void); - struct trace_screen * trace_screen(struct pipe_screen *screen); -#define trace_screen_add_to_list(tr_scr, name, obj) \ - do { \ - pipe_mutex_lock(tr_scr->list_mutex); \ - insert_at_head(&tr_scr->name, &obj->list); \ - tr_scr->num_##name++; \ - pipe_mutex_unlock(tr_scr->list_mutex); \ - } while (0) - -#define trace_screen_remove_from_list(tr_scr, name, obj) \ - do { \ - pipe_mutex_lock(tr_scr->list_mutex); \ - remove_from_list(&obj->list); \ - tr_scr->num_##name--; \ - pipe_mutex_unlock(tr_scr->list_mutex); \ - } while (0) - - #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c deleted file mode 100644 index d8c11640bf3..00000000000 --- a/src/gallium/drivers/trace/tr_state.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2009 VMware, Inc. - * 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 - * 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 - * VMWARE 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 "tr_state.h" - -#include "util/u_memory.h" -#include "util/u_simple_list.h" - -#include "tgsi/tgsi_parse.h" - -struct trace_shader * trace_shader_create(struct trace_context *tr_ctx, - const struct pipe_shader_state *state, - void *result, - enum trace_shader_type type) -{ - struct trace_shader *tr_shdr = CALLOC_STRUCT(trace_shader); - - tr_shdr->state = result; - tr_shdr->type = type; - tr_shdr->tokens = tgsi_dup_tokens(state->tokens); - - /* works on context as well */ - trace_screen_add_to_list(tr_ctx, shaders, tr_shdr); - - return tr_shdr; -} - -void trace_shader_destroy(struct trace_context *tr_ctx, - struct trace_shader *tr_shdr) -{ - trace_screen_remove_from_list(tr_ctx, shaders, tr_shdr); - - if (tr_shdr->replaced) { - if (tr_shdr->type == TRACE_SHADER_FRAGMENT) - tr_ctx->pipe->delete_fs_state(tr_ctx->pipe, tr_shdr->replaced); - else if (tr_shdr->type == TRACE_SHADER_VERTEX) - tr_ctx->pipe->delete_vs_state(tr_ctx->pipe, tr_shdr->replaced); - else - assert(0); - } - - FREE(tr_shdr->replaced_tokens); - FREE(tr_shdr->tokens); - FREE(tr_shdr); -} diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h deleted file mode 100644 index e2f981d0513..00000000000 --- a/src/gallium/drivers/trace/tr_state.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2009 VMware, Inc. - * 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 - * 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 - * VMWARE 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 TR_STATE_H_ -#define TR_STATE_H_ - -#include "tr_context.h" - -struct tgsi_token; - -enum trace_shader_type { - TRACE_SHADER_FRAGMENT = 0, - TRACE_SHADER_VERTEX = 1, - TRACE_SHADER_GEOMETRY = 2 -}; - -struct trace_shader -{ - struct tr_list list; - - enum trace_shader_type type; - - void *state; - void *replaced; - - struct tgsi_token *tokens; - struct tgsi_token *replaced_tokens; - - boolean disabled; -}; - - -static INLINE struct trace_shader * -trace_shader(void *state) -{ - return (struct trace_shader *)state; -} - -struct trace_shader * trace_shader_create(struct trace_context *tr_ctx, - const struct pipe_shader_state *state, - void *result, - enum trace_shader_type type); - -void trace_shader_destroy(struct trace_context *tr_ctx, - struct trace_shader *tr_shdr); - -#endif diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c index 1132dc92724..9914b98b39c 100644 --- a/src/gallium/drivers/trace/tr_texture.c +++ b/src/gallium/drivers/trace/tr_texture.c @@ -56,8 +56,6 @@ trace_resource_create(struct trace_screen *tr_scr, tr_tex->base.screen = &tr_scr->base; tr_tex->resource = texture; - trace_screen_add_to_list(tr_scr, textures, tr_tex); - return &tr_tex->base; error: @@ -70,8 +68,6 @@ void trace_resource_destroy(struct trace_screen *tr_scr, struct trace_resource *tr_tex) { - trace_screen_remove_from_list(tr_scr, textures, tr_tex); - pipe_resource_reference(&tr_tex->resource, NULL); FREE(tr_tex); } @@ -81,7 +77,6 @@ struct pipe_surface * trace_surface_create(struct trace_resource *tr_tex, struct pipe_surface *surface) { - struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen); struct trace_surface *tr_surf; if(!surface) @@ -100,8 +95,6 @@ trace_surface_create(struct trace_resource *tr_tex, pipe_resource_reference(&tr_surf->base.texture, &tr_tex->base); tr_surf->surface = surface; - trace_screen_add_to_list(tr_scr, surfaces, tr_surf); - return &tr_surf->base; error: @@ -113,10 +106,6 @@ error: void trace_surface_destroy(struct trace_surface *tr_surf) { - struct trace_screen *tr_scr = trace_screen(tr_surf->base.texture->screen); - - trace_screen_remove_from_list(tr_scr, surfaces, tr_surf); - pipe_resource_reference(&tr_surf->base.texture, NULL); pipe_surface_reference(&tr_surf->surface, NULL); FREE(tr_surf); @@ -128,7 +117,6 @@ trace_transfer_create(struct trace_context *tr_ctx, struct trace_resource *tr_tex, struct pipe_transfer *transfer) { - struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen); struct trace_transfer *tr_trans; if(!transfer) @@ -148,8 +136,6 @@ trace_transfer_create(struct trace_context *tr_ctx, pipe_resource_reference(&tr_trans->base.resource, &tr_tex->base); assert(tr_trans->base.resource == &tr_tex->base); - trace_screen_add_to_list(tr_scr, transfers, tr_trans); - return &tr_trans->base; error: @@ -162,12 +148,9 @@ void trace_transfer_destroy(struct trace_context *tr_context, struct trace_transfer *tr_trans) { - struct trace_screen *tr_scr = trace_screen(tr_context->base.screen); struct pipe_context *context = tr_context->pipe; struct pipe_transfer *transfer = tr_trans->transfer; - trace_screen_remove_from_list(tr_scr, transfers, tr_trans); - pipe_resource_reference(&tr_trans->base.resource, NULL); context->transfer_destroy(context, transfer); FREE(tr_trans); diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index c5928dde471..b81702a4fac 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -165,6 +165,11 @@ #define PIPE_OS_UNIX #endif +#if defined(__CYGWIN__) +#define PIPE_OS_CYGWIN +#define PIPE_OS_UNIX +#endif + /* * Try to auto-detect the subsystem. * diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index a852ad97cab..b54a6ef8247 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -119,11 +119,11 @@ enum pipe_error { #define PIPE_POLYGON_MODE_LINE 1 #define PIPE_POLYGON_MODE_POINT 2 -/** Polygon front/back window, also for culling */ -#define PIPE_WINDING_NONE 0 -#define PIPE_WINDING_CW 1 -#define PIPE_WINDING_CCW 2 -#define PIPE_WINDING_BOTH (PIPE_WINDING_CW | PIPE_WINDING_CCW) +/** Polygon face specification, eg for culling */ +#define PIPE_FACE_NONE 0 +#define PIPE_FACE_FRONT 1 +#define PIPE_FACE_BACK 2 +#define PIPE_FACE_FRONT_AND_BACK (PIPE_FACE_FRONT | PIPE_FACE_BACK) /** Stencil ops */ #define PIPE_STENCIL_OP_KEEP 0 @@ -377,7 +377,8 @@ enum pipe_transfer_usage { #define PIPE_QUERY_OCCLUSION_COUNTER 0 #define PIPE_QUERY_PRIMITIVES_GENERATED 1 #define PIPE_QUERY_PRIMITIVES_EMITTED 2 -#define PIPE_QUERY_TYPES 3 +#define PIPE_QUERY_TIME_ELAPSED 3 +#define PIPE_QUERY_TYPES 4 /** @@ -411,46 +412,76 @@ enum pipe_transfer_usage { * Implementation capabilities/limits which are queried through * pipe_screen::get_param() and pipe_screen::get_paramf(). */ -#define PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS 1 -#define PIPE_CAP_NPOT_TEXTURES 2 -#define PIPE_CAP_TWO_SIDED_STENCIL 3 -#define PIPE_CAP_GLSL 4 /* XXX need something better */ -#define PIPE_CAP_DUAL_SOURCE_BLEND 5 -#define PIPE_CAP_ANISOTROPIC_FILTER 6 -#define PIPE_CAP_POINT_SPRITE 7 -#define PIPE_CAP_MAX_RENDER_TARGETS 8 -#define PIPE_CAP_OCCLUSION_QUERY 9 -#define PIPE_CAP_TEXTURE_SHADOW_MAP 10 -#define PIPE_CAP_MAX_TEXTURE_2D_LEVELS 11 -#define PIPE_CAP_MAX_TEXTURE_3D_LEVELS 12 -#define PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS 13 -#define PIPE_CAP_MAX_LINE_WIDTH 14 -#define PIPE_CAP_MAX_LINE_WIDTH_AA 15 -#define PIPE_CAP_MAX_POINT_WIDTH 16 -#define PIPE_CAP_MAX_POINT_WIDTH_AA 17 -#define PIPE_CAP_MAX_TEXTURE_ANISOTROPY 18 -#define PIPE_CAP_MAX_TEXTURE_LOD_BIAS 19 -#define PIPE_CAP_GUARD_BAND_LEFT 20 /*< float */ -#define PIPE_CAP_GUARD_BAND_TOP 21 /*< float */ -#define PIPE_CAP_GUARD_BAND_RIGHT 22 /*< float */ -#define PIPE_CAP_GUARD_BAND_BOTTOM 23 /*< float */ -#define PIPE_CAP_TEXTURE_MIRROR_CLAMP 24 -#define PIPE_CAP_TEXTURE_MIRROR_REPEAT 25 -#define PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS 26 -#define PIPE_CAP_TGSI_CONT_SUPPORTED 27 -#define PIPE_CAP_BLEND_EQUATION_SEPARATE 28 -#define PIPE_CAP_SM3 29 /*< Shader Model 3 supported */ -#define PIPE_CAP_MAX_PREDICATE_REGISTERS 30 -#define PIPE_CAP_MAX_COMBINED_SAMPLERS 31 /*< Maximum texture image units accessible from vertex - and fragment shaders combined */ -#define PIPE_CAP_MAX_CONST_BUFFERS 32 -#define PIPE_CAP_MAX_CONST_BUFFER_SIZE 33 /*< In bytes */ -#define PIPE_CAP_INDEP_BLEND_ENABLE 34 /*< blend enables and write masks per rendertarget */ -#define PIPE_CAP_INDEP_BLEND_FUNC 35 /*< different blend funcs per rendertarget */ -#define PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT 36 -#define PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT 37 -#define PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER 38 -#define PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER 39 +enum pipe_cap { + PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS, + PIPE_CAP_NPOT_TEXTURES, + PIPE_CAP_TWO_SIDED_STENCIL, + PIPE_CAP_GLSL, /* XXX need something better */ + PIPE_CAP_DUAL_SOURCE_BLEND, + PIPE_CAP_ANISOTROPIC_FILTER, + PIPE_CAP_POINT_SPRITE, + PIPE_CAP_MAX_RENDER_TARGETS, + PIPE_CAP_OCCLUSION_QUERY, + PIPE_CAP_TIMER_QUERY, + PIPE_CAP_TEXTURE_SHADOW_MAP, + PIPE_CAP_MAX_TEXTURE_2D_LEVELS, + PIPE_CAP_MAX_TEXTURE_3D_LEVELS, + PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS, + PIPE_CAP_MAX_LINE_WIDTH, + PIPE_CAP_MAX_LINE_WIDTH_AA, + PIPE_CAP_MAX_POINT_WIDTH, + PIPE_CAP_MAX_POINT_WIDTH_AA, + PIPE_CAP_MAX_TEXTURE_ANISOTROPY, + PIPE_CAP_MAX_TEXTURE_LOD_BIAS, + PIPE_CAP_GUARD_BAND_LEFT, /*< float */ + PIPE_CAP_GUARD_BAND_TOP, /*< float */ + PIPE_CAP_GUARD_BAND_RIGHT, /*< float */ + PIPE_CAP_GUARD_BAND_BOTTOM, /*< float */ + PIPE_CAP_TEXTURE_MIRROR_CLAMP, + PIPE_CAP_TEXTURE_MIRROR_REPEAT, + PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS, + PIPE_CAP_TGSI_CONT_SUPPORTED, + PIPE_CAP_BLEND_EQUATION_SEPARATE, + PIPE_CAP_SM3, /*< Shader Model, supported */ + PIPE_CAP_MAX_PREDICATE_REGISTERS, + /** Maximum texture image units accessible from vertex and fragment shaders + * combined */ + PIPE_CAP_MAX_COMBINED_SAMPLERS, + PIPE_CAP_MAX_CONST_BUFFERS, + PIPE_CAP_MAX_CONST_BUFFER_SIZE, /*< In bytes */ + /** blend enables and write masks per rendertarget */ + PIPE_CAP_INDEP_BLEND_ENABLE, + /** different blend funcs per rendertarget */ + PIPE_CAP_INDEP_BLEND_FUNC, + PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT, + PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT, + PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER, + PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER, + + /* + * Shader limits. + */ + PIPE_CAP_MAX_FS_INSTRUCTIONS, + PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS, + PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS, + PIPE_CAP_MAX_FS_TEX_INDIRECTIONS, + PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH, + PIPE_CAP_MAX_FS_INPUTS, + PIPE_CAP_MAX_FS_CONSTS, + PIPE_CAP_MAX_FS_TEMPS, + PIPE_CAP_MAX_FS_ADDRS, + PIPE_CAP_MAX_FS_PREDS, + PIPE_CAP_MAX_VS_INSTRUCTIONS, + PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS, + PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS, + PIPE_CAP_MAX_VS_TEX_INDIRECTIONS, + PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH, + PIPE_CAP_MAX_VS_INPUTS, + PIPE_CAP_MAX_VS_CONSTS, + PIPE_CAP_MAX_VS_TEMPS, + PIPE_CAP_MAX_VS_ADDRS, + PIPE_CAP_MAX_VS_PREDS +}; /** diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 9cb949a4465..21f428ed4af 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -54,7 +54,6 @@ struct winsys_handle; /** Opaque type */ struct pipe_fence_handle; struct pipe_winsys; -struct pipe_texture; struct pipe_resource; struct pipe_surface; struct pipe_transfer; @@ -79,13 +78,13 @@ struct pipe_screen { * Query an integer-valued capability/parameter/limit * \param param one of PIPE_CAP_x */ - int (*get_param)( struct pipe_screen *, int param ); + int (*get_param)( struct pipe_screen *, enum pipe_cap param ); /** * Query a float-valued capability/parameter/limit * \param param one of PIPE_CAP_x */ - float (*get_paramf)( struct pipe_screen *, int param ); + float (*get_paramf)( struct pipe_screen *, enum pipe_cap param ); struct pipe_context * (*context_create)( struct pipe_screen *, void *priv ); diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index f9ad07d8f87..5255b2003f8 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -79,12 +79,13 @@ struct pipe_rasterizer_state { unsigned flatshade:1; unsigned light_twoside:1; - unsigned front_winding:2; /**< PIPE_WINDING_x */ - unsigned cull_mode:2; /**< PIPE_WINDING_x */ - unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ - unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ - unsigned offset_cw:1; - unsigned offset_ccw:1; + unsigned front_ccw:1; + unsigned cull_face:2; /**< PIPE_FACE_x */ + unsigned fill_front:2; /**< PIPE_POLYGON_MODE_x */ + unsigned fill_back:2; /**< PIPE_POLYGON_MODE_x */ + unsigned offset_point:1; + unsigned offset_line:1; + unsigned offset_tri:1; unsigned scissor:1; unsigned poly_smooth:1; unsigned poly_stipple_enable:1; diff --git a/src/gallium/include/state_tracker/dri1_api.h b/src/gallium/include/state_tracker/dri1_api.h index a48c5de5a05..0d702d90928 100644 --- a/src/gallium/include/state_tracker/dri1_api.h +++ b/src/gallium/include/state_tracker/dri1_api.h @@ -9,7 +9,6 @@ struct pipe_screen; struct pipe_winsys; -struct pipe_buffer; struct pipe_context; struct pipe_resource; diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h index 3d8fdd86fc7..8fd0995444d 100644 --- a/src/gallium/include/state_tracker/drm_api.h +++ b/src/gallium/include/state_tracker/drm_api.h @@ -6,7 +6,6 @@ struct pipe_screen; struct pipe_winsys; -struct pipe_buffer; struct pipe_context; struct pipe_resource; diff --git a/src/gallium/include/state_tracker/graw.h b/src/gallium/include/state_tracker/graw.h index a58e18e4739..e5b298e03d9 100644 --- a/src/gallium/include/state_tracker/graw.h +++ b/src/gallium/include/state_tracker/graw.h @@ -17,20 +17,27 @@ #include "pipe/p_format.h" struct pipe_screen; - -struct pipe_screen *graw_init( void ); +struct pipe_context; /* Returns a handle to be used with flush_frontbuffer()/present(). * * Query format support with screen::is_format_supported and usage * XXX. */ -void *graw_create_window( int x, - int y, - unsigned width, - unsigned height, - enum pipe_format format ); +PUBLIC struct pipe_screen *graw_create_window_and_screen( int x, + int y, + unsigned width, + unsigned height, + enum pipe_format format, + void **handle); + +PUBLIC void graw_set_display_func( void (*func)( void ) ); +PUBLIC void graw_main_loop( void ); + +PUBLIC void *graw_parse_vertex_shader( struct pipe_context *pipe, + const char *text ); -void graw_destroy_window( void *handle ); +PUBLIC void *graw_parse_fragment_shader( struct pipe_context *pipe, + const char *text ); #endif diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h index 002d1c6b840..21f2d639b14 100644 --- a/src/gallium/include/state_tracker/st_api.h +++ b/src/gallium/include/state_tracker/st_api.h @@ -61,7 +61,7 @@ enum st_texture_type { ST_TEXTURE_1D, ST_TEXTURE_2D, ST_TEXTURE_3D, - ST_TEXTURE_RECT, + ST_TEXTURE_RECT }; /** @@ -102,7 +102,7 @@ enum st_context_resource_type { ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Z, ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Z, ST_CONTEXT_RESOURCE_OPENGL_RENDERBUFFER, - ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE, + ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE }; /** diff --git a/src/gallium/state_trackers/dri/drm/Makefile b/src/gallium/state_trackers/dri/drm/Makefile index d9a973e3c3e..6c9d03fc5de 100644 --- a/src/gallium/state_trackers/dri/drm/Makefile +++ b/src/gallium/state_trackers/dri/drm/Makefile @@ -5,6 +5,7 @@ LIBNAME = dridrm LIBRARY_INCLUDES = \ -I$(TOP)/include \ + -I$(TOP)/src/mapi \ -I$(TOP)/src/mesa \ -I$(TOP)/src/gallium/state_trackers/dri/common \ -I$(TOP)/src/mesa/drivers/dri/common \ diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript index 8800b655343..965dc95760f 100644 --- a/src/gallium/state_trackers/dri/drm/SConscript +++ b/src/gallium/state_trackers/dri/drm/SConscript @@ -10,6 +10,7 @@ if env['dri']: env.ParseConfig('pkg-config --cflags --libs libdrm') env.Append(CPPPATH = [ + '#/src/mapi', '#/src/mesa', '#/src/gallium/state_trackers/dri/common', '#/src/mesa/drivers/dri/common', diff --git a/src/gallium/state_trackers/dri/sw/Makefile b/src/gallium/state_trackers/dri/sw/Makefile index c0ae71451b2..a1dadeba5e6 100644 --- a/src/gallium/state_trackers/dri/sw/Makefile +++ b/src/gallium/state_trackers/dri/sw/Makefile @@ -8,6 +8,7 @@ LIBRARY_DEFINES = -D__NOT_HAVE_DRM_H LIBRARY_INCLUDES = \ -I../dri \ -I$(TOP)/include \ + -I$(TOP)/src/mapi \ -I$(TOP)/src/mesa \ -I$(TOP)/src/gallium/state_trackers/dri/common \ -I$(TOP)/src/mesa/drivers/dri/common \ diff --git a/src/gallium/state_trackers/dri/sw/SConscript b/src/gallium/state_trackers/dri/sw/SConscript index 6bb282d1a4c..0c5194d6edc 100644 --- a/src/gallium/state_trackers/dri/sw/SConscript +++ b/src/gallium/state_trackers/dri/sw/SConscript @@ -8,6 +8,7 @@ if env['dri']: env = env.Clone() env.Append(CPPPATH = [ + '#/src/mapi', '#/src/mesa', '#/src/gallium/state_trackers/dri/common', '#/src/mesa/drivers/dri/common', diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index 1768241352f..a3c1bb43469 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -15,6 +15,7 @@ common_OBJECTS = $(common_SOURCES:.c=.o) x11_INCLUDES = \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/glx \ + -I$(TOP)/src/mapi \ -I$(TOP)/src/mesa \ $(X11_CFLAGS) \ $(shell pkg-config --cflags-only-I libdrm) diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 871c33267ae..d63b81a1c59 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -50,8 +50,8 @@ egl_g3d_init_st(_EGLDriver *drv) if (gdrv->api_mask) return; + egl_g3d_init_st_apis(gdrv->stapis); for (i = 0; i < ST_API_COUNT; i++) { - gdrv->stapis[i] = egl_g3d_create_st_api(i); if (gdrv->stapis[i]) gdrv->api_mask |= egl_g3d_st_api_bit(i); } @@ -581,13 +581,8 @@ static void egl_g3d_unload(_EGLDriver *drv) { struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - EGLint i; - - for (i = 0; i < ST_API_COUNT; i++) { - if (gdrv->stapis[i]) - gdrv->stapis[i]->destroy(gdrv->stapis[i]); - } + egl_g3d_destroy_st_apis(); egl_g3d_destroy_probe(drv, NULL); FREE(gdrv); } diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c index 97445478684..1df57d07774 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c @@ -27,8 +27,10 @@ */ #include "util/u_memory.h" +#include "util/u_string.h" #include "util/u_inlines.h" #include "util/u_dl.h" +#include "egldriver.h" #include "eglimage.h" #include "eglmutex.h" @@ -46,42 +48,160 @@ egl_g3d_st_manager(struct st_manager *smapi) return (struct egl_g3d_st_manager *) smapi; } -struct st_api * -egl_g3d_create_st_api(enum st_api_type api) -{ +static struct egl_g3d_st_module { + const char *filename; struct util_dl_library *lib; - const char *proc_name; - struct st_api * (*proc)(void) = NULL; - - switch (api) { - case ST_API_OPENGL: - proc_name = ST_CREATE_OPENGL_SYMBOL; - break; - case ST_API_OPENGL_ES1: - proc_name = ST_CREATE_OPENGL_ES1_SYMBOL; - break; - case ST_API_OPENGL_ES2: - proc_name = ST_CREATE_OPENGL_ES2_SYMBOL; - break; - case ST_API_OPENVG: - proc_name = ST_CREATE_OPENVG_SYMBOL; - break; - default: - assert(!"Unknown API Type\n"); - return NULL; + struct st_api *stapi; +} egl_g3d_st_modules[ST_API_COUNT]; + +static EGLBoolean +egl_g3d_search_path_callback(const char *dir, size_t len, void *callback_data) +{ + struct egl_g3d_st_module *stmod = + (struct egl_g3d_st_module *) callback_data; + char path[1024]; + int ret; + + ret = util_snprintf(path, sizeof(path), + "%.*s/%s", len, dir, stmod->filename); + if (ret > 0 && ret < sizeof(path)) + stmod->lib = util_dl_open(path); + + return !(stmod->lib); +} + +static boolean +egl_g3d_load_st_module(struct egl_g3d_st_module *stmod, + const char *filename, const char *procname) +{ + struct st_api *(*create_api)(void); + + stmod->filename = filename; + if (stmod->filename) + _eglSearchPathForEach(egl_g3d_search_path_callback, (void *) stmod); + else + stmod->lib = util_dl_open(NULL); + + if (stmod->lib) { + create_api = (struct st_api *(*)(void)) + util_dl_get_proc_address(stmod->lib, procname); + if (create_api) + stmod->stapi = create_api(); + + if (!stmod->stapi) { + util_dl_close(stmod->lib); + stmod->lib = NULL; + } } - lib = util_dl_open(NULL); - if (lib) { - proc = util_dl_get_proc_address(lib, proc_name); - debug_printf("%s: %s %p\n", __func__, proc_name, proc); - util_dl_close(lib); + if (stmod->stapi) { + return TRUE; } + else { + stmod->filename = NULL; + return FALSE; + } +} - if (!proc) - return NULL; +void +egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT]) +{ + const char *skip_checks[ST_API_COUNT], *symbols[ST_API_COUNT]; + const char *filenames[ST_API_COUNT][4]; + struct util_dl_library *self; + int num_needed = 0, api; + + self = util_dl_open(NULL); + + /* collect the necessary data for loading modules */ + for (api = 0; api < ST_API_COUNT; api++) { + int count = 0; + + switch (api) { + case ST_API_OPENGL: + skip_checks[api] = "glColor4d"; + symbols[api] = ST_CREATE_OPENGL_SYMBOL; + filenames[api][count++] = "api_GL.so"; + break; + case ST_API_OPENGL_ES1: + skip_checks[api] = "glColor4x"; + symbols[api] = ST_CREATE_OPENGL_ES1_SYMBOL; + filenames[api][count++] = "api_GLESv1_CM.so"; + filenames[api][count++] = "api_GL.so"; + break; + case ST_API_OPENGL_ES2: + skip_checks[api] = "glShaderBinary"; + symbols[api] = ST_CREATE_OPENGL_ES2_SYMBOL; + filenames[api][count++] = "api_GLESv2.so"; + filenames[api][count++] = "api_GL.so"; + break; + case ST_API_OPENVG: + skip_checks[api] = "vgClear"; + symbols[api] = ST_CREATE_OPENVG_SYMBOL; + filenames[api][count++]= "api_OpenVG.so"; + break; + default: + assert(!"Unknown API Type\n"); + skip_checks[api] = NULL; + symbols[api] = NULL; + break; + } + filenames[api][count++]= NULL; + assert(count < Elements(filenames[api])); + + /* heuristicically decide if the module is needed */ + if (!self || !skip_checks[api] || + util_dl_get_proc_address(self, skip_checks[api])) { + /* unset so the module is not skipped */ + skip_checks[api] = NULL; + num_needed++; + } + } + /* mark all moudles needed if we wrongly decided that none is needed */ + if (!num_needed) + memset(skip_checks, 0, sizeof(skip_checks)); + + if (self) + util_dl_close(self); + + for (api = 0; api < ST_API_COUNT; api++) { + struct egl_g3d_st_module *stmod = &egl_g3d_st_modules[api]; + const char **p; + + /* skip the module */ + if (skip_checks[api]) + continue; + + /* try all filenames, including NULL */ + for (p = filenames[api]; *p; p++) { + if (egl_g3d_load_st_module(stmod, *p, symbols[api])) + break; + } + if (!stmod->stapi) + egl_g3d_load_st_module(stmod, NULL, symbols[api]); - return proc(); + stapis[api] = stmod->stapi; + } +} + +void +egl_g3d_destroy_st_apis(void) +{ + int api; + + for (api = 0; api < ST_API_COUNT; api++) { + struct egl_g3d_st_module *stmod = &egl_g3d_st_modules[api]; + + if (stmod->stapi) { + stmod->stapi->destroy(stmod->stapi); + stmod->stapi = NULL; + } + if (stmod->lib) { + util_dl_close(stmod->lib); + stmod->lib = NULL; + } + stmod->filename = NULL; + } } static boolean diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.h b/src/gallium/state_trackers/egl/common/egl_g3d_st.h index c82681a22d8..ee53799b029 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.h @@ -33,8 +33,11 @@ #include "state_tracker/st_api.h" #include "egltypedefs.h" -struct st_api * -egl_g3d_create_st_api(enum st_api_type api); +void +egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT]); + +void +egl_g3d_destroy_st_apis(void); struct st_manager * egl_g3d_create_st_manager(_EGLDisplay *dpy); diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile deleted file mode 100644 index 7370634ea24..00000000000 --- a/src/gallium/state_trackers/es/Makefile +++ /dev/null @@ -1,84 +0,0 @@ -# src/gallium/state_trackers/es/Makefile - -# Build the ES 1/2 state tracker libraries -# This consists of core Mesa ES, plus GL/gallium state tracker. - -TOP = ../../../.. -include $(TOP)/configs/current - -GLES_1_VERSION_MAJOR = 1 -GLES_1_VERSION_MINOR = 1 -GLES_1_VERSION_PATCH = 0 - -GLES_2_VERSION_MAJOR = 2 -GLES_2_VERSION_MINOR = 0 -GLES_2_VERSION_PATCH = 0 - - -# Maybe move these into configs/default: -GLES_1_LIB = GLESv1_CM -GLES_1_LIB_NAME = lib$(GLES_1_LIB).so -GLES_2_LIB = GLESv2 -GLES_2_LIB_NAME = lib$(GLES_2_LIB).so - - -# These two objects indirectly reference all public functions thanks to the use -# of _glapi_get_proc_address. -ES1_OBJECTS = st_es1.o -ES2_OBJECTS = st_es2.o - - -ES1_LIBS = \ - $(TOP)/src/mesa/es/libes1gallium.a \ - $(TOP)/src/mesa/es/libes1api.a - -ES2_LIBS = \ - $(TOP)/src/mesa/es/libes2gallium.a \ - $(TOP)/src/mesa/es/libes2api.a - -SYS_LIBS = -lm -pthread - - -INCLUDE_DIRS = \ - -I$(TOP)/include \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/gallium/include - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@ - - -# Default: make both GL ES 1.1 and GL ES 2.0 libraries -default: $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME) - -# Make the shared libs -$(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) - $(MKLIB) -o $(GLES_1_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -major $(GLES_1_VERSION_MAJOR) \ - -minor $(GLES_1_VERSION_MINOR) \ - -patch $(GLES_1_VERSION_PATCH) \ - -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ - $(ES1_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) $(SYS_LIBS) - -$(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) - $(MKLIB) -o $(GLES_2_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -major $(GLES_2_VERSION_MAJOR) \ - -minor $(GLES_2_VERSION_MINOR) \ - -patch $(GLES_2_VERSION_PATCH) \ - -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ - $(ES2_OBJECTS) $(ES2_LIBS) $(GALLIUM_AUXILIARIES) $(SYS_LIBS) - -install: default - $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES - $(INSTALL) -m 644 $(TOP)/include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES - $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES2 - $(INSTALL) -m 644 $(TOP)/include/GLES2/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES2 - $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv1* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv2* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) - -clean: - -rm -f *.o *~ - -rm -f $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME)* $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME)* - -depend: diff --git a/src/gallium/state_trackers/glx/xlib/Makefile b/src/gallium/state_trackers/glx/xlib/Makefile index 35509fd708b..84cb36ec367 100644 --- a/src/gallium/state_trackers/glx/xlib/Makefile +++ b/src/gallium/state_trackers/glx/xlib/Makefile @@ -5,6 +5,7 @@ LIBNAME = xlib LIBRARY_INCLUDES = \ -I$(TOP)/include \ + -I$(TOP)/src/mapi \ -I$(TOP)/src/mesa \ $(X11_CFLAGS) diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript index d6c16ad2f52..9df351a2769 100644 --- a/src/gallium/state_trackers/glx/xlib/SConscript +++ b/src/gallium/state_trackers/glx/xlib/SConscript @@ -9,6 +9,7 @@ if env['platform'] == 'linux' \ env = env.Clone() env.Append(CPPPATH = [ + '#/src/mapi', '#/src/mesa', '#/src/mesa/main', ]) diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c index bd4a85caa04..26fcae78ece 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_getproc.c +++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c @@ -34,7 +34,6 @@ #include <string.h> #include "GL/glx.h" #include "glapi/glapi.h" -#include "pipe/p_compiler.h" struct name_address_pair { diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index aac28cacfde..dce24bc17d6 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -184,8 +184,7 @@ st_context_create(struct st_device *st_dev) { struct pipe_rasterizer_state rasterizer; memset(&rasterizer, 0, sizeof(rasterizer)); - rasterizer.front_winding = PIPE_WINDING_CW; - rasterizer.cull_mode = PIPE_WINDING_NONE; + rasterizer.cull_face = PIPE_FACE_NONE; cso_set_rasterizer(st_ctx->cso, &rasterizer); } diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile index b871990cd9a..e0a87151c43 100644 --- a/src/gallium/state_trackers/vega/Makefile +++ b/src/gallium/state_trackers/vega/Makefile @@ -3,16 +3,14 @@ TOP = ../../../.. include $(TOP)/configs/current -VG_LIB = OpenVG -VG_LIB_NAME = lib$(VG_LIB).so +LIBNAME = vega -VG_MAJOR = 1 -VG_MINOR = 0 -VG_TINY = 0 - -### Lists of source files, included by Makefiles +LIBRARY_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/mapi -VG_SOURCES = \ +C_SOURCES = \ + api.c \ api_context.c \ api_filters.c \ api_images.c \ @@ -40,55 +38,4 @@ VG_SOURCES = \ shader.c \ shaders_cache.c -VG_OBJECTS = $(VG_SOURCES:.c=.o) - -VG_LIBS = $(GALLIUM_AUXILIARIES) -VG_LIB_DEPS = $(EXTRA_LIB_PATH) -lm - -### Include directories - -INCLUDE_DIRS = \ - -I$(TOP)/include \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary - - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ - -default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) - -# Make the OpenVG library -$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(VG_LIBS) - $(MKLIB) -o $(VG_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -major $(VG_MAJOR) \ - -minor $(VG_MINOR) \ - -patch $(VG_TINY) \ - -install $(TOP)/$(LIB_DIR) \ - $(VG_OBJECTS) $(VG_LIBS) $(VG_LIB_DEPS) - -###################################################################### -# Generic stuff - -depend: $(VG_SOURCES) - @ echo "running $(MKDEP)" - @ rm -f depend # workaround oops on gutsy?!? - @ touch depend - @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(VG_SOURCES) \ - > /dev/null 2>/dev/null - -install: default - $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/VG - $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(DESTDIR)$(INSTALL_DIR)/include/VG - $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) - -# Emacs tags -tags: - etags `find . -name \*.[ch]` $(TOP)/include/VG/*.h - -clean: - rm -f $(VG_OBJECTS) - rm -f depend depend.bak - -sinclude depend +include ../../Makefile.template diff --git a/src/gallium/state_trackers/vega/api.c b/src/gallium/state_trackers/vega/api.c new file mode 100644 index 00000000000..bf1d37493af --- /dev/null +++ b/src/gallium/state_trackers/vega/api.c @@ -0,0 +1,88 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Chia-I Wu <[email protected]> + */ + +#include "mapi/mapi.h" + +#include "api.h" + +static const char vega_spec[] = + "1" +#define MAPI_ABI_ENTRY(ret, name, params) \ + "\0" #name "\0" +#define MAPI_ALIAS_ENTRY(alias, ret, name, params) \ + #name "\0" +#include "vgapi/vgapi_tmp.h" + "\0"; + +static const mapi_proc vega_procs[] = { +#define MAPI_ABI_ENTRY(ret, name, params) \ + (mapi_proc) vega ## name, +#include "vgapi/vgapi_tmp.h" +}; + +static void api_init(void) +{ + static boolean initialized = FALSE; + if (!initialized) { + mapi_init(vega_spec); + initialized = TRUE; + } +} + +struct mapi_table *api_create_dispatch(void) +{ + struct mapi_table *tbl; + + api_init(); + + tbl = mapi_table_create(); + if (tbl) + mapi_table_fill(tbl, vega_procs); + + return tbl; +} + +void api_destroy_dispatch(struct mapi_table *tbl) +{ + mapi_table_destroy(tbl); +} + +void api_make_dispatch_current(const struct mapi_table *tbl) +{ + mapi_table_make_current(tbl); +} + +mapi_proc api_get_proc_address(const char *proc_name) +{ + if (!proc_name || proc_name[0] != 'v' || proc_name[1] != 'g') + return NULL; + proc_name += 2; + + api_init(); + return mapi_get_proc_address(proc_name); +} diff --git a/src/gallium/state_trackers/vega/api.h b/src/gallium/state_trackers/vega/api.h new file mode 100644 index 00000000000..955508dae9a --- /dev/null +++ b/src/gallium/state_trackers/vega/api.h @@ -0,0 +1,51 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Chia-I Wu <[email protected]> + */ + +#ifndef API_H +#define API_H + +#include "VG/openvg.h" +#include "VG/vgext.h" +#include "vg_manager.h" + +/* declare the prototypes */ +#define MAPI_ABI_ENTRY(ret, name, params) \ + ret VG_API_ENTRY vega ## name params; +#include "vgapi/vgapi_tmp.h" + +struct mapi_table; + +struct mapi_table *api_create_dispatch(void); + +void api_destroy_dispatch(struct mapi_table *tbl); + +void api_make_dispatch_current(const struct mapi_table *tbl); + +st_proc_t api_get_proc_address(const char *proc_name); + +#endif /* API_H */ diff --git a/src/gallium/state_trackers/vega/api_context.c b/src/gallium/state_trackers/vega/api_context.c index eb2fbe26e7f..0d04d8e8718 100644 --- a/src/gallium/state_trackers/vega/api_context.c +++ b/src/gallium/state_trackers/vega/api_context.c @@ -28,11 +28,12 @@ #include "vg_manager.h" #include "vg_context.h" +#include "api.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" -VGErrorCode vgGetError(void) +VGErrorCode vegaGetError(void) { struct vg_context *ctx = vg_current_context(); VGErrorCode error = VG_NO_CONTEXT_ERROR; @@ -46,7 +47,7 @@ VGErrorCode vgGetError(void) return error; } -void vgFlush(void) +void vegaFlush(void) { struct vg_context *ctx = vg_current_context(); struct pipe_context *pipe; @@ -60,7 +61,7 @@ void vgFlush(void) vg_manager_flush_frontbuffer(ctx); } -void vgFinish(void) +void vegaFinish(void) { struct vg_context *ctx = vg_current_context(); struct pipe_fence_handle *fence = NULL; diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c index b1c08af9382..144fb8f323d 100644 --- a/src/gallium/state_trackers/vega/api_filters.c +++ b/src/gallium/state_trackers/vega/api_filters.c @@ -28,6 +28,7 @@ #include "vg_context.h" #include "image.h" +#include "api.h" #include "renderer.h" #include "shaders_cache.h" #include "st_inlines.h" @@ -361,8 +362,8 @@ static void execute_filter(struct vg_context *ctx, pipe_surface_reference(&dst_surf, NULL); } -void vgColorMatrix(VGImage dst, VGImage src, - const VGfloat * matrix) +void vegaColorMatrix(VGImage dst, VGImage src, + const VGfloat * matrix) { struct vg_context *ctx = vg_current_context(); struct vg_image *d, *s; @@ -403,13 +404,13 @@ static VGfloat texture_offset(VGfloat width, VGint kernelSize, VGint current, VG return diff / width; } -void vgConvolve(VGImage dst, VGImage src, - VGint kernelWidth, VGint kernelHeight, - VGint shiftX, VGint shiftY, - const VGshort * kernel, - VGfloat scale, - VGfloat bias, - VGTilingMode tilingMode) +void vegaConvolve(VGImage dst, VGImage src, + VGint kernelWidth, VGint kernelHeight, + VGint shiftX, VGint shiftY, + const VGshort * kernel, + VGfloat scale, + VGfloat bias, + VGTilingMode tilingMode) { struct vg_context *ctx = vg_current_context(); VGfloat *buffer; @@ -508,15 +509,15 @@ void vgConvolve(VGImage dst, VGImage src, free(buffer); } -void vgSeparableConvolve(VGImage dst, VGImage src, - VGint kernelWidth, - VGint kernelHeight, - VGint shiftX, VGint shiftY, - const VGshort * kernelX, - const VGshort * kernelY, - VGfloat scale, - VGfloat bias, - VGTilingMode tilingMode) +void vegaSeparableConvolve(VGImage dst, VGImage src, + VGint kernelWidth, + VGint kernelHeight, + VGint shiftX, VGint shiftY, + const VGshort * kernelX, + const VGshort * kernelY, + VGfloat scale, + VGfloat bias, + VGTilingMode tilingMode) { struct vg_context *ctx = vg_current_context(); VGshort *kernel; @@ -600,10 +601,10 @@ static void compute_gaussian_kernel(VGfloat *kernel, } } -void vgGaussianBlur(VGImage dst, VGImage src, - VGfloat stdDeviationX, - VGfloat stdDeviationY, - VGTilingMode tilingMode) +void vegaGaussianBlur(VGImage dst, VGImage src, + VGfloat stdDeviationX, + VGfloat stdDeviationY, + VGTilingMode tilingMode) { struct vg_context *ctx = vg_current_context(); struct vg_image *d, *s; @@ -699,13 +700,13 @@ void vgGaussianBlur(VGImage dst, VGImage src, free(kernel); } -void vgLookup(VGImage dst, VGImage src, - const VGubyte * redLUT, - const VGubyte * greenLUT, - const VGubyte * blueLUT, - const VGubyte * alphaLUT, - VGboolean outputLinear, - VGboolean outputPremultiplied) +void vegaLookup(VGImage dst, VGImage src, + const VGubyte * redLUT, + const VGubyte * greenLUT, + const VGubyte * blueLUT, + const VGubyte * alphaLUT, + VGboolean outputLinear, + VGboolean outputPremultiplied) { struct vg_context *ctx = vg_current_context(); struct vg_image *d, *s; @@ -758,11 +759,11 @@ void vgLookup(VGImage dst, VGImage src, pipe_sampler_view_reference(&lut_texture_view, NULL); } -void vgLookupSingle(VGImage dst, VGImage src, - const VGuint * lookupTable, - VGImageChannel sourceChannel, - VGboolean outputLinear, - VGboolean outputPremultiplied) +void vegaLookupSingle(VGImage dst, VGImage src, + const VGuint * lookupTable, + VGImageChannel sourceChannel, + VGboolean outputLinear, + VGboolean outputPremultiplied) { struct vg_context *ctx = vg_current_context(); struct vg_image *d, *s; diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c index 6c7fd3b346c..547508f815a 100644 --- a/src/gallium/state_trackers/vega/api_images.c +++ b/src/gallium/state_trackers/vega/api_images.c @@ -32,6 +32,7 @@ #include "vg_translate.h" #include "api_consts.h" #include "image.h" +#include "api.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" @@ -92,9 +93,9 @@ static INLINE VGboolean supported_image_format(VGImageFormat format) return VG_FALSE; } -VGImage vgCreateImage(VGImageFormat format, - VGint width, VGint height, - VGbitfield allowedQuality) +VGImage vegaCreateImage(VGImageFormat format, + VGint width, VGint height, + VGbitfield allowedQuality) { struct vg_context *ctx = vg_current_context(); @@ -126,7 +127,7 @@ VGImage vgCreateImage(VGImageFormat format, return (VGImage)image_create(format, width, height); } -void vgDestroyImage(VGImage image) +void vegaDestroyImage(VGImage image) { struct vg_context *ctx = vg_current_context(); struct vg_image *img = (struct vg_image *)image; @@ -142,9 +143,9 @@ void vgDestroyImage(VGImage image) image_destroy(img); } -void vgClearImage(VGImage image, - VGint x, VGint y, - VGint width, VGint height) +void vegaClearImage(VGImage image, + VGint x, VGint y, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; @@ -167,12 +168,12 @@ void vgClearImage(VGImage image, } -void vgImageSubData(VGImage image, - const void * data, - VGint dataStride, - VGImageFormat dataFormat, - VGint x, VGint y, - VGint width, VGint height) +void vegaImageSubData(VGImage image, + const void * data, + VGint dataStride, + VGImageFormat dataFormat, + VGint x, VGint y, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; @@ -195,12 +196,12 @@ void vgImageSubData(VGImage image, x, y, width, height); } -void vgGetImageSubData(VGImage image, - void * data, - VGint dataStride, - VGImageFormat dataFormat, - VGint x, VGint y, - VGint width, VGint height) +void vegaGetImageSubData(VGImage image, + void * data, + VGint dataStride, + VGImageFormat dataFormat, + VGint x, VGint y, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; @@ -222,9 +223,9 @@ void vgGetImageSubData(VGImage image, x, y, width, height); } -VGImage vgChildImage(VGImage parent, - VGint x, VGint y, - VGint width, VGint height) +VGImage vegaChildImage(VGImage parent, + VGint x, VGint y, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *p; @@ -252,7 +253,7 @@ VGImage vgChildImage(VGImage parent, return (VGImage)image_child_image(p, x, y, width, height); } -VGImage vgGetParent(VGImage image) +VGImage vegaGetParent(VGImage image) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; @@ -269,10 +270,10 @@ VGImage vgGetParent(VGImage image) return image; } -void vgCopyImage(VGImage dst, VGint dx, VGint dy, - VGImage src, VGint sx, VGint sy, - VGint width, VGint height, - VGboolean dither) +void vegaCopyImage(VGImage dst, VGint dx, VGint dy, + VGImage src, VGint sx, VGint sy, + VGint width, VGint height, + VGboolean dither) { struct vg_context *ctx = vg_current_context(); @@ -291,7 +292,7 @@ void vgCopyImage(VGImage dst, VGint dx, VGint dy, width, height, dither); } -void vgDrawImage(VGImage image) +void vegaDrawImage(VGImage image) { struct vg_context *ctx = vg_current_context(); @@ -307,9 +308,9 @@ void vgDrawImage(VGImage image) image_draw((struct vg_image*)image); } -void vgSetPixels(VGint dx, VGint dy, - VGImage src, VGint sx, VGint sy, - VGint width, VGint height) +void vegaSetPixels(VGint dx, VGint dy, + VGImage src, VGint sx, VGint sy, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); @@ -327,9 +328,9 @@ void vgSetPixels(VGint dx, VGint dy, height); } -void vgGetPixels(VGImage dst, VGint dx, VGint dy, - VGint sx, VGint sy, - VGint width, VGint height) +void vegaGetPixels(VGImage dst, VGint dx, VGint dy, + VGint sx, VGint sy, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; @@ -349,10 +350,10 @@ void vgGetPixels(VGImage dst, VGint dx, VGint dy, sx, sy, width, height); } -void vgWritePixels(const void * data, VGint dataStride, - VGImageFormat dataFormat, - VGint dx, VGint dy, - VGint width, VGint height) +void vegaWritePixels(const void * data, VGint dataStride, + VGImageFormat dataFormat, + VGint dx, VGint dy, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct pipe_context *pipe = ctx->pipe; @@ -390,10 +391,10 @@ void vgWritePixels(const void * data, VGint dataStride, pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); } -void vgReadPixels(void * data, VGint dataStride, - VGImageFormat dataFormat, - VGint sx, VGint sy, - VGint width, VGint height) +void vegaReadPixels(void * data, VGint dataStride, + VGImageFormat dataFormat, + VGint sx, VGint sy, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct pipe_context *pipe = ctx->pipe; @@ -461,9 +462,9 @@ void vgReadPixels(void * data, VGint dataStride, } } -void vgCopyPixels(VGint dx, VGint dy, - VGint sx, VGint sy, - VGint width, VGint height) +void vegaCopyPixels(VGint dx, VGint dy, + VGint sx, VGint sy, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c index 7c28ea5c872..94c1ff5375f 100644 --- a/src/gallium/state_trackers/vega/api_masks.c +++ b/src/gallium/state_trackers/vega/api_masks.c @@ -28,6 +28,7 @@ #include "mask.h" #include "renderer.h" +#include "api.h" #include "vg_context.h" #include "pipe/p_context.h" @@ -37,7 +38,6 @@ #include "util/u_draw_quad.h" #include "util/u_memory.h" - #define DISABLE_1_1_MASKING 1 /** @@ -151,9 +151,9 @@ clear_with_quad(struct vg_context *st, float x0, float y0, } -void vgMask(VGHandle mask, VGMaskOperation operation, - VGint x, VGint y, - VGint width, VGint height) +void vegaMask(VGHandle mask, VGMaskOperation operation, + VGint x, VGint y, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); @@ -189,8 +189,8 @@ void vgMask(VGHandle mask, VGMaskOperation operation, } } -void vgClear(VGint x, VGint y, - VGint width, VGint height) +void vegaClear(VGint x, VGint y, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct pipe_framebuffer_state *fb; @@ -225,9 +225,9 @@ void vgClear(VGint x, VGint y, #ifdef OPENVG_VERSION_1_1 -void vgRenderToMask(VGPath path, - VGbitfield paintModes, - VGMaskOperation operation) +void vegaRenderToMask(VGPath path, + VGbitfield paintModes, + VGMaskOperation operation) { struct vg_context *ctx = vg_current_context(); @@ -258,7 +258,7 @@ void vgRenderToMask(VGPath path, mask_render_to((struct path *)path, paintModes, operation); } -VGMaskLayer vgCreateMaskLayer(VGint width, VGint height) +VGMaskLayer vegaCreateMaskLayer(VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); @@ -272,7 +272,7 @@ VGMaskLayer vgCreateMaskLayer(VGint width, VGint height) return (VGMaskLayer)mask_layer_create(width, height); } -void vgDestroyMaskLayer(VGMaskLayer maskLayer) +void vegaDestroyMaskLayer(VGMaskLayer maskLayer) { struct vg_mask_layer *mask = 0; struct vg_context *ctx = vg_current_context(); @@ -290,10 +290,10 @@ void vgDestroyMaskLayer(VGMaskLayer maskLayer) mask_layer_destroy(mask); } -void vgFillMaskLayer(VGMaskLayer maskLayer, - VGint x, VGint y, - VGint width, VGint height, - VGfloat value) +void vegaFillMaskLayer(VGMaskLayer maskLayer, + VGint x, VGint y, + VGint width, VGint height, + VGfloat value) { struct vg_mask_layer *mask = 0; struct vg_context *ctx = vg_current_context(); @@ -336,10 +336,10 @@ void vgFillMaskLayer(VGMaskLayer maskLayer, mask_layer_fill(mask, x, y, width, height, value); } -void vgCopyMask(VGMaskLayer maskLayer, - VGint sx, VGint sy, - VGint dx, VGint dy, - VGint width, VGint height) +void vegaCopyMask(VGMaskLayer maskLayer, + VGint sx, VGint sy, + VGint dx, VGint dy, + VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_mask_layer *mask = 0; diff --git a/src/gallium/state_trackers/vega/api_misc.c b/src/gallium/state_trackers/vega/api_misc.c index 78ba0bc1103..e648549745b 100644 --- a/src/gallium/state_trackers/vega/api_misc.c +++ b/src/gallium/state_trackers/vega/api_misc.c @@ -27,10 +27,11 @@ #include "VG/openvg.h" #include "vg_context.h" +#include "api.h" /* Hardware Queries */ -VGHardwareQueryResult vgHardwareQuery(VGHardwareQueryType key, - VGint setting) +VGHardwareQueryResult vegaHardwareQuery(VGHardwareQueryType key, + VGint setting) { struct vg_context *ctx = vg_current_context(); @@ -58,7 +59,7 @@ VGHardwareQueryResult vgHardwareQuery(VGHardwareQueryType key, } /* Renderer and Extension Information */ -const VGubyte *vgGetString(VGStringID name) +const VGubyte *vegaGetString(VGStringID name) { struct vg_context *ctx = vg_current_context(); static const VGubyte *vendor = (VGubyte *)"Tungsten Graphics, Inc"; diff --git a/src/gallium/state_trackers/vega/api_paint.c b/src/gallium/state_trackers/vega/api_paint.c index dd3ac5bdb09..d88341b04ff 100644 --- a/src/gallium/state_trackers/vega/api_paint.c +++ b/src/gallium/state_trackers/vega/api_paint.c @@ -29,13 +29,14 @@ #include "vg_context.h" #include "paint.h" #include "image.h" +#include "api.h" -VGPaint vgCreatePaint(void) +VGPaint vegaCreatePaint(void) { return (VGPaint) paint_create(vg_current_context()); } -void vgDestroyPaint(VGPaint p) +void vegaDestroyPaint(VGPaint p) { struct vg_context *ctx = vg_current_context(); struct vg_paint *paint; @@ -49,7 +50,7 @@ void vgDestroyPaint(VGPaint p) paint_destroy(paint); } -void vgSetPaint(VGPaint paint, VGbitfield paintModes) +void vegaSetPaint(VGPaint paint, VGbitfield paintModes) { struct vg_context *ctx = vg_current_context(); @@ -74,7 +75,7 @@ void vgSetPaint(VGPaint paint, VGbitfield paintModes) } } -VGPaint vgGetPaint(VGPaintMode paintMode) +VGPaint vegaGetPaint(VGPaintMode paintMode) { struct vg_context *ctx = vg_current_context(); VGPaint paint = VG_INVALID_HANDLE; @@ -95,7 +96,7 @@ VGPaint vgGetPaint(VGPaintMode paintMode) return paint; } -void vgSetColor(VGPaint paint, VGuint rgba) +void vegaSetColor(VGPaint paint, VGuint rgba) { struct vg_context *ctx = vg_current_context(); @@ -114,7 +115,7 @@ void vgSetColor(VGPaint paint, VGuint rgba) } } -VGuint vgGetColor(VGPaint paint) +VGuint vegaGetColor(VGPaint paint) { struct vg_context *ctx = vg_current_context(); struct vg_paint *p; @@ -134,7 +135,7 @@ VGuint vgGetColor(VGPaint paint) return paint_colori(p); } -void vgPaintPattern(VGPaint paint, VGImage pattern) +void vegaPaintPattern(VGPaint paint, VGImage pattern) { struct vg_context *ctx = vg_current_context(); diff --git a/src/gallium/state_trackers/vega/api_params.c b/src/gallium/state_trackers/vega/api_params.c index db77fd9cb05..a10b009e631 100644 --- a/src/gallium/state_trackers/vega/api_params.c +++ b/src/gallium/state_trackers/vega/api_params.c @@ -32,6 +32,7 @@ #include "image.h" #include "matrix.h" #include "api_consts.h" +#include "api.h" #include "pipe/p_compiler.h" #include "util/u_pointer.h" @@ -63,7 +64,7 @@ static INLINE VGboolean count_in_bounds(VGParamType type, VGint count) } } -void vgSetf (VGParamType type, VGfloat value) +void vegaSetf (VGParamType type, VGfloat value) { struct vg_context *ctx = vg_current_context(); struct vg_state *state = current_state(); @@ -123,7 +124,7 @@ void vgSetf (VGParamType type, VGfloat value) vg_set_error(ctx, error); } -void vgSeti (VGParamType type, VGint value) +void vegaSeti (VGParamType type, VGint value) { struct vg_context *ctx = vg_current_context(); struct vg_state *state = current_state(); @@ -254,8 +255,8 @@ void vgSeti (VGParamType type, VGint value) vg_set_error(ctx, error); } -void vgSetfv(VGParamType type, VGint count, - const VGfloat * values) +void vegaSetfv(VGParamType type, VGint count, + const VGfloat * values) { struct vg_context *ctx = vg_current_context(); struct vg_state *state = current_state(); @@ -382,8 +383,8 @@ void vgSetfv(VGParamType type, VGint count, vg_set_error(ctx, error); } -void vgSetiv(VGParamType type, VGint count, - const VGint * values) +void vegaSetiv(VGParamType type, VGint count, + const VGint * values) { struct vg_context *ctx = vg_current_context(); struct vg_state *state = current_state(); @@ -506,7 +507,7 @@ void vgSetiv(VGParamType type, VGint count, } } -VGfloat vgGetf(VGParamType type) +VGfloat vegaGetf(VGParamType type) { struct vg_context *ctx = vg_current_context(); const struct vg_state *state = current_state(); @@ -568,7 +569,7 @@ VGfloat vgGetf(VGParamType type) return value; } -VGint vgGeti(VGParamType type) +VGint vegaGeti(VGParamType type) { const struct vg_state *state = current_state(); struct vg_context *ctx = vg_current_context(); @@ -683,7 +684,7 @@ VGint vgGeti(VGParamType type) return value; } -VGint vgGetVectorSize(VGParamType type) +VGint vegaGetVectorSize(VGParamType type) { struct vg_context *ctx = vg_current_context(); const struct vg_state *state = current_state(); @@ -757,8 +758,8 @@ VGint vgGetVectorSize(VGParamType type) } } -void vgGetfv(VGParamType type, VGint count, - VGfloat * values) +void vegaGetfv(VGParamType type, VGint count, + VGfloat * values) { const struct vg_state *state = current_state(); struct vg_context *ctx = vg_current_context(); @@ -858,8 +859,8 @@ void vgGetfv(VGParamType type, VGint count, } } -void vgGetiv(VGParamType type, VGint count, - VGint * values) +void vegaGetiv(VGParamType type, VGint count, + VGint * values) { const struct vg_state *state = current_state(); struct vg_context *ctx = vg_current_context(); @@ -964,9 +965,9 @@ void vgGetiv(VGParamType type, VGint count, } } -void vgSetParameterf(VGHandle object, - VGint paramType, - VGfloat value) +void vegaSetParameterf(VGHandle object, + VGint paramType, + VGfloat value) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; @@ -1018,9 +1019,9 @@ void vgSetParameterf(VGHandle object, } } -void vgSetParameteri(VGHandle object, - VGint paramType, - VGint value) +void vegaSetParameteri(VGHandle object, + VGint paramType, + VGint value) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; @@ -1093,10 +1094,10 @@ void vgSetParameteri(VGHandle object, } } -void vgSetParameterfv(VGHandle object, - VGint paramType, - VGint count, - const VGfloat * values) +void vegaSetParameterfv(VGHandle object, + VGint paramType, + VGint count, + const VGfloat * values) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; @@ -1206,10 +1207,10 @@ void vgSetParameterfv(VGHandle object, } } -void vgSetParameteriv(VGHandle object, - VGint paramType, - VGint count, - const VGint * values) +void vegaSetParameteriv(VGHandle object, + VGint paramType, + VGint count, + const VGint * values) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; @@ -1311,8 +1312,8 @@ void vgSetParameteriv(VGHandle object, } } -VGint vgGetParameterVectorSize(VGHandle object, - VGint paramType) +VGint vegaGetParameterVectorSize(VGHandle object, + VGint paramType) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; @@ -1367,8 +1368,8 @@ VGint vgGetParameterVectorSize(VGHandle object, } -VGfloat vgGetParameterf(VGHandle object, - VGint paramType) +VGfloat vegaGetParameterf(VGHandle object, + VGint paramType) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; @@ -1424,8 +1425,8 @@ VGfloat vgGetParameterf(VGHandle object, return 0; } -VGint vgGetParameteri(VGHandle object, - VGint paramType) +VGint vegaGetParameteri(VGHandle object, + VGint paramType) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; @@ -1511,10 +1512,10 @@ VGint vgGetParameteri(VGHandle object, return 0; } -void vgGetParameterfv(VGHandle object, - VGint paramType, - VGint count, - VGfloat * values) +void vegaGetParameterfv(VGHandle object, + VGint paramType, + VGint count, + VGfloat * values) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; @@ -1598,10 +1599,10 @@ void vgGetParameterfv(VGHandle object, } } -void vgGetParameteriv(VGHandle object, - VGint paramType, - VGint count, - VGint * values) +void vegaGetParameteriv(VGHandle object, + VGint paramType, + VGint count, + VGint * values) { struct vg_context *ctx = vg_current_context(); void *ptr = (void*)object; diff --git a/src/gallium/state_trackers/vega/api_path.c b/src/gallium/state_trackers/vega/api_path.c index 58ebb3b60ea..6c9a2e8d658 100644 --- a/src/gallium/state_trackers/vega/api_path.c +++ b/src/gallium/state_trackers/vega/api_path.c @@ -30,17 +30,18 @@ #include "path.h" #include "polygon.h" #include "paint.h" +#include "api.h" #include "pipe/p_context.h" #include "util/u_inlines.h" #include "util/u_draw_quad.h" -VGPath vgCreatePath(VGint pathFormat, - VGPathDatatype datatype, - VGfloat scale, VGfloat bias, - VGint segmentCapacityHint, - VGint coordCapacityHint, - VGbitfield capabilities) +VGPath vegaCreatePath(VGint pathFormat, + VGPathDatatype datatype, + VGfloat scale, VGfloat bias, + VGint segmentCapacityHint, + VGint coordCapacityHint, + VGbitfield capabilities) { struct vg_context *ctx = vg_current_context(); @@ -63,7 +64,7 @@ VGPath vgCreatePath(VGint pathFormat, capabilities); } -void vgClearPath(VGPath path, VGbitfield capabilities) +void vegaClearPath(VGPath path, VGbitfield capabilities) { struct vg_context *ctx = vg_current_context(); struct path *p = 0; @@ -77,7 +78,7 @@ void vgClearPath(VGPath path, VGbitfield capabilities) path_clear(p, capabilities); } -void vgDestroyPath(VGPath p) +void vegaDestroyPath(VGPath p) { struct path *path = 0; struct vg_context *ctx = vg_current_context(); @@ -91,8 +92,8 @@ void vgDestroyPath(VGPath p) path_destroy(path); } -void vgRemovePathCapabilities(VGPath path, - VGbitfield capabilities) +void vegaRemovePathCapabilities(VGPath path, + VGbitfield capabilities) { struct vg_context *ctx = vg_current_context(); VGbitfield current; @@ -109,7 +110,7 @@ void vgRemovePathCapabilities(VGPath path, (~(capabilities & VG_PATH_CAPABILITY_ALL)))); } -VGbitfield vgGetPathCapabilities(VGPath path) +VGbitfield vegaGetPathCapabilities(VGPath path) { struct vg_context *ctx = vg_current_context(); struct path *p = 0; @@ -122,7 +123,7 @@ VGbitfield vgGetPathCapabilities(VGPath path) return path_capabilities(p); } -void vgAppendPath(VGPath dstPath, VGPath srcPath) +void vegaAppendPath(VGPath dstPath, VGPath srcPath) { struct vg_context *ctx = vg_current_context(); struct path *src, *dst; @@ -142,10 +143,10 @@ void vgAppendPath(VGPath dstPath, VGPath srcPath) path_append_path(dst, src); } -void vgAppendPathData(VGPath dstPath, - VGint numSegments, - const VGubyte * pathSegments, - const void * pathData) +void vegaAppendPathData(VGPath dstPath, + VGint numSegments, + const VGubyte * pathSegments, + const void * pathData) { struct vg_context *ctx = vg_current_context(); struct path *p = 0; @@ -185,10 +186,10 @@ void vgAppendPathData(VGPath dstPath, path_append_data(p, numSegments, pathSegments, pathData); } -void vgModifyPathCoords(VGPath dstPath, - VGint startIndex, - VGint numSegments, - const void * pathData) +void vegaModifyPathCoords(VGPath dstPath, + VGint startIndex, + VGint numSegments, + const void * pathData) { struct vg_context *ctx = vg_current_context(); struct path *p = 0; @@ -220,7 +221,7 @@ void vgModifyPathCoords(VGPath dstPath, path_modify_coords(p, startIndex, numSegments, pathData); } -void vgTransformPath(VGPath dstPath, VGPath srcPath) +void vegaTransformPath(VGPath dstPath, VGPath srcPath) { struct vg_context *ctx = vg_current_context(); struct path *src = 0, *dst = 0; @@ -240,10 +241,10 @@ void vgTransformPath(VGPath dstPath, VGPath srcPath) path_transform(dst, src); } -VGboolean vgInterpolatePath(VGPath dstPath, - VGPath startPath, - VGPath endPath, - VGfloat amount) +VGboolean vegaInterpolatePath(VGPath dstPath, + VGPath startPath, + VGPath endPath, + VGfloat amount) { struct vg_context *ctx = vg_current_context(); struct path *start = 0, *dst = 0, *end = 0; @@ -269,9 +270,9 @@ VGboolean vgInterpolatePath(VGPath dstPath, start, end, amount); } -VGfloat vgPathLength(VGPath path, - VGint startSegment, - VGint numSegments) +VGfloat vegaPathLength(VGPath path, + VGint startSegment, + VGint numSegments) { struct vg_context *ctx = vg_current_context(); struct path *p = 0; @@ -302,13 +303,13 @@ VGfloat vgPathLength(VGPath path, return path_length(p, startSegment, numSegments); } -void vgPointAlongPath(VGPath path, - VGint startSegment, - VGint numSegments, - VGfloat distance, - VGfloat * x, VGfloat * y, - VGfloat * tangentX, - VGfloat * tangentY) +void vegaPointAlongPath(VGPath path, + VGint startSegment, + VGint numSegments, + VGfloat distance, + VGfloat * x, VGfloat * y, + VGfloat * tangentX, + VGfloat * tangentY) { struct vg_context *ctx = vg_current_context(); struct path *p = 0; @@ -362,11 +363,11 @@ void vgPointAlongPath(VGPath path, } } -void vgPathBounds(VGPath path, - VGfloat * minX, - VGfloat * minY, - VGfloat * width, - VGfloat * height) +void vegaPathBounds(VGPath path, + VGfloat * minX, + VGfloat * minY, + VGfloat * width, + VGfloat * height) { struct vg_context *ctx = vg_current_context(); struct path *p = 0; @@ -399,11 +400,11 @@ void vgPathBounds(VGPath path, path_bounding_rect(p, minX, minY, width, height); } -void vgPathTransformedBounds(VGPath path, - VGfloat * minX, - VGfloat * minY, - VGfloat * width, - VGfloat * height) +void vegaPathTransformedBounds(VGPath path, + VGfloat * minX, + VGfloat * minY, + VGfloat * width, + VGfloat * height) { struct vg_context *ctx = vg_current_context(); struct path *p = 0; @@ -466,7 +467,7 @@ void vgPathTransformedBounds(VGPath path, } -void vgDrawPath(VGPath path, VGbitfield paintModes) +void vegaDrawPath(VGPath path, VGbitfield paintModes) { struct vg_context *ctx = vg_current_context(); diff --git a/src/gallium/state_trackers/vega/api_text.c b/src/gallium/state_trackers/vega/api_text.c index d8411cf3e87..b35f3be90ab 100644 --- a/src/gallium/state_trackers/vega/api_text.c +++ b/src/gallium/state_trackers/vega/api_text.c @@ -27,6 +27,7 @@ #include "VG/openvg.h" #include "vg_context.h" +#include "api.h" #include "util/u_memory.h" @@ -39,7 +40,7 @@ struct vg_font { VGint num_glyphs; }; -VGFont vgCreateFont(VGint glyphCapacityHint) +VGFont vegaCreateFont(VGint glyphCapacityHint) { struct vg_font *font = 0; struct vg_context *ctx = vg_current_context(); @@ -55,7 +56,7 @@ VGFont vgCreateFont(VGint glyphCapacityHint) return (VGFont)font; } -void vgDestroyFont(VGFont f) +void vegaDestroyFont(VGFont f) { struct vg_font *font = (struct vg_font *)f; struct vg_context *ctx = vg_current_context(); @@ -69,12 +70,12 @@ void vgDestroyFont(VGFont f) /*free(font);*/ } -void vgSetGlyphToPath(VGFont font, - VGuint glyphIndex, - VGPath path, - VGboolean isHinted, - VGfloat glyphOrigin [2], - VGfloat escapement[2]) +void vegaSetGlyphToPath(VGFont font, + VGuint glyphIndex, + VGPath path, + VGboolean isHinted, + VGfloat glyphOrigin [2], + VGfloat escapement[2]) { struct vg_context *ctx = vg_current_context(); struct vg_object *pathObj; @@ -106,11 +107,11 @@ void vgSetGlyphToPath(VGFont font, ++f->num_glyphs; } -void vgSetGlyphToImage(VGFont font, - VGuint glyphIndex, - VGImage image, - VGfloat glyphOrigin [2], - VGfloat escapement[2]) +void vegaSetGlyphToImage(VGFont font, + VGuint glyphIndex, + VGImage image, + VGfloat glyphOrigin [2], + VGfloat escapement[2]) { struct vg_context *ctx = vg_current_context(); struct vg_object *img_obj; @@ -153,8 +154,8 @@ static INLINE VGboolean font_contains_glyph(struct vg_font *font, return VG_FALSE; } -void vgClearGlyph(VGFont font, - VGuint glyphIndex) +void vegaClearGlyph(VGFont font, + VGuint glyphIndex) { struct vg_context *ctx = vg_current_context(); struct vg_font *f; @@ -184,10 +185,10 @@ void vgClearGlyph(VGFont font, } } -void vgDrawGlyph(VGFont font, - VGuint glyphIndex, - VGbitfield paintModes, - VGboolean allowAutoHinting) +void vegaDrawGlyph(VGFont font, + VGuint glyphIndex, + VGbitfield paintModes, + VGboolean allowAutoHinting) { struct vg_context *ctx = vg_current_context(); struct vg_font *f; @@ -211,13 +212,13 @@ void vgDrawGlyph(VGFont font, } } -void vgDrawGlyphs(VGFont font, - VGint glyphCount, - VGuint *glyphIndices, - VGfloat *adjustments_x, - VGfloat *adjustments_y, - VGbitfield paintModes, - VGboolean allowAutoHinting) +void vegaDrawGlyphs(VGFont font, + VGint glyphCount, + VGuint *glyphIndices, + VGfloat *adjustments_x, + VGfloat *adjustments_y, + VGbitfield paintModes, + VGboolean allowAutoHinting) { struct vg_context *ctx = vg_current_context(); VGint i; diff --git a/src/gallium/state_trackers/vega/api_transform.c b/src/gallium/state_trackers/vega/api_transform.c index 763a5ec415c..0a40fc69b95 100644 --- a/src/gallium/state_trackers/vega/api_transform.c +++ b/src/gallium/state_trackers/vega/api_transform.c @@ -29,15 +29,16 @@ #include "vg_context.h" #include "matrix.h" +#include "api.h" -void vgLoadIdentity(void) +void vegaLoadIdentity(void) { struct vg_context *ctx = vg_current_context(); struct matrix *mat = vg_state_matrix(&ctx->state.vg); matrix_load_identity(mat); } -void vgLoadMatrix(const VGfloat * m) +void vegaLoadMatrix(const VGfloat * m) { struct vg_context *ctx = vg_current_context(); struct matrix *mat; @@ -59,7 +60,7 @@ void vgLoadMatrix(const VGfloat * m) } } -void vgGetMatrix(VGfloat * m) +void vegaGetMatrix(VGfloat * m) { struct vg_context *ctx = vg_current_context(); struct matrix *mat; @@ -76,7 +77,7 @@ void vgGetMatrix(VGfloat * m) memcpy(m, mat->m, sizeof(VGfloat)*9); } -void vgMultMatrix(const VGfloat * m) +void vegaMultMatrix(const VGfloat * m) { struct vg_context *ctx = vg_current_context(); struct matrix *dst, src; @@ -99,28 +100,28 @@ void vgMultMatrix(const VGfloat * m) } -void vgTranslate(VGfloat tx, VGfloat ty) +void vegaTranslate(VGfloat tx, VGfloat ty) { struct vg_context *ctx = vg_current_context(); struct matrix *dst = vg_state_matrix(&ctx->state.vg); matrix_translate(dst, tx, ty); } -void vgScale(VGfloat sx, VGfloat sy) +void vegaScale(VGfloat sx, VGfloat sy) { struct vg_context *ctx = vg_current_context(); struct matrix *dst = vg_state_matrix(&ctx->state.vg); matrix_scale(dst, sx, sy); } -void vgShear(VGfloat shx, VGfloat shy) +void vegaShear(VGfloat shx, VGfloat shy) { struct vg_context *ctx = vg_current_context(); struct matrix *dst = vg_state_matrix(&ctx->state.vg); matrix_shear(dst, shx, shy); } -void vgRotate(VGfloat angle) +void vegaRotate(VGfloat angle) { struct vg_context *ctx = vg_current_context(); struct matrix *dst = vg_state_matrix(&ctx->state.vg); diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index d2b7e489124..e9c8f031373 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -379,7 +379,7 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) dsa.stencil[0].func = PIPE_FUNC_ALWAYS; dsa.stencil[0].valuemask = ~0; - raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH; + raster.cull_face = PIPE_FACE_BACK; dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; @@ -389,7 +389,7 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) cso_set_rasterizer(ctx->cso_context, &raster); draw_polygon(ctx, poly); - raster.cull_mode = raster.front_winding; + raster.cull_face = PIPE_FACE_FRONT; dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; @@ -501,7 +501,7 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) dsa.stencil[0].func = PIPE_FUNC_ALWAYS; dsa.stencil[0].valuemask = ~0; - raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH; + raster.cull_face = PIPE_FACE_BACK; dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; @@ -514,7 +514,7 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) draw_polygon(ctx, poly); } - raster.cull_mode = raster.front_winding; + raster.cull_face = PIPE_FACE_FRONT; dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; diff --git a/src/gallium/state_trackers/vega/vg_api.h b/src/gallium/state_trackers/vega/vg_api.h new file mode 100644 index 00000000000..ce2a0d6bb47 --- /dev/null +++ b/src/gallium/state_trackers/vega/vg_api.h @@ -0,0 +1,37 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Chia-I Wu <[email protected]> + */ + +#ifndef VG_API_H +#define VG_API_H + +struct st_api; + +const struct st_api * +vg_api_get(void); + +#endif /* VG_API_H */ diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index b55a2b57bed..f02db8949df 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -33,6 +33,7 @@ #include "asm_util.h" #include "st_inlines.h" #include "vg_manager.h" +#include "api.h" #include "pipe/p_context.h" #include "util/u_inlines.h" @@ -67,6 +68,7 @@ static void init_clear(struct vg_context *st) void vg_set_current_context(struct vg_context *ctx) { _vg_context = ctx; + api_make_dispatch_current((ctx) ? ctx->dispatch : NULL); } struct vg_context * vg_create_context(struct pipe_context *pipe, @@ -80,6 +82,8 @@ struct vg_context * vg_create_context(struct pipe_context *pipe, ctx->pipe = pipe; + ctx->dispatch = api_create_dispatch(); + vg_init_state(&ctx->state.vg); ctx->state.dirty = ALL_DIRTY; @@ -185,6 +189,8 @@ void vg_destroy_context(struct vg_context *ctx) cso_hash_delete(ctx->owned_objects[VG_OBJECT_FONT]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_PATH]); + api_destroy_dispatch(ctx->dispatch); + free(ctx); } diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h index dac67192a54..7b59ad512a0 100644 --- a/src/gallium/state_trackers/vega/vg_context.h +++ b/src/gallium/state_trackers/vega/vg_context.h @@ -42,6 +42,7 @@ struct renderer; struct shaders_cache; struct shader; struct vg_shader; +struct mapi_table; struct st_renderbuffer { enum pipe_format format; @@ -90,6 +91,7 @@ enum dirty_state { struct vg_context { struct st_context_iface iface; + struct mapi_table *dispatch; struct pipe_context *pipe; diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c index 8a62a191207..3b04816df04 100644 --- a/src/gallium/state_trackers/vega/vg_manager.c +++ b/src/gallium/state_trackers/vega/vg_manager.c @@ -36,10 +36,12 @@ #include "util/u_format.h" #include "util/u_sampler.h" +#include "vg_api.h" #include "vg_manager.h" #include "vg_context.h" #include "image.h" #include "mask.h" +#include "api.h" static struct pipe_resource * create_texture(struct pipe_context *pipe, enum pipe_format format, @@ -526,17 +528,15 @@ vg_api_is_visual_supported(struct st_api *stapi, static st_proc_t vg_api_get_proc_address(struct st_api *stapi, const char *procname) { - /* TODO */ - return (st_proc_t) NULL; + return api_get_proc_address(procname); } static void vg_api_destroy(struct st_api *stapi) { - free(stapi); } -struct st_api st_vg_api = { +static const struct st_api vg_api = { vg_api_destroy, vg_api_get_proc_address, vg_api_is_visual_supported, @@ -545,8 +545,8 @@ struct st_api st_vg_api = { vg_api_get_current, }; -struct st_api * -st_api_create_OpenVG(void) +const struct st_api * +vg_api_get(void) { - return &st_vg_api; + return &vg_api; } diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript index f59f3a9638a..0f580b859c6 100644 --- a/src/gallium/state_trackers/wgl/SConscript +++ b/src/gallium/state_trackers/wgl/SConscript @@ -7,6 +7,7 @@ if env['platform'] in ['windows']: env = env.Clone() env.Append(CPPPATH = [ + '#src/mapi', '#src/mesa', '.', ]) diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript index 5d0b6613ac7..0b598dab6e3 100644 --- a/src/gallium/state_trackers/xorg/SConscript +++ b/src/gallium/state_trackers/xorg/SConscript @@ -11,13 +11,15 @@ if 'xorg' in env['statetrackers']: '#/src/mesa', ]) - env.ParseConfig('pkg-config --cflags --libs xorg-server') + env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server') conf = env.Configure() if conf.CheckHeader('X11/extensions/dpmsconst.h'): env.Append(CPPDEFINES = [('HAVE_XEXTPROTO_71', '1')]) + conf.Finish() + st_xorg = env.ConvenienceLibrary( target = 'st_xorg', source = [ 'xorg_composite.c', diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 669bd9edcf0..f9022a9f934 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -90,11 +90,10 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); modesettingPtr ms = modesettingPTR(crtc->scrn); xf86OutputPtr output = NULL; - drmModeConnectorPtr drm_connector; struct crtc_private *crtcp = crtc->driver_private; drmModeCrtcPtr drm_crtc = crtcp->drm_crtc; drmModeModeInfo drm_mode; - int i, ret; + int i, ret, connector_id; for (i = 0; i < config->num_output; output = NULL, i++) { output = config->output[i]; @@ -106,7 +105,7 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (!output) return FALSE; - drm_connector = output->driver_private; + connector_id = xorg_output_get_id(output); drm_mode.clock = mode->Clock; drm_mode.hdisplay = mode->HDisplay; @@ -127,7 +126,7 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0'; ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y, - &drm_connector->connector_id, 1, &drm_mode); + &connector_id, 1, &drm_mode); if (ret) return FALSE; diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 35741f86842..e719644d340 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -403,7 +403,7 @@ xorg_dri2_init(ScreenPtr pScreen) } #endif - dri2info.version = DRI2INFOREC_VERSION; + dri2info.version = min(DRI2INFOREC_VERSION, 3); dri2info.fd = ms->fd; dri2info.driverName = pScrn->driverName; diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 3687ee0db4e..44520b81b66 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -141,8 +141,6 @@ xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device) static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn); static Bool drv_close_screen(int scrnIndex, ScreenPtr pScreen); -static Bool drv_save_hw_state(ScrnInfoPtr pScrn); -static Bool drv_restore_hw_state(ScrnInfoPtr pScrn); /* @@ -336,17 +334,9 @@ static Bool drv_close_resource_management(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); - int i; if (ms->screen) { assert(ms->ctx == NULL); - - for (i = 0; i < XORG_NR_FENCES; i++) { - if (ms->fence[i]) { - ms->screen->fence_finish(ms->screen, ms->fence[i], 0); - ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL); - } - } ms->screen->destroy(ms->screen); } ms->screen = NULL; @@ -359,6 +349,22 @@ drv_close_resource_management(ScrnInfoPtr pScrn) return TRUE; } +static void +drv_cleanup_fences(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + int i; + + assert(ms->screen); + + for (i = 0; i < XORG_NR_FENCES; i++) { + if (ms->fence[i]) { + ms->screen->fence_finish(ms->screen, ms->fence[i], 0); + ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL); + } + } +} + static Bool drv_pre_init(ScrnInfoPtr pScrn, int flags) { @@ -388,7 +394,6 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) return FALSE; ms = modesettingPTR(pScrn); - ms->SaveGeneration = -1; ms->pEnt = pEnt; ms->cust = cust; @@ -471,19 +476,14 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) ms->SWCursor = TRUE; } - drv_save_hw_state(pScrn); - xorg_crtc_init(pScrn); xorg_output_init(pScrn); if (!xf86InitialConfiguration(pScrn, TRUE)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - drv_restore_hw_state(pScrn); return FALSE; } - drv_restore_hw_state(pScrn); - /* * If the driver can do gamma correction, it should call xf86SetGamma() here. */ @@ -521,22 +521,6 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) return TRUE; } -static Bool -drv_save_hw_state(ScrnInfoPtr pScrn) -{ - /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/ - - return TRUE; -} - -static Bool -drv_restore_hw_state(ScrnInfoPtr pScrn) -{ - /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/ - - return TRUE; -} - static void drv_block_handler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) { @@ -848,7 +832,9 @@ drv_leave_vt(int scrnIndex, int flags) drmModeRmFB(ms->fd, ms->fb_id); ms->fb_id = -1; - drv_restore_hw_state(pScrn); + /* idle hardware */ + if (!ms->kms) + drv_cleanup_fences(pScrn); if (drmDropMaster(ms->fd)) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -878,15 +864,6 @@ drv_enter_vt(int scrnIndex, int flags) } } - /* - * Only save state once per server generation since that's what most - * drivers do. Could change this to save state at each VT enter. - */ - if (ms->SaveGeneration != serverGeneration) { - ms->SaveGeneration = serverGeneration; - drv_save_hw_state(pScrn); - } - if (!ms->create_front_buffer(pScrn)) return FALSE; @@ -917,10 +894,6 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen) modesettingPtr ms = modesettingPTR(pScrn); CustomizerPtr cust = ms->cust; - if (pScrn->vtSema) { - drv_leave_vt(scrnIndex, 0); - } - if (ms->cursor) { FreeCursor(ms->cursor, None); ms->cursor = NULL; @@ -952,6 +925,11 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen) xorg_exa_close(pScrn); ms->exa = NULL; + /* calls drop master make sure we don't talk to 3D HW after that */ + if (pScrn->vtSema) { + drv_leave_vt(scrnIndex, 0); + } + drv_close_resource_management(pScrn); drv_close_drm(pScrn); diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 6657f7391b2..ee40bc8ccbd 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -968,6 +968,8 @@ xorg_exa_close(ScrnInfoPtr pScrn) renderer_destroy(exa->renderer); + xorg_exa_finish(exa); + if (exa->pipe) exa->pipe->destroy(exa->pipe); exa->pipe = NULL; diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c index 13c3fb97e3b..056098f76b4 100644 --- a/src/gallium/state_trackers/xorg/xorg_output.c +++ b/src/gallium/state_trackers/xorg/xorg_output.c @@ -51,6 +51,13 @@ #include "xorg_tracker.h" +struct output_private +{ + drmModeConnectorPtr drm_connector; + + int c; +}; + static char *output_enum_list[] = { "Unknown", "VGA", @@ -82,22 +89,38 @@ output_dpms(xf86OutputPtr output, int mode) static xf86OutputStatus output_detect(xf86OutputPtr output) { - drmModeConnectorPtr drm_connector = output->driver_private; + modesettingPtr ms = modesettingPTR(output->scrn); + struct output_private *priv = output->driver_private; + drmModeConnectorPtr drm_connector; + xf86OutputStatus status; + + drm_connector = drmModeGetConnector(ms->fd, priv->drm_connector->connector_id); + if (drm_connector) { + drmModeFreeConnector(priv->drm_connector); + priv->drm_connector = drm_connector; + } else { + drm_connector = priv->drm_connector; + } switch (drm_connector->connection) { case DRM_MODE_CONNECTED: - return XF86OutputStatusConnected; + status = XF86OutputStatusConnected; + break; case DRM_MODE_DISCONNECTED: - return XF86OutputStatusDisconnected; + status = XF86OutputStatusDisconnected; + break; default: - return XF86OutputStatusUnknown; + status = XF86OutputStatusUnknown; } + + return status; } static DisplayModePtr output_get_modes(xf86OutputPtr output) { - drmModeConnectorPtr drm_connector = output->driver_private; + struct output_private *priv = output->driver_private; + drmModeConnectorPtr drm_connector = priv->drm_connector; drmModeModeInfoPtr drm_mode = NULL; DisplayModePtr modes = NULL, mode = NULL; int i; @@ -161,7 +184,10 @@ output_get_property(xf86OutputPtr output, Atom property) static void output_destroy(xf86OutputPtr output) { - drmModeFreeConnector(output->driver_private); + struct output_private *priv = output->driver_private; + drmModeFreeConnector(priv->drm_connector); + xfree(priv); + output->driver_private = NULL; } static const xf86OutputFuncsRec output_funcs = { @@ -188,6 +214,7 @@ xorg_output_init(ScrnInfoPtr pScrn) drmModeResPtr res; drmModeConnectorPtr drm_connector = NULL; drmModeEncoderPtr drm_encoder = NULL; + struct output_private *priv; char name[32]; int c, v, p; @@ -226,9 +253,16 @@ xorg_output_init(ScrnInfoPtr pScrn) drm_connector->connector_type_id); + priv = xcalloc(sizeof(*priv), 1); + if (!priv) { + continue; + } + output = xf86OutputCreate(pScrn, &output_funcs, name); - if (!output) + if (!output) { + xfree(priv); continue; + } drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]); if (drm_encoder) { @@ -238,7 +272,9 @@ xorg_output_init(ScrnInfoPtr pScrn) output->possible_crtcs = 0; output->possible_clones = 0; } - output->driver_private = drm_connector; + priv->c = c; + priv->drm_connector = drm_connector; + output->driver_private = priv; output->subpixel_order = SubPixelHorizontalRGB; output->interlaceAllowed = FALSE; output->doubleScanAllowed = FALSE; @@ -248,4 +284,11 @@ xorg_output_init(ScrnInfoPtr pScrn) drmModeFreeResources(res); } +unsigned +xorg_output_get_id(xf86OutputPtr output) +{ + struct output_private *priv = output->driver_private; + return priv->drm_connector->connector_id; +} + /* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index 1576e5ea01b..e5def3e2edd 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -7,7 +7,6 @@ #include "util/u_draw_quad.h" #include "util/u_math.h" #include "util/u_memory.h" -#include "util/u_rect.h" #include "util/u_sampler.h" #include "util/u_surface.h" diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h index cb6773424a8..65fbc3234ba 100644 --- a/src/gallium/state_trackers/xorg/xorg_tracker.h +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -96,8 +96,6 @@ typedef struct _modesettingRec /* Broken-out options. */ OptionInfoPtr Options; - unsigned int SaveGeneration; - void (*blockHandler)(int, pointer, pointer, pointer); struct pipe_fence_handle *fence[XORG_NR_FENCES]; @@ -192,6 +190,9 @@ xorg_crtc_cursor_destroy(xf86CrtcPtr crtc); void xorg_output_init(ScrnInfoPtr pScrn); +unsigned +xorg_output_get_id(xf86OutputPtr output); + /*********************************************************************** * xorg_xv.c diff --git a/src/gallium/targets/Makefile.dri b/src/gallium/targets/Makefile.dri index 3cbaf615e2f..3eff07538fe 100644 --- a/src/gallium/targets/Makefile.dri +++ b/src/gallium/targets/Makefile.dri @@ -1,7 +1,6 @@ # -*-makefile-*- ifeq ($(MESA_LLVM),1) -DRIVER_DEFINES += -DGALLIUM_LLVMPIPE PIPE_DRIVERS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a LDFLAGS += $(LLVM_LDFLAGS) LD = g++ @@ -42,13 +41,13 @@ SHARED_INCLUDES = \ -Iserver \ -I$(TOP)/include \ -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/mapi \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/gallium/winsys \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa/glapi \ -I$(TOP)/src/mesa/math \ -I$(TOP)/src/mesa/transform \ -I$(TOP)/src/mesa/shader \ diff --git a/src/gallium/targets/Makefile.egl b/src/gallium/targets/Makefile.egl index 9265e2eb7bc..4f8641e0561 100644 --- a/src/gallium/targets/Makefile.egl +++ b/src/gallium/targets/Makefile.egl @@ -19,10 +19,17 @@ x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a \ $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/identity/libidentity.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes +ifeq ($(MESA_LLVM),1) +x11_ST += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a +x11_LIBS += $(LLVM_LIBS) +LDFLAGS += $(LLVM_LDFLAGS) +endif + kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a kms_LIBS = $(common_LIBS) @@ -36,19 +43,20 @@ kms_LIBS = $(common_LIBS) EGL_DISPLAY_DRIVERS = $(foreach dpy, $(EGL_DISPLAYS), egl_$(dpy)_$(EGL_DRIVER_NAME).so) -EGL_DISPLAY_LIBS = $(foreach drv, $(EGL_DISPLAY_DRIVERS), $(TOP)/$(LIB_DIR)/$(drv)) +EGL_DISPLAY_LIBS = $(foreach drv, $(EGL_DISPLAY_DRIVERS), $(TOP)/$(LIB_DIR)/egl/$(drv)) default: $(EGL_DISPLAY_LIBS) -$(EGL_DISPLAY_LIBS): $(TOP)/$(LIB_DIR)/%.so: %.so - $(INSTALL) $< $(TOP)/$(LIB_DIR) +$(EGL_DISPLAY_LIBS): $(TOP)/$(LIB_DIR)/egl/%.so: %.so + @$(INSTALL) -d $(TOP)/$(LIB_DIR)/egl + $(INSTALL) $< $(TOP)/$(LIB_DIR)/egl define mklib-egl $(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \ -Wl,--start-group $($(1)_ST) $(EGL_DRIVER_PIPES) \ $(GALLIUM_AUXILIARIES) -Wl,--end-group \ - $($(1)_LIBS) $(EGL_DRIVER_LIBS) + $($(1)_LIBS) $(EGL_DRIVER_LIBS) -L$(TOP)/$(LIB_DIR) -l$(EGL_LIB) endef egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile diff --git a/src/gallium/targets/SConscript b/src/gallium/targets/SConscript index 1292d4f6193..9077cbf6a45 100644 --- a/src/gallium/targets/SConscript +++ b/src/gallium/targets/SConscript @@ -1,5 +1,8 @@ +import os Import('*') +# Compatibility with old build scripts: +# if 'xlib' in env['winsys']: SConscript([ 'libgl-xlib/SConscript', @@ -10,10 +13,10 @@ if 'gdi' in env['winsys']: 'libgl-gdi/SConscript', ]) -if 'graw-xlib' in env['winsys']: - SConscript([ - 'graw-xlib/SConscript', - ]) +if not 'graw-xlib' in env['targets'] and not env['msvc']: + # XXX: disable until MSVC can link correctly + SConscript('graw-null/SConscript') + if env['dri']: SConscript([ @@ -25,3 +28,13 @@ if 'xorg' in env['statetrackers']: SConscript([ 'xorg-vmwgfx/SConscript', ]) + +# Ideally all non-target directories would produce convenience +# libraries, and the actual shared libraries and other installables +# would be finally assembled in the targets subtree: +# +for target in env['targets']: + SConscript(os.path.join(target, 'SConscript')) + + + diff --git a/src/gallium/targets/SConscript.dri b/src/gallium/targets/SConscript.dri index 28fbe02ab8d..4bbb16c2272 100644 --- a/src/gallium/targets/SConscript.dri +++ b/src/gallium/targets/SConscript.dri @@ -9,6 +9,7 @@ drienv.Replace(CPPPATH = [ '#src/mesa/drivers/dri/common', '#include', '#include/GL/internal', + '#src/mapi', '#src/gallium/include', '#src/gallium/auxiliary', '#src/gallium/drivers', diff --git a/src/gallium/targets/dri-i915/Makefile b/src/gallium/targets/dri-i915/Makefile index 50a8e11e17c..fdcfd08c227 100644 --- a/src/gallium/targets/dri-i915/Makefile +++ b/src/gallium/targets/dri-i915/Makefile @@ -7,6 +7,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/identity/libidentity.a \ $(TOP)/src/gallium/drivers/i915/libi915.a diff --git a/src/gallium/targets/dri-i915/SConscript b/src/gallium/targets/dri-i915/SConscript index 2fcc8028f12..65c42398875 100644 --- a/src/gallium/targets/dri-i915/SConscript +++ b/src/gallium/targets/dri-i915/SConscript @@ -13,6 +13,7 @@ env.Prepend(LIBS = [ i915drm, i915, trace, + rbug, mesa, glsl, gallium, diff --git a/src/gallium/targets/dri-i965/Makefile b/src/gallium/targets/dri-i965/Makefile index e267ba3a023..13987c643e2 100644 --- a/src/gallium/targets/dri-i965/Makefile +++ b/src/gallium/targets/dri-i965/Makefile @@ -7,6 +7,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ diff --git a/src/gallium/targets/dri-i965/SConscript b/src/gallium/targets/dri-i965/SConscript index eb9e6cd172a..13ac5a2d8ea 100644 --- a/src/gallium/targets/dri-i965/SConscript +++ b/src/gallium/targets/dri-i965/SConscript @@ -11,8 +11,11 @@ env.ParseConfig('pkg-config --cflags --libs libdrm_intel') env.Prepend(LIBS = [ st_dri, i965drm, + ws_drm, + ws_wrapper, i965, trace, + rbug, mesa, glsl, gallium, diff --git a/src/gallium/targets/dri-radeong/Makefile b/src/gallium/targets/dri-radeong/Makefile index 66dd392b68b..8ef24c08215 100644 --- a/src/gallium/targets/dri-radeong/Makefile +++ b/src/gallium/targets/dri-radeong/Makefile @@ -8,6 +8,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/r300/libr300.a C_SOURCES = \ diff --git a/src/gallium/targets/dri-radeong/SConscript b/src/gallium/targets/dri-radeong/SConscript index d926c272889..4c6cfb84eba 100644 --- a/src/gallium/targets/dri-radeong/SConscript +++ b/src/gallium/targets/dri-radeong/SConscript @@ -13,6 +13,7 @@ env.Prepend(LIBS = [ radeonwinsys, r300, trace, + rbug, mesa, glsl, gallium, diff --git a/src/gallium/targets/dri-swrast/Makefile b/src/gallium/targets/dri-swrast/Makefile index 3db9781c209..0a53eb56c45 100644 --- a/src/gallium/targets/dri-swrast/Makefile +++ b/src/gallium/targets/dri-swrast/Makefile @@ -9,7 +9,8 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/sw/libdrisw.a \ $(TOP)/src/gallium/winsys/sw/dri/libswdri.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a SWRAST_COMMON_GALLIUM_SOURCES = \ $(TOP)/src/mesa/drivers/dri/common/utils.c \ diff --git a/src/gallium/targets/dri-swrast/SConscript b/src/gallium/targets/dri-swrast/SConscript index 77f44384d06..679afab41c7 100644 --- a/src/gallium/targets/dri-swrast/SConscript +++ b/src/gallium/targets/dri-swrast/SConscript @@ -10,6 +10,7 @@ env.Prepend(LIBS = [ st_drisw, ws_dri, trace, + rbug, mesa, glsl, gallium, diff --git a/src/gallium/targets/dri-vmwgfx/Makefile b/src/gallium/targets/dri-vmwgfx/Makefile index 4b002e828fa..b5b679f3c7c 100644 --- a/src/gallium/targets/dri-vmwgfx/Makefile +++ b/src/gallium/targets/dri-vmwgfx/Makefile @@ -7,6 +7,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/svga/libsvga.a C_SOURCES = \ diff --git a/src/gallium/targets/dri-vmwgfx/SConscript b/src/gallium/targets/dri-vmwgfx/SConscript index 6a1f8827bc3..09a0c254c30 100644 --- a/src/gallium/targets/dri-vmwgfx/SConscript +++ b/src/gallium/targets/dri-vmwgfx/SConscript @@ -11,6 +11,7 @@ env.Prepend(LIBS = [ svgadrm, svga, trace, + rbug, mesa, glsl, gallium, diff --git a/src/gallium/targets/egl-apis/Makefile b/src/gallium/targets/egl-apis/Makefile new file mode 100644 index 00000000000..88915bfc5ec --- /dev/null +++ b/src/gallium/targets/egl-apis/Makefile @@ -0,0 +1,77 @@ +# src/gallium/targets/egl-apis + +TOP = ../../../.. +include $(TOP)/configs/current + +OUTPUT_PREFIX := api_ +OUTPUT_PATH := $(TOP)/$(LIB_DIR)/egl + +OUTPUTS := $(addsuffix .so, $(EGL_CLIENT_APIS)) +OUTPUTS := $(addprefix $(OUTPUT_PATH)/$(OUTPUT_PREFIX), $(OUTPUTS)) + +# include dirs +GL_INCLUDES := -I$(TOP)/src/mesa -I$(TOP)/src/gallium/include +GLESv1_CM_INCLUDES := $(GL_INCLUDES) +GLESv2_INCLUDES := $(GL_INCLUDES) +OpenVG_INCLUDES := -I$(TOP)/src/gallium/state_trackers/vega -I$(TOP)/src/gallium/include + +# system libs +GL_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) +GLESv1_CM_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GLESv1_CM_LIB) +GLESv2_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GLESv2_LIB) +OpenVG_SYS := -lm -L$(TOP)/$(LIB_DIR) -l$(VG_LIB) + +# $(LLVM_LIBS) will be discarded except for OpenGL, which creates a private +# draw context for selection/feedback mode. +ifeq ($(MESA_LLVM),1) +GL_SYS += $(LLVM_LIBS) +GLESv1_CM_SYS += $(LLVM_LIBS) +GLESv2_SYS += $(LLVM_LIBS) +OpenVG_SYS += $(LLVM_LIBS) +LDFLAGS += $(LLVM_LDFLAGS) +endif + +# project libs +GL_LIBS := $(TOP)/src/mesa/libmesagallium.a +GLESv1_CM_LIBS := $(TOP)/src/mesa/libes1gallium.a +GLESv2_LIBS := $(TOP)/src/mesa/libes2gallium.a +OpenVG_LIBS := $(TOP)/src/gallium/state_trackers/vega/libvega.a + +# objects +GL_OBJECTS := api_GL.o +GLESv1_CM_OBJECTS := api_GLESv1_CM.o +GLESv2_OBJECTS := api_GLESv2.o +OpenVG_OBJECTS := api_OpenVG.o + +default: $(OUTPUTS) + +api_%.o: api_%.c + $(CC) -c -o $@ $< $($*_INCLUDES) $(DEFINES) $(CFLAGS) + +define mklib +$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) \ + $($(1)_OBJECTS) $($(1)_LIBS) $(GALLIUM_AUXILIARIES) $($(1)_SYS) +endef + +$(OUTPUT_PATH)/$(OUTPUT_PREFIX)$(GL_LIB).so: $(GL_OBJECTS) $(GL_LIBS) + $(call mklib,GL) + +$(OUTPUT_PATH)/$(OUTPUT_PREFIX)$(GLESv1_CM_LIB).so: $(GLESv1_CM_OBJECTS) $(GLESv1_CM_LIBS) + $(call mklib,GLESv1_CM) + +$(OUTPUT_PATH)/$(OUTPUT_PREFIX)$(GLESv2_LIB).so: $(GLESv2_OBJECTS) $(GLESv2_LIBS) + $(call mklib,GLESv2) + +$(OUTPUT_PATH)/$(OUTPUT_PREFIX)$(VG_LIB).so: $(OpenVG_OBJECTS) $(OpenVG_LIBS) + $(call mklib,OpenVG) + +install: $(OUTPUTS) + $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR) + for out in $(OUTPUTS); do \ + $(MINSTALL) -m 755 "$$out" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \ + done + +clean: + -rm -f $(OUTPUTS) + -rm -f *.o diff --git a/src/gallium/targets/egl-apis/api_GL.c b/src/gallium/targets/egl-apis/api_GL.c new file mode 100644 index 00000000000..6d172745c01 --- /dev/null +++ b/src/gallium/targets/egl-apis/api_GL.c @@ -0,0 +1,7 @@ +#include "state_tracker/st_gl_api.h" + +PUBLIC struct st_api * +st_api_create_OpenGL() +{ + return st_gl_api_create(); +} diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/targets/egl-apis/api_GLESv1_CM.c index 825fdac2150..825fdac2150 100644 --- a/src/gallium/state_trackers/es/st_es1.c +++ b/src/gallium/targets/egl-apis/api_GLESv1_CM.c diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/targets/egl-apis/api_GLESv2.c index 5c773aaf93b..5c773aaf93b 100644 --- a/src/gallium/state_trackers/es/st_es2.c +++ b/src/gallium/targets/egl-apis/api_GLESv2.c diff --git a/src/gallium/targets/egl-apis/api_OpenVG.c b/src/gallium/targets/egl-apis/api_OpenVG.c new file mode 100644 index 00000000000..f85ebea8a1c --- /dev/null +++ b/src/gallium/targets/egl-apis/api_OpenVG.c @@ -0,0 +1,8 @@ +#include "state_tracker/st_api.h" +#include "vg_api.h" + +PUBLIC struct st_api * +st_api_create_OpenVG() +{ + return (struct st_api *) vg_api_get(); +} diff --git a/src/gallium/targets/egl-i915/Makefile b/src/gallium/targets/egl-i915/Makefile index 02258fb69a4..a4b41842ff7 100644 --- a/src/gallium/targets/egl-i915/Makefile +++ b/src/gallium/targets/egl-i915/Makefile @@ -8,6 +8,7 @@ EGL_DRIVER_LIBS = -ldrm_intel EGL_DRIVER_PIPES = \ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/i915/libi915.a include ../Makefile.egl diff --git a/src/gallium/targets/egl-i965/Makefile b/src/gallium/targets/egl-i965/Makefile index fad56ef5554..d4730824a5b 100644 --- a/src/gallium/targets/egl-i965/Makefile +++ b/src/gallium/targets/egl-i965/Makefile @@ -8,6 +8,7 @@ EGL_DRIVER_LIBS = -ldrm_intel EGL_DRIVER_PIPES = \ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/i965/libi965.a \ $(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \ diff --git a/src/gallium/targets/egl-radeon/Makefile b/src/gallium/targets/egl-radeon/Makefile index 8daadb59791..8fcca268265 100644 --- a/src/gallium/targets/egl-radeon/Makefile +++ b/src/gallium/targets/egl-radeon/Makefile @@ -8,6 +8,7 @@ EGL_DRIVER_LIBS = -ldrm_radeon EGL_DRIVER_PIPES = \ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/r300/libr300.a include ../Makefile.egl diff --git a/src/gallium/targets/egl-vmwgfx/Makefile b/src/gallium/targets/egl-vmwgfx/Makefile index 5f9385f42b0..a9f6874b981 100644 --- a/src/gallium/targets/egl-vmwgfx/Makefile +++ b/src/gallium/targets/egl-vmwgfx/Makefile @@ -8,6 +8,7 @@ EGL_DRIVER_LIBS = EGL_DRIVER_PIPES = \ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/svga/libsvga.a include ../Makefile.egl diff --git a/src/gallium/targets/graw-null/SConscript b/src/gallium/targets/graw-null/SConscript new file mode 100644 index 00000000000..106dcd9a835 --- /dev/null +++ b/src/gallium/targets/graw-null/SConscript @@ -0,0 +1,57 @@ +####################################################################### +# SConscript for xlib winsys + +Import('*') + +env = env.Clone() + +env.Prepend(LIBS = [ + ws_null, + trace, + rbug, + identity, +# gallium, +]) + +env.Append(CPPPATH = [ + '#src/gallium/drivers', +]) + +if env['platform'] == 'windows': + # For trace + env.Append(LIBS = [ + 'ws2_32', + ]) + +sources = [ + 'graw_null.c', +] + +if True: + env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') + env.Prepend(LIBS = [softpipe]) + +if env['llvm']: + env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') + env.Tool('udis86') + env.Prepend(LIBS = [llvmpipe]) + +# Need this for trace, identity drivers referenced by +# gallium_wrap_screen(). +# +env.Prepend(LIBS = [gallium]) + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +graw = env.SharedLibrary( + target ='graw', + source = sources, +) + +env.InstallSharedLibrary(graw, version=(1, 0)) + +if env['platform'] == 'windows': + graw = env.FindIxes(graw, 'LIBPREFIX', 'LIBSUFFIX') +else: + graw = env.FindIxes(graw, 'SHLIBPREFIX', 'SHLIBSUFFIX') + +Export('graw') diff --git a/src/gallium/targets/graw-null/graw_null.c b/src/gallium/targets/graw-null/graw_null.c new file mode 100644 index 00000000000..6965f5873e4 --- /dev/null +++ b/src/gallium/targets/graw-null/graw_null.c @@ -0,0 +1,81 @@ +#include "pipe/p_compiler.h" +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "target-helpers/wrap_screen.h" +#include "sw/null/null_sw_winsys.h" + +#ifdef GALLIUM_SOFTPIPE +#include "softpipe/sp_public.h" +#endif + +#ifdef GALLIUM_LLVMPIPE +#include "llvmpipe/lp_public.h" +#endif + +/* Haven't figured out a decent way to build the helper code yet - + * #include it here temporarily. + */ +#include "sw/sw_public.h" +#include "sw/sw.c" + +#include <stdio.h> + + +struct pipe_screen * +graw_init( void ) +{ + const char *default_driver; + const char *driver; + struct pipe_screen *screen = NULL; + struct sw_winsys *winsys = NULL; + + /* Create the underlying winsys, which performs presents to Xlib + * drawables: + */ + winsys = null_sw_create(); + if (winsys == NULL) + return NULL; + +#if defined(GALLIUM_LLVMPIPE) + default_driver = "llvmpipe"; +#elif defined(GALLIUM_SOFTPIPE) + default_driver = "softpipe"; +#else + default_driver = ""; +#endif + + driver = debug_get_option("GALLIUM_DRIVER", default_driver); + +#if defined(GALLIUM_LLVMPIPE) + if (screen == NULL && strcmp(driver, "llvmpipe") == 0) + screen = llvmpipe_create_screen( winsys ); +#endif + +#if defined(GALLIUM_SOFTPIPE) + if (screen == NULL) + screen = softpipe_create_screen( winsys ); +#endif + + /* Inject any wrapping layers we want to here: + */ + return gallium_wrap_screen( screen ); +} + + +void * +graw_create_window( int x, + int y, + unsigned width, + unsigned height, + enum pipe_format format ) +{ + static int dummy; + return &dummy; +} + + +void +graw_destroy_window( void *window ) +{ +} + diff --git a/src/gallium/targets/graw-xlib/SConscript b/src/gallium/targets/graw-xlib/SConscript index 979252b22d7..40332fa4e14 100644 --- a/src/gallium/targets/graw-xlib/SConscript +++ b/src/gallium/targets/graw-xlib/SConscript @@ -8,9 +8,12 @@ if env['platform'] != 'linux': env = env.Clone() +env.Tool('x11') + env.Prepend(LIBS = [ ws_xlib, trace, + rbug, identity, # gallium, ]) @@ -22,6 +25,7 @@ env.Append(CPPPATH = [ sources = [ 'graw_xlib.c', + 'graw_util.c', ] if True: diff --git a/src/gallium/targets/graw-xlib/graw.h b/src/gallium/targets/graw-xlib/graw.h deleted file mode 100644 index a58e18e4739..00000000000 --- a/src/gallium/targets/graw-xlib/graw.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef GALLIUM_RAW_H -#define GALLIUM_RAW_H - -/* This is an API for exercising gallium functionality in a - * platform-neutral fashion. Whatever platform integration is - * necessary to implement this interface is orchestrated by the - * individual target building this entity. - * - * For instance, the graw-xlib target includes code to implent these - * interfaces on top of the X window system. - * - * Programs using this interface may additionally benefit from some of - * the utilities currently in the libgallium.a library, especially - * those for parsing text representations of TGSI shaders. - */ - -#include "pipe/p_format.h" - -struct pipe_screen; - -struct pipe_screen *graw_init( void ); - -/* Returns a handle to be used with flush_frontbuffer()/present(). - * - * Query format support with screen::is_format_supported and usage - * XXX. - */ -void *graw_create_window( int x, - int y, - unsigned width, - unsigned height, - enum pipe_format format ); - -void graw_destroy_window( void *handle ); - -#endif diff --git a/src/gallium/targets/graw-xlib/graw_util.c b/src/gallium/targets/graw-xlib/graw_util.c new file mode 100644 index 00000000000..147532cdee1 --- /dev/null +++ b/src/gallium/targets/graw-xlib/graw_util.c @@ -0,0 +1,36 @@ + +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" +#include "tgsi/tgsi_text.h" +#include "util/u_memory.h" +#include "state_tracker/graw.h" + + +/* Helper functions. These are the same for all graw implementations. + */ +void *graw_parse_vertex_shader(struct pipe_context *pipe, + const char *text) +{ + struct tgsi_token tokens[1024]; + struct pipe_shader_state state; + + if (!tgsi_text_translate(text, tokens, Elements(tokens))) + return NULL; + + state.tokens = tokens; + return pipe->create_vs_state(pipe, &state); +} + +void *graw_parse_fragment_shader(struct pipe_context *pipe, + const char *text) +{ + struct tgsi_token tokens[1024]; + struct pipe_shader_state state; + + if (!tgsi_text_translate(text, tokens, Elements(tokens))) + return NULL; + + state.tokens = tokens; + return pipe->create_fs_state(pipe, &state); +} + diff --git a/src/gallium/targets/graw-xlib/graw_xlib.c b/src/gallium/targets/graw-xlib/graw_xlib.c index fb8ef9d78b6..41120ba3c70 100644 --- a/src/gallium/targets/graw-xlib/graw_xlib.c +++ b/src/gallium/targets/graw-xlib/graw_xlib.c @@ -1,4 +1,5 @@ #include "pipe/p_compiler.h" +#include "pipe/p_context.h" #include "util/u_debug.h" #include "util/u_memory.h" #include "target-helpers/wrap_screen.h" @@ -18,7 +19,7 @@ #include "sw/sw_public.h" #include "sw/sw.c" -#include "graw.h" +#include "state_tracker/graw.h" #include <X11/Xlib.h> #include <X11/Xlibint.h> @@ -27,21 +28,18 @@ static struct { Display *display; + void (*draw)(void); } graw; -struct pipe_screen * -graw_init( void ) +static struct pipe_screen * +graw_create_screen( void ) { const char *default_driver; const char *driver; struct pipe_screen *screen = NULL; struct sw_winsys *winsys = NULL; - graw.display = XOpenDisplay(NULL); - if (graw.display == NULL) - return NULL; - /* Create the underlying winsys, which performs presents to Xlib * drawables: */ @@ -78,14 +76,16 @@ graw_init( void ) -void * -graw_create_window( int x, - int y, - unsigned width, - unsigned height, - enum pipe_format format ) +struct pipe_screen * +graw_create_window_and_screen( int x, + int y, + unsigned width, + unsigned height, + enum pipe_format format, + void **handle) { - struct xlib_drawable *handle = NULL; + struct pipe_screen *screen = NULL; + struct xlib_drawable *xlib_handle = NULL; XSetWindowAttributes attr; Window root; Window win = 0; @@ -94,6 +94,9 @@ graw_create_window( int x, int n; int scrnum; + graw.display = XOpenDisplay(NULL); + if (graw.display == NULL) + return NULL; scrnum = DefaultScreen( graw.display ); root = RootWindow( graw.display, scrnum ); @@ -105,8 +108,8 @@ graw_create_window( int x, if (graw.display == NULL) goto fail; - handle = CALLOC_STRUCT(xlib_drawable); - if (handle == NULL) + xlib_handle = CALLOC_STRUCT(xlib_drawable); + if (xlib_handle == NULL) goto fail; @@ -148,7 +151,6 @@ graw_create_window( int x, None, (char **)NULL, 0, &sizehints); } - XFree(visinfo); XMapWindow(graw.display, win); while (1) { XEvent e; @@ -158,14 +160,27 @@ graw_create_window( int x, } } - handle->visual = visinfo->visual; - handle->drawable = (Drawable)win; - handle->depth = visinfo->depth; - return (void *)handle; + xlib_handle->visual = visinfo->visual; + xlib_handle->drawable = (Drawable)win; + xlib_handle->depth = visinfo->depth; + *handle = (void *)xlib_handle; + + screen = graw_create_screen(); + if (screen == NULL) + goto fail; -fail: - FREE(handle); XFree(visinfo); + return screen; + +fail: + if (screen) + screen->destroy(screen); + + if (xlib_handle) + FREE(xlib_handle); + + if (visinfo) + XFree(visinfo); if (win) XDestroyWindow(graw.display, win); @@ -174,8 +189,19 @@ fail: } +void +graw_set_display_func( void (*draw)( void ) ) +{ + graw.draw = draw; +} + void -graw_destroy_window( void *xlib_drawable ) +graw_main_loop( void ) { + int i; + for (i = 0; i < 10; i++) { + graw.draw(); + sleep(1); + } } diff --git a/src/gallium/targets/libgl-gdi/SConscript b/src/gallium/targets/libgl-gdi/SConscript index 2a55c7a5776..144084f74f8 100644 --- a/src/gallium/targets/libgl-gdi/SConscript +++ b/src/gallium/targets/libgl-gdi/SConscript @@ -35,7 +35,7 @@ if env['platform'] == 'windows': else: sources += ['#src/gallium/state_trackers/wgl/opengl32.def'] - drivers += [trace] + drivers += [trace, rbug] env['no_import_lib'] = 1 diff --git a/src/gallium/targets/libgl-xlib/Makefile b/src/gallium/targets/libgl-xlib/Makefile index add3a273945..b173ceb994a 100644 --- a/src/gallium/targets/libgl-xlib/Makefile +++ b/src/gallium/targets/libgl-xlib/Makefile @@ -15,6 +15,7 @@ GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) INCLUDE_DIRS = \ -I$(TOP)/include \ + -I$(TOP)/src/mapi \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/gallium/include \ @@ -41,8 +42,9 @@ LIBS = \ $(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \ $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/identity/libidentity.a \ - $(TOP)/src/mesa/libglapi.a \ + $(TOP)/src/mapi/glapi/libglapi.a \ $(TOP)/src/mesa/libmesagallium.a \ $(GALLIUM_AUXILIARIES) \ $(CELL_SPU_LIB) \ diff --git a/src/gallium/targets/libgl-xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript index 63e4531263a..78703fd096d 100644 --- a/src/gallium/targets/libgl-xlib/SConscript +++ b/src/gallium/targets/libgl-xlib/SConscript @@ -17,6 +17,7 @@ if env['dri']: env = env.Clone() env.Append(CPPPATH = [ + '#/src/mapi', '#/src/mesa', '#/src/mesa/main', '#src/gallium/state_trackers/glx/xlib', @@ -28,6 +29,7 @@ env.Prepend(LIBS = [ st_xlib, ws_xlib, trace, + rbug, identity, glapi, mesa, diff --git a/src/gallium/targets/xorg-i915/Makefile b/src/gallium/targets/xorg-i915/Makefile index 52a9e97b409..2f2439c6d42 100644 --- a/src/gallium/targets/xorg-i915/Makefile +++ b/src/gallium/targets/xorg-i915/Makefile @@ -20,6 +20,7 @@ LIBS = \ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \ $(TOP)/src/gallium/drivers/i915/libi915.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(GALLIUM_AUXILIARIES) diff --git a/src/gallium/targets/xorg-i965/Makefile b/src/gallium/targets/xorg-i965/Makefile index 104a1434a84..0aab30ff3c6 100644 --- a/src/gallium/targets/xorg-i965/Makefile +++ b/src/gallium/targets/xorg-i965/Makefile @@ -20,6 +20,7 @@ LIBS = \ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \ $(TOP)/src/gallium/drivers/i965/libi965.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(GALLIUM_AUXILIARIES) diff --git a/src/gallium/targets/xorg-radeon/Makefile b/src/gallium/targets/xorg-radeon/Makefile index cd32914c0d3..85aa711a4f3 100644 --- a/src/gallium/targets/xorg-radeon/Makefile +++ b/src/gallium/targets/xorg-radeon/Makefile @@ -20,6 +20,7 @@ LIBS = \ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ $(TOP)/src/gallium/drivers/r300/libr300.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(GALLIUM_AUXILIARIES) diff --git a/src/gallium/targets/xorg-vmwgfx/Makefile b/src/gallium/targets/xorg-vmwgfx/Makefile index 12bc307ef9b..e334d889957 100644 --- a/src/gallium/targets/xorg-vmwgfx/Makefile +++ b/src/gallium/targets/xorg-vmwgfx/Makefile @@ -22,6 +22,7 @@ LIBS = \ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/svga/libsvga.a \ $(GALLIUM_AUXILIARIES) diff --git a/src/gallium/targets/xorg-vmwgfx/SConscript b/src/gallium/targets/xorg-vmwgfx/SConscript index b63ab99e050..d5edbebae87 100644 --- a/src/gallium/targets/xorg-vmwgfx/SConscript +++ b/src/gallium/targets/xorg-vmwgfx/SConscript @@ -39,6 +39,7 @@ if env['platform'] == 'linux': env.Prepend(LIBS = [ trace, + rbug, st_xorg, svgadrm, svga, diff --git a/src/gallium/tests/graw/SConscript b/src/gallium/tests/graw/SConscript new file mode 100644 index 00000000000..7eab973db31 --- /dev/null +++ b/src/gallium/tests/graw/SConscript @@ -0,0 +1,25 @@ +Import('*') + +try: + graw +except NameError: + print 'warning: graw library not avaiable: skipping build of graw test' + Return() + +env = env.Clone() + +env.Prepend(LIBPATH = [graw.dir]) +env.Prepend(LIBS = ['graw']) + +progs = [ + 'clear', + 'tri', + 'quad-tex', +] + +for prog in progs: + env.Program( + target = prog, + source = prog + '.c', + ) + diff --git a/src/gallium/tests/raw/clear.c b/src/gallium/tests/graw/clear.c index 706e3be3728..28c986eee64 100644 --- a/src/gallium/tests/raw/clear.c +++ b/src/gallium/tests/graw/clear.c @@ -7,9 +7,9 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include <unistd.h> /* for sleep() */ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "os/os_time.h" /* os_time_sleep() */ enum pipe_format formats[] = { PIPE_FORMAT_R8G8B8A8_UNORM, @@ -20,33 +20,58 @@ enum pipe_format formats[] = { static const int WIDTH = 300; static const int HEIGHT = 300; -int main( int argc, char *argv[] ) +struct pipe_screen *screen; +struct pipe_context *ctx; +struct pipe_surface *surf; +static void *window = NULL; + +static void draw( void ) { - struct pipe_screen *screen; - struct pipe_context *pipe; - struct pipe_surface *surf; - struct pipe_framebuffer_state fb; - struct pipe_texture *tex, templat; - void *window = NULL; float clear_color[4] = {1,0,1,1}; - int i; - screen = graw_init(); - if (screen == NULL) - exit(1); + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource *tex, templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ for (i = 0; window == NULL && formats[i] != PIPE_FORMAT_NONE; i++) { - window = graw_create_window(0,0,300,300, formats[i]); + screen = graw_create_window_and_screen(0,0,300,300, + formats[i], + &window); } - if (window == NULL) exit(2); - pipe = screen->context_create(screen, NULL); - if (pipe == NULL) + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) exit(3); templat.target = PIPE_TEXTURE_2D; @@ -57,10 +82,10 @@ int main( int argc, char *argv[] ) templat.last_level = 0; templat.nr_samples = 1; templat.bind = (PIPE_BIND_RENDER_TARGET | - PIPE_BIND_DISPLAY_TARGET); + PIPE_BIND_DISPLAY_TARGET); tex = screen->resource_create(screen, - &templat); + &templat); if (tex == NULL) exit(4); @@ -76,20 +101,16 @@ int main( int argc, char *argv[] ) fb.height = HEIGHT; fb.cbufs[0] = surf; - pipe->set_framebuffer_state(pipe, &fb); - pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0, 0); - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->set_framebuffer_state(ctx, &fb); +} - /* At the moment, libgraw includes/makes available all the symbols - * from gallium/auxiliary, including these debug helpers. Will - * eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - */ - if (0) - debug_dump_surface_bmp(pipe, "result.bmp", surf); - screen->flush_frontbuffer(screen, surf, window); - sleep(100); +int main( int argc, char *argv[] ) +{ + init(); + + graw_set_display_func( draw ); + graw_main_loop(); return 0; } diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c new file mode 100644 index 00000000000..225cbfc8e88 --- /dev/null +++ b/src/gallium/tests/graw/quad-tex.c @@ -0,0 +1,403 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include <unistd.h> /* for sleep() */ + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_inlines.h" +#include "util/u_memory.h" /* Offset() */ +#include "util/u_box.h" + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 300; +static const int HEIGHT = 300; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_resource *rttex = NULL; +static struct pipe_resource *samptex = NULL; +static struct pipe_surface *surf = NULL; +static struct pipe_sampler_view *sv = NULL; +static void *sampler = NULL; +static void *window = NULL; + +struct vertex { + float position[4]; + float color[4]; +}; + +static struct vertex vertices[] = +{ + { { 0.9, -0.9, 0.0, 1.0 }, + { 1, 0, 0, 1 } }, + + { { 0.9, 0.9, 0.0, 1.0 }, + { 1, 1, 0, 1 } }, + + { {-0.9, 0.9, 0.0, 1.0 }, + { 0, 1, 0, 1 } }, + + { {-0.9, -0.9, 0.0, 1.0 }, + { 0, 0, 0, 1 } }, +}; + + + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[2]; + struct pipe_vertex_buffer vbuf; + void *handle; + + memset(ve, 0, sizeof ve); + + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + handle = ctx->create_vertex_elements_state(ctx, 2, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + + vbuf.stride = sizeof( struct vertex ); + vbuf.max_index = sizeof(vertices) / vbuf.stride; + vbuf.buffer_offset = 0; + vbuf.buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + + ctx->set_vertex_buffers(ctx, 1, &vbuf); +} + +static void set_vertex_shader( void ) +{ + void *handle; + const char *text = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], GENERIC[0]\n" + " 0: MOV OUT[1], IN[1]\n" + " 1: MOV OUT[0], IN[0]\n" + " 2: END\n"; + + handle = graw_parse_vertex_shader(ctx, text); + ctx->bind_vs_state(ctx, handle); +} + +static void set_fragment_shader( void ) +{ + void *handle; + const char *text = + "FRAG\n" + "DCL IN[0], GENERIC[0], PERSPECTIVE\n" + "DCL OUT[0], COLOR\n" + "DCL TEMP[0]\n" + "DCL SAMP[0]\n" + " 0: TXP TEMP[0], IN[0], SAMP[0], 2D\n" + " 1: MOV OUT[0], TEMP[0]\n" + " 2: END\n"; + + handle = graw_parse_fragment_shader(ctx, text); + ctx->bind_fs_state(ctx, handle); +} + + +static void draw( void ) +{ + float clear_color[4] = {.5,.5,.5,1}; + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + ctx->draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} + +#define SIZE 16 + +static void init_tex( void ) +{ + struct pipe_sampler_view sv_template; + struct pipe_sampler_state sampler_desc; + struct pipe_resource templat; + struct pipe_box box; + ubyte tex2d[SIZE][SIZE][4]; + int s, t; + +#if (SIZE != 2) + for (s = 0; s < SIZE; s++) { + for (t = 0; t < SIZE; t++) { + if (0) { + int x = (s ^ t) & 1; + tex2d[t][s][0] = (x) ? 0 : 63; + tex2d[t][s][1] = (x) ? 0 : 128; + tex2d[t][s][2] = 0; + tex2d[t][s][3] = 0xff; + } + else { + int x = ((s ^ t) >> 2) & 1; + tex2d[t][s][0] = s*255/(SIZE-1); + tex2d[t][s][1] = t*255/(SIZE-1); + tex2d[t][s][2] = (x) ? 0 : 128; + tex2d[t][s][3] = 0xff; + } + } + } +#else + tex2d[0][0][0] = 0; + tex2d[0][0][1] = 255; + tex2d[0][0][2] = 255; + tex2d[0][0][3] = 0; + + tex2d[0][1][0] = 0; + tex2d[0][1][1] = 0; + tex2d[0][1][2] = 255; + tex2d[0][1][3] = 255; + + tex2d[1][0][0] = 255; + tex2d[1][0][1] = 255; + tex2d[1][0][2] = 0; + tex2d[1][0][3] = 255; + + tex2d[1][1][0] = 255; + tex2d[1][1][1] = 0; + tex2d[1][1][2] = 0; + tex2d[1][1][3] = 255; +#endif + + templat.target = PIPE_TEXTURE_2D; + templat.format = PIPE_FORMAT_B8G8R8A8_UNORM; + templat.width0 = SIZE; + templat.height0 = SIZE; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = PIPE_BIND_SAMPLER_VIEW; + + + samptex = screen->resource_create(screen, + &templat); + if (samptex == NULL) + exit(4); + + u_box_2d(0,0,SIZE,SIZE, &box); + + ctx->transfer_inline_write(ctx, + samptex, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + tex2d, + sizeof tex2d[0], + sizeof tex2d); + + /* Possibly read back & compare against original data: + */ + if (0) + { + struct pipe_transfer *t; + uint32_t *ptr; + t = pipe_get_transfer(ctx, samptex, + 0, 0, 0, /* face, level, zslice */ + PIPE_TRANSFER_READ, + 0, 0, SIZE, SIZE); /* x, y, width, height */ + + ptr = ctx->transfer_map(ctx, t); + + if (memcmp(ptr, tex2d, sizeof tex2d) != 0) { + assert(0); + exit(9); + } + + ctx->transfer_unmap(ctx, t); + + ctx->transfer_destroy(ctx, t); + } + + memset(&sv_template, 0, sizeof sv_template); + sv_template.format = samptex->format; + sv_template.texture = samptex; + sv_template.first_level = 0; + sv_template.last_level = 0; + sv_template.swizzle_r = 0; + sv_template.swizzle_g = 1; + sv_template.swizzle_b = 2; + sv_template.swizzle_a = 3; + sv = ctx->create_sampler_view(ctx, samptex, &sv_template); + if (sv == NULL) + exit(5); + + ctx->set_fragment_sampler_views(ctx, 1, &sv); + + + memset(&sampler_desc, 0, sizeof sampler_desc); + sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler_desc.compare_func = 0; + sampler_desc.normalized_coords = 1; + sampler_desc.max_anisotropy = 0; + + sampler = ctx->create_sampler_state(ctx, &sampler_desc); + if (sampler == NULL) + exit(6); + + ctx->bind_fragment_sampler_states(ctx, 1, &sampler); + +} + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,300,300, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + rttex = screen->resource_create(screen, + &templat); + if (rttex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, rttex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + + init_tex(); + + set_vertices(); + set_vertex_shader(); + set_fragment_shader(); +} + + +int main( int argc, char *argv[] ) +{ + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/raw/SConscript b/src/gallium/tests/raw/SConscript deleted file mode 100644 index 073b97951e7..00000000000 --- a/src/gallium/tests/raw/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -Import('*') - -env = env.Clone() - -env.Prepend(LIBPATH = [graw.dir]) -env.Prepend(LIBS = [graw.name]) - -progs = [ - 'clear' -] - -for prog in progs: - env.Program( - target = prog, - source = prog + '.c', - ) - diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c index 522ff3cb42d..93f24876cbb 100644 --- a/src/gallium/tests/trivial/quad-tex.c +++ b/src/gallium/tests/trivial/quad-tex.c @@ -201,8 +201,7 @@ static void init_prog(struct program *p) /* rasterizer */ memset(&p->rasterizer, 0, sizeof(p->rasterizer)); - p->rasterizer.front_winding = PIPE_WINDING_CW; - p->rasterizer.cull_mode = PIPE_WINDING_NONE; + p->rasterizer.cull_face = PIPE_FACE_NONE; p->rasterizer.gl_rasterization_rules = 1; /* sampler */ diff --git a/src/gallium/tests/trivial/tri.c b/src/gallium/tests/trivial/tri.c index 48305240a4b..7823c27727d 100644 --- a/src/gallium/tests/trivial/tri.c +++ b/src/gallium/tests/trivial/tri.c @@ -151,8 +151,7 @@ static void init_prog(struct program *p) /* rasterizer */ memset(&p->rasterizer, 0, sizeof(p->rasterizer)); - p->rasterizer.front_winding = PIPE_WINDING_CW; - p->rasterizer.cull_mode = PIPE_WINDING_NONE; + p->rasterizer.cull_face = PIPE_FACE_NONE; p->rasterizer.gl_rasterization_rules = 1; /* drawing destination */ diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 2013ee97c1c..330b1ab834c 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,5 +1,10 @@ Import('*') + +SConscript([ + 'sw/wrapper/SConscript', +]) + if 'xlib' in env['winsys']: SConscript([ 'sw/xlib/SConscript', @@ -12,6 +17,7 @@ if 'gdi' in env['winsys']: if env['dri']: SConscript([ + 'sw/drm/SConscript', 'sw/dri/SConscript', ]) diff --git a/src/gallium/winsys/i965/drm/i965_drm_buffer.c b/src/gallium/winsys/i965/drm/i965_drm_buffer.c index 33a17496b2b..fb5e50ce810 100644 --- a/src/gallium/winsys/i965/drm/i965_drm_buffer.c +++ b/src/gallium/winsys/i965/drm/i965_drm_buffer.c @@ -463,7 +463,7 @@ i965_libdrm_bo_flush_range(struct brw_winsys_buffer *buffer, brw_dump_data( idws->id, buf->data_type, buf->bo->offset + offset, - buf->bo->virtual + offset, + (char*)buf->bo->virtual + offset, length ); } diff --git a/src/gallium/winsys/i965/xlib/Makefile b/src/gallium/winsys/i965/xlib/Makefile index 3730db6997e..cc8249395c5 100644 --- a/src/gallium/winsys/i965/xlib/Makefile +++ b/src/gallium/winsys/i965/xlib/Makefile @@ -38,7 +38,7 @@ LIBS = \ $(TOP)/src/gallium/drivers/i965/libi965.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \ - $(TOP)/src/mesa/libglapi.a \ + $(TOP)/src/mapi/glapi/libglapi.a \ $(TOP)/src/mesa/libmesagallium.a \ $(GALLIUM_AUXILIARIES) diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h index b48b6358e01..b9ecf9ded07 100644 --- a/src/gallium/winsys/radeon/drm/radeon_buffer.h +++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h @@ -88,4 +88,7 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf, boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf, enum r300_reference_domain domain); + +void radeon_drm_bufmgr_wait(struct pb_buffer *_buf); + #endif diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c index b8366498922..a05205da886 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c @@ -419,3 +419,10 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr) make_empty_list(&mgr->buffer_map_list); } + +void radeon_drm_bufmgr_wait(struct pb_buffer *_buf) +{ + struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + + radeon_bo_wait(buf->bo); +} diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c index fb779e4033b..e188f7e7ccd 100644 --- a/src/gallium/winsys/radeon/drm/radeon_r300.c +++ b/src/gallium/winsys/radeon/drm/radeon_r300.c @@ -86,7 +86,7 @@ static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws, unsigned usage) { struct pb_buffer *_buf = radeon_pb_buffer(buf); - + return pb_map(_buf, usage); } @@ -98,6 +98,13 @@ static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws, pb_unmap(_buf); } +static void radeon_r300_winsys_buffer_wait(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + radeon_drm_bufmgr_wait(_buf); +} + static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, struct r300_winsys_buffer **pdst, struct r300_winsys_buffer *src) @@ -343,6 +350,7 @@ radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) ws->base.buffer_get_tiling = radeon_r300_winsys_buffer_get_tiling; ws->base.buffer_map = radeon_r300_winsys_buffer_map; ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap; + ws->base.buffer_wait = radeon_r300_winsys_buffer_wait; ws->base.buffer_reference = radeon_r300_winsys_buffer_reference; ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle; ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle; diff --git a/src/gallium/winsys/svga/drm/SConscript b/src/gallium/winsys/svga/drm/SConscript index edaf9458bee..3ad4c725727 100644 --- a/src/gallium/winsys/svga/drm/SConscript +++ b/src/gallium/winsys/svga/drm/SConscript @@ -2,6 +2,8 @@ Import('*') env = env.Clone() +env.ParseConfig('pkg-config --cflags libdrm') + if env['gcc']: env.Append(CCFLAGS = ['-fvisibility=hidden']) env.Append(CPPDEFINES = [ diff --git a/src/gallium/winsys/sw/drm/SConscript b/src/gallium/winsys/sw/drm/SConscript new file mode 100644 index 00000000000..15a2e05d5af --- /dev/null +++ b/src/gallium/winsys/sw/drm/SConscript @@ -0,0 +1,21 @@ +####################################################################### +# SConscript for xlib winsys + + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/gallium/include', + '#/src/gallium/auxiliary', + '#/src/gallium/drivers', +]) + +ws_drm = env.ConvenienceLibrary( + target = 'ws_drm', + source = [ + 'sw_drm_api.c', + ] +) +Export('ws_drm') diff --git a/src/gallium/winsys/sw/wrapper/SConscript b/src/gallium/winsys/sw/wrapper/SConscript new file mode 100644 index 00000000000..4c60488df0b --- /dev/null +++ b/src/gallium/winsys/sw/wrapper/SConscript @@ -0,0 +1,21 @@ +####################################################################### +# SConscript for xlib winsys + + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/gallium/include', + '#/src/gallium/auxiliary', + '#/src/gallium/drivers', +]) + +ws_wrapper = env.ConvenienceLibrary( + target = 'ws_wrapper', + source = [ + 'wrapper_sw_winsys.c', + ] +) +Export('ws_wrapper') diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c index d4d4270eb86..b997abda9b0 100644 --- a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c +++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c @@ -145,6 +145,7 @@ wsw_dt_create(struct sw_winsys *ws, * XXX Why don't we just get the template. */ memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; templ.width0 = width; templ.height0 = height; templ.format = format; @@ -175,6 +176,18 @@ wsw_dt_from_handle(struct sw_winsys *ws, return wsw_dt_wrap_texture(wsw, tex, stride); } +static boolean +wsw_dt_get_handle(struct sw_winsys *ws, + struct sw_displaytarget *dt, + struct winsys_handle *whandle) +{ + struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws); + struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt); + struct pipe_resource *tex = wdt->tex; + + return wsw->screen->resource_get_handle(wsw->screen, tex, whandle); +} + static void * wsw_dt_map(struct sw_winsys *ws, struct sw_displaytarget *dt, @@ -267,6 +280,7 @@ wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen) wsw->base.displaytarget_create = wsw_dt_create; wsw->base.displaytarget_from_handle = wsw_dt_from_handle; + wsw->base.displaytarget_get_handle = wsw_dt_get_handle; wsw->base.displaytarget_map = wsw_dt_map; wsw->base.displaytarget_unmap = wsw_dt_unmap; wsw->base.displaytarget_destroy = wsw_dt_destroy; |