diff options
Diffstat (limited to 'src/gallium')
150 files changed, 4790 insertions, 5278 deletions
diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 98487d43bd..2e3da436cd 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -31,8 +31,8 @@ INCLUDES = \ default: depend lib$(LIBNAME).a -lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template - $(MKLIB) -o $(LIBNAME) -static $(OBJECTS) +lib$(LIBNAME).a: $(OBJECTS) $(EXTRA_OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template + $(MKLIB) -o $(LIBNAME) -static $(OBJECTS) $(EXTRA_OBJECTS) depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) rm -f depend diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 2e3f5b2fc0..1c6d657297 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -158,6 +158,60 @@ static void do_triangle( struct draw_context *draw, +#define QUAD(i0,i1,i2,i3) \ + do_triangle( draw, \ + ( DRAW_PIPE_RESET_STIPPLE | \ + DRAW_PIPE_EDGE_FLAG_0 | \ + DRAW_PIPE_EDGE_FLAG_2 ), \ + verts + stride * elts[i0], \ + verts + stride * elts[i1], \ + verts + stride * elts[i3]); \ + do_triangle( draw, \ + ( DRAW_PIPE_EDGE_FLAG_0 | \ + DRAW_PIPE_EDGE_FLAG_1 ), \ + verts + stride * elts[i1], \ + verts + stride * elts[i2], \ + verts + stride * elts[i3]) + +#define TRIANGLE(flags,i0,i1,i2) \ + do_triangle( draw, \ + elts[i0], /* flags */ \ + verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * elts[i1], \ + verts + stride * elts[i2]) + +#define LINE(flags,i0,i1) \ + do_line( draw, \ + elts[i0], \ + verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * elts[i1]) + +#define POINT(i0) \ + do_point( draw, \ + verts + stride * elts[i0] ) + +#define FUNC pipe_run +#define ARGS \ + struct draw_context *draw, \ + unsigned prim, \ + struct vertex_header *vertices, \ + unsigned stride, \ + const ushort *elts + +#define LOCAL_VARS \ + char *verts = (char *)vertices; \ + boolean flatfirst = (draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); \ + unsigned i; \ + ushort flags + +#define FLUSH + +#include "draw_pt_decompose.h" +#undef ARGS +#undef LOCAL_VARS + + /* Code to run the pipeline on a fairly arbitary collection of vertices. * @@ -178,34 +232,12 @@ void draw_pipeline_run( struct draw_context *draw, unsigned count ) { char *verts = (char *)vertices; - unsigned i; draw->pipeline.verts = verts; draw->pipeline.vertex_stride = stride; draw->pipeline.vertex_count = vertex_count; - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) - do_point( draw, - verts + stride * elts[i] ); - break; - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) - do_line( draw, - elts[i+0], /* flags */ - verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK), - verts + stride * elts[i+1]); - break; - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) - do_triangle( draw, - elts[i+0], /* flags */ - verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK), - verts + stride * elts[i+1], - verts + stride * elts[i+2]); - break; - } + pipe_run(draw, prim, vertices, stride, elts, count); draw->pipeline.verts = NULL; draw->pipeline.vertex_count = 0; diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 30a6d2919d..283502cdf3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -256,7 +256,10 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, uint size = 4; immed = tgsi_default_full_immediate(); immed.Immediate.NrTokens = 1 + size; /* one for the token itself */ - immed.u.Pointer = (void *) value; + immed.u[0].Float = value[0]; + immed.u[1].Float = value[1]; + immed.u[2].Float = value[2]; + immed.u[3].Float = value[3]; ctx->emit_immediate(ctx, &immed); } diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 014d8c7346..7d76a7dbf3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -28,6 +28,30 @@ /* Authors: Keith Whitwell <keith@tungstengraphics.com> */ +/** + * Notes on wide points and sprite mode: + * + * In wide point/sprite mode we effectively need to convert each incoming + * vertex into four outgoing vertices specifying the corners of a quad. + * Since we don't (yet) have geometry shaders, we have to handle this here + * in the draw module. + * + * For sprites, it also means that this is where we have to handle texcoords + * for the vertices of the quad. OpenGL's GL_COORD_REPLACE state specifies + * if/how enabled texcoords are automatically generated for sprites. We pass + * that info through gallium in the pipe_rasterizer_state::sprite_coord_mode + * array. + * + * Additionally, GLSL's gl_PointCoord fragment attribute has to be handled + * here as well. This is basically an additional texture/generic attribute + * that varies .x from 0 to 1 horizontally across the point and varies .y + * vertically from 0 to 1 down the sprite. + * + * With geometry shaders, the state tracker could create a GS to do + * most/all of this. + */ + + #include "util/u_math.h" #include "util/u_memory.h" #include "pipe/p_defines.h" @@ -52,7 +76,7 @@ struct widepoint_stage { int psize_slot; - int point_coord_fs_input; /**< input for pointcoord (and fog) */ + int point_coord_fs_input; /**< input for pointcoord */ }; @@ -64,8 +88,6 @@ widepoint_stage( struct draw_stage *stage ) } - - /** * Set the vertex texcoords for sprite mode. * Coords may be left untouched or set to a right-side-up or upside-down @@ -89,10 +111,12 @@ static void set_texcoords(const struct widepoint_stage *wide, } if (wide->point_coord_fs_input >= 0) { - /* put gl_PointCoord into extra vertex output's zw components */ - uint k = wide->stage.draw->extra_vp_outputs.slot; - v->data[k][2] = tc[0]; - v->data[k][3] = tc[1]; + /* put gl_PointCoord into the extra vertex slot */ + uint slot = wide->stage.draw->extra_vp_outputs.slot; + v->data[slot][0] = tc[0]; + v->data[slot][1] = tc[1]; + v->data[slot][2] = 0.0F; + v->data[slot][3] = 1.0F; } } @@ -182,10 +206,10 @@ static void widepoint_point( struct draw_stage *stage, static int -find_fog_input_attrib(struct draw_context *draw) +find_pntc_input_attrib(struct draw_context *draw) { - /* Scan the fragment program's input decls to find the fogcoord - * attribute. The z/w components will store the point coord. + /* Scan the fragment program's input decls to find the pointcoord + * attribute. The xy components will store the point coord. */ return 0; /* XXX fix this */ } @@ -229,8 +253,8 @@ static void widepoint_first_point( struct draw_stage *stage, } wide->num_texcoords = j; - /* find fragment shader PointCoord/Fog input */ - wide->point_coord_fs_input = find_fog_input_attrib(draw); + /* find fragment shader PointCoord input */ + wide->point_coord_fs_input = find_pntc_input_attrib(draw); /* setup extra vp output (point coord implemented as a texcoord) */ draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 9e37a26c1e..62e04a65f3 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1758,24 +1758,24 @@ emit_instruction( struct aos_compilation *cp, case TGSI_OPCODE_SUB: return emit_SUB(cp, inst); - case TGSI_OPCODE_LERP: + case TGSI_OPCODE_LRP: // return emit_LERP(cp, inst); return FALSE; - case TGSI_OPCODE_FRAC: + case TGSI_OPCODE_FRC: return emit_FRC(cp, inst); case TGSI_OPCODE_CLAMP: // return emit_CLAMP(cp, inst); return FALSE; - case TGSI_OPCODE_FLOOR: + case TGSI_OPCODE_FLR: return emit_FLR(cp, inst); case TGSI_OPCODE_ROUND: return emit_RND(cp, inst); - case TGSI_OPCODE_EXPBASE2: + case TGSI_OPCODE_EX2: #if FAST_MATH return emit_EXPBASE2(cp, inst); #elif 0 @@ -1787,13 +1787,13 @@ emit_instruction( struct aos_compilation *cp, return FALSE; #endif - case TGSI_OPCODE_LOGBASE2: + case TGSI_OPCODE_LG2: return emit_LG2(cp, inst); - case TGSI_OPCODE_POWER: + case TGSI_OPCODE_POW: return emit_POW(cp, inst); - case TGSI_OPCODE_CROSSPRODUCT: + case TGSI_OPCODE_XPD: return emit_XPD(cp, inst); case TGSI_OPCODE_ABS: @@ -1891,8 +1891,9 @@ static boolean note_immediate( struct aos_compilation *cp, unsigned pos = cp->num_immediates++; unsigned j; + assert( imm->Immediate.NrTokens <= 4 + 1 ); for (j = 0; j < imm->Immediate.NrTokens - 1; j++) { - cp->vaos->machine->immediate[pos][j] = imm->u.ImmediateFloat32[j].Float; + cp->vaos->machine->immediate[pos][j] = imm->u[j].Float; } return TRUE; diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 727977bc3a..b3535c0e48 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -119,7 +119,7 @@ draw_create_vs_llvm(struct draw_context *draw, vs->base.create_varient = draw_vs_varient_generic; vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; - vs->machine = &draw->vs.machine; + vs->machine = draw->vs.machine; { struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 2d2af3085e..721b7d2d83 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -128,7 +128,7 @@ void InstructionsSoa::createFunctionMap() m_functionsMap[TGSI_OPCODE_DP4] = "dp4"; m_functionsMap[TGSI_OPCODE_MIN] = "min"; m_functionsMap[TGSI_OPCODE_MAX] = "max"; - m_functionsMap[TGSI_OPCODE_POWER] = "pow"; + m_functionsMap[TGSI_OPCODE_POW] = "pow"; m_functionsMap[TGSI_OPCODE_LIT] = "lit"; m_functionsMap[TGSI_OPCODE_RSQ] = "rsq"; m_functionsMap[TGSI_OPCODE_SLT] = "slt"; @@ -311,7 +311,7 @@ std::vector<llvm::Value*> InstructionsSoa::mul(const std::vector<llvm::Value*> i std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> in1, const std::vector<llvm::Value*> in2) { - llvm::Function *func = function(TGSI_OPCODE_POWER); + llvm::Function *func = function(TGSI_OPCODE_POW); return callBuiltin(func, in1, in2); } diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 5b08200d14..bf84401e11 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -160,10 +160,11 @@ translate_immediate(Storage *storage, { float vec[4]; int i; + assert( imm->Immediate.NrTokens <= 4 + 1 ); for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) { switch (imm->Immediate.DataType) { case TGSI_IMM_FLOAT32: - vec[i] = imm->u.ImmediateFloat32[i].Float; + vec[i] = imm->u[i].Float; break; default: assert(0); @@ -179,10 +180,11 @@ translate_immediateir(StorageSoa *storage, { float vec[4]; int i; + assert( imm->Immediate.NrTokens <= 4 + 1 ); for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) { switch (imm->Immediate.DataType) { case TGSI_IMM_FLOAT32: - vec[i] = imm->u.ImmediateFloat32[i].Float; + vec[i] = imm->u[i].Float; break; default: assert(0); @@ -336,7 +338,7 @@ translate_instruction(llvm::Module *module, out = instr->sub(inputs[0], inputs[1]); } break; - case TGSI_OPCODE_LERP: { + case TGSI_OPCODE_LRP: { out = instr->lerp(inputs[0], inputs[1], inputs[2]); } break; @@ -348,17 +350,11 @@ translate_instruction(llvm::Module *module, out = instr->cnd0(inputs[0], inputs[1], inputs[2]); } break; - case TGSI_OPCODE_DOT2ADD: { + case TGSI_OPCODE_DP2A: { out = instr->dot2add(inputs[0], inputs[1], inputs[2]); } break; - case TGSI_OPCODE_INDEX: - break; - case TGSI_OPCODE_NEGATE: { - out = instr->neg(inputs[0]); - } - break; - case TGSI_OPCODE_FRAC: { + case TGSI_OPCODE_FRC: { out = instr->frc(inputs[0]); } break; @@ -366,30 +362,28 @@ translate_instruction(llvm::Module *module, out = instr->clamp(inputs[0]); } break; - case TGSI_OPCODE_FLOOR: { + case TGSI_OPCODE_FLR: { out = instr->floor(inputs[0]); } break; case TGSI_OPCODE_ROUND: break; - case TGSI_OPCODE_EXPBASE2: { + case TGSI_OPCODE_EX2: { out = instr->ex2(inputs[0]); } break; - case TGSI_OPCODE_LOGBASE2: { + case TGSI_OPCODE_LG2: { out = instr->lg2(inputs[0]); } break; - case TGSI_OPCODE_POWER: { + case TGSI_OPCODE_POW: { out = instr->pow(inputs[0], inputs[1]); } break; - case TGSI_OPCODE_CROSSPRODUCT: { + case TGSI_OPCODE_XPD: { out = instr->cross(inputs[0], inputs[1]); } break; - case TGSI_OPCODE_MULTIPLYMATRIX: - break; case TGSI_OPCODE_ABS: { out = instr->abs(inputs[0]); } @@ -522,7 +516,7 @@ translate_instruction(llvm::Module *module, return; //just update the state } break; - case TGSI_OPCODE_LOOP: + case TGSI_OPCODE_BGNFOR: break; case TGSI_OPCODE_REP: break; @@ -538,7 +532,7 @@ translate_instruction(llvm::Module *module, return; //just update the state } break; - case TGSI_OPCODE_ENDLOOP: + case TGSI_OPCODE_ENDFOR: break; case TGSI_OPCODE_ENDREP: break; @@ -580,7 +574,7 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_ENDPRIM: break; - case TGSI_OPCODE_BGNLOOP2: { + case TGSI_OPCODE_BGNLOOP: { instr->beginLoop(); storage->setCurrentBlock(instr->currentBlock()); return; @@ -593,7 +587,7 @@ translate_instruction(llvm::Module *module, return; } break; - case TGSI_OPCODE_ENDLOOP2: { + case TGSI_OPCODE_ENDLOOP: { instr->endLoop(); storage->setCurrentBlock(instr->currentBlock()); return; @@ -617,14 +611,6 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_NOP: break; - case TGSI_OPCODE_M4X3: - break; - case TGSI_OPCODE_M3X4: - break; - case TGSI_OPCODE_M3X3: - break; - case TGSI_OPCODE_M3X2: - break; case TGSI_OPCODE_CALLNZ: break; case TGSI_OPCODE_IFC: @@ -778,44 +764,38 @@ translate_instructionir(llvm::Module *module, out = instr->sub(inputs[0], inputs[1]); } break; - case TGSI_OPCODE_LERP: { + case TGSI_OPCODE_LRP: { } break; case TGSI_OPCODE_CND: break; case TGSI_OPCODE_CND0: break; - case TGSI_OPCODE_DOT2ADD: + case TGSI_OPCODE_DP2A: break; - case TGSI_OPCODE_INDEX: - break; - case TGSI_OPCODE_NEGATE: - break; - case TGSI_OPCODE_FRAC: { + case TGSI_OPCODE_FRC: { } break; case TGSI_OPCODE_CLAMP: break; - case TGSI_OPCODE_FLOOR: { + case TGSI_OPCODE_FLR: { } break; case TGSI_OPCODE_ROUND: break; - case TGSI_OPCODE_EXPBASE2: { + case TGSI_OPCODE_EX2: { } break; - case TGSI_OPCODE_LOGBASE2: { + case TGSI_OPCODE_LG2: { } break; - case TGSI_OPCODE_POWER: { + case TGSI_OPCODE_POW: { out = instr->pow(inputs[0], inputs[1]); } break; - case TGSI_OPCODE_CROSSPRODUCT: { + case TGSI_OPCODE_XPD: { } break; - case TGSI_OPCODE_MULTIPLYMATRIX: - break; case TGSI_OPCODE_ABS: { out = instr->abs(inputs[0]); } @@ -910,7 +890,7 @@ translate_instructionir(llvm::Module *module, case TGSI_OPCODE_IF: { } break; - case TGSI_OPCODE_LOOP: + case TGSI_OPCODE_BGNFOR: break; case TGSI_OPCODE_REP: break; @@ -920,7 +900,7 @@ translate_instructionir(llvm::Module *module, case TGSI_OPCODE_ENDIF: { } break; - case TGSI_OPCODE_ENDLOOP: + case TGSI_OPCODE_ENDFOR: break; case TGSI_OPCODE_ENDREP: break; @@ -961,13 +941,13 @@ translate_instructionir(llvm::Module *module, break; case TGSI_OPCODE_ENDPRIM: break; - case TGSI_OPCODE_BGNLOOP2: { + case TGSI_OPCODE_BGNLOOP: { } break; case TGSI_OPCODE_BGNSUB: { } break; - case TGSI_OPCODE_ENDLOOP2: { + case TGSI_OPCODE_ENDLOOP: { } break; case TGSI_OPCODE_ENDSUB: { @@ -983,14 +963,6 @@ translate_instructionir(llvm::Module *module, break; case TGSI_OPCODE_NOP: break; - case TGSI_OPCODE_M4X3: - break; - case TGSI_OPCODE_M3X4: - break; - case TGSI_OPCODE_M3X3: - break; - case TGSI_OPCODE_M3X2: - break; case TGSI_OPCODE_NRM4: break; case TGSI_OPCODE_CALLNZ: diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index b4900e8dba..5f0a580b09 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -16,6 +16,7 @@ C_SOURCES = \ tgsi_sse2.c \ tgsi_text.c \ tgsi_transform.c \ + tgsi_ureg.c \ tgsi_util.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 8200cce42f..b6bc2924f0 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -16,6 +16,7 @@ tgsi = env.ConvenienceLibrary( 'tgsi_sse2.c', 'tgsi_text.c', 'tgsi_transform.c', + 'tgsi_ureg.c', 'tgsi_util.c', ]) diff --git a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt index a3f4947c73..802ec37118 100644 --- a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt +++ b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt @@ -665,9 +665,18 @@ TGSI Instruction Specification TBD -1.9.8 LOOP - Loop +1.9.8 BGNFOR - Begin a For-Loop - TBD + dst.x = floor(src.x) + dst.y = floor(src.y) + dst.z = floor(src.z) + + if (dst.y <= 0) + pc = [matching ENDFOR] + 1 + endif + + Note: The destination must be a loop register. + The source must be a constant register. 1.9.9 REP - Repeat @@ -685,9 +694,16 @@ TGSI Instruction Specification TBD -1.9.12 ENDLOOP - End Loop +1.9.12 ENDFOR - End a For-Loop - TBD + dst.x = dst.x + dst.z + dst.y = dst.y - 1.0 + + if (dst.y > 0) + pc = [matching BGNFOR instruction] + 1 + endif + + Note: The destination must be a loop register. 1.9.13 ENDREP - End Repeat @@ -840,7 +856,7 @@ TGSI Instruction Specification ---------- -1.13.1 BGNLOOP2 - Begin Loop +1.13.1 BGNLOOP - Begin a Loop TBD @@ -850,7 +866,7 @@ TGSI Instruction Specification TBD -1.13.3 ENDLOOP2 - End Loop +1.13.3 ENDLOOP - End a Loop TBD diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index d272533d63..010d501c60 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -335,7 +335,10 @@ tgsi_default_full_immediate( void ) struct tgsi_full_immediate fullimm; fullimm.Immediate = tgsi_default_immediate(); - fullimm.u.Pointer = (void *) 0; + fullimm.u[0].Float = 0.0f; + fullimm.u[1].Float = 0.0f; + fullimm.u[2].Float = 0.0f; + fullimm.u[3].Float = 0.0f; return fullimm; } @@ -352,19 +355,19 @@ immediate_grow( header_bodysize_grow( header ); } -struct tgsi_immediate_float32 +union tgsi_immediate_data tgsi_build_immediate_float32( float value, struct tgsi_immediate *immediate, struct tgsi_header *header ) { - struct tgsi_immediate_float32 immediate_float32; + union tgsi_immediate_data immediate_data; - immediate_float32.Float = value; + immediate_data.Float = value; immediate_grow( immediate, header ); - return immediate_float32; + return immediate_data; } unsigned @@ -384,16 +387,18 @@ tgsi_build_full_immediate( *immediate = tgsi_build_immediate( header ); + assert( full_imm->Immediate.NrTokens <= 4 + 1 ); + for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) { - struct tgsi_immediate_float32 *if32; + union tgsi_immediate_data *data; if( maxsize <= size ) return 0; - if32 = (struct tgsi_immediate_float32 *) &tokens[size]; + data = (union tgsi_immediate_data *) &tokens[size]; size++; - *if32 = tgsi_build_immediate_float32( - full_imm->u.ImmediateFloat32[i].Float, + *data = tgsi_build_immediate_float32( + full_imm->u[i].Float, immediate, header ); } diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h index 9a3a077cf2..17d977b059 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/tgsi_build.h @@ -119,7 +119,7 @@ tgsi_build_immediate( struct tgsi_full_immediate tgsi_default_full_immediate( void ); -struct tgsi_immediate_float32 +union tgsi_immediate_data tgsi_build_immediate_float32( float value, struct tgsi_immediate *immediate, diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index a6994ecd48..f36b1114a9 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -82,7 +82,7 @@ static const char *processor_type_names[] = "GEOM" }; -static const char *file_names[] = +static const char *file_names[TGSI_FILE_COUNT] = { "NULL", "CONST", @@ -91,7 +91,8 @@ static const char *file_names[] = "TEMP", "SAMP", "ADDR", - "IMM" + "IMM", + "LOOP" }; static const char *interpolate_names[] = @@ -295,10 +296,12 @@ iter_immediate( ENM( imm->Immediate.DataType, immediate_type_names ); TXT( " { " ); + + assert( imm->Immediate.NrTokens <= 4 + 1 ); for (i = 0; i < imm->Immediate.NrTokens - 1; i++) { switch (imm->Immediate.DataType) { case TGSI_IMM_FLOAT32: - FLT( imm->u.ImmediateFloat32[i].Float ); + FLT( imm->u[i].Float ); break; default: assert( 0 ); @@ -470,8 +473,8 @@ iter_instruction( switch (inst->Instruction.Opcode) { case TGSI_OPCODE_IF: case TGSI_OPCODE_ELSE: - case TGSI_OPCODE_BGNLOOP2: - case TGSI_OPCODE_ENDLOOP2: + case TGSI_OPCODE_BGNLOOP: + case TGSI_OPCODE_ENDLOOP: case TGSI_OPCODE_CAL: TXT( " :" ); UID( inst->InstructionExtLabel.Label ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c index 3dc61c48ca..4a9c02b141 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c @@ -69,7 +69,7 @@ static const char *TGSI_TOKEN_TYPES[] = "TOKEN_TYPE_INSTRUCTION" }; -static const char *TGSI_FILES[] = +static const char *TGSI_FILES[TGSI_FILE_COUNT] = { "FILE_NULL", "FILE_CONSTANT", @@ -78,7 +78,8 @@ static const char *TGSI_FILES[] = "FILE_TEMPORARY", "FILE_SAMPLER", "FILE_ADDRESS", - "FILE_IMMEDIATE" + "FILE_IMMEDIATE", + "FILE_LOOP" }; static const char *TGSI_INTERPOLATES[] = @@ -283,12 +284,13 @@ dump_immediate_verbose( UIX( imm->Immediate.Padding ); } + assert( imm->Immediate.NrTokens <= 4 + 1 ); for( i = 0; i < imm->Immediate.NrTokens - 1; i++ ) { EOL(); switch( imm->Immediate.DataType ) { case TGSI_IMM_FLOAT32: TXT( "\nFloat: " ); - FLT( imm->u.ImmediateFloat32[i].Float ); + FLT( imm->u[i].Float ); break; default: diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index fe571a86bc..951ecfd552 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -301,14 +301,14 @@ tgsi_exec_machine_bind_shader( case TGSI_TOKEN_TYPE_IMMEDIATE: { uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1; - assert( size % 4 == 0 ); - assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES ); + assert( size <= 4 ); + assert( mach->ImmLimit + 1 <= TGSI_EXEC_NUM_IMMEDIATES ); for( i = 0; i < size; i++ ) { - mach->Imms[mach->ImmLimit + i / 4][i % 4] = - parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + mach->Imms[mach->ImmLimit][i] = + parse.FullToken.FullImmediate.u[i].Float; } - mach->ImmLimit += size / 4; + mach->ImmLimit += 1; } break; @@ -375,15 +375,9 @@ tgsi_exec_machine_create( void ) if (!mach) goto fail; - mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR]; + memset(mach, 0, sizeof(*mach)); - mach->Samplers = NULL; - mach->Consts = NULL; - mach->Tokens = NULL; - mach->Primitives = NULL; - mach->InterpCoefs = NULL; - mach->Instructions = NULL; - mach->Declarations = NULL; + mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR]; /* Setup constants. */ for( i = 0; i < 4; i++ ) { @@ -2020,8 +2014,7 @@ exec_instruction( switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ARL: - case TGSI_OPCODE_FLOOR: - /* TGSI_OPCODE_FLR */ + case TGSI_OPCODE_FLR: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); micro_flr( &r[0], &r[0] ); @@ -2290,8 +2283,7 @@ exec_instruction( } break; - case TGSI_OPCODE_LERP: - /* TGSI_OPCODE_LRP */ + case TGSI_OPCODE_LRP: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH(&r[0], 0, chan_index); FETCH(&r[1], 1, chan_index); @@ -2325,8 +2317,7 @@ exec_instruction( } break; - case TGSI_OPCODE_DOT2ADD: - /* TGSI_OPCODE_DP2A */ + case TGSI_OPCODE_DP2A: FETCH( &r[0], 0, CHAN_X ); FETCH( &r[1], 1, CHAN_X ); micro_mul( &r[0], &r[0], &r[1] ); @@ -2344,18 +2335,7 @@ exec_instruction( } break; - case TGSI_OPCODE_INDEX: - /* XXX: considered for removal */ - assert (0); - break; - - case TGSI_OPCODE_NEGATE: - /* XXX: considered for removal */ - assert (0); - break; - - case TGSI_OPCODE_FRAC: - /* TGSI_OPCODE_FRC */ + case TGSI_OPCODE_FRC: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); micro_frc( &r[0], &r[0] ); @@ -2383,8 +2363,7 @@ exec_instruction( } break; - case TGSI_OPCODE_EXPBASE2: - /* TGSI_OPCODE_EX2 */ + case TGSI_OPCODE_EX2: FETCH(&r[0], 0, CHAN_X); #if FAST_MATH @@ -2398,8 +2377,7 @@ exec_instruction( } break; - case TGSI_OPCODE_LOGBASE2: - /* TGSI_OPCODE_LG2 */ + case TGSI_OPCODE_LG2: FETCH( &r[0], 0, CHAN_X ); micro_lg2( &r[0], &r[0] ); FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { @@ -2407,8 +2385,7 @@ exec_instruction( } break; - case TGSI_OPCODE_POWER: - /* TGSI_OPCODE_POW */ + case TGSI_OPCODE_POW: FETCH(&r[0], 0, CHAN_X); FETCH(&r[1], 1, CHAN_X); @@ -2419,8 +2396,7 @@ exec_instruction( } break; - case TGSI_OPCODE_CROSSPRODUCT: - /* TGSI_OPCODE_XPD */ + case TGSI_OPCODE_XPD: FETCH(&r[0], 0, CHAN_Y); FETCH(&r[1], 1, CHAN_Z); @@ -2462,11 +2438,6 @@ exec_instruction( } break; - case TGSI_OPCODE_MULTIPLYMATRIX: - /* XXX: considered for removal */ - assert (0); - break; - case TGSI_OPCODE_ABS: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH(&r[0], 0, chan_index); @@ -3110,9 +3081,9 @@ exec_instruction( mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; break; - case TGSI_OPCODE_LOOP: + case TGSI_OPCODE_BGNFOR: /* fall-through (for now) */ - case TGSI_OPCODE_BGNLOOP2: + case TGSI_OPCODE_BGNLOOP: /* push LoopMask and ContMasks */ assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; @@ -3120,9 +3091,9 @@ exec_instruction( mach->ContStack[mach->ContStackTop++] = mach->ContMask; break; - case TGSI_OPCODE_ENDLOOP: + case TGSI_OPCODE_ENDFOR: /* fall-through (for now at least) */ - case TGSI_OPCODE_ENDLOOP2: + case TGSI_OPCODE_ENDLOOP: /* Restore ContMask, but don't pop */ assert(mach->ContStackTop > 0); mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c index 37f2b66d1f..ccf4b205ff 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.c +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -26,136 +26,156 @@ **************************************************************************/ #include "util/u_debug.h" +#include "util/u_memory.h" #include "tgsi_info.h" static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] = { - { 1, 1, 0, 0, "ARL", NULL, NULL }, - { 1, 1, 0, 0, "MOV", NULL, NULL }, - { 1, 1, 0, 0, "LIT", NULL, NULL }, - { 1, 1, 0, 0, "RCP", "RECIP", NULL }, - { 1, 1, 0, 0, "RSQ", "RECIPSQRT", NULL }, - { 1, 1, 0, 0, "EXP", "EXPP", NULL }, - { 1, 1, 0, 0, "LOG", NULL, NULL }, - { 1, 2, 0, 0, "MUL", NULL, NULL }, - { 1, 2, 0, 0, "ADD", NULL, NULL }, - { 1, 2, 0, 0, "DP3", "DOT3", NULL }, - { 1, 2, 0, 0, "DP4", "DOT4", NULL }, - { 1, 2, 0, 0, "DST", NULL, NULL }, - { 1, 2, 0, 0, "MIN", NULL, NULL }, - { 1, 2, 0, 0, "MAX", NULL, NULL }, - { 1, 2, 0, 0, "SLT", "SETLT", NULL }, - { 1, 2, 0, 0, "SGE", "SETGE", NULL }, - { 1, 3, 0, 0, "MAD", "MADD", NULL }, - { 1, 2, 0, 0, "SUB", NULL, NULL }, - { 1, 3, 0, 0, "LRP", "LERP", NULL }, - { 1, 3, 0, 0, "CND", NULL, NULL }, - { 1, 3, 0, 0, "CND0", NULL, NULL }, - { 1, 3, 0, 0, "DP2A", "DP2ADD", "DOT2ADD" }, - { 1, 2, 0, 0, "INDEX", NULL, NULL }, - { 1, 1, 0, 0, "NEGATE", NULL, NULL }, - { 1, 1, 0, 0, "FRC", "FRAC", NULL }, - { 1, 3, 0, 0, "CLAMP", NULL, NULL }, - { 1, 1, 0, 0, "FLR", "FLOOR", NULL }, - { 1, 1, 0, 0, "ROUND", NULL, NULL }, - { 1, 1, 0, 0, "EX2", "EXPBASE2", NULL }, - { 1, 1, 0, 0, "LG2", "LOGBASE2", "LOGP" }, - { 1, 2, 0, 0, "POW", "POWER", NULL }, - { 1, 2, 0, 0, "XPD", "CRS", "CROSSPRODUCT" }, - { 1, 2, 0, 0, "M4X4", "MULTIPLYMATRIX", NULL }, - { 1, 1, 0, 0, "ABS", NULL, NULL }, - { 1, 1, 0, 0, "RCC", NULL, NULL }, - { 1, 2, 0, 0, "DPH", NULL, NULL }, - { 1, 1, 0, 0, "COS", NULL, NULL }, - { 1, 1, 0, 0, "DDX", "DSX", NULL }, - { 1, 1, 0, 0, "DDY", "DSY", NULL }, - { 0, 0, 0, 0, "KILP", NULL, NULL }, - { 1, 1, 0, 0, "PK2H", NULL, NULL }, - { 1, 1, 0, 0, "PK2US", NULL, NULL }, - { 1, 1, 0, 0, "PK4B", NULL, NULL }, - { 1, 1, 0, 0, "PK4UB", NULL, NULL }, - { 1, 2, 0, 0, "RFL", NULL, NULL }, - { 1, 2, 0, 0, "SEQ", NULL, NULL }, - { 1, 2, 0, 0, "SFL", NULL, NULL }, - { 1, 2, 0, 0, "SGT", NULL, NULL }, - { 1, 1, 0, 0, "SIN", NULL, NULL }, - { 1, 2, 0, 0, "SLE", NULL, NULL }, - { 1, 2, 0, 0, "SNE", NULL, NULL }, - { 1, 2, 0, 0, "STR", NULL, NULL }, - { 1, 2, 1, 0, "TEX", "TEXLD", NULL }, - { 1, 4, 1, 0, "TXD", "TEXLDD", NULL }, - { 1, 2, 1, 0, "TXP", NULL, NULL }, - { 1, 1, 0, 0, "UP2H", NULL, NULL }, - { 1, 1, 0, 0, "UP2US", NULL, NULL }, - { 1, 1, 0, 0, "UP4B", NULL, NULL }, - { 1, 1, 0, 0, "UP4UB", NULL, NULL }, - { 1, 3, 0, 0, "X2D", NULL, NULL }, - { 1, 1, 0, 0, "ARA", NULL, NULL }, - { 1, 1, 0, 0, "ARR", "MOVA", NULL }, - { 0, 1, 0, 0, "BRA", NULL, NULL }, - { 0, 0, 0, 1, "CAL", "CALL", NULL }, - { 0, 0, 0, 0, "RET", NULL, NULL }, - { 1, 1, 0, 0, "SGN", "SSG", NULL }, - { 1, 3, 0, 0, "CMP", NULL, NULL }, - { 1, 1, 0, 0, "SCS", "SINCOS", NULL }, - { 1, 2, 1, 0, "TXB", "TEXLDB", NULL }, - { 1, 1, 0, 0, "NRM", NULL, NULL }, - { 1, 2, 0, 0, "DIV", NULL, NULL }, - { 1, 2, 0, 0, "DP2", NULL, NULL }, - { 1, 2, 1, 0, "TXL", NULL, NULL }, - { 0, 0, 0, 0, "BRK", "BREAK", NULL }, - { 0, 1, 0, 1, "IF", NULL, NULL }, - { 0, 0, 0, 0, "LOOP", NULL, NULL }, - { 0, 1, 0, 0, "REP", NULL, NULL }, - { 0, 0, 0, 1, "ELSE", NULL, NULL }, - { 0, 0, 0, 0, "ENDIF", NULL, NULL }, - { 0, 0, 0, 0, "ENDLOOP", NULL, NULL }, - { 0, 0, 0, 0, "ENDREP", NULL, NULL }, - { 0, 1, 0, 0, "PUSHA", NULL, NULL }, - { 1, 0, 0, 0, "POPA", NULL, NULL }, - { 1, 1, 0, 0, "CEIL", NULL, NULL }, - { 1, 1, 0, 0, "I2F", NULL, NULL }, - { 1, 1, 0, 0, "NOT", NULL, NULL }, - { 1, 1, 0, 0, "INT", "TRUNC", NULL }, - { 1, 2, 0, 0, "SHL", NULL, NULL }, - { 1, 2, 0, 0, "SHR", NULL, NULL }, - { 1, 2, 0, 0, "AND", NULL, NULL }, - { 1, 2, 0, 0, "OR", NULL, NULL }, - { 1, 2, 0, 0, "MOD", NULL, NULL }, - { 1, 2, 0, 0, "XOR", NULL, NULL }, - { 1, 3, 0, 0, "SAD", NULL, NULL }, - { 1, 2, 1, 0, "TXF", NULL, NULL }, - { 1, 2, 1, 0, "TXQ", NULL, NULL }, - { 0, 0, 0, 0, "CONT", NULL, NULL }, - { 0, 0, 0, 0, "EMIT", NULL, NULL }, - { 0, 0, 0, 0, "ENDPRIM", NULL, NULL }, - { 0, 0, 0, 1, "BGNLOOP2", NULL, NULL }, - { 0, 0, 0, 0, "BGNSUB", NULL, NULL }, - { 0, 0, 0, 1, "ENDLOOP2", NULL, NULL }, - { 0, 0, 0, 0, "ENDSUB", NULL, NULL }, - { 1, 1, 0, 0, "NOISE1", NULL, NULL }, - { 1, 1, 0, 0, "NOISE2", NULL, NULL }, - { 1, 1, 0, 0, "NOISE3", NULL, NULL }, - { 1, 1, 0, 0, "NOISE4", NULL, NULL }, - { 0, 0, 0, 0, "NOP", NULL, NULL }, - { 1, 2, 0, 0, "M4X3", NULL, NULL }, - { 1, 2, 0, 0, "M3X4", NULL, NULL }, - { 1, 2, 0, 0, "M3X3", NULL, NULL }, - { 1, 2, 0, 0, "M3X2", NULL, NULL }, - { 1, 1, 0, 0, "NRM4", NULL, NULL }, - { 0, 1, 0, 0, "CALLNZ", NULL, NULL }, - { 0, 1, 0, 0, "IFC", NULL, NULL }, - { 0, 1, 0, 0, "BREAKC", NULL, NULL }, - { 0, 1, 0, 0, "KIL", "TEXKILL", NULL }, - { 0, 0, 0, 0, "END", NULL, NULL }, - { 1, 1, 0, 0, "SWZ", NULL, NULL } + { 1, 1, 0, 0, "ARL", TGSI_OPCODE_ARL }, + { 1, 1, 0, 0, "MOV", TGSI_OPCODE_MOV }, + { 1, 1, 0, 0, "LIT", TGSI_OPCODE_LIT }, + { 1, 1, 0, 0, "RCP", TGSI_OPCODE_RCP }, + { 1, 1, 0, 0, "RSQ", TGSI_OPCODE_RSQ }, + { 1, 1, 0, 0, "EXP", TGSI_OPCODE_EXP }, + { 1, 1, 0, 0, "LOG", TGSI_OPCODE_LOG }, + { 1, 2, 0, 0, "MUL", TGSI_OPCODE_MUL }, + { 1, 2, 0, 0, "ADD", TGSI_OPCODE_ADD }, + { 1, 2, 0, 0, "DP3", TGSI_OPCODE_DP3 }, + { 1, 2, 0, 0, "DP4", TGSI_OPCODE_DP4 }, + { 1, 2, 0, 0, "DST", TGSI_OPCODE_DST }, + { 1, 2, 0, 0, "MIN", TGSI_OPCODE_MIN }, + { 1, 2, 0, 0, "MAX", TGSI_OPCODE_MAX }, + { 1, 2, 0, 0, "SLT", TGSI_OPCODE_SLT }, + { 1, 2, 0, 0, "SGE", TGSI_OPCODE_SGE }, + { 1, 3, 0, 0, "MAD", TGSI_OPCODE_MAD }, + { 1, 2, 0, 0, "SUB", TGSI_OPCODE_SUB }, + { 1, 3, 0, 0, "LRP", TGSI_OPCODE_LRP }, + { 1, 3, 0, 0, "CND", TGSI_OPCODE_CND }, + { 1, 3, 0, 0, "CND0", TGSI_OPCODE_CND0 }, + { 1, 3, 0, 0, "DP2A", TGSI_OPCODE_DP2A }, + { 0, 0, 0, 0, "", 22 }, /* removed */ + { 0, 0, 0, 0, "", 23 }, /* removed */ + { 1, 1, 0, 0, "FRC", TGSI_OPCODE_FRC }, + { 1, 3, 0, 0, "CLAMP", TGSI_OPCODE_CLAMP }, + { 1, 1, 0, 0, "FLR", TGSI_OPCODE_FLR }, + { 1, 1, 0, 0, "ROUND", TGSI_OPCODE_ROUND }, + { 1, 1, 0, 0, "EX2", TGSI_OPCODE_EX2 }, + { 1, 1, 0, 0, "LG2", TGSI_OPCODE_LG2 }, + { 1, 2, 0, 0, "POW", TGSI_OPCODE_POW }, + { 1, 2, 0, 0, "XPD", TGSI_OPCODE_XPD }, + { 0, 0, 0, 0, "", 32 }, /* removed */ + { 1, 1, 0, 0, "ABS", TGSI_OPCODE_ABS }, + { 1, 1, 0, 0, "RCC", TGSI_OPCODE_RCC }, + { 1, 2, 0, 0, "DPH", TGSI_OPCODE_DPH }, + { 1, 1, 0, 0, "COS", TGSI_OPCODE_COS }, + { 1, 1, 0, 0, "DDX", TGSI_OPCODE_DDX }, + { 1, 1, 0, 0, "DDY", TGSI_OPCODE_DDY }, + { 0, 0, 0, 0, "KILP", TGSI_OPCODE_KILP }, + { 1, 1, 0, 0, "PK2H", TGSI_OPCODE_PK2H }, + { 1, 1, 0, 0, "PK2US", TGSI_OPCODE_PK2US }, + { 1, 1, 0, 0, "PK4B", TGSI_OPCODE_PK4B }, + { 1, 1, 0, 0, "PK4UB", TGSI_OPCODE_PK4UB }, + { 1, 2, 0, 0, "RFL", TGSI_OPCODE_RFL }, + { 1, 2, 0, 0, "SEQ", TGSI_OPCODE_SEQ }, + { 1, 2, 0, 0, "SFL", TGSI_OPCODE_SFL }, + { 1, 2, 0, 0, "SGT", TGSI_OPCODE_SGT }, + { 1, 1, 0, 0, "SIN", TGSI_OPCODE_SIN }, + { 1, 2, 0, 0, "SLE", TGSI_OPCODE_SLE }, + { 1, 2, 0, 0, "SNE", TGSI_OPCODE_SNE }, + { 1, 2, 0, 0, "STR", TGSI_OPCODE_STR }, + { 1, 2, 1, 0, "TEX", TGSI_OPCODE_TEX }, + { 1, 4, 1, 0, "TXD", TGSI_OPCODE_TXD }, + { 1, 2, 1, 0, "TXP", TGSI_OPCODE_TXP }, + { 1, 1, 0, 0, "UP2H", TGSI_OPCODE_UP2H }, + { 1, 1, 0, 0, "UP2US", TGSI_OPCODE_UP2US }, + { 1, 1, 0, 0, "UP4B", TGSI_OPCODE_UP4B }, + { 1, 1, 0, 0, "UP4UB", TGSI_OPCODE_UP4UB }, + { 1, 3, 0, 0, "X2D", TGSI_OPCODE_X2D }, + { 1, 1, 0, 0, "ARA", TGSI_OPCODE_ARA }, + { 1, 1, 0, 0, "ARR", TGSI_OPCODE_ARR }, + { 0, 1, 0, 0, "BRA", TGSI_OPCODE_BRA }, + { 0, 0, 0, 1, "CAL", TGSI_OPCODE_CAL }, + { 0, 0, 0, 0, "RET", TGSI_OPCODE_RET }, + { 1, 1, 0, 0, "SSG", TGSI_OPCODE_SSG }, + { 1, 3, 0, 0, "CMP", TGSI_OPCODE_CMP }, + { 1, 1, 0, 0, "SCS", TGSI_OPCODE_SCS }, + { 1, 2, 1, 0, "TXB", TGSI_OPCODE_TXB }, + { 1, 1, 0, 0, "NRM", TGSI_OPCODE_NRM }, + { 1, 2, 0, 0, "DIV", TGSI_OPCODE_DIV }, + { 1, 2, 0, 0, "DP2", TGSI_OPCODE_DP2 }, + { 1, 2, 1, 0, "TXL", TGSI_OPCODE_TXL }, + { 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK }, + { 0, 1, 0, 1, "IF", TGSI_OPCODE_IF }, + { 1, 1, 0, 0, "BGNFOR", TGSI_OPCODE_BGNFOR }, + { 0, 1, 0, 0, "REP", TGSI_OPCODE_REP }, + { 0, 0, 0, 1, "ELSE", TGSI_OPCODE_ELSE }, + { 0, 0, 0, 0, "ENDIF", TGSI_OPCODE_ENDIF }, + { 1, 0, 0, 0, "ENDFOR", TGSI_OPCODE_ENDFOR }, + { 0, 0, 0, 0, "ENDREP", TGSI_OPCODE_ENDREP }, + { 0, 1, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA }, + { 1, 0, 0, 0, "POPA", TGSI_OPCODE_POPA }, + { 1, 1, 0, 0, "CEIL", TGSI_OPCODE_CEIL }, + { 1, 1, 0, 0, "I2F", TGSI_OPCODE_I2F }, + { 1, 1, 0, 0, "NOT", TGSI_OPCODE_NOT }, + { 1, 1, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC }, + { 1, 2, 0, 0, "SHL", TGSI_OPCODE_SHL }, + { 1, 2, 0, 0, "SHR", TGSI_OPCODE_SHR }, + { 1, 2, 0, 0, "AND", TGSI_OPCODE_AND }, + { 1, 2, 0, 0, "OR", TGSI_OPCODE_OR }, + { 1, 2, 0, 0, "MOD", TGSI_OPCODE_MOD }, + { 1, 2, 0, 0, "XOR", TGSI_OPCODE_XOR }, + { 1, 3, 0, 0, "SAD", TGSI_OPCODE_SAD }, + { 1, 2, 1, 0, "TXF", TGSI_OPCODE_TXF }, + { 1, 2, 1, 0, "TXQ", TGSI_OPCODE_TXQ }, + { 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT }, + { 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT }, + { 0, 0, 0, 0, "ENDPRIM", TGSI_OPCODE_ENDPRIM }, + { 0, 0, 0, 1, "BGNLOOP", TGSI_OPCODE_BGNLOOP }, + { 0, 0, 0, 0, "BGNSUB", TGSI_OPCODE_BGNSUB }, + { 0, 0, 0, 1, "ENDLOOP", TGSI_OPCODE_ENDLOOP }, + { 0, 0, 0, 0, "ENDSUB", TGSI_OPCODE_ENDSUB }, + { 1, 1, 0, 0, "NOISE1", TGSI_OPCODE_NOISE1 }, + { 1, 1, 0, 0, "NOISE2", TGSI_OPCODE_NOISE2 }, + { 1, 1, 0, 0, "NOISE3", TGSI_OPCODE_NOISE3 }, + { 1, 1, 0, 0, "NOISE4", TGSI_OPCODE_NOISE4 }, + { 0, 0, 0, 0, "NOP", TGSI_OPCODE_NOP }, + { 0, 0, 0, 0, "", 108 }, /* removed */ + { 0, 0, 0, 0, "", 109 }, /* removed */ + { 0, 0, 0, 0, "", 110 }, /* removed */ + { 0, 0, 0, 0, "", 111 }, /* removed */ + { 1, 1, 0, 0, "NRM4", TGSI_OPCODE_NRM4 }, + { 0, 1, 0, 0, "CALLNZ", TGSI_OPCODE_CALLNZ }, + { 0, 1, 0, 0, "IFC", TGSI_OPCODE_IFC }, + { 0, 1, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC }, + { 0, 1, 0, 0, "KIL", TGSI_OPCODE_KIL }, + { 0, 0, 0, 0, "END", TGSI_OPCODE_END }, + { 1, 1, 0, 0, "SWZ", TGSI_OPCODE_SWZ } }; const struct tgsi_opcode_info * tgsi_get_opcode_info( uint opcode ) { + static boolean firsttime = 1; + + if (firsttime) { + unsigned i; + firsttime = 0; + for (i = 0; i < Elements(opcode_info); i++) + assert(opcode_info[i].opcode == i); + } + if (opcode < TGSI_OPCODE_LAST) return &opcode_info[opcode]; + assert( 0 ); return NULL; } + + +const char * +tgsi_get_opcode_name( uint opcode ) +{ + const struct tgsi_opcode_info *info = tgsi_get_opcode_info(opcode); + return info->mnemonic; +} + diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.h b/src/gallium/auxiliary/tgsi/tgsi_info.h index 077e25acd7..b2375c6971 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.h +++ b/src/gallium/auxiliary/tgsi/tgsi_info.h @@ -41,13 +41,16 @@ struct tgsi_opcode_info boolean is_tex; boolean is_branch; const char *mnemonic; - const char *alt_mnemonic1; - const char *alt_mnemonic2; + uint opcode; }; const struct tgsi_opcode_info * tgsi_get_opcode_info( uint opcode ); +const char * +tgsi_get_opcode_name( uint opcode ); + + #if defined __cplusplus } #endif diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h new file mode 100644 index 0000000000..ed594a3e2c --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h @@ -0,0 +1,173 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +#ifndef OP12_TEX +#define OP12_TEX(a) OP12(a) +#endif + +#ifndef OP14_TEX +#define OP14_TEX(a) OP14(a) +#endif + +#ifndef OP00_LBL +#define OP00_LBL(a) OP00(a) +#endif + +#ifndef OP01_LBL +#define OP01_LBL(a) OP01(a) +#endif + +OP11(ARL) +OP11(MOV) +OP11(LIT) +OP11(RCP) +OP11(RSQ) +OP11(EXP) +OP11(LOG) +OP12(MUL) +OP12(ADD) +OP12(DP3) +OP12(DP4) +OP12(DST) +OP12(MIN) +OP12(MAX) +OP12(SLT) +OP12(SGE) +OP13(MAD) +OP12(SUB) +OP13(LRP) +OP13(CND) +OP13(CND0) +OP13(DP2A) +OP11(FRC) +OP13(CLAMP) +OP11(FLR) +OP11(ROUND) +OP11(EX2) +OP11(LG2) +OP12(POW) +OP12(XPD) +OP11(ABS) +OP11(RCC) +OP12(DPH) +OP11(COS) +OP11(DDX) +OP11(DDY) +OP00(KILP) +OP11(PK2H) +OP11(PK2US) +OP11(PK4B) +OP11(PK4UB) +OP12(RFL) +OP12(SEQ) +OP12(SFL) +OP12(SGT) +OP11(SIN) +OP12(SLE) +OP12(SNE) +OP12(STR) +OP12_TEX(TEX) +OP14_TEX(TXD) +OP12_TEX(TXP) +OP11(UP2H) +OP11(UP2US) +OP11(UP4B) +OP11(UP4UB) +OP13(X2D) +OP11(ARA) +OP11(ARR) +OP01(BRA) +OP00_LBL(CAL) +OP00(RET) +OP11(SSG) +OP13(CMP) +OP11(SCS) +OP12_TEX(TXB) +OP11(NRM) +OP12(DIV) +OP12(DP2) +OP12_TEX(TXL) +OP00(BRK) +OP01_LBL(IF) +OP11(BGNFOR) +OP01(REP) +OP00_LBL(ELSE) +OP00(ENDIF) +OP10(ENDFOR) +OP00(ENDREP) +OP01(PUSHA) +OP10(POPA) +OP11(CEIL) +OP11(I2F) +OP11(NOT) +OP11(TRUNC) +OP12(SHL) +OP12(SHR) +OP12(AND) +OP12(OR) +OP12(MOD) +OP12(XOR) +OP13(SAD) +OP12_TEX(TXF) +OP12_TEX(TXQ) +OP00(CONT) +OP00(EMIT) +OP00(ENDPRIM) +OP00_LBL(BGNLOOP) +OP00(BGNSUB) +OP00_LBL(ENDLOOP) +OP00(ENDSUB) +OP11(NOISE1) +OP11(NOISE2) +OP11(NOISE3) +OP11(NOISE4) +OP00(NOP) +OP11(NRM4) +OP01(CALLNZ) +OP01(IFC) +OP01(BREAKC) +OP01(KIL) +OP00(END) +OP11(SWZ) + + +#undef OP00 +#undef OP01 +#undef OP10 +#undef OP11 +#undef OP12 +#undef OP13 + +#ifdef OP14 +#undef OP14 +#endif + +#undef OP00_LBL +#undef OP01_LBL + +#undef OP12_TEX +#undef OP14_TEX + diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c index 7f2cfb7988..4870f82b6b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c @@ -42,9 +42,6 @@ void tgsi_full_token_free( union tgsi_full_token *full_token ) { - if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) { - FREE( (void *) full_token->FullImmediate.u.Pointer ); - } } unsigned @@ -156,14 +153,8 @@ tgsi_parse_token( case TGSI_IMM_FLOAT32: { uint imm_count = imm->Immediate.NrTokens - 1; - struct tgsi_immediate_float32 *data; - - data = (struct tgsi_immediate_float32 *) MALLOC(sizeof(struct tgsi_immediate_float32) * imm_count); - if (data) { - for (i = 0; i < imm_count; i++) { - next_token(ctx, &data[i]); - } - imm->u.ImmediateFloat32 = data; + for (i = 0; i < imm_count; i++) { + next_token(ctx, &imm->u[i]); } } break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h index a289e26e3a..1035bda1a8 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h @@ -73,11 +73,7 @@ struct tgsi_full_declaration struct tgsi_full_immediate { struct tgsi_immediate Immediate; - union - { - const void *Pointer; - const struct tgsi_immediate_float32 *ImmediateFloat32; - } u; + union tgsi_immediate_data u[4]; }; #define TGSI_FULL_MAX_DST_REGISTERS 2 diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c index 0c64ae5713..2d6ad12ffb 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c @@ -38,6 +38,7 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_sse.h" +#include "tgsi/tgsi_info.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi_dump.h" @@ -619,17 +620,17 @@ emit_unaryop(struct gen_context *gen, struct tgsi_full_instruction *inst) ppc_vandc(gen->f, v1, v0, bit31_vec); /* v1 = v0 & ~bit31 */ } break; - case TGSI_OPCODE_FLOOR: + case TGSI_OPCODE_FLR: ppc_vrfim(gen->f, v1, v0); /* v1 = floor(v0) */ break; - case TGSI_OPCODE_FRAC: + case TGSI_OPCODE_FRC: ppc_vrfim(gen->f, v1, v0); /* tmp = floor(v0) */ ppc_vsubfp(gen->f, v1, v0, v1); /* v1 = v0 - v1 */ break; - case TGSI_OPCODE_EXPBASE2: + case TGSI_OPCODE_EX2: ppc_vexptefp(gen->f, v1, v0); /* v1 = 2^v0 */ break; - case TGSI_OPCODE_LOGBASE2: + case TGSI_OPCODE_LG2: /* XXX this may be broken! */ ppc_vlogefp(gen->f, v1, v0); /* v1 = log2(v0) */ break; @@ -1111,10 +1112,10 @@ emit_instruction(struct gen_context *gen, case TGSI_OPCODE_MOV: case TGSI_OPCODE_SWZ: case TGSI_OPCODE_ABS: - case TGSI_OPCODE_FLOOR: - case TGSI_OPCODE_FRAC: - case TGSI_OPCODE_EXPBASE2: - case TGSI_OPCODE_LOGBASE2: + case TGSI_OPCODE_FLR: + case TGSI_OPCODE_FRC: + case TGSI_OPCODE_EX2: + case TGSI_OPCODE_LG2: emit_unaryop(gen, inst); break; case TGSI_OPCODE_RSQ: @@ -1317,8 +1318,10 @@ tgsi_emit_ppc(const struct tgsi_token *tokens, ok = emit_instruction(&gen, &parse.FullToken.FullInstruction); if (!ok) { - debug_printf("failed to translate tgsi opcode %d to PPC (%s)\n", - parse.FullToken.FullInstruction.Instruction.Opcode, + uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode; + debug_printf("failed to translate tgsi opcode %d (%s) to PPC (%s)\n", + opcode, + tgsi_get_opcode_name(opcode), parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ? "vertex shader" : "fragment shader"); } @@ -1333,7 +1336,7 @@ tgsi_emit_ppc(const struct tgsi_token *tokens, assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); for (i = 0; i < size; i++) { immediates[num_immediates][i] = - parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + parse.FullToken.FullImmediate.u[i].Float; } num_immediates++; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index 6f1f5c2b4b..4fe8553c42 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -131,7 +131,7 @@ is_register_used( return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; } -static const char *file_names[] = +static const char *file_names[TGSI_FILE_COUNT] = { "NULL", "CONST", @@ -140,7 +140,8 @@ static const char *file_names[] = "TEMP", "SAMP", "ADDR", - "IMM" + "IMM", + "LOOP" }; static boolean @@ -234,9 +235,29 @@ iter_instruction( index, "indirect", FALSE ); - if (file != TGSI_FILE_ADDRESS || index != 0) - report_warning( ctx, "Indirect register not ADDR[0]" ); + if (!(file == TGSI_FILE_ADDRESS || file == TGSI_FILE_LOOP) || index != 0) { + report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]"); + } + } + } + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_BGNFOR: + case TGSI_OPCODE_ENDFOR: + if (inst->FullDstRegisters[0].DstRegister.File != TGSI_FILE_LOOP || + inst->FullDstRegisters[0].DstRegister.Index != 0) { + report_error(ctx, "Destination register must be LOOP[0]"); + } + break; + } + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_BGNFOR: + if (inst->FullSrcRegisters[0].SrcRegister.File != TGSI_FILE_CONSTANT && + inst->FullSrcRegisters[0].SrcRegister.File != TGSI_FILE_IMMEDIATE) { + report_error(ctx, "Source register file must be either CONST or IMM"); } + break; } ctx->num_instructions++; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 4c3343d26c..cfec5cfc01 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -36,6 +36,7 @@ #if defined(PIPE_ARCH_SSE) #include "util/u_sse.h" #endif +#include "tgsi/tgsi_info.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi_exec.h" @@ -1467,15 +1468,15 @@ emit_tex( struct x86_function *func, switch (inst->InstructionExtTexture.Texture) { case TGSI_TEXTURE_1D: - case TGSI_TEXTURE_SHADOW1D: count = 1; break; case TGSI_TEXTURE_2D: case TGSI_TEXTURE_RECT: - case TGSI_TEXTURE_SHADOW2D: - case TGSI_TEXTURE_SHADOWRECT: count = 2; break; + case TGSI_TEXTURE_SHADOW1D: + case TGSI_TEXTURE_SHADOW2D: + case TGSI_TEXTURE_SHADOWRECT: case TGSI_TEXTURE_3D: case TGSI_TEXTURE_CUBE: count = 3; @@ -2064,8 +2065,7 @@ emit_instruction( } break; - case TGSI_OPCODE_LERP: - /* TGSI_OPCODE_LRP */ + case TGSI_OPCODE_LRP: FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); @@ -2085,8 +2085,7 @@ emit_instruction( return 0; break; - case TGSI_OPCODE_DOT2ADD: - /* TGSI_OPCODE_DP2A */ + case TGSI_OPCODE_DP2A: FETCH( func, *inst, 0, 0, CHAN_X ); /* xmm0 = src[0].x */ FETCH( func, *inst, 1, 1, CHAN_X ); /* xmm1 = src[1].x */ emit_mul( func, 0, 1 ); /* xmm0 = xmm0 * xmm1 */ @@ -2101,16 +2100,7 @@ emit_instruction( } break; - case TGSI_OPCODE_INDEX: - return 0; - break; - - case TGSI_OPCODE_NEGATE: - return 0; - break; - - case TGSI_OPCODE_FRAC: - /* TGSI_OPCODE_FRC */ + case TGSI_OPCODE_FRC: FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); emit_frc( func, 0, 0 ); @@ -2122,8 +2112,7 @@ emit_instruction( return 0; break; - case TGSI_OPCODE_FLOOR: - /* TGSI_OPCODE_FLR */ + case TGSI_OPCODE_FLR: FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); emit_flr( func, 0, 0 ); @@ -2139,8 +2128,7 @@ emit_instruction( } break; - case TGSI_OPCODE_EXPBASE2: - /* TGSI_OPCODE_EX2 */ + case TGSI_OPCODE_EX2: FETCH( func, *inst, 0, 0, CHAN_X ); emit_ex2( func, 0, 0 ); FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { @@ -2148,8 +2136,7 @@ emit_instruction( } break; - case TGSI_OPCODE_LOGBASE2: - /* TGSI_OPCODE_LG2 */ + case TGSI_OPCODE_LG2: FETCH( func, *inst, 0, 0, CHAN_X ); emit_lg2( func, 0, 0 ); FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { @@ -2157,8 +2144,7 @@ emit_instruction( } break; - case TGSI_OPCODE_POWER: - /* TGSI_OPCODE_POW */ + case TGSI_OPCODE_POW: FETCH( func, *inst, 0, 0, CHAN_X ); FETCH( func, *inst, 1, 1, CHAN_X ); emit_pow( func, 0, 0, 0, 1 ); @@ -2167,8 +2153,7 @@ emit_instruction( } break; - case TGSI_OPCODE_CROSSPRODUCT: - /* TGSI_OPCODE_XPD */ + case TGSI_OPCODE_XPD: if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { FETCH( func, *inst, 1, 1, CHAN_Z ); @@ -2214,10 +2199,6 @@ emit_instruction( } break; - case TGSI_OPCODE_MULTIPLYMATRIX: - return 0; - break; - case TGSI_OPCODE_ABS: FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); @@ -2551,7 +2532,7 @@ emit_instruction( return 0; break; - case TGSI_OPCODE_LOOP: + case TGSI_OPCODE_BGNFOR: return 0; break; @@ -2567,7 +2548,7 @@ emit_instruction( return 0; break; - case TGSI_OPCODE_ENDLOOP: + case TGSI_OPCODE_ENDFOR: return 0; break; @@ -2937,8 +2918,10 @@ tgsi_emit_sse2( &parse.FullToken.FullInstruction ); if (!ok) { - debug_printf("failed to translate tgsi opcode %d to SSE (%s)\n", - parse.FullToken.FullInstruction.Instruction.Opcode, + uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode; + 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"); } @@ -2953,7 +2936,7 @@ tgsi_emit_sse2( assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); for( i = 0; i < size; i++ ) { immediates[num_immediates][i] = - parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + parse.FullToken.FullImmediate.u[i].Float; } #if 0 debug_printf("SSE FS immediate[%d] = %f %f %f %f\n", diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index a76bbc9140..d438450b1e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -231,7 +231,8 @@ static const char *file_names[TGSI_FILE_COUNT] = "TEMP", "SAMP", "ADDR", - "IMM" + "IMM", + "LOOP" }; static boolean @@ -789,16 +790,6 @@ match_inst_mnemonic(const char **pcur, if (str_match_no_case(pcur, info->mnemonic)) { return TRUE; } - if (info->alt_mnemonic1) { - if (str_match_no_case(pcur, info->alt_mnemonic1)) { - return TRUE; - } - if (info->alt_mnemonic2) { - if (str_match_no_case(pcur, info->alt_mnemonic2)) { - return TRUE; - } - } - } return FALSE; } @@ -1091,7 +1082,10 @@ static boolean parse_immediate( struct translate_ctx *ctx ) imm = tgsi_default_full_immediate(); imm.Immediate.NrTokens += 4; imm.Immediate.DataType = TGSI_IMM_FLOAT32; - imm.u.Pointer = values; + imm.u[0].Float = values[0]; + imm.u[1].Float = values[1]; + imm.u[2].Float = values[2]; + imm.u[3].Float = values[3]; advance = tgsi_build_full_immediate( &imm, diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c new file mode 100644 index 0000000000..ba84a82b2b --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -0,0 +1,797 @@ +/************************************************************************** + * + * 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 VMWARE, INC 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 "pipe/p_state.h" +#include "tgsi/tgsi_ureg.h" +#include "tgsi/tgsi_dump.h" +#include "util/u_memory.h" + +union tgsi_any_token { + struct tgsi_version version; + struct tgsi_header header; + struct tgsi_processor processor; + struct tgsi_token token; + struct tgsi_declaration decl; + struct tgsi_declaration_range decl_range; + struct tgsi_declaration_semantic decl_semantic; + struct tgsi_immediate imm; + union tgsi_immediate_data imm_data; + struct tgsi_instruction insn; + struct tgsi_instruction_ext_nv insn_ext_nv; + struct tgsi_instruction_ext_label insn_ext_label; + struct tgsi_instruction_ext_texture insn_ext_texture; + struct tgsi_instruction_ext_predicate insn_ext_predicate; + struct tgsi_src_register src; + struct tgsi_src_register_ext_swz src_ext_swz; + struct tgsi_src_register_ext_mod src_ext_mod; + struct tgsi_dimension dim; + struct tgsi_dst_register dst; + struct tgsi_dst_register_ext_concode dst_ext_code; + struct tgsi_dst_register_ext_modulate dst_ext_mod; + struct tgsi_dst_register_ext_predicate dst_ext_pred; + unsigned value; +}; + + +struct ureg_tokens { + union tgsi_any_token *tokens; + unsigned size; + unsigned order; + unsigned count; +}; + +#define UREG_MAX_INPUT PIPE_MAX_ATTRIBS +#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS +#define UREG_MAX_IMMEDIATE 32 +#define UREG_MAX_TEMP 256 + +#define DOMAIN_DECL 0 +#define DOMAIN_INSN 1 + +struct ureg_program +{ + unsigned processor; + struct pipe_context *pipe; + + struct { + unsigned semantic_name; + unsigned semantic_index; + unsigned interp; + } input[UREG_MAX_INPUT]; + unsigned nr_inputs; + + struct { + unsigned semantic_name; + unsigned semantic_index; + } output[UREG_MAX_OUTPUT]; + unsigned nr_outputs; + + struct { + float v[4]; + unsigned nr; + } immediate[UREG_MAX_IMMEDIATE]; + unsigned nr_immediates; + + unsigned temps_active[UREG_MAX_TEMP / 32]; + unsigned nr_temps; + + unsigned nr_constants; + unsigned nr_samplers; + + struct ureg_tokens domain[2]; +}; + +static union tgsi_any_token error_tokens[32]; + +static void tokens_error( struct ureg_tokens *tokens ) +{ + tokens->tokens = error_tokens; + tokens->size = Elements(error_tokens); + tokens->count = 0; +} + + +static void tokens_expand( struct ureg_tokens *tokens, + unsigned count ) +{ + unsigned old_size = tokens->size * sizeof(unsigned); + + if (tokens->tokens == error_tokens) + goto fail; + + while (tokens->count + count > tokens->size) { + tokens->size = (1 << ++tokens->order); + } + + tokens->tokens = REALLOC(tokens->tokens, + old_size, + tokens->size * sizeof(unsigned)); + if (tokens->tokens == NULL) + goto fail; + + return; + +fail: + tokens_error(tokens); +} + +static void set_bad( struct ureg_program *ureg ) +{ + tokens_error(&ureg->domain[0]); +} + + + +static union tgsi_any_token *get_tokens( struct ureg_program *ureg, + unsigned domain, + unsigned count ) +{ + struct ureg_tokens *tokens = &ureg->domain[domain]; + union tgsi_any_token *result; + + if (tokens->count + count > tokens->size) + tokens_expand(tokens, count); + + result = &tokens->tokens[tokens->count]; + tokens->count += count; + return result; +} + + +static union tgsi_any_token *retrieve_token( struct ureg_program *ureg, + unsigned domain, + unsigned nr ) +{ + if (ureg->domain[domain].tokens == error_tokens) + return &error_tokens[0]; + + return &ureg->domain[domain].tokens[nr]; +} + + + +static INLINE struct ureg_dst +ureg_dst_register( unsigned file, + unsigned index ) +{ + struct ureg_dst dst; + + dst.File = file; + dst.WriteMask = TGSI_WRITEMASK_XYZW; + dst.Indirect = 0; + dst.Saturate = 0; + dst.Index = index; + dst.Pad1 = 0; + dst.Pad2 = 0; + + return dst; +} + +static INLINE struct ureg_src +ureg_src_register( unsigned file, + unsigned index ) +{ + struct ureg_src src; + + src.File = file; + src.SwizzleX = TGSI_SWIZZLE_X; + src.SwizzleY = TGSI_SWIZZLE_Y; + src.SwizzleZ = TGSI_SWIZZLE_Z; + src.SwizzleW = TGSI_SWIZZLE_W; + src.Pad = 0; + src.Indirect = 0; + src.Absolute = 0; + src.Index = index; + src.Negate = 0; + + return src; +} + + + + +static struct ureg_src +ureg_DECL_input( struct ureg_program *ureg, + unsigned name, + unsigned index, + unsigned interp_mode ) +{ + unsigned i; + + for (i = 0; i < ureg->nr_inputs; i++) { + if (ureg->input[i].semantic_name == name && + ureg->input[i].semantic_index == index) + goto out; + } + + if (ureg->nr_inputs < UREG_MAX_INPUT) { + ureg->input[i].semantic_name = name; + ureg->input[i].semantic_index = index; + ureg->input[i].interp = interp_mode; + ureg->nr_inputs++; + } + else { + set_bad( ureg ); + } + +out: + return ureg_src_register( TGSI_FILE_INPUT, i ); +} + + + +struct ureg_src +ureg_DECL_fs_input( struct ureg_program *ureg, + unsigned name, + unsigned index, + unsigned interp ) +{ + return ureg_DECL_input( ureg, name, index, interp ); +} + + +struct ureg_src +ureg_DECL_vs_input( struct ureg_program *ureg, + unsigned name, + unsigned index ) +{ + return ureg_DECL_input( ureg, name, index, TGSI_INTERPOLATE_CONSTANT ); +} + + +struct ureg_dst +ureg_DECL_output( struct ureg_program *ureg, + unsigned name, + unsigned index ) +{ + unsigned i; + + for (i = 0; i < ureg->nr_outputs; i++) { + if (ureg->output[i].semantic_name == name && + ureg->output[i].semantic_index == index) + goto out; + } + + if (ureg->nr_outputs < UREG_MAX_OUTPUT) { + ureg->output[i].semantic_name = name; + ureg->output[i].semantic_index = index; + ureg->nr_outputs++; + } + else { + set_bad( ureg ); + } + +out: + return ureg_dst_register( TGSI_FILE_OUTPUT, i ); +} + + +/* Returns a new constant register. Keep track of which have been + * referred to so that we can emit decls later. + * + * There is nothing in this code to bind this constant to any tracked + * value or manage any constant_buffer contents -- that's the + * resposibility of the calling code. + */ +struct ureg_src ureg_DECL_constant(struct ureg_program *ureg ) +{ + return ureg_src_register( TGSI_FILE_TEMPORARY, ureg->nr_constants++ ); +} + + +/* Allocate a new temporary. Temporaries greater than UREG_MAX_TEMP + * are legal, but will not be released. + */ +struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg ) +{ + unsigned i; + + for (i = 0; i < UREG_MAX_TEMP; i += 32) { + int bit = ffs(~ureg->temps_active[i/32]); + if (bit != 0) { + i += bit - 1; + goto out; + } + } + + /* No reusable temps, so allocate a new one: + */ + i = ureg->nr_temps++; + +out: + if (i < UREG_MAX_TEMP) + ureg->temps_active[i/32] |= 1 << (i % 32); + + if (i >= ureg->nr_temps) + ureg->nr_temps = i + 1; + + return ureg_dst_register( TGSI_FILE_TEMPORARY, i ); +} + + +void ureg_release_temporary( struct ureg_program *ureg, + struct ureg_dst tmp ) +{ + if (tmp.Index < UREG_MAX_TEMP) + ureg->temps_active[tmp.Index/32] &= ~(1 << (tmp.Index % 32)); +} + + +/* Allocate a new sampler. + */ +struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg ) +{ + return ureg_src_register( TGSI_FILE_SAMPLER, ureg->nr_samplers++ ); +} + + + + +static int match_or_expand_immediate( const float *v, + unsigned nr, + float *v2, + unsigned *nr2, + unsigned *swizzle ) +{ + unsigned i, j; + + for (i = 0; i < nr; i++) { + boolean found = FALSE; + + for (j = 0; j < *nr2 && !found; j++) { + if (v[i] == v2[j]) { + *swizzle |= j << (i * 2); + found = TRUE; + } + } + + if (!found) { + if (*nr2 >= 4) + return FALSE; + + v2[*nr2] = v[i]; + *swizzle |= *nr2 << (i * 2); + (*nr2)++; + } + } + + return TRUE; +} + + + + +struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg, + const float *v, + unsigned nr ) +{ + unsigned i; + unsigned swizzle; + + /* Could do a first pass where we examine all existing immediates + * without expanding. + */ + + for (i = 0; i < ureg->nr_immediates; i++) { + if (match_or_expand_immediate( v, + nr, + ureg->immediate[i].v, + &ureg->immediate[i].nr, + &swizzle )) + goto out; + } + + if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) { + i = ureg->nr_immediates++; + if (match_or_expand_immediate( v, + nr, + ureg->immediate[i].v, + &ureg->immediate[i].nr, + &swizzle )) + goto out; + } + + set_bad( ureg ); + +out: + return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ), + (swizzle >> 0) & 0x3, + (swizzle >> 2) & 0x3, + (swizzle >> 4) & 0x3, + (swizzle >> 6) & 0x3); +} + + +void +ureg_emit_src( struct ureg_program *ureg, + struct ureg_src src ) +{ + unsigned size = (1 + + (src.Absolute ? 1 : 0) + + (src.Indirect ? 1 : 0)); + + union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size ); + unsigned n = 0; + + out[n].value = 0; + out[n].src.File = src.File; + out[n].src.SwizzleX = src.SwizzleX; + out[n].src.SwizzleY = src.SwizzleY; + out[n].src.SwizzleZ = src.SwizzleZ; + out[n].src.SwizzleW = src.SwizzleW; + out[n].src.Indirect = src.Indirect; + out[n].src.Index = src.Index; + n++; + + if (src.Absolute) { + out[n].value = 0; + out[n].src_ext_mod.Absolute = 1; + n++; + } + + if (src.Indirect) { + out[n].value = 0; + out[n].src.File = TGSI_FILE_ADDRESS; + out[n].src.SwizzleX = TGSI_SWIZZLE_X; + out[n].src.SwizzleY = TGSI_SWIZZLE_X; + out[n].src.SwizzleZ = TGSI_SWIZZLE_X; + out[n].src.SwizzleW = TGSI_SWIZZLE_X; + out[n].src.Indirect = 0; + out[n].src.Index = 0; + n++; + } + + assert(n == size); +} + + +void +ureg_emit_dst( struct ureg_program *ureg, + struct ureg_dst dst ) +{ + unsigned size = (1 + + (dst.Indirect ? 1 : 0)); + + union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size ); + unsigned n = 0; + + out[n].value = 0; + out[n].dst.File = dst.File; + out[n].dst.WriteMask = dst.WriteMask; + out[n].dst.Indirect = dst.Indirect; + out[n].dst.Index = dst.Index; + n++; + + if (dst.Indirect) { + out[n].value = 0; + out[n].src.File = TGSI_FILE_ADDRESS; + out[n].src.SwizzleX = TGSI_SWIZZLE_X; + out[n].src.SwizzleY = TGSI_SWIZZLE_X; + out[n].src.SwizzleZ = TGSI_SWIZZLE_X; + out[n].src.SwizzleW = TGSI_SWIZZLE_X; + out[n].src.Indirect = 0; + out[n].src.Index = 0; + n++; + } + + assert(n == size); +} + + + +unsigned +ureg_emit_insn(struct ureg_program *ureg, + unsigned opcode, + boolean saturate, + unsigned num_dst, + unsigned num_src ) +{ + union tgsi_any_token *out; + + out = get_tokens( ureg, DOMAIN_INSN, 1 ); + out[0].value = 0; + out[0].insn.Type = TGSI_TOKEN_TYPE_INSTRUCTION; + out[0].insn.NrTokens = 0; + out[0].insn.Opcode = opcode; + out[0].insn.Saturate = saturate; + out[0].insn.NrTokens = 0; + out[0].insn.NumDstRegs = num_dst; + out[0].insn.NumSrcRegs = num_src; + out[0].insn.Padding = 0; + out[0].insn.Extended = 0; + + return ureg->domain[DOMAIN_INSN].count - 1; +} + + +void +ureg_emit_label(struct ureg_program *ureg, + unsigned insn_token, + unsigned *label_token ) +{ + union tgsi_any_token *out, *insn; + + out = get_tokens( ureg, DOMAIN_INSN, 1 ); + insn = retrieve_token( ureg, DOMAIN_INSN, insn_token ); + + insn->insn.Extended = 1; + + out[0].value = 0; + out[0].insn_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL; +} + + +void +ureg_emit_texture(struct ureg_program *ureg, + unsigned insn_token, + unsigned target ) +{ + union tgsi_any_token *out, *insn; + + out = get_tokens( ureg, DOMAIN_INSN, 1 ); + insn = retrieve_token( ureg, DOMAIN_INSN, insn_token ); + + insn->insn.Extended = 1; + + out[0].value = 0; + out[0].insn_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE; + out[0].insn_ext_texture.Texture = target; +} + + +void +ureg_fixup_insn_size(struct ureg_program *ureg, + unsigned insn ) +{ + union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn ); + + out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1; +} + + + + + +static void emit_decl( struct ureg_program *ureg, + unsigned file, + unsigned index, + unsigned semantic_name, + unsigned semantic_index, + unsigned interp ) +{ + union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 3 ); + + out[0].value = 0; + out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; + out[0].decl.NrTokens = 3; + out[0].decl.File = file; + out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */ + out[0].decl.Interpolate = interp; + out[0].decl.Semantic = 1; + + out[1].value = 0; + out[1].decl_range.First = + out[1].decl_range.Last = index; + + out[2].value = 0; + out[2].decl_semantic.SemanticName = semantic_name; + out[2].decl_semantic.SemanticIndex = semantic_index; + +} + + +static void emit_decl_range( struct ureg_program *ureg, + unsigned file, + unsigned first, + unsigned count ) +{ + union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 ); + + out[0].value = 0; + out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; + out[0].decl.NrTokens = 2; + out[0].decl.File = file; + out[0].decl.UsageMask = 0xf; + out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT; + out[0].decl.Semantic = 0; + + out[1].value = 0; + out[1].decl_range.First = first; + out[1].decl_range.Last = first + count - 1; +} + +static void emit_immediate( struct ureg_program *ureg, + const float *v ) +{ + union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 ); + + out[0].value = 0; + out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE; + out[0].imm.NrTokens = 5; + out[0].imm.DataType = TGSI_IMM_FLOAT32; + out[0].imm.Padding = 0; + out[0].imm.Extended = 0; + + out[1].imm_data.Float = v[0]; + out[2].imm_data.Float = v[1]; + out[3].imm_data.Float = v[2]; + out[4].imm_data.Float = v[3]; +} + + + + +static void emit_decls( struct ureg_program *ureg ) +{ + unsigned i; + + for (i = 0; i < ureg->nr_inputs; i++) { + emit_decl( ureg, + TGSI_FILE_INPUT, + i, + ureg->input[i].semantic_name, + ureg->input[i].semantic_index, + ureg->input[i].interp ); + } + + for (i = 0; i < ureg->nr_outputs; i++) { + emit_decl( ureg, + TGSI_FILE_OUTPUT, + i, + ureg->output[i].semantic_name, + ureg->output[i].semantic_index, + TGSI_INTERPOLATE_CONSTANT ); + } + + if (ureg->nr_samplers) { + emit_decl_range( ureg, + TGSI_FILE_SAMPLER, + 0, ureg->nr_samplers ); + } + + if (ureg->nr_constants) { + emit_decl_range( ureg, + TGSI_FILE_CONSTANT, + 0, ureg->nr_constants ); + } + + if (ureg->nr_temps) { + emit_decl_range( ureg, + TGSI_FILE_TEMPORARY, + 0, ureg->nr_temps ); + } + + for (i = 0; i < ureg->nr_immediates; i++) { + emit_immediate( ureg, + ureg->immediate[i].v ); + } +} + +/* Append the instruction tokens onto the declarations to build a + * contiguous stream suitable to send to the driver. + */ +static void copy_instructions( struct ureg_program *ureg ) +{ + unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count; + union tgsi_any_token *out = get_tokens( ureg, + DOMAIN_DECL, + nr_tokens ); + + memcpy(out, + ureg->domain[DOMAIN_INSN].tokens, + nr_tokens * sizeof out[0] ); +} + + +static void +fixup_header_size(struct ureg_program *ureg, + unsigned insn ) +{ + union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 ); + + out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 3; +} + + +static void +emit_header( struct ureg_program *ureg ) +{ + union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 3 ); + + out[0].version.MajorVersion = 1; + out[0].version.MinorVersion = 1; + out[0].version.Padding = 0; + + out[1].header.HeaderSize = 2; + out[1].header.BodySize = 0; + + out[2].processor.Processor = ureg->processor; + out[2].processor.Padding = 0; +} + + +void *ureg_create_shader( struct ureg_program *ureg ) +{ + struct pipe_shader_state state; + unsigned insn; + + emit_header( ureg ); + emit_decls( ureg ); + copy_instructions( ureg ); + fixup_header_size( ureg, insn ); + + if (ureg->domain[0].tokens == error_tokens || + ureg->domain[1].tokens == error_tokens) { + debug_printf("%s: error in generated shader\n", __FUNCTION__); + assert(0); + return NULL; + } + + state.tokens = (const struct tgsi_token *)ureg->domain[DOMAIN_DECL].tokens; + + if (0) { + debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__, + ureg->domain[DOMAIN_DECL].count); + tgsi_dump( state.tokens, 0 ); + } + + if (ureg->processor == TGSI_PROCESSOR_VERTEX) + return ureg->pipe->create_vs_state( ureg->pipe, &state ); + else + return ureg->pipe->create_fs_state( ureg->pipe, &state ); +} + + + + +struct ureg_program *ureg_create( struct pipe_context *pipe, + unsigned processor ) +{ + struct ureg_program *ureg = CALLOC_STRUCT( ureg_program ); + if (ureg == NULL) + return NULL; + + ureg->pipe = pipe; + ureg->processor = processor; + return ureg; +} + + +void ureg_destroy( struct ureg_program *ureg ) +{ + unsigned i; + + for (i = 0; i < Elements(ureg->domain); i++) { + if (ureg->domain[i].tokens && + ureg->domain[i].tokens != error_tokens) + FREE(ureg->domain[i].tokens); + } + + FREE(ureg); +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h new file mode 100644 index 0000000000..0a976fd63b --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -0,0 +1,439 @@ +/************************************************************************** + * + * 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 VMWARE, INC 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 TGSI_UREG_H +#define TGSI_UREG_H + +#include "pipe/p_compiler.h" +#include "pipe/p_shader_tokens.h" + +struct ureg_program; + +/* Almost a tgsi_src_register, but we need to pull in the Absolute + * flag from the _ext token. Indirect flag always implies ADDR[0]. + */ +struct ureg_src +{ + unsigned File : 4; /* TGSI_FILE_ */ + unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */ + unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */ + unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */ + unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */ + unsigned Pad : 1; /* BOOL */ + unsigned Indirect : 1; /* BOOL */ + unsigned Absolute : 1; /* BOOL */ + int Index : 16; /* SINT */ + unsigned Negate : 1; /* BOOL */ +}; + +/* Very similar to a tgsi_dst_register, removing unsupported fields + * and adding a Saturate flag. It's easier to push saturate into the + * destination register than to try and create a _SAT varient of each + * instruction function. + */ +struct ureg_dst +{ + unsigned File : 4; /* TGSI_FILE_ */ + unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ + unsigned Indirect : 1; /* BOOL */ + unsigned Saturate : 1; /* BOOL */ + int Index : 16; /* SINT */ + unsigned Pad1 : 5; + unsigned Pad2 : 1; /* BOOL */ +}; + +struct pipe_context; + +struct ureg_program * +ureg_create( struct pipe_context *pipe, + unsigned processor ); + +void * +ureg_create_shader( struct ureg_program * ); + +void +ureg_destroy( struct ureg_program * ); + + +/*********************************************************************** + * Convenience routine: + */ +static INLINE void *ureg_create_shader_and_destroy( struct ureg_program *p ) +{ + void *result = ureg_create_shader( p ); + ureg_destroy( p ); + return result; +} + + + +/*********************************************************************** + * Build shader declarations: + */ + +struct ureg_src +ureg_DECL_fs_input( struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index, + unsigned interp_mode ); + +struct ureg_src +ureg_DECL_vs_input( struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index ); + +struct ureg_dst +ureg_DECL_output( struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index ); + +struct ureg_src +ureg_DECL_immediate( struct ureg_program *, + const float *v, + unsigned nr ); + +struct ureg_src +ureg_DECL_constant( struct ureg_program * ); + +struct ureg_dst +ureg_DECL_temporary( struct ureg_program * ); + +void +ureg_release_temporary( struct ureg_program *ureg, + struct ureg_dst tmp ); + +struct ureg_src +ureg_DECL_sampler( struct ureg_program * ); + + +static INLINE struct ureg_src +ureg_DECL_immediate4f( struct ureg_program *ureg, + float a, float b, + float c, float d) +{ + float v[4]; + v[0] = a; + v[1] = b; + v[2] = c; + v[3] = d; + return ureg_DECL_immediate( ureg, v, 4 ); +} + +static INLINE struct ureg_src +ureg_DECL_immediate3f( struct ureg_program *ureg, + float a, float b, + float c) +{ + float v[3]; + v[0] = a; + v[1] = b; + v[2] = c; + return ureg_DECL_immediate( ureg, v, 3 ); +} + +static INLINE struct ureg_src +ureg_DECL_immediate2f( struct ureg_program *ureg, + float a, float b) +{ + float v[2]; + v[0] = a; + v[1] = b; + return ureg_DECL_immediate( ureg, v, 2 ); +} + +static INLINE struct ureg_src +ureg_DECL_immediate1f( struct ureg_program *ureg, + float a) +{ + float v[1]; + v[0] = a; + return ureg_DECL_immediate( ureg, v, 1 ); +} + +/*********************************************************************** + * Internal instruction helpers, don't call these directly: + */ + +unsigned +ureg_emit_insn(struct ureg_program *ureg, + unsigned opcode, + boolean saturate, + unsigned num_dst, + unsigned num_src ); + +void +ureg_emit_label(struct ureg_program *ureg, + unsigned insn_token, + unsigned *label_token ); + +void +ureg_emit_texture(struct ureg_program *ureg, + unsigned insn_token, + unsigned target ); + +void +ureg_emit_dst( struct ureg_program *ureg, + struct ureg_dst dst ); + +void +ureg_emit_src( struct ureg_program *ureg, + struct ureg_src src ); + +void +ureg_fixup_insn_size(struct ureg_program *ureg, + unsigned insn ); + + +#define OP00( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + +#define OP01( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_src src ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \ + ureg_emit_src( ureg, src ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + +#define OP00_LBL( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + unsigned *label_token ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \ + ureg_emit_label( ureg, insn, label_token ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + +#define OP01_LBL( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_src src, \ + unsigned *label_token ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \ + ureg_emit_label( ureg, insn, label_token ); \ + ureg_emit_src( ureg, src ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + +#define OP10( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 0 ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + + +#define OP11( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 1 ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + +#define OP12( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src0, \ + struct ureg_src src1 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + +#define OP12_TEX( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + unsigned target, \ + struct ureg_src src0, \ + struct ureg_src src1 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \ + ureg_emit_texture( ureg, insn, target ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + +#define OP13( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src0, \ + struct ureg_src src1, \ + struct ureg_src src2 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 3 ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_emit_src( ureg, src2 ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + +#define OP14_TEX( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + unsigned target, \ + struct ureg_src src0, \ + struct ureg_src src1, \ + struct ureg_src src2, \ + struct ureg_src src3 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 4 ); \ + ureg_emit_texture( ureg, insn, target ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_emit_src( ureg, src2 ); \ + ureg_emit_src( ureg, src3 ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + + +/* Use a template include to generate a correctly-typed ureg_OP() + * function for each TGSI opcode: + */ +#include "tgsi_opcode_tmp.h" + + +/*********************************************************************** + * Inline helpers for manipulating register structs: + */ +static INLINE struct ureg_src +ureg_negate( struct ureg_src reg ) +{ + reg.Negate ^= 1; + return reg; +} + +static INLINE struct ureg_src +ureg_abs( struct ureg_src reg ) +{ + reg.Absolute = 1; + reg.Negate = 0; + return reg; +} + +static INLINE struct ureg_src +ureg_swizzle( struct ureg_src reg, + int x, int y, int z, int w ) +{ + unsigned swz = ( (reg.SwizzleX << 0) | + (reg.SwizzleY << 2) | + (reg.SwizzleZ << 4) | + (reg.SwizzleW << 6)); + + reg.SwizzleX = (swz >> (x*2)) & 0x3; + reg.SwizzleY = (swz >> (y*2)) & 0x3; + reg.SwizzleZ = (swz >> (z*2)) & 0x3; + reg.SwizzleW = (swz >> (w*2)) & 0x3; + return reg; +} + +static INLINE struct ureg_src +ureg_scalar( struct ureg_src reg, int x ) +{ + return ureg_swizzle(reg, x, x, x, x); +} + +static INLINE struct ureg_dst +ureg_writemask( struct ureg_dst reg, + unsigned writemask ) +{ + reg.WriteMask &= writemask; + return reg; +} + +static INLINE struct ureg_dst +ureg_saturate( struct ureg_dst reg ) +{ + reg.Saturate = 1; + return reg; +} + +static INLINE struct ureg_dst +ureg_dst( struct ureg_src src ) +{ + struct ureg_dst dst; + + dst.File = src.File; + dst.WriteMask = TGSI_WRITEMASK_XYZW; + dst.Indirect = src.Indirect; + dst.Saturate = 0; + dst.Index = src.Index; + dst.Pad1 = 0; + dst.Pad2 = 0; + + return dst; +} + +static INLINE struct ureg_src +ureg_src( struct ureg_dst dst ) +{ + struct ureg_src src; + + src.File = dst.File; + src.SwizzleX = TGSI_SWIZZLE_X; + src.SwizzleY = TGSI_SWIZZLE_Y; + src.SwizzleZ = TGSI_SWIZZLE_Z; + src.SwizzleW = TGSI_SWIZZLE_W; + src.Pad = 0; + src.Indirect = dst.Indirect; + src.Absolute = 0; + src.Index = dst.Index; + src.Negate = 0; + + return src; +} + + + +#endif diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 414cf91025..cda6dbd46d 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -45,6 +45,7 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_simple_shaders.h" +#include "util/u_surface.h" #include "cso_cache/cso_context.h" @@ -155,7 +156,11 @@ util_destroy_blit(struct blit_state *ctx) } -static unsigned get_next_slot( struct blit_state *ctx ) +/** + * Get offset of next free slot in vertex buffer for quad vertices. + */ +static unsigned +get_next_slot( struct blit_state *ctx ) { const unsigned max_slots = 4096 / sizeof ctx->vertices; @@ -173,7 +178,6 @@ static unsigned get_next_slot( struct blit_state *ctx ) } - /** * Setup vertex data for the textured quad we'll draw. * Note: y=0=top @@ -260,9 +264,38 @@ setup_vertex_data_tex(struct blit_state *ctx, return offset; } + + +/** + * \return TRUE if two regions overlap, FALSE otherwise + */ +static boolean +regions_overlap(int srcX0, int srcY0, + int srcX1, int srcY1, + int dstX0, int dstY0, + int dstX1, int dstY1) +{ + if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1)) + return FALSE; /* src completely left of dst */ + + if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1)) + return FALSE; /* dst completely left of src */ + + if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1)) + return FALSE; /* src completely above dst */ + + if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1)) + return FALSE; /* dst completely above src */ + + return TRUE; /* some overlap */ +} + + /** * Copy pixel block from src surface to dst surface. * Overlapping regions are acceptable. + * Flipping and stretching are supported. + * XXX what about clipping??? * XXX need some control over blitting Z and/or stencil. */ void @@ -285,10 +318,41 @@ util_blit_pixels(struct blit_state *ctx, const int srcLeft = MIN2(srcX0, srcX1); const int srcTop = MIN2(srcY0, srcY1); unsigned offset; + boolean overlap; assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); + assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_SAMPLER, 0)); + assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); + + /* do the regions overlap? */ + overlap = util_same_surface(src, dst) && + regions_overlap(srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1); + + /* + * Check for simple case: no format conversion, no flipping, no stretching, + * no overlapping. + * Filter mode should not matter since there's no stretching. + */ + if (dst->format == src->format && + srcX0 < srcX1 && + dstX0 < dstX1 && + srcY0 < srcY1 && + dstY0 < dstY1 && + (dstX1 - dstX0) == (srcX1 - srcX0) && + (dstY1 - dstY0) == (srcY1 - srcY0) && + !overlap) { + pipe->surface_copy(pipe, + dst, dstX0, dstY0, /* dest */ + src, srcX0, srcY0, /* src */ + srcW, srcH); /* size */ + return; + } + if (srcLeft != srcX0) { /* left-right flip */ int tmp = dstX0; @@ -303,20 +367,6 @@ util_blit_pixels(struct blit_state *ctx, dstY1 = tmp; } - assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_SAMPLER, 0)); - assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_SAMPLER, 0)); - - if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) { - /* FIXME: this will most surely fail for overlapping rectangles */ - pipe->surface_copy(pipe, - dst, dstX0, dstY0, /* dest */ - src, srcX0, srcY0, /* src */ - srcW, srcH); /* size */ - return; - } - assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index a5ca0b72bd..96d400c839 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -143,11 +143,9 @@ void _debug_vprintf(const char *format, va_list ap) #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) /* TODO */ #else /* !PIPE_SUBSYSTEM_WINDOWS */ -#ifdef DEBUG fflush(stdout); vfprintf(stderr, format, ap); #endif -#endif } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index ca797486a0..edc37561ab 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -46,10 +46,6 @@ #include "util/u_gen_mipmap.h" #include "util/u_simple_shaders.h" -#include "tgsi/tgsi_build.h" -#include "tgsi/tgsi_dump.h" -#include "tgsi/tgsi_parse.h" - #include "cso_cache/cso_context.h" diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index e5003af01d..57410e78b0 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -53,11 +53,11 @@ __inline double ceil(double val) { double ceil_val; - if((val - (long) val) == 0) { + if ((val - (long) val) == 0) { ceil_val = val; } else { - if(val > 0) { + if (val > 0) { ceil_val = (long) val + 1; } else { @@ -73,11 +73,11 @@ __inline double floor(double val) { double floor_val; - if((val - (long) val) == 0) { + if ((val - (long) val) == 0) { floor_val = val; } else { - if(val > 0) { + if (val > 0) { floor_val = (long) val; } else { @@ -189,7 +189,10 @@ static INLINE double log2( double x ) extern float pow2_table[POW2_TABLE_SIZE]; - +/** + * Initialize math module. This should be called before using any + * other functions in this module. + */ extern void util_init_math(void); @@ -216,23 +219,24 @@ util_fast_exp2(float x) int32_t ipart; float fpart, mpart; union fi epart; - + if(x > 129.00000f) return 3.402823466e+38f; - - if(x < -126.99999f) + + if (x < -126.99999f) return 0.0f; ipart = (int32_t) x; fpart = x - (float) ipart; - + /* same as * epart.f = (float) (1 << ipart) - * but faster and without integer overflow for ipart > 31 */ + * but faster and without integer overflow for ipart > 31 + */ epart.i = (ipart + 127 ) << 23; - + mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)]; - + return epart.f * mpart; } @@ -254,6 +258,9 @@ util_fast_exp(float x) extern float log2_table[LOG2_TABLE_SIZE]; +/** + * Fast approximation to log2(x). + */ static INLINE float util_fast_log2(float x) { @@ -267,6 +274,9 @@ util_fast_log2(float x) } +/** + * Fast approximation to x^y. + */ static INLINE float util_fast_pow(float x, float y) { @@ -274,7 +284,6 @@ util_fast_pow(float x, float y) } - /** * Floor(x), returned as int. */ @@ -284,8 +293,8 @@ util_ifloor(float f) int ai, bi; double af, bf; union fi u; - af = (3 << 22) + 0.5 + (double)f; - bf = (3 << 22) + 0.5 - (double)f; + af = (3 << 22) + 0.5 + (double) f; + bf = (3 << 22) + 0.5 - (double) f; u.f = (float) af; ai = u.i; u.f = (float) bf; bi = u.i; return (ai - bi) >> 1; @@ -305,9 +314,9 @@ util_iround(float f) #elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) int r; _asm { - fld f - fistp r - } + fld f + fistp r + } return r; #else if (f >= 0.0f) @@ -340,7 +349,7 @@ static INLINE unsigned long ffs( unsigned long u ) { unsigned long i; - if(_BitScanForward(&i, u)) + if (_BitScanForward(&i, u)) return i + 1; else return 0; @@ -351,7 +360,7 @@ unsigned ffs( unsigned u ) { unsigned i; - if( u == 0 ) { + if (u == 0) { return 0; } @@ -378,7 +387,10 @@ fui( float f ) } - +/** + * Convert ubyte to float in [0, 1]. + * XXX a 256-entry lookup table would be slightly faster. + */ static INLINE float ubyte_to_float(ubyte ub) { @@ -409,7 +421,23 @@ float_to_ubyte(float f) } +/** + * Calc log base 2 + */ +static INLINE unsigned +util_logbase2(unsigned n) +{ + unsigned log2 = 0; + while (n >>= 1) + ++log2; + return log2; +} + +/** + * Clamp X to [MIN, MAX]. + * This is a macro to allow float, int, uint, etc. types. + */ #define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) @@ -422,6 +450,11 @@ align(int value, int alignment) return (value + alignment - 1) & ~(alignment - 1); } +static INLINE unsigned +minify(unsigned value) +{ + return MAX2(1, value >> 1); +} #ifndef COPY_4V #define COPY_4V( DST, SRC ) \ diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h index 0b18d043ad..c3f8c91833 100644 --- a/src/gallium/auxiliary/util/u_memory.h +++ b/src/gallium/auxiliary/util/u_memory.h @@ -100,8 +100,14 @@ ExFreePool(void *P); #define MALLOC( SIZE ) malloc( SIZE ) #define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE ) #define FREE( PTR ) free( PTR ) -#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE ) +static INLINE void * +_REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) +{ + (void) old_size; + return realloc(old_ptr, new_size); +} +#define REALLOC( a, b, c ) _REALLOC( a, b, c ) #endif diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c index 151a480d34..4b75d4ba1d 100644 --- a/src/gallium/auxiliary/util/u_mm.c +++ b/src/gallium/auxiliary/util/u_mm.c @@ -33,30 +33,32 @@ void u_mmDumpMemInfo(const struct mem_block *heap) { - debug_printf("Memory heap %p:\n", (void *)heap); + debug_printf("Memory heap %p:\n", (void *) heap); if (heap == 0) { debug_printf(" heap == 0\n"); - } else { + } + else { const struct mem_block *p; - for(p = heap->next; p != heap; p = p->next) { - debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); + for (p = heap->next; p != heap; p = p->next) { + debug_printf(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); } debug_printf("\nFree list:\n"); - for(p = heap->next_free; p != heap; p = p->next_free) { - debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); + for (p = heap->next_free; p != heap; p = p->next_free) { + debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); } } debug_printf("End of memory blocks\n"); } + struct mem_block * u_mmInit(int ofs, int size) { diff --git a/src/gallium/auxiliary/util/u_mm.h b/src/gallium/auxiliary/util/u_mm.h index ce20e48763..6b158aae6e 100644 --- a/src/gallium/auxiliary/util/u_mm.h +++ b/src/gallium/auxiliary/util/u_mm.h @@ -84,7 +84,7 @@ extern struct mem_block *u_mmFindBlock(struct mem_block *heap, int start); extern void u_mmDestroy(struct mem_block *mmInit); /** - * For debuging purpose. + * For debugging purposes. */ extern void u_mmDumpMemInfo(const struct mem_block *mmInit); diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c index 8114b53cd0..f01296b40f 100644 --- a/src/gallium/auxiliary/util/u_simple_screen.c +++ b/src/gallium/auxiliary/util/u_simple_screen.c @@ -65,12 +65,13 @@ pass_surface_buffer_create(struct pipe_screen *screen, unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride) { struct pipe_buffer *buffer = screen->winsys->surface_buffer_create(screen->winsys, width, height, - format, usage, stride); + format, usage, tex_usage, stride); buffer->screen = screen; diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index e519c354d2..1152d62e73 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -42,9 +42,7 @@ #include "util/u_memory.h" #include "util/u_simple_shaders.h" -#include "tgsi/tgsi_build.h" -#include "tgsi/tgsi_dump.h" -#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_ureg.h" @@ -58,93 +56,31 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, const uint *semantic_indexes) { - struct pipe_shader_state shader; - struct tgsi_token tokens[100]; - struct tgsi_header *header; - struct tgsi_processor *processor; - struct tgsi_full_declaration decl; - struct tgsi_full_instruction inst; - const uint procType = TGSI_PROCESSOR_VERTEX; - uint ti, i; + struct ureg_program *ureg; + uint i; - /* shader header - */ - *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + ureg = ureg_create( pipe, TGSI_PROCESSOR_VERTEX ); + if (ureg == NULL) + return NULL; - header = (struct tgsi_header *) &tokens[1]; - *header = tgsi_build_header(); - - processor = (struct tgsi_processor *) &tokens[2]; - *processor = tgsi_build_processor( procType, header ); - - ti = 3; - - /* declare inputs */ - for (i = 0; i < num_attribs; i++) { - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = semantic_names[i]; - decl.Semantic.SemanticIndex = semantic_indexes[i]; - - decl.DeclarationRange.First = - decl.DeclarationRange.Last = i; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - Elements(tokens) - ti); - } - - /* declare outputs */ for (i = 0; i < num_attribs; i++) { - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_OUTPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = semantic_names[i]; - decl.Semantic.SemanticIndex = semantic_indexes[i]; - decl.DeclarationRange.First = - decl.DeclarationRange.Last = i; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - Elements(tokens) - ti); + struct ureg_src src; + struct ureg_dst dst; + + src = ureg_DECL_vs_input( ureg, + semantic_names[i], + semantic_indexes[i]); + + dst = ureg_DECL_output( ureg, + semantic_names[i], + semantic_indexes[i]); + + ureg_MOV( ureg, dst, src ); } - /* emit MOV instructions */ - for (i = 0; i < num_attribs; i++) { - /* MOVE out[i], in[i]; */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_MOV; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = i; - inst.Instruction.NumSrcRegs = 1; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = i; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - Elements(tokens) - ti ); - } - - /* END instruction */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_END; - inst.Instruction.NumDstRegs = 0; - inst.Instruction.NumSrcRegs = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - Elements(tokens) - ti ); - -#if 0 /*debug*/ - tgsi_dump(tokens, 0); -#endif - - shader.tokens = tokens; + ureg_END( ureg ); - return pipe->create_vs_state(pipe, &shader); + return ureg_create_shader_and_destroy( ureg ); } @@ -158,99 +94,29 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, void * util_make_fragment_tex_shader(struct pipe_context *pipe) { - struct pipe_shader_state shader; - struct tgsi_token tokens[100]; - struct tgsi_header *header; - struct tgsi_processor *processor; - struct tgsi_full_declaration decl; - struct tgsi_full_instruction inst; - const uint procType = TGSI_PROCESSOR_FRAGMENT; - uint ti; - - /* shader header - */ - *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); - - header = (struct tgsi_header *) &tokens[1]; - *header = tgsi_build_header(); - - processor = (struct tgsi_processor *) &tokens[2]; - *processor = tgsi_build_processor( procType, header ); - - ti = 3; - - /* declare TEX[0] input */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - /* XXX this could be linear... */ - decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; - decl.Semantic.SemanticIndex = 0; - decl.DeclarationRange.First = - decl.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - Elements(tokens) - ti); - - /* declare color[0] output */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_OUTPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; - decl.Semantic.SemanticIndex = 0; - decl.DeclarationRange.First = - decl.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - Elements(tokens) - ti); - - /* declare sampler */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.DeclarationRange.First = - decl.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - Elements(tokens) - ti); - - /* TEX instruction */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_TEX; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = 0; - inst.Instruction.NumSrcRegs = 2; - inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 0; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - inst.FullSrcRegisters[1].SrcRegister.Index = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - Elements(tokens) - ti ); - - /* END instruction */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_END; - inst.Instruction.NumDstRegs = 0; - inst.Instruction.NumSrcRegs = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - Elements(tokens) - ti ); - -#if 0 /*debug*/ - tgsi_dump(tokens, 0); -#endif - - shader.tokens = tokens; - - return pipe->create_fs_state(pipe, &shader); + struct ureg_program *ureg; + struct ureg_src sampler; + struct ureg_src tex; + struct ureg_dst out; + + ureg = ureg_create( pipe, TGSI_PROCESSOR_FRAGMENT ); + if (ureg == NULL) + return NULL; + + sampler = ureg_DECL_sampler( ureg ); + + tex = ureg_DECL_fs_input( ureg, + TGSI_SEMANTIC_GENERIC, 0, + TGSI_INTERPOLATE_PERSPECTIVE ); + + out = ureg_DECL_output( ureg, + TGSI_SEMANTIC_COLOR, + 0 ); + + ureg_TEX( ureg, out, TGSI_TEXTURE_2D, tex, sampler ); + ureg_END( ureg ); + + return ureg_create_shader_and_destroy( ureg ); } @@ -263,87 +129,23 @@ util_make_fragment_tex_shader(struct pipe_context *pipe) void * util_make_fragment_passthrough_shader(struct pipe_context *pipe) { - struct pipe_shader_state shader; - struct tgsi_token tokens[40]; - struct tgsi_header *header; - struct tgsi_processor *processor; - struct tgsi_full_declaration decl; - struct tgsi_full_instruction inst; - const uint procType = TGSI_PROCESSOR_FRAGMENT; - uint ti; - - /* shader header - */ - *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); - - header = (struct tgsi_header *) &tokens[1]; - *header = tgsi_build_header(); - - processor = (struct tgsi_processor *) &tokens[2]; - *processor = tgsi_build_processor( procType, header ); - - ti = 3; - - /* declare input */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; - decl.Semantic.SemanticIndex = 0; - decl.DeclarationRange.First = - decl.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - Elements(tokens) - ti); - - /* declare output */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_OUTPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; - decl.Semantic.SemanticIndex = 0; - decl.DeclarationRange.First = - decl.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - Elements(tokens) - ti); - - - /* MOVE out[0], in[0]; */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_MOV; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = 0; - inst.Instruction.NumSrcRegs = 1; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - Elements(tokens) - ti ); - - /* END instruction */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_END; - inst.Instruction.NumDstRegs = 0; - inst.Instruction.NumSrcRegs = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - Elements(tokens) - ti ); - - assert(ti < Elements(tokens)); - -#if 0 /*debug*/ - tgsi_dump(tokens, 0); -#endif - - shader.tokens = tokens; - - return pipe->create_fs_state(pipe, &shader); + struct ureg_program *ureg; + struct ureg_src src; + struct ureg_dst dst; + + ureg = ureg_create( pipe, TGSI_PROCESSOR_FRAGMENT ); + if (ureg == NULL) + return NULL; + + src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0, + TGSI_INTERPOLATE_PERSPECTIVE ); + + dst = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ); + + ureg_MOV( ureg, dst, src ); + ureg_END( ureg ); + + return ureg_create_shader_and_destroy( ureg ); } diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h index a5b73cfc20..ce84ed7ad0 100644 --- a/src/gallium/auxiliary/util/u_surface.h +++ b/src/gallium/auxiliary/util/u_surface.h @@ -37,6 +37,23 @@ struct pipe_texture; struct pipe_surface; +/** + * Are s1 and s2 the same surface? + * Surfaces are basically views into textures so check if the two surfaces + * name the same part of the same texture. + */ +static INLINE boolean +util_same_surface(const struct pipe_surface *s1, const struct pipe_surface *s2) +{ + return (s1->texture == s2->texture && + s1->face == s2->face && + s1->level == s2->level && + s1->zslice == s2->zslice); +} + + + + extern boolean util_create_rgba_surface(struct pipe_screen *screen, uint width, uint height, diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index a0c8ed88f7..422bc76003 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -153,7 +153,7 @@ a8r8g8b8_put_tile_rgba(unsigned *dst, } -/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ +/*** PIPE_FORMAT_X8R8G8B8_UNORM ***/ static void x8r8g8b8_get_tile_rgba(const unsigned *src, diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index 5268cbf79c..c16cdd0b22 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -35,7 +35,7 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) #include <sys/time.h> #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) #include <windows.h> @@ -77,7 +77,7 @@ util_time_get_frequency(void) void util_time_get(struct util_time *t) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) gettimeofday(&t->tv, NULL); #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) LONGLONG temp; @@ -102,7 +102,7 @@ util_time_add(const struct util_time *t1, int64_t usecs, struct util_time *t2) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000; t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000; #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) @@ -124,7 +124,7 @@ int64_t util_time_diff(const struct util_time *t1, const struct util_time *t2) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) return (t2->tv.tv_usec - t1->tv.tv_usec) + (t2->tv.tv_sec - t1->tv.tv_sec)*1000000; #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) @@ -144,7 +144,7 @@ util_time_micros( void ) util_time_get(&t1); -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) return t1.tv.tv_usec + t1.tv.tv_sec*1000000LL; #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) util_time_get_frequency(); @@ -166,7 +166,7 @@ static INLINE int util_time_compare(const struct util_time *t1, const struct util_time *t2) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) if (t1->tv.tv_sec < t2->tv.tv_sec) return -1; else if(t1->tv.tv_sec > t2->tv.tv_sec) diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index 6bca6077a2..7a5c54d9b2 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -38,7 +38,7 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) #include <time.h> /* timeval */ #include <unistd.h> /* usleep */ #endif @@ -58,7 +58,7 @@ extern "C" { */ struct util_time { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) struct timeval tv; #else int64_t counter; @@ -89,7 +89,7 @@ util_time_timeout(const struct util_time *start, const struct util_time *end, const struct util_time *curr); -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) #define util_time_sleep usleep #else void diff --git a/src/gallium/auxiliary/util/u_timed_winsys.c b/src/gallium/auxiliary/util/u_timed_winsys.c index 77b2a3a1c8..178acdca4d 100644 --- a/src/gallium/auxiliary/util/u_timed_winsys.c +++ b/src/gallium/auxiliary/util/u_timed_winsys.c @@ -212,13 +212,14 @@ timed_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride) { struct pipe_winsys *backend = timed_winsys(winsys)->backend; uint64_t start = time_start(); struct pipe_buffer *ret = backend->surface_buffer_create( backend, width, height, - format, usage, stride ); + format, usage, tex_usage, stride ); time_finish(winsys, start, 7, __FUNCTION__); diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fp.c b/src/gallium/drivers/cell/ppu/cell_gen_fp.c index 5a889a6119..58a8b5d0b0 100644 --- a/src/gallium/drivers/cell/ppu/cell_gen_fp.c +++ b/src/gallium/drivers/cell/ppu/cell_gen_fp.c @@ -1834,9 +1834,9 @@ emit_instruction(struct codegen *gen, case TGSI_OPCODE_ENDIF: return emit_ENDIF(gen, inst); - case TGSI_OPCODE_BGNLOOP2: + case TGSI_OPCODE_BGNLOOP: return emit_BGNLOOP(gen, inst); - case TGSI_OPCODE_ENDLOOP2: + case TGSI_OPCODE_ENDLOOP: return emit_ENDLOOP(gen, inst); case TGSI_OPCODE_BRK: return emit_BRK(gen, inst); @@ -1875,9 +1875,9 @@ emit_immediate(struct codegen *gen, const struct tgsi_full_immediate *immed) assert(gen->num_imm < MAX_TEMPS); for (ch = 0; ch < 4; ch++) { - float val = immed->u.ImmediateFloat32[ch].Float; + float val = immed->u[ch].Float; - if (ch > 0 && val == immed->u.ImmediateFloat32[ch - 1].Float) { + if (ch > 0 && val == immed->u[ch - 1].Float) { /* re-use previous register */ gen->imm_regs[gen->num_imm][ch] = gen->imm_regs[gen->num_imm][ch - 1]; } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index e26594448f..6a63a0e6ce 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -44,13 +44,6 @@ -static unsigned -minify(unsigned d) -{ - return MAX2(1, d>>1); -} - - static void cell_texture_layout(struct cell_texture *ct) { @@ -424,7 +417,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer) if (!ctrans->map) return NULL; /* out of memory */ - if (transfer->usage & PIPE_TRANSFER_READ) { + if (transfer->usage == PIPE_TRANSFER_READ || + transfer->usage == PIPE_TRANSFER_READ_WRITE) { /* need to untwiddle the texture to make a linear version */ const uint bpp = pf_get_size(ct->base.format); if (bpp == 4) { @@ -465,7 +459,8 @@ cell_transfer_unmap(struct pipe_screen *screen, PIPE_BUFFER_USAGE_CPU_READ); } - if (transfer->usage & PIPE_TRANSFER_WRITE) { + if (transfer->usage == PIPE_TRANSFER_WRITE || + transfer->usage == PIPE_TRANSFER_READ_WRITE) { /* The user wrote new texture data into the mapped buffer. * We need to convert the new linear data into the twiddled/tiled format. */ diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index e27df2dfb3..6db9501128 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -952,7 +952,6 @@ exec_instruction( break; case TGSI_OPCODE_RCP: - /* TGSI_OPCODE_RECIP */ FETCH( &r[0], 0, CHAN_X ); r[0].q = micro_div(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, r[0].q); FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { @@ -961,7 +960,6 @@ exec_instruction( break; case TGSI_OPCODE_RSQ: - /* TGSI_OPCODE_RECIPSQRT */ FETCH( &r[0], 0, CHAN_X ); r[0].q = micro_sqrt(r[0].q); r[0].q = micro_div(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, r[0].q); @@ -1115,7 +1113,6 @@ exec_instruction( break; case TGSI_OPCODE_MAD: - /* TGSI_OPCODE_MADD */ FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); FETCH( &r[1], 1, chan_index ); @@ -1136,8 +1133,7 @@ exec_instruction( } break; - case TGSI_OPCODE_LERP: - /* TGSI_OPCODE_LRP */ + case TGSI_OPCODE_LRP: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH(&r[0], 0, chan_index); FETCH(&r[1], 1, chan_index); @@ -1158,21 +1154,11 @@ exec_instruction( ASSERT (0); break; - case TGSI_OPCODE_DOT2ADD: - /* TGSI_OPCODE_DP2A */ + case TGSI_OPCODE_DP2A: ASSERT (0); break; - case TGSI_OPCODE_INDEX: - ASSERT (0); - break; - - case TGSI_OPCODE_NEGATE: - ASSERT (0); - break; - - case TGSI_OPCODE_FRAC: - /* TGSI_OPCODE_FRC */ + case TGSI_OPCODE_FRC: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); r[0].q = micro_frc(r[0].q); @@ -1184,8 +1170,7 @@ exec_instruction( ASSERT (0); break; - case TGSI_OPCODE_FLOOR: - /* TGSI_OPCODE_FLR */ + case TGSI_OPCODE_FLR: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); r[0].q = micro_flr(r[0].q); @@ -1201,8 +1186,7 @@ exec_instruction( } break; - case TGSI_OPCODE_EXPBASE2: - /* TGSI_OPCODE_EX2 */ + case TGSI_OPCODE_EX2: FETCH(&r[0], 0, CHAN_X); r[0].q = micro_pow(mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].q, r[0].q); @@ -1212,8 +1196,7 @@ exec_instruction( } break; - case TGSI_OPCODE_LOGBASE2: - /* TGSI_OPCODE_LG2 */ + case TGSI_OPCODE_LG2: FETCH( &r[0], 0, CHAN_X ); r[0].q = micro_lg2(r[0].q); FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { @@ -1221,8 +1204,7 @@ exec_instruction( } break; - case TGSI_OPCODE_POWER: - /* TGSI_OPCODE_POW */ + case TGSI_OPCODE_POW: FETCH(&r[0], 0, CHAN_X); FETCH(&r[1], 1, CHAN_X); @@ -1233,7 +1215,7 @@ exec_instruction( } break; - case TGSI_OPCODE_CROSSPRODUCT: + case TGSI_OPCODE_XPD: /* TGSI_OPCODE_XPD */ FETCH(&r[0], 0, CHAN_Y); FETCH(&r[1], 1, CHAN_Z); @@ -1275,10 +1257,6 @@ exec_instruction( } break; - case TGSI_OPCODE_MULTIPLYMATRIX: - ASSERT (0); - break; - case TGSI_OPCODE_ABS: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH(&r[0], 0, chan_index); @@ -1780,9 +1758,9 @@ exec_instruction( mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; break; - case TGSI_OPCODE_LOOP: + case TGSI_OPCODE_BGNFOR: /* fall-through (for now) */ - case TGSI_OPCODE_BGNLOOP2: + case TGSI_OPCODE_BGNLOOP: /* push LoopMask and ContMasks */ ASSERT(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; @@ -1790,9 +1768,9 @@ exec_instruction( mach->ContStack[mach->ContStackTop++] = mach->ContMask; break; - case TGSI_OPCODE_ENDLOOP: + case TGSI_OPCODE_ENDFOR: /* fall-through (for now at least) */ - case TGSI_OPCODE_ENDLOOP2: + case TGSI_OPCODE_ENDLOOP: /* Restore ContMask, but don't pop */ ASSERT(mach->ContStackTop > 0); mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h index a433cf054d..c6e68ea38a 100644 --- a/src/gallium/drivers/i915simple/i915_batch.h +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -50,8 +50,8 @@ i915_batchbuffer_check( struct i915_batchbuffer *batch, size_t dwords, size_t relocs ) { - /** TODO JB: Check relocs */ - return dwords * 4 <= batch->size - (batch->ptr - batch->map); + return dwords * 4 <= batch->size - (batch->ptr - batch->map) && + relocs <= (batch->max_relocs - batch->relocs); } static INLINE size_t diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index ccf9bb31fb..bf69c8e9f5 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -142,10 +142,14 @@ i915_is_texture_referenced( struct pipe_context *pipe, unsigned face, unsigned level) { /** - * FIXME: Optimize. + * FIXME: Return the corrent result. We can't alays return referenced + * since it causes a double flush within the vbo module. */ - +#if 0 return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +#else + return 0; +#endif } static unsigned int @@ -153,10 +157,14 @@ i915_is_buffer_referenced( struct pipe_context *pipe, struct pipe_buffer *buf) { /** - * FIXME: Optimize. + * FIXME: Return the corrent result. We can't alays return referenced + * since it causes a double flush within the vbo module. */ - +#if 0 return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +#else + return 0; +#endif } diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 961c1bf213..89504ced27 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -975,8 +975,9 @@ i915_translate_instructions(struct i915_fp_compile *p, = &parse.FullToken.FullImmediate; const uint pos = p->num_immediates++; uint j; + assert( imm->Immediate.NrTokens <= 4 + 1 ); for (j = 0; j < imm->Immediate.NrTokens - 1; j++) { - p->immediates[pos][j] = imm->u.ImmediateFloat32[j].Float; + p->immediates[pos][j] = imm->u[j].Float; } } break; diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index f4aa8e60d8..a3de38d586 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -232,6 +232,8 @@ i915_get_tex_transfer(struct pipe_screen *screen, if (trans) { pipe_texture_reference(&trans->base.texture, texture); trans->base.format = trans->base.format; + trans->base.x = x; + trans->base.y = y; trans->base.width = w; trans->base.height = h; trans->base.block = texture->block; diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index ca8e87af8d..03f0e14e7c 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -72,11 +72,6 @@ static const int step_offsets[6][2] = { {-1, 1} }; -static unsigned minify( unsigned d ) -{ - return MAX2(1, d>>1); -} - static unsigned power_of_two(unsigned x) { @@ -160,10 +155,10 @@ i915_miptree_set_image_offset(struct i915_texture *tex, /** - * Special case to deal with display targets. + * Special case to deal with scanout textures. */ static boolean -i915_displaytarget_layout(struct i915_texture *tex) +i915_scanout_layout(struct i915_texture *tex) { struct pipe_texture *pt = &tex->base; @@ -177,9 +172,13 @@ i915_displaytarget_layout(struct i915_texture *tex) i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); if (tex->base.width[0] >= 128) { +#if 0 tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size); +#else + tex->stride = 2048 * 4; /* TODO fix when backend is smarter */ +#endif tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8); -#if 0 /* used for tiled display targets */ +#if 0 /* used for tiled textures */ tex->tiled = 1; #endif } else { @@ -209,9 +208,9 @@ i945_miptree_layout_2d( struct i915_texture *tex ) unsigned nblocksx = pt->nblocksx[0]; unsigned nblocksy = pt->nblocksy[0]; - /* used for tiled display targets */ - if (0) - if (i915_displaytarget_layout(tex)) + /* used for scanouts that need special layouts */ + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) + if (i915_scanout_layout(tex)) return; tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); @@ -584,6 +583,7 @@ i915_texture_create(struct pipe_screen *screen, struct i915_screen *i915screen = i915_screen(screen); struct i915_texture *tex = CALLOC_STRUCT(i915_texture); size_t tex_size; + unsigned buf_usage = 0; if (!tex) return NULL; @@ -605,9 +605,11 @@ i915_texture_create(struct pipe_screen *screen, tex_size = tex->stride * tex->total_nblocksy; - tex->buffer = screen->buffer_create(screen, 64, - PIPE_BUFFER_USAGE_PIXEL, - tex_size); + buf_usage = PIPE_BUFFER_USAGE_PIXEL; + if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) + buf_usage |= I915_BUFFER_USAGE_SCANOUT; + + tex->buffer = screen->buffer_create(screen, 64, buf_usage, tex_size); if (!tex->buffer) goto fail; diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index ff5b34f193..711db91c36 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -109,6 +109,7 @@ struct i915_winsys { #define I915_BUFFER_ACCESS_READ 0x2 #define I915_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0) +#define I915_BUFFER_USAGE_SCANOUT (PIPE_BUFFER_USAGE_CUSTOM << 1) /** diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 8aea8c0558..998ffaeac4 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -65,11 +65,6 @@ unsigned intel_compressed_alignment(unsigned internalFormat) } #endif -static unsigned minify( unsigned d ) -{ - return MAX2(1, d>>1); -} - static void intel_miptree_set_image_offset(struct brw_texture *tex, unsigned level, diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c index e03d653482..3ee82d95b3 100644 --- a/src/gallium/drivers/i965simple/brw_vs_emit.c +++ b/src/gallium/drivers/i965simple/brw_vs_emit.c @@ -1294,10 +1294,10 @@ void brw_vs_emit(struct brw_vs_compile *c) case TGSI_TOKEN_TYPE_IMMEDIATE: { struct tgsi_full_immediate *imm = &parse.FullToken.FullImmediate; assert(imm->Immediate.NrTokens == 4 + 1); - c->prog_data.imm_buf[c->prog_data.num_imm][0] = imm->u.ImmediateFloat32[0].Float; - c->prog_data.imm_buf[c->prog_data.num_imm][1] = imm->u.ImmediateFloat32[1].Float; - c->prog_data.imm_buf[c->prog_data.num_imm][2] = imm->u.ImmediateFloat32[2].Float; - c->prog_data.imm_buf[c->prog_data.num_imm][3] = imm->u.ImmediateFloat32[3].Float; + c->prog_data.imm_buf[c->prog_data.num_imm][0] = imm->u[0].Float; + c->prog_data.imm_buf[c->prog_data.num_imm][1] = imm->u[1].Float; + c->prog_data.imm_buf[c->prog_data.num_imm][2] = imm->u[2].Float; + c->prog_data.imm_buf[c->prog_data.num_imm][3] = imm->u[3].Float; c->prog_data.num_imm++; } break; diff --git a/src/gallium/drivers/i965simple/brw_wm_glsl.c b/src/gallium/drivers/i965simple/brw_wm_glsl.c index ab6410aa60..db75963932 100644 --- a/src/gallium/drivers/i965simple/brw_wm_glsl.c +++ b/src/gallium/drivers/i965simple/brw_wm_glsl.c @@ -947,7 +947,7 @@ static void brw_wm_emit_instruction( struct brw_wm_compile *c, #endif break; - case TGSI_OPCODE_LOOP: + case TGSI_OPCODE_BGNFOR: c->loop_inst[c->loop_insn++] = brw_DO(p, BRW_EXECUTE_8); break; case TGSI_OPCODE_BRK: @@ -958,11 +958,11 @@ static void brw_wm_emit_instruction( struct brw_wm_compile *c, brw_CONT(p); brw_set_predicate_control(p, BRW_PREDICATE_NONE); break; - case TGSI_OPCODE_ENDLOOP: + case TGSI_OPCODE_ENDFOR: c->loop_insn--; c->inst0 = c->inst1 = brw_WHILE(p, c->loop_inst[c->loop_insn]); /* patch all the BREAK instructions from - last BEGINLOOP */ + last BGNFOR */ while (c->inst0 > c->loop_inst[c->loop_insn]) { c->inst0--; if (c->inst0->header.opcode == BRW_OPCODE_BREAK) { diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index a500ec6045..4e700089e3 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -501,7 +501,7 @@ identity_set_sampler_textures(struct pipe_context *_pipe, pipe->set_sampler_textures(pipe, num_textures, - _textures); + textures); } static void diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c index 555220f853..e5342ac06e 100644 --- a/src/gallium/drivers/identity/id_drm.c +++ b/src/gallium/drivers/identity/id_drm.c @@ -60,7 +60,7 @@ identity_drm_create_screen(struct drm_api *_api, int fd, screen = api->create_screen(api, fd, arg); return identity_screen_create(screen); -}; +} static struct pipe_context * identity_drm_create_context(struct drm_api *_api, @@ -77,7 +77,7 @@ identity_drm_create_context(struct drm_api *_api, pipe = identity_context_create(_screen, pipe); return pipe; -}; +} static boolean identity_drm_buffer_from_texture(struct drm_api *_api, diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 259f1be36e..26439637d0 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -289,6 +289,7 @@ identity_screen_surface_buffer_create(struct pipe_screen *_screen, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride) { struct identity_screen *id_screen = identity_screen(_screen); @@ -300,6 +301,7 @@ identity_screen_surface_buffer_create(struct pipe_screen *_screen, height, format, usage, + tex_usage, stride); if (result) diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 832366e646..e4cf91c005 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -4,6 +4,8 @@ #include <util/u_memory.h> +#include <errno.h> + #include "nouveau/nouveau_bo.h" #include "nouveau_winsys.h" #include "nouveau_screen.h" @@ -141,12 +143,13 @@ nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb, unsigned offset, unsigned length, unsigned usage) { struct nouveau_bo *bo = nouveau_bo(pb); + uint32_t flags = nouveau_screen_map_flags(usage); int ret; - ret = nouveau_bo_map_range(bo, offset, length, - nouveau_screen_map_flags(usage)); + ret = nouveau_bo_map_range(bo, offset, length, flags); if (ret) { - debug_printf("map_range failed: %d\n", ret); + if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY) + debug_printf("map_range failed: %d\n", ret); return NULL; } diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c index f315cf54f0..bbbcb54c46 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.c +++ b/src/gallium/drivers/nv04/nv04_surface_2d.c @@ -110,10 +110,10 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, unsigned cx; unsigned cy; - /* POT or GTFO */ - assert(!(w & (w - 1)) && !(h & (h - 1))); +#if 0 /* That's the way she likes it */ assert(src_pitch == ((struct nv04_surface *)dst)->pitch); +#endif BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); OUT_RELOCo(chan, dst_bo, @@ -133,7 +133,7 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, for (cy = 0; cy < h; cy += sub_h) { for (cx = 0; cx < w; cx += sub_w) { BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); - OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(cx, cy) * + OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(cx+dx, cy+dy) * dst->texture->block.size, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -153,8 +153,8 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, OUT_RING (chan, src_pitch | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); - OUT_RELOCl(chan, src_bo, src->offset + cy * src_pitch + - cx * src->texture->block.size, NOUVEAU_BO_GART | + OUT_RELOCl(chan, src_bo, src->offset + (cy+sy) * src_pitch + + (cx+sx) * src->texture->block.size, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RING (chan, 0); } @@ -210,6 +210,43 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx, } static int +nv04_surface_copy_m2mf_swizzle(struct nv04_surface_2d *ctx, + struct pipe_surface *dst, int dx, int dy, + struct pipe_surface *src, int sx, int sy) +{ + struct nouveau_channel *chan = ctx->m2mf->channel; + struct nouveau_grobj *m2mf = ctx->m2mf; + struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src)); + struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst)); + unsigned src_pitch = ((struct nv04_surface *)src)->pitch; + unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch; + unsigned dst_offset = dst->offset + nv04_swizzle_bits(dx, dy) * + dst->texture->block.size; + unsigned src_offset = src->offset + sy * src_pitch + + sx * src->texture->block.size; + + BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); + OUT_RELOCo(chan, src_bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst_bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, src_bo, src_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst_bo, dst_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RING (chan, src_pitch); + OUT_RING (chan, dst_pitch); + OUT_RING (chan, 1 * src->texture->block.size); + OUT_RING (chan, 1); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); + + return 0; +} + +static int nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst, int dx, int dy, struct pipe_surface *src, int sx, int sy, int w, int h) @@ -258,8 +295,59 @@ nv04_surface_copy(struct nv04_surface_2d *ctx, struct pipe_surface *dst, assert(src->format == dst->format); /* Setup transfer to swizzle the texture to vram if needed */ - if (src_linear && !dst_linear && w > 1 && h > 1) { - nv04_surface_copy_swizzle(ctx, dst, dx, dy, src, sx, sy, w, h); + if (src_linear && !dst_linear) { + int x,y; + + if ((w>1) && (h>1)) { + int potWidth = 1<<log2i(w); + int potHeight = 1<<log2i(h); + int remainWidth = w-potWidth; + int remainHeight = h-potHeight; + int squareDim = (potWidth>potHeight ? potHeight : potWidth); + + /* top left is always POT, but we can only swizzle squares */ + for (y=0; y<potHeight; y+=squareDim) { + for (x=0; x<potWidth; x+= squareDim) { + nv04_surface_copy_swizzle(ctx, dst, dx+x, dy+y, + src, sx+x, sy+y, + squareDim, squareDim); + } + } + + /* top right */ + if (remainWidth>0) { + nv04_surface_copy(ctx, dst, dx+potWidth, dy, + src, sx+potWidth, sy, + remainWidth, potHeight); + } + + /* bottom left */ + if (remainHeight>0) { + nv04_surface_copy(ctx, dst, dx, dy+potHeight, + src, sx, sy+potHeight, + potWidth, remainHeight); + } + + /* bottom right */ + if ((remainWidth>0) && (remainHeight>0)) { + nv04_surface_copy(ctx, dst, dx+potWidth, dy+potHeight, + src, sx+potWidth, sy+potHeight, + remainWidth, remainHeight); + } + } else if (w==1) { + /* We have a column to copy to a swizzled texture */ + for (y=0; y<h; y++) { + nv04_surface_copy_m2mf_swizzle(ctx, dst, dx, dy+y, + src, sx, sy+y); + } + } else if (h==1) { + /* We have a row to copy to a swizzled texture */ + for (x=0; x<w; x++) { + nv04_surface_copy_m2mf_swizzle(ctx, dst, dx+x, dy, + src, sx+x, sy); + } + } + return; } diff --git a/src/gallium/drivers/nv20/nv20_vertprog.c b/src/gallium/drivers/nv20/nv20_vertprog.c index c1e588902b..388245ecb0 100644 --- a/src/gallium/drivers/nv20/nv20_vertprog.c +++ b/src/gallium/drivers/nv20/nv20_vertprog.c @@ -617,10 +617,10 @@ nv20_vertprog_translate(struct nv20_context *nv20, assert(imm->Immediate.NrTokens == 4 + 1); vpc->imm[vpc->nr_imm++] = constant(vpc, -1, - imm->u.ImmediateFloat32[0].Float, - imm->u.ImmediateFloat32[1].Float, - imm->u.ImmediateFloat32[2].Float, - imm->u.ImmediateFloat32[3].Float); + imm->u[0].Float, + imm->u[1].Float, + imm->u[2].Float, + imm->u[3].Float); } break; case TGSI_TOKEN_TYPE_INSTRUCTION: diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 1d1c556fb1..a48ba9782b 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -704,10 +704,10 @@ nv30_fragprog_prepare(struct nv30_fpc *fpc) assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); assert(fpc->nr_imm < MAX_IMM); - vals[0] = imm->u.ImmediateFloat32[0].Float; - vals[1] = imm->u.ImmediateFloat32[1].Float; - vals[2] = imm->u.ImmediateFloat32[2].Float; - vals[3] = imm->u.ImmediateFloat32[3].Float; + vals[0] = imm->u[0].Float; + vals[1] = imm->u[1].Float; + vals[2] = imm->u[2].Float; + vals[3] = imm->u[3].Float; fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals); } break; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index c8b40784b0..f8285e4455 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -95,7 +95,7 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen, } } else if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { - switch (tex_usage) { + switch (format) { case PIPE_FORMAT_Z24S8_UNORM: case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z16_UNORM: diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index c7514efcfe..14a5c0260d 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -617,10 +617,10 @@ nv30_vertprog_translate(struct nv30_context *nv30, assert(imm->Immediate.NrTokens == 4 + 1); vpc->imm[vpc->nr_imm++] = constant(vpc, -1, - imm->u.ImmediateFloat32[0].Float, - imm->u.ImmediateFloat32[1].Float, - imm->u.ImmediateFloat32[2].Float, - imm->u.ImmediateFloat32[3].Float); + imm->u[0].Float, + imm->u[1].Float, + imm->u[2].Float, + imm->u[3].Float); } break; case TGSI_TOKEN_TYPE_INSTRUCTION: diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 680976da56..32d9ed1a7f 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -790,10 +790,10 @@ nv40_fragprog_prepare(struct nv40_fpc *fpc) assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); assert(fpc->nr_imm < MAX_IMM); - vals[0] = imm->u.ImmediateFloat32[0].Float; - vals[1] = imm->u.ImmediateFloat32[1].Float; - vals[2] = imm->u.ImmediateFloat32[2].Float; - vals[3] = imm->u.ImmediateFloat32[3].Float; + vals[0] = imm->u[0].Float; + vals[1] = imm->u[1].Float; + vals[2] = imm->u[2].Float; + vals[3] = imm->u[3].Float; fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals); } break; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index e75e8d3f42..0382dbba8f 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -788,10 +788,10 @@ nv40_vertprog_translate(struct nv40_context *nv40, assert(imm->Immediate.NrTokens == 4 + 1); vpc->imm[vpc->nr_imm++] = constant(vpc, -1, - imm->u.ImmediateFloat32[0].Float, - imm->u.ImmediateFloat32[1].Float, - imm->u.ImmediateFloat32[2].Float, - imm->u.ImmediateFloat32[3].Float); + imm->u[0].Float, + imm->u[1].Float, + imm->u[2].Float, + imm->u[3].Float); } break; case TGSI_TOKEN_TYPE_INSTRUCTION: diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index e02afc4be9..6e8f4f9750 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -31,15 +31,23 @@ static void nv50_flush(struct pipe_context *pipe, unsigned flags, struct pipe_fence_handle **fence) { - struct nv50_context *nv50 = (struct nv50_context *)pipe; - - FIRE_RING(nv50->screen->base.channel); + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_grobj *eng2d = nv50->screen->eng2d; + + /* We need this in the ddx for reliable composite, not sure what we're + * actually flushing. We generate all our own flushes with flags = 0. */ + WAIT_RING(chan, 3); + BEGIN_RING(chan, eng2d, 0x0110, 1); + OUT_RING (chan, 0); + + FIRE_RING(chan); } static void nv50_destroy(struct pipe_context *pipe) { - struct nv50_context *nv50 = (struct nv50_context *)pipe; + struct nv50_context *nv50 = nv50_context(pipe); draw_destroy(nv50->draw); FREE(nv50); @@ -112,5 +120,3 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) return &nv50->pipe; } - - diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 9b8cc4d37d..5cbc2c8f82 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -71,6 +71,7 @@ struct nv50_sampler_stateobj { struct nv50_miptree_level { int *image_offset; unsigned pitch; + unsigned tile_mode; }; struct nv50_miptree { diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 22465e0227..dd1b0303bd 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -42,9 +42,14 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) mt->base.screen = pscreen; switch (pt->format) { - case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z32_FLOAT: + tile_flags = 0x4800; + break; case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z16_UNORM: + tile_flags = 0x1800; + break; + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: tile_flags = 0x2800; break; default: @@ -82,20 +87,27 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) lvl->image_offset = CALLOC(mt->image_nr, sizeof(int)); lvl->pitch = align(pt->width[l] * pt->block.size, 64); + lvl->tile_mode = tile_mode; width = MAX2(1, width >> 1); height = MAX2(1, height >> 1); depth = MAX2(1, depth >> 1); + + if (tile_mode && height <= (tile_h >> 1)) { + tile_mode--; + tile_h >>= 1; + } } for (i = 0; i < mt->image_nr; i++) { for (l = 0; l <= pt->last_level; l++) { struct nv50_miptree_level *lvl = &mt->level[l]; int size; + tile_h = 1 << (lvl->tile_mode + 2); size = align(pt->width[l], 8) * pt->block.size; size = align(size, 64); - size *= align(pt->height[l], tile_h) * pt->block.size; + size *= align(pt->height[l], tile_h); lvl->image_offset[i] = mt->total_size; @@ -104,12 +116,12 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) } ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size, - tile_mode, tile_flags, &mt->bo); + mt->level[0].tile_mode, tile_flags, &mt->bo); if (ret) { FREE(mt); return NULL; } - + return &mt->base; } @@ -146,7 +158,7 @@ nv50_miptree_destroy(struct pipe_texture *pt) struct nv50_miptree *mt = nv50_miptree(pt); nouveau_bo_ref(NULL, &mt->bo); - FREE(mt); + FREE(mt); } static struct pipe_surface * @@ -189,8 +201,8 @@ nv50_miptree_surface_del(struct pipe_surface *ps) { struct nv50_surface *s = nv50_surface(ps); - pipe_texture_reference(&ps->texture, NULL); - FREE(s); + pipe_texture_reference(&ps->texture, NULL); + FREE(s); } void diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 5f7d06dbec..289c3485e0 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -251,7 +251,7 @@ alloc_temp4(struct nv50_pc *pc, struct nv50_reg *dst[4], int idx) if (pc->r_temp[idx] || pc->r_temp[idx + 1] || pc->r_temp[idx + 2] || pc->r_temp[idx + 3]) - return alloc_temp4(pc, dst, idx + 1); + return alloc_temp4(pc, dst, idx + 4); for (i = 0; i < 4; i++) { dst[i] = CALLOC_STRUCT(nv50_reg); @@ -296,7 +296,7 @@ kill_temp_temp(struct nv50_pc *pc) static int ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w) { - pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * r * sizeof(float)), + pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * 4 * sizeof(float)), (pc->immd_nr + 1) * 4 * sizeof(float)); pc->immd_buf[(pc->immd_nr * 4) + 0] = x; pc->immd_buf[(pc->immd_nr * 4) + 1] = y; @@ -1014,6 +1014,7 @@ emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask, break; } + /* some cards need t[0]'s hw index to be a multiple of 4 */ alloc_temp4(pc, t, 0); if (proj) { @@ -1809,10 +1810,10 @@ nv50_program_tx_prep(struct nv50_pc *pc) const struct tgsi_full_immediate *imm = &p.FullToken.FullImmediate; - ctor_immd(pc, imm->u.ImmediateFloat32[0].Float, - imm->u.ImmediateFloat32[1].Float, - imm->u.ImmediateFloat32[2].Float, - imm->u.ImmediateFloat32[3].Float); + ctor_immd(pc, imm->u[0].Float, + imm->u[1].Float, + imm->u[2].Float, + imm->u[3].Float); } break; case TGSI_TOKEN_TYPE_DECLARATION: @@ -2221,9 +2222,9 @@ nv50_program_upload_data(struct nv50_context *nv50, float *map, while (count) { unsigned nr = count > 2047 ? 2047 : count; - BEGIN_RING(chan, tesla, 0x00000f00, 1); + BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, (cbuf << 0) | (start << 8)); - BEGIN_RING(chan, tesla, 0x40000f04, nr); + BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, nr); OUT_RINGp (chan, map, nr); map += nr; @@ -2345,7 +2346,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) } so = so_new(4,2); - so_method(so, nv50->screen->tesla, 0x1280, 3); + so_method(so, nv50->screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PUPLOAD << 16) | 0x0800); //(p->exec_size * 4)); @@ -2364,9 +2365,9 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) continue; } - BEGIN_RING(chan, tesla, 0x0f00, 1); + BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, (start << 8) | NV50_CB_PUPLOAD); - BEGIN_RING(chan, tesla, 0x40000f04, nr); + BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, nr); OUT_RINGp (chan, up + start, nr); start += nr; @@ -2399,15 +2400,15 @@ nv50_vertprog_validate(struct nv50_context *nv50) NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, 0x1650, 2); + so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2); so_data (so, p->cfg.vp.attr[0]); so_data (so, p->cfg.vp.attr[1]); - so_method(so, tesla, 0x16b8, 1); + so_method(so, tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); so_data (so, p->cfg.high_result); - so_method(so, tesla, 0x16ac, 2); + so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 2); so_data (so, p->cfg.high_result); //8); so_data (so, p->cfg.high_temp); - so_method(so, tesla, 0x140c, 1); + so_method(so, tesla, NV50TCL_VP_START_ID, 1); so_data (so, 0); /* program start offset */ so_ref(so, &nv50->state.vertprog); so_ref(NULL, &so); @@ -2436,24 +2437,24 @@ nv50_fragprog_validate(struct nv50_context *nv50) NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, 0x1904, 4); + so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4); so_data (so, p->cfg.fp.regs[0]); /* 0x01000404 / 0x00040404 */ so_data (so, 0x00000004); so_data (so, 0x00000000); so_data (so, 0x00000000); - so_method(so, tesla, 0x16bc, p->cfg.fp.high_map); + so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), p->cfg.fp.high_map); for (i = 0; i < p->cfg.fp.high_map; i++) so_data(so, p->cfg.fp.map[i]); - so_method(so, tesla, 0x1988, 2); + so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 2); so_data (so, p->cfg.fp.regs[1]); /* 0x08040404 / 0x0f000401 */ so_data (so, p->cfg.high_temp); - so_method(so, tesla, 0x1298, 1); + so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1); so_data (so, p->cfg.high_result); - so_method(so, tesla, 0x19a8, 1); + so_method(so, tesla, NV50TCL_FP_CTRL_UNK19A8, 1); so_data (so, p->cfg.fp.regs[2]); - so_method(so, tesla, 0x196c, 1); + so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1); so_data (so, p->cfg.fp.regs[3]); - so_method(so, tesla, 0x1414, 1); + so_method(so, tesla, NV50TCL_FP_START_ID, 1); so_data (so, 0); /* program start offset */ so_ref(so, &nv50->state.fragprog); so_ref(NULL, &so); @@ -2478,4 +2479,3 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) p->translated = 0; } - diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 940e04365f..5305c93d59 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -94,7 +94,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) struct nv50_query *q = nv50_query(pq); WAIT_RING (chan, 5); - BEGIN_RING(chan, tesla, 0x1b00, 4); + BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4); OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RING (chan, 0x00000000); @@ -107,13 +107,13 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq, boolean wait, uint64_t *result) { struct nv50_query *q = nv50_query(pq); - - /*XXX: Want to be able to return FALSE here instead of blocking - * until the result is available.. - */ + int ret; if (!q->ready) { - nouveau_bo_map(q->bo, NOUVEAU_BO_RD); + ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD | + wait ? 0 : NOUVEAU_BO_NOWAIT); + if (ret) + return false; q->result = ((uint32_t *)q->bo->map)[1]; q->ready = TRUE; nouveau_bo_unmap(q->bo); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index ce8f906b15..c7f80a2203 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -44,9 +44,10 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, } else if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { switch (format) { + case PIPE_FORMAT_Z32_FLOAT: case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: return TRUE; default: break; @@ -188,7 +189,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nv50_transfer_init_screen_functions(pscreen); /* DMA engine object */ - ret = nouveau_grobj_alloc(chan, 0xbeef5039, 0x5039, &screen->m2mf); + ret = nouveau_grobj_alloc(chan, 0xbeef5039, + NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf); if (ret) { NOUVEAU_ERR("Error creating M2MF object: %d\n", ret); nv50_screen_destroy(pscreen); @@ -197,7 +199,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BIND_RING(chan, screen->m2mf, 1); /* 2D object */ - ret = nouveau_grobj_alloc(chan, 0xbeef502d, 0x502d, &screen->eng2d); + ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d); if (ret) { NOUVEAU_ERR("Error creating 2D object: %d\n", ret); nv50_screen_destroy(pscreen); @@ -208,14 +210,15 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) /* 3D object */ switch (chipset & 0xf0) { case 0x50: - tesla_class = 0x5097; + tesla_class = NV50TCL; break; case 0x80: case 0x90: - tesla_class = 0x8297; + /* this stupid name should be corrected. */ + tesla_class = NV54TCL; break; case 0xa0: - tesla_class = 0x8397; + tesla_class = NVA0TCL; break; default: NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset); @@ -229,7 +232,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } - ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla); + ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, + &screen->tesla); if (ret) { NOUVEAU_ERR("Error creating 3D object: %d\n", ret); nv50_screen_destroy(pscreen); @@ -247,7 +251,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) /* Static M2MF init */ so = so_new(32, 0); - so_method(so, screen->m2mf, 0x0180, 3); + so_method(so, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); so_data (so, screen->sync->handle); so_data (so, chan->vram->handle); so_data (so, chan->vram->handle); @@ -290,9 +294,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_method(so, screen->tesla, 0x13bc, 1); so_data (so, 0x54); + /* origin is top left (set to 1 for bottom left) */ so_method(so, screen->tesla, 0x13ac, 1); - so_data (so, 1); - so_method(so, screen->tesla, 0x16b8, 1); + so_data (so, 0); + so_method(so, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); so_data (so, 8); /* constant buffers for immediates and VP/FP parameters */ @@ -330,33 +335,33 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_data (so, 0x000BBNP1); */ - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PMISC << 16) | 0x00000800); - so_method(so, screen->tesla, 0x1694, 1); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000001 | (NV50_CB_PMISC << 12)); - so_method(so, screen->tesla, 0x1694, 1); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000031 | (NV50_CB_PMISC << 12)); - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PVP << 16) | 0x00000800); - so_method(so, screen->tesla, 0x1694, 1); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000101 | (NV50_CB_PVP << 12)); - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PFP << 16) | 0x00000800); - so_method(so, screen->tesla, 0x1694, 1); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000131 | (NV50_CB_PFP << 12)); /* Texture sampler/image unit setup - we abuse the constant buffer @@ -370,13 +375,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_TIC << 16) | 0x0800); - so_method(so, screen->tesla, 0x1574, 3); + so_method(so, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | @@ -389,13 +394,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_TSC << 16) | 0x0800); - so_method(so, screen->tesla, 0x155c, 3); + so_method(so, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | @@ -405,7 +410,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) /* Vertex array limits - max them out */ for (i = 0; i < 16; i++) { - so_method(so, screen->tesla, 0x1080 + (i * 8), 2); + so_method(so, screen->tesla, NV50TCL_UNK1080_OFFSET_HIGH(i), 2); so_data (so, 0x000000ff); so_data (so, 0xffffffff); } @@ -417,6 +422,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_method(so, screen->tesla, 0x1234, 1); so_data (so, 1); + /* activate first scissor rectangle */ + so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE, 1); + so_data (so, 1); + so_emit(chan, so); so_ref (so, &screen->static_init); so_ref (NULL, &so); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 116866a8e7..ef4154d303 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -205,11 +205,16 @@ nv50_sampler_state_create(struct pipe_context *pipe, } limit = CLAMP(cso->lod_bias, -16.0, 15.0); - tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 11; + tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 12; tsc[2] |= ((int)CLAMP(cso->max_lod, 0.0, 15.0) << 20) | ((int)CLAMP(cso->min_lod, 0.0, 15.0) << 8); + tsc[4] = fui(cso->border_color[0]); + tsc[5] = fui(cso->border_color[1]); + tsc[6] = fui(cso->border_color[2]); + tsc[7] = fui(cso->border_color[3]); + sso->normalized = cso->normalized_coords; return (void *)sso; } @@ -404,35 +409,35 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, 0); } - /*XXX: yes, I know they're backwards.. header needs fixing */ + /* XXX: keep hex values until header is updated (names reversed) */ if (cso->stencil[0].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 5); + so_method(so, tesla, 0x1380, 8); so_data (so, 1); so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); - so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 3); so_data (so, cso->stencil[0].ref_value); so_data (so, cso->stencil[0].writemask); so_data (so, cso->stencil[0].valuemask); } else { - so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1); + so_method(so, tesla, 0x1380, 1); so_data (so, 0); } if (cso->stencil[1].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, tesla, 0x1594, 5); so_data (so, 1); so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); + so_method(so, tesla, 0x0f54, 3); so_data (so, cso->stencil[1].ref_value); so_data (so, cso->stencil[1].writemask); so_data (so, cso->stencil[1].valuemask); } else { - so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1); + so_method(so, tesla, 0x1594, 1); so_data (so, 0); } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index d313e9de4f..a879df2e6e 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -55,15 +55,15 @@ nv50_state_validate_fb(struct nv50_context *nv50) NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0); switch (fb->cbufs[i]->format) { case PIPE_FORMAT_A8R8G8B8_UNORM: - so_data(so, 0xcf); + so_data(so, NV50TCL_RT_FORMAT_A8R8G8B8_UNORM); break; case PIPE_FORMAT_R5G6B5_UNORM: - so_data(so, 0xe8); + so_data(so, NV50TCL_RT_FORMAT_R5G6B5_UNORM); break; default: NOUVEAU_ERR("AIIII unknown format %s\n", pf_name(fb->cbufs[i]->format)); - so_data(so, 0xe6); + so_data(so, NV50TCL_RT_FORMAT_X8R8G8B8_UNORM); break; } so_data(so, bo->tile_mode << 4); @@ -92,17 +92,22 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_reloc (so, bo, fb->zsbuf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0); switch (fb->zsbuf->format) { + case PIPE_FORMAT_Z32_FLOAT: + so_data(so, NV50TCL_ZETA_FORMAT_Z32_FLOAT); + break; case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - so_data(so, 0x16); + so_data(so, NV50TCL_ZETA_FORMAT_Z24S8_UNORM); + break; + case PIPE_FORMAT_X8Z24_UNORM: + so_data(so, NV50TCL_ZETA_FORMAT_X8Z24_UNORM); break; - case PIPE_FORMAT_Z16_UNORM: - so_data(so, 0x15); + case PIPE_FORMAT_S8Z24_UNORM: + so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM); break; default: NOUVEAU_ERR("AIIII unknown format %s\n", pf_name(fb->zsbuf->format)); - so_data(so, 0x16); + so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM); break; } so_data(so, bo->tile_mode << 4); @@ -110,7 +115,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_method(so, tesla, 0x1538, 1); so_data (so, 1); - so_method(so, tesla, 0x1228, 3); + so_method(so, tesla, NV50TCL_ZETA_HORIZ, 3); so_data (so, fb->zsbuf->width); so_data (so, fb->zsbuf->height); so_data (so, 0x00010001); @@ -119,12 +124,18 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2); so_data (so, w << 16); so_data (so, h << 16); - so_method(so, tesla, 0x0e04, 2); + /* set window lower left corner */ + so_method(so, tesla, NV50TCL_WINDOW_LEFT, 2); + so_data (so, 0); + so_data (so, 0); + /* set screen scissor rectangle */ + so_method(so, tesla, NV50TCL_SCREEN_SCISSOR_HORIZ, 2); so_data (so, w << 16); so_data (so, h << 16); - so_method(so, tesla, 0xdf8, 2); - so_data (so, 0); - so_data (so, h); + + /* we set scissors to framebuffer size when they're 'turned off' */ + nv50->dirty |= NV50_NEW_SCISSOR; + so_ref(NULL, &nv50->state.scissor); so_ref(so, &nv50->state.fb); so_ref(NULL, &so); @@ -137,7 +148,32 @@ nv50_state_emit(struct nv50_context *nv50) struct nouveau_channel *chan = screen->base.channel; if (nv50->pctx_id != screen->cur_pctx) { - nv50->state.dirty |= 0xffffffff; + if (nv50->state.fb) + nv50->state.dirty |= NV50_NEW_FRAMEBUFFER; + if (nv50->state.blend) + nv50->state.dirty |= NV50_NEW_BLEND; + if (nv50->state.zsa) + nv50->state.dirty |= NV50_NEW_ZSA; + if (nv50->state.vertprog) + nv50->state.dirty |= NV50_NEW_VERTPROG; + if (nv50->state.fragprog) + nv50->state.dirty |= NV50_NEW_FRAGPROG; + if (nv50->state.rast) + nv50->state.dirty |= NV50_NEW_RASTERIZER; + if (nv50->state.blend_colour) + nv50->state.dirty |= NV50_NEW_BLEND_COLOUR; + if (nv50->state.stipple) + nv50->state.dirty |= NV50_NEW_STIPPLE; + if (nv50->state.scissor) + nv50->state.dirty |= NV50_NEW_SCISSOR; + if (nv50->state.viewport) + nv50->state.dirty |= NV50_NEW_VIEWPORT; + if (nv50->state.tsc_upload) + nv50->state.dirty |= NV50_NEW_SAMPLER; + if (nv50->state.tic_upload) + nv50->state.dirty |= NV50_NEW_TEXTURE; + if (nv50->state.vtxfmt && nv50->state.vtxbuf) + nv50->state.dirty |= NV50_NEW_ARRAYS; screen->cur_pctx = nv50->pctx_id; } @@ -233,13 +269,13 @@ nv50_state_validate(struct nv50_context *nv50) nv50->state.scissor_enabled = rast->scissor; so = so_new(3, 0); - so_method(so, tesla, 0x0ff4, 2); + so_method(so, tesla, NV50TCL_SCISSOR_HORIZ, 2); if (nv50->state.scissor_enabled) { - so_data(so, ((s->maxx - s->minx) << 16) | s->minx); - so_data(so, ((s->maxy - s->miny) << 16) | s->miny); + so_data(so, (s->maxx << 16) | s->minx); + so_data(so, (s->maxy << 16) | s->miny); } else { - so_data(so, (8192 << 16)); - so_data(so, (8192 << 16)); + so_data(so, (nv50->framebuffer.width << 16)); + so_data(so, (nv50->framebuffer.height << 16)); } so_ref(so, &nv50->state.scissor); so_ref(NULL, &so); @@ -263,20 +299,22 @@ scissor_uptodate: so = so_new(12, 0); if (!bypass) { - so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3); + so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3); so_data (so, fui(nv50->viewport.translate[0])); so_data (so, fui(nv50->viewport.translate[1])); so_data (so, fui(nv50->viewport.translate[2])); - so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3); + so_method(so, tesla, NV50TCL_VIEWPORT_SCALE(0), 3); so_data (so, fui(nv50->viewport.scale[0])); - so_data (so, fui(-nv50->viewport.scale[1])); + so_data (so, fui(nv50->viewport.scale[1])); so_data (so, fui(nv50->viewport.scale[2])); - so_method(so, tesla, 0x192c, 1); + + so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); so_data (so, 1); + /* no idea what 0f90 does */ so_method(so, tesla, 0x0f90, 1); so_data (so, 0); } else { - so_method(so, tesla, 0x192c, 1); + so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); so_data (so, 0); so_method(so, tesla, 0x0f90, 1); so_data (so, 1); @@ -292,9 +330,10 @@ viewport_uptodate: int i; so = so_new(nv50->sampler_nr * 8 + 3, 0); - so_method(so, tesla, 0x0f00, 1); + so_method(so, tesla, NV50TCL_CB_ADDR, 1); so_data (so, NV50_CB_TSC); - so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8); + so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000, + nv50->sampler_nr * 8); for (i = 0; i < nv50->sampler_nr; i++) so_datap (so, nv50->sampler[i]->tsc, 8); so_ref(so, &nv50->state.tsc_upload); diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 3da9d6e728..edaf4b055a 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -35,13 +35,13 @@ nv50_format(enum pipe_format format) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: - return NV50_2D_DST_FORMAT_32BPP; + return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM; case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV50_2D_DST_FORMAT_24BPP; + return NV50_2D_DST_FORMAT_X8R8G8B8_UNORM; case PIPE_FORMAT_R5G6B5_UNORM: - return NV50_2D_DST_FORMAT_16BPP; + return NV50_2D_DST_FORMAT_R5G6B5_UNORM; case PIPE_FORMAT_A8_UNORM: - return NV50_2D_DST_FORMAT_8BPP; + return NV50_2D_DST_FORMAT_R8_UNORM; default: return -1; } @@ -144,7 +144,7 @@ nv50_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { - struct nv50_context *nv50 = (struct nv50_context *)pipe; + struct nv50_context *nv50 = nv50_context(pipe); struct nv50_screen *screen = nv50->screen; assert(src->format == dest->format); @@ -158,7 +158,7 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, unsigned destx, unsigned desty, unsigned width, unsigned height, unsigned value) { - struct nv50_context *nv50 = (struct nv50_context *)pipe; + struct nv50_context *nv50 = nv50_context(pipe); struct nv50_screen *screen = nv50->screen; struct nouveau_channel *chan = screen->eng2d->channel; struct nouveau_grobj *eng2d = screen->eng2d; diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index ff40c2ad81..14c68b96e1 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -32,30 +32,30 @@ nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so, switch (mt->base.format) { case PIPE_FORMAT_A8R8G8B8_UNORM: so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | - NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | - NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_8_8_8_8); break; case PIPE_FORMAT_A1R5G5B5_UNORM: so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | - NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | - NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_1_5_5_5); break; case PIPE_FORMAT_A4R4G4B4_UNORM: so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | - NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | - NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_4_4_4_4); break; case PIPE_FORMAT_R5G6B5_UNORM: so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM | - NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | - NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_5_6_5); break; case PIPE_FORMAT_L8_UNORM: @@ -145,25 +145,28 @@ nv50_tex_validate(struct nv50_context *nv50) push += MAX2(nv50->miptree_nr, nv50->state.miptree_nr) * 2; so = so_new(push, nv50->miptree_nr * 2); - so_method(so, tesla, 0x0f00, 1); + so_method(so, tesla, NV50TCL_CB_ADDR, 1); so_data (so, NV50_CB_TIC); for (unit = 0; unit < nv50->miptree_nr; unit++) { struct nv50_miptree *mt = nv50->miptree[unit]; - so_method(so, tesla, 0x40000f04, 8); + so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 8); if (nv50_tex_construct(nv50, so, mt, unit)) { NOUVEAU_ERR("failed tex validate\n"); so_ref(NULL, &so); return; } - so_method(so, tesla, 0x1458, 1); - so_data (so, (unit << 9) | (unit << 1) | 1); + so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1); + so_data (so, (unit << NV50TCL_SET_SAMPLER_TEX_TIC_SHIFT) | + (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | + NV50TCL_SET_SAMPLER_TEX_VALID); } for (; unit < nv50->state.miptree_nr; unit++) { - so_method(so, tesla, 0x1458, 1); - so_data (so, (unit << 1) | 0); + so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1); + so_data (so, + (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | 0); } so_ref(so, &nv50->state.tic_upload); diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h index aca622c73b..207fb039f7 100644 --- a/src/gallium/drivers/nv50/nv50_texture.h +++ b/src/gallium/drivers/nv50/nv50_texture.h @@ -14,13 +14,13 @@ #define NV50TIC_0_0_MAPA_C2 0x20000000 #define NV50TIC_0_0_MAPA_C3 0x28000000 #define NV50TIC_0_0_MAPA_ONE 0x38000000 -#define NV50TIC_0_0_MAPR_MASK 0x07000000 -#define NV50TIC_0_0_MAPR_ZERO 0x00000000 -#define NV50TIC_0_0_MAPR_C0 0x02000000 -#define NV50TIC_0_0_MAPR_C1 0x03000000 -#define NV50TIC_0_0_MAPR_C2 0x04000000 -#define NV50TIC_0_0_MAPR_C3 0x05000000 -#define NV50TIC_0_0_MAPR_ONE 0x07000000 +#define NV50TIC_0_0_MAPB_MASK 0x07000000 +#define NV50TIC_0_0_MAPB_ZERO 0x00000000 +#define NV50TIC_0_0_MAPB_C0 0x02000000 +#define NV50TIC_0_0_MAPB_C1 0x03000000 +#define NV50TIC_0_0_MAPB_C2 0x04000000 +#define NV50TIC_0_0_MAPB_C3 0x05000000 +#define NV50TIC_0_0_MAPB_ONE 0x07000000 #define NV50TIC_0_0_MAPG_MASK 0x00e00000 #define NV50TIC_0_0_MAPG_ZERO 0x00000000 #define NV50TIC_0_0_MAPG_C0 0x00400000 @@ -28,31 +28,49 @@ #define NV50TIC_0_0_MAPG_C2 0x00800000 #define NV50TIC_0_0_MAPG_C3 0x00a00000 #define NV50TIC_0_0_MAPG_ONE 0x00e00000 -#define NV50TIC_0_0_MAPB_MASK 0x001c0000 -#define NV50TIC_0_0_MAPB_ZERO 0x00000000 -#define NV50TIC_0_0_MAPB_C0 0x00080000 -#define NV50TIC_0_0_MAPB_C1 0x000c0000 -#define NV50TIC_0_0_MAPB_C2 0x00100000 -#define NV50TIC_0_0_MAPB_C3 0x00140000 -#define NV50TIC_0_0_MAPB_ONE 0x001c0000 +#define NV50TIC_0_0_MAPR_MASK 0x001c0000 +#define NV50TIC_0_0_MAPR_ZERO 0x00000000 +#define NV50TIC_0_0_MAPR_C0 0x00080000 +#define NV50TIC_0_0_MAPR_C1 0x000c0000 +#define NV50TIC_0_0_MAPR_C2 0x00100000 +#define NV50TIC_0_0_MAPR_C3 0x00140000 +#define NV50TIC_0_0_MAPR_ONE 0x001c0000 #define NV50TIC_0_0_TYPEA_MASK 0x00038000 #define NV50TIC_0_0_TYPEA_UNORM 0x00010000 -#define NV50TIC_0_0_TYPER_MASK 0x00007000 -#define NV50TIC_0_0_TYPER_UNORM 0x00002000 +#define NV50TIC_0_0_TYPEA_SNORM 0x00008000 +#define NV50TIC_0_0_TYPEA_FLOAT 0x00038000 +#define NV50TIC_0_0_TYPEB_MASK 0x00007000 +#define NV50TIC_0_0_TYPEB_UNORM 0x00002000 +#define NV50TIC_0_0_TYPEB_SNORM 0x00001000 +#define NV50TIC_0_0_TYPEB_FLOAT 0x00007000 #define NV50TIC_0_0_TYPEG_MASK 0x00000e00 #define NV50TIC_0_0_TYPEG_UNORM 0x00000400 -#define NV50TIC_0_0_TYPEB_MASK 0x000001c0 -#define NV50TIC_0_0_TYPEB_UNORM 0x00000080 -#define NV50TIC_0_0_FMT_MASK 0x0000003c +#define NV50TIC_0_0_TYPEG_SNORM 0x00000200 +#define NV50TIC_0_0_TYPEG_FLOAT 0x00000e00 +#define NV50TIC_0_0_TYPER_MASK 0x000001c0 +#define NV50TIC_0_0_TYPER_UNORM 0x00000080 +#define NV50TIC_0_0_TYPER_SNORM 0x00000040 +#define NV50TIC_0_0_TYPER_FLOAT 0x000001c0 +#define NV50TIC_0_0_FMT_MASK 0x0000003f +#define NV50TIC_0_0_FMT_32_32_32_32 0x00000001 +#define NV50TIC_0_0_FMT_16_16_16_16 0x00000003 +#define NV50TIC_0_0_FMT_32_32 0x00000004 #define NV50TIC_0_0_FMT_8_8_8_8 0x00000008 +#define NV50TIC_0_0_FMT_2_10_10_10 0x00000009 +#define NV50TIC_0_0_FMT_32 0x0000000f #define NV50TIC_0_0_FMT_4_4_4_4 0x00000012 -#define NV50TIC_0_0_FMT_1_5_5_5 0x00000013 +/* #define NV50TIC_0_0_FMT_1_5_5_5 0x00000013 */ +#define NV50TIC_0_0_FMT_1_5_5_5 0x00000014 #define NV50TIC_0_0_FMT_5_6_5 0x00000015 #define NV50TIC_0_0_FMT_8_8 0x00000018 +#define NV50TIC_0_0_FMT_16 0x0000001b #define NV50TIC_0_0_FMT_8 0x0000001d +#define NV50TIC_0_0_FMT_10_11_11 0x00000021 #define NV50TIC_0_0_FMT_DXT1 0x00000024 #define NV50TIC_0_0_FMT_DXT3 0x00000025 #define NV50TIC_0_0_FMT_DXT5 0x00000026 +#define NV50TIC_0_0_FMT_RGTC1 0x00000027 +#define NV50TIC_0_0_FMT_RGTC2 0x00000028 #define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff #define NV50TIC_0_1_OFFSET_LOW_SHIFT 0 @@ -102,6 +120,7 @@ #define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_EDGE 0x00000140 #define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_BORDER 0x00000180 #define NV50TSC_1_0_WRAPR_MIRROR_CLAMP 0x000001c0 +#define NV50TSC_1_0_MAX_ANISOTROPY_MASK 0x00700000 #define NV50TSC_1_1_MAGF_MASK 0x00000003 #define NV50TSC_1_1_MAGF_NEAREST 0x00000001 @@ -113,17 +132,19 @@ #define NV50TSC_1_1_MIPF_NONE 0x00000040 #define NV50TSC_1_1_MIPF_NEAREST 0x00000080 #define NV50TSC_1_1_MIPF_LINEAR 0x000000c0 +#define NV50TSC_1_1_LOD_BIAS_MASK 0x01fff000 -#define NV50TSC_1_2_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_2_MIN_LOD_MASK 0x00000f00 +#define NV50TSC_1_2_MAX_LOD_MASK 0x00f00000 #define NV50TSC_1_3_UNKNOWN_MASK 0xffffffff -#define NV50TSC_1_4_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_4_BORDER_COLOR_RED_MASK 0xffffffff -#define NV50TSC_1_5_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_5_BORDER_COLOR_GREEN_MASK 0xffffffff -#define NV50TSC_1_6_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_6_BORDER_COLOR_BLUE_MASK 0xffffffff -#define NV50TSC_1_7_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_7_BORDER_COLOR_ALPHA_MASK 0xffffffff #endif diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index d0b7f0bef4..d2b5e4d75d 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -8,6 +8,7 @@ struct nv50_transfer { struct pipe_transfer base; struct nouveau_bo *bo; unsigned level_offset; + unsigned level_tiling; int level_pitch; int level_width; int level_height; @@ -16,11 +17,14 @@ struct nv50_transfer { }; static void -nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo, - unsigned src_offset, int src_pitch, int sx, int sy, - int sw, int sh, struct nouveau_bo *dst_bo, - unsigned dst_offset, int dst_pitch, int dx, int dy, - int dw, int dh, int cpp, int width, int height, +nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, + struct nouveau_bo *src_bo, unsigned src_offset, + int src_pitch, unsigned src_tile_mode, + int sx, int sy, int sw, int sh, + struct nouveau_bo *dst_bo, unsigned dst_offset, + int dst_pitch, unsigned dst_tile_mode, + int dx, int dy, int dw, int dh, + int cpp, int width, int height, unsigned src_reloc, unsigned dst_reloc) { struct nv50_screen *screen = nv50_screen(pscreen); @@ -33,15 +37,18 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo, WAIT_RING (chan, 14); if (!src_bo->tile_flags) { - BEGIN_RING(chan, m2mf, 0x0200, 1); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 1); OUT_RING (chan, 1); - BEGIN_RING(chan, m2mf, 0x0314, 1); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_IN, 1); OUT_RING (chan, src_pitch); src_offset += (sy * src_pitch) + (sx * cpp); } else { - BEGIN_RING(chan, m2mf, 0x0200, 6); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 6); OUT_RING (chan, 0); - OUT_RING (chan, src_bo->tile_mode << 4); + OUT_RING (chan, src_tile_mode << 4); OUT_RING (chan, sw * cpp); OUT_RING (chan, sh); OUT_RING (chan, 1); @@ -49,15 +56,18 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo, } if (!dst_bo->tile_flags) { - BEGIN_RING(chan, m2mf, 0x021c, 1); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 1); OUT_RING (chan, 1); - BEGIN_RING(chan, m2mf, 0x0318, 1); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT, 1); OUT_RING (chan, dst_pitch); dst_offset += (dy * dst_pitch) + (dx * cpp); } else { - BEGIN_RING(chan, m2mf, 0x021c, 6); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 6); OUT_RING (chan, 0); - OUT_RING (chan, dst_bo->tile_mode << 4); + OUT_RING (chan, dst_tile_mode << 4); OUT_RING (chan, dw * cpp); OUT_RING (chan, dh); OUT_RING (chan, 1); @@ -68,25 +78,30 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo, int line_count = height > 2047 ? 2047 : height; WAIT_RING (chan, 15); - BEGIN_RING(chan, m2mf, 0x0238, 2); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2); OUT_RELOCh(chan, src_bo, src_offset, src_reloc); OUT_RELOCh(chan, dst_bo, dst_offset, dst_reloc); - BEGIN_RING(chan, m2mf, 0x030c, 2); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 2); OUT_RELOCl(chan, src_bo, src_offset, src_reloc); OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc); if (src_bo->tile_flags) { - BEGIN_RING(chan, m2mf, 0x0218, 1); - OUT_RING (chan, (dy << 16) | sx); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1); + OUT_RING (chan, (sy << 16) | sx); } else { src_offset += (line_count * src_pitch); } if (dst_bo->tile_flags) { - BEGIN_RING(chan, m2mf, 0x0234, 1); - OUT_RING (chan, (sy << 16) | dx); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1); + OUT_RING (chan, (dy << 16) | dx); } else { dst_offset += (line_count * dst_pitch); } - BEGIN_RING(chan, m2mf, 0x031c, 4); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN, 4); OUT_RING (chan, width * cpp); OUT_RING (chan, line_count); OUT_RING (chan, 0x00000101); @@ -136,6 +151,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->level_width = mt->base.width[level]; tx->level_height = mt->base.height[level]; tx->level_offset = lvl->image_offset[image]; + tx->level_tiling = lvl->tile_mode; tx->level_x = x; tx->level_y = y; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, @@ -147,9 +163,11 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, if (usage != PIPE_TRANSFER_WRITE) { nv50_transfer_rect_m2mf(pscreen, mt->bo, tx->level_offset, - tx->level_pitch, x, y, tx->level_width, - tx->level_height, tx->bo, 0, - tx->base.stride, 0, 0, + tx->level_pitch, tx->level_tiling, + x, y, + tx->level_width, tx->level_height, + tx->bo, 0, tx->base.stride, + tx->bo->tile_mode, 0, 0, tx->base.width, tx->base.height, tx->base.block.size, w, h, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, @@ -168,12 +186,14 @@ nv50_transfer_del(struct pipe_transfer *ptx) if (ptx->usage != PIPE_TRANSFER_READ) { struct pipe_screen *pscreen = ptx->texture->screen; nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride, - 0, 0, tx->base.width, tx->base.height, - mt->bo, tx->level_offset, - tx->level_pitch, tx->level_x, - tx->level_y, tx->level_width, - tx->level_height, tx->base.block.size, + tx->bo->tile_mode, 0, 0, tx->base.width, tx->base.height, + mt->bo, tx->level_offset, + tx->level_pitch, tx->level_tiling, + tx->level_x, tx->level_y, + tx->level_width, tx->level_height, + tx->base.block.size, tx->base.width, + tx->base.height, NOUVEAU_BO_GART, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART); } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index f81929f238..17283f3f41 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -49,6 +49,57 @@ nv50_prim(unsigned mode) return NV50TCL_VERTEX_BEGIN_POINTS; } +static INLINE unsigned +nv50_vtxeltfmt(unsigned pf) +{ + static const uint8_t vtxelt_32[4] = { 0x90, 0x20, 0x10, 0x08 }; + static const uint8_t vtxelt_16[4] = { 0xd8, 0x78, 0x28, 0x18 }; + static const uint8_t vtxelt_08[4] = { 0xe8, 0xc0, 0x98, 0x50 }; + + unsigned nf, c = 0; + + switch (pf_type(pf)) { + case PIPE_FORMAT_TYPE_FLOAT: + nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT; break; + case PIPE_FORMAT_TYPE_UNORM: + nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM; break; + case PIPE_FORMAT_TYPE_SNORM: + nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM; break; + case PIPE_FORMAT_TYPE_USCALED: + nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED; break; + case PIPE_FORMAT_TYPE_SSCALED: + nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED; break; + default: + NOUVEAU_ERR("invalid vbo type %d\n",pf_type(pf)); + assert(0); + nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT; + break; + } + + if (pf_size_y(pf)) c++; + if (pf_size_z(pf)) c++; + if (pf_size_w(pf)) c++; + + if (pf_exp2(pf) == 3) { + switch (pf_size_x(pf)) { + case 1: return (nf | (vtxelt_08[c] << 16)); + case 2: return (nf | (vtxelt_16[c] << 16)); + case 4: return (nf | (vtxelt_32[c] << 16)); + default: + break; + } + } else + if (pf_exp2(pf) == 6 && pf_size_x(pf) == 1) { + NOUVEAU_ERR("unsupported vbo component size 64\n"); + assert(0); + return (nf | 0x08000000); + } + + NOUVEAU_ERR("invalid vbo format %s\n",pf_name(pf)); + assert(0); + return (nf | 0x08000000); +} + boolean nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -139,7 +190,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map, } static INLINE void -nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint8_t *map, +nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map, unsigned start, unsigned count) { struct nouveau_channel *chan = nv50->screen->tesla->channel; @@ -208,9 +259,14 @@ nv50_vbo_validate(struct nv50_context *nv50) struct nouveau_stateobj *vtxbuf, *vtxfmt; int i; + /* don't validate if Gallium took away our buffers */ + if (nv50->vtxbuf_nr == 0) + return; + vtxbuf = so_new(nv50->vtxelt_nr * 4, nv50->vtxelt_nr * 2); vtxfmt = so_new(nv50->vtxelt_nr + 1, 0); - so_method(vtxfmt, tesla, 0x1ac0, nv50->vtxelt_nr); + so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), + nv50->vtxelt_nr); for (i = 0; i < nv50->vtxelt_nr; i++) { struct pipe_vertex_element *ve = &nv50->vtxelt[i]; @@ -218,32 +274,9 @@ nv50_vbo_validate(struct nv50_context *nv50) &nv50->vtxbuf[ve->vertex_buffer_index]; struct nouveau_bo *bo = nouveau_bo(vb->buffer); - switch (ve->src_format) { - case PIPE_FORMAT_R32G32B32A32_FLOAT: - so_data(vtxfmt, 0x7e080000 | i); - break; - case PIPE_FORMAT_R32G32B32_FLOAT: - so_data(vtxfmt, 0x7e100000 | i); - break; - case PIPE_FORMAT_R32G32_FLOAT: - so_data(vtxfmt, 0x7e200000 | i); - break; - case PIPE_FORMAT_R32_FLOAT: - so_data(vtxfmt, 0x7e900000 | i); - break; - case PIPE_FORMAT_R8G8B8A8_UNORM: - so_data(vtxfmt, 0x24500000 | i); - break; - default: - { - NOUVEAU_ERR("invalid vbo format %s\n", - pf_name(ve->src_format)); - assert(0); - return; - } - } + so_data(vtxfmt, nv50_vtxeltfmt(ve->src_format) | i); - so_method(vtxbuf, tesla, 0x900 + (i * 16), 3); + so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3); so_data (vtxbuf, 0x20000000 | vb->stride); so_reloc (vtxbuf, bo, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index faceec9842..d7a2c8c462 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -9,7 +9,6 @@ C_SOURCES = \ r300_chipset.c \ r300_clear.c \ r300_context.c \ - r300_debug.c \ r300_emit.c \ r300_flush.c \ r300_fs.c \ @@ -21,6 +20,22 @@ C_SOURCES = \ r300_state_invariant.c \ r300_vs.c \ r300_surface.c \ - r300_texture.c + r300_texture.c \ + r300_tgsi_to_rc.c + +LIBRARY_INCLUDES = \ + -I$(TOP)/src/mesa/drivers/dri/r300/compiler \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include + +COMPILER_ARCHIVE = $(TOP)/src/mesa/drivers/dri/r300/compiler/libr300compiler.a + +EXTRA_OBJECTS = \ + $(COMPILER_ARCHIVE) include ../../Makefile.template + +.PHONY : $(COMPILER_ARCHIVE) + +$(COMPILER_ARCHIVE): + cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 233a32b53c..c8510bc63e 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -52,7 +52,7 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe, draw_set_mapped_constant_buffer(r300->draw, r300->shader_constants[PIPE_SHADER_VERTEX].constants, - r300->shader_constants[PIPE_SHADER_VERTEX].user_count * + r300->shader_constants[PIPE_SHADER_VERTEX].count * (sizeof(float) * 4)); draw_arrays(r300->draw, mode, start, count); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index d891fd6265..fc8a449893 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -34,6 +34,9 @@ #include "r300_screen.h" #include "r300_winsys.h" +struct r300_fragment_shader; +struct r300_vertex_shader; + struct r300_blend_state { uint32_t blend_control; /* R300_RB3D_CBLEND: 0x4e04 */ uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */ @@ -143,71 +146,10 @@ struct r300_constant_buffer { /* Buffer of constants */ /* XXX first number should be raised */ float constants[32][4]; - /* Number of user-defined constants */ - unsigned user_count; /* Total number of constants */ unsigned count; }; -struct r300_fragment_shader { - /* Parent class */ - struct pipe_shader_state state; - struct tgsi_shader_info info; - - /* Has this shader been translated yet? */ - boolean translated; - - /* Pixel stack size */ - int stack_size; - - /* Are there immediates in this shader? - * If not, we can heavily optimize recompilation. */ - boolean uses_imms; -}; - -struct r3xx_fragment_shader { - /* Parent class */ - struct r300_fragment_shader shader; - - /* Number of ALU instructions */ - int alu_instruction_count; - - /* Number of texture instructions */ - int tex_instruction_count; - - /* Number of texture indirections */ - int indirections; - - /* Indirection node offsets */ - int alu_offset[4]; - - /* Machine instructions */ - struct { - uint32_t alu_rgb_inst; - uint32_t alu_rgb_addr; - uint32_t alu_alpha_inst; - uint32_t alu_alpha_addr; - } instructions[64]; /* XXX magic num */ -}; - -struct r5xx_fragment_shader { - /* Parent class */ - struct r300_fragment_shader shader; - - /* Number of used instructions */ - int instruction_count; - - /* Machine instructions */ - struct { - uint32_t inst0; - uint32_t inst1; - uint32_t inst2; - uint32_t inst3; - uint32_t inst4; - uint32_t inst5; - } instructions[256]; /*< XXX magic number */ -}; - struct r300_texture { /* Parent class */ struct pipe_texture tex; @@ -242,33 +184,6 @@ struct r300_vertex_format { int fs_tab[16]; }; -struct r300_vertex_shader { - /* Parent class */ - struct pipe_shader_state state; - struct tgsi_shader_info info; - - /* Fallback shader, because Draw has issues */ - struct draw_vertex_shader* draw; - - /* Has this shader been translated yet? */ - boolean translated; - - /* Are there immediates in this shader? - * If not, we can heavily optimize recompilation. */ - boolean uses_imms; - - /* Number of used instructions */ - int instruction_count; - - /* Machine instructions */ - struct { - uint32_t inst0; - uint32_t inst1; - uint32_t inst2; - uint32_t inst3; - } instructions[128]; /*< XXX magic number */ -}; - static 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}, diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c deleted file mode 100644 index c83e8526cf..0000000000 --- a/src/gallium/drivers/r300/r300_debug.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "r300_debug.h" - -void r3xx_dump_fs(struct r3xx_fragment_shader* fs) -{ - int i; - - for (i = 0; i < fs->alu_instruction_count; i++) { - } -} - -void r5xx_fs_dump(struct r5xx_fragment_shader* fs) -{ - int i; - uint32_t inst; - - for (i = 0; i < fs->instruction_count; i++) { - inst = fs->instructions[i].inst0; - debug_printf("%d: 0: CMN_INST 0x%08x:", i, inst); - switch (inst & 0x3) { - case R500_INST_TYPE_ALU: - debug_printf("ALU "); - break; - case R500_INST_TYPE_OUT: - debug_printf("OUT "); - break; - case R500_INST_TYPE_FC: - debug_printf("FC "); - break; - case R500_INST_TYPE_TEX: - debug_printf("TEX "); - break; - } - debug_printf("%s %s %s %s ", - inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "", - inst & R500_INST_LAST ? "LAST" : "", - inst & R500_INST_NOP ? "NOP" : "", - inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : ""); - debug_printf("wmask: %s omask: %s\n", - r5xx_fs_mask[(inst >> 11) & 0xf], - r5xx_fs_mask[(inst >> 15) & 0xf]); - switch (inst & 0x3) { - case R500_INST_TYPE_ALU: - case R500_INST_TYPE_OUT: - inst = fs->instructions[i].inst1; - debug_printf(" 1: RGB_ADDR 0x%08x:", inst); - debug_printf("Addr0: %d%c, Addr1: %d%c, " - "Addr2: %d%c, srcp:%d\n", - inst & 0xff, (inst & (1 << 8)) ? 'c' : 't', - (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't', - (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't', - (inst >> 30)); - - inst = fs->instructions[i].inst2; - debug_printf(" 2: ALPHA_ADDR 0x%08x:", inst); - debug_printf("Addr0: %d%c, Addr1: %d%c, " - "Addr2: %d%c, srcp:%d\n", - inst & 0xff, (inst & (1 << 8)) ? 'c' : 't', - (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't', - (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't', - (inst >> 30)); - - inst = fs->instructions[i].inst3; - debug_printf(" 3: RGB_INST 0x%08x:", inst); - debug_printf("rgb_A_src:%d %s/%s/%s %d " - "rgb_B_src:%d %s/%s/%s %d\n", - inst & 0x3, r5xx_fs_swiz[(inst >> 2) & 0x7], - r5xx_fs_swiz[(inst >> 5) & 0x7], - r5xx_fs_swiz[(inst >> 8) & 0x7], - (inst >> 11) & 0x3, (inst >> 13) & 0x3, - r5xx_fs_swiz[(inst >> 15) & 0x7], - r5xx_fs_swiz[(inst >> 18) & 0x7], - r5xx_fs_swiz[(inst >> 21) & 0x7], - (inst >> 24) & 0x3); - - inst = fs->instructions[i].inst4; - debug_printf(" 4: ALPHA_INST 0x%08x:", inst); - debug_printf("%s dest:%d%s alp_A_src:%d %s %d " - "alp_B_src:%d %s %d w:%d\n", - r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f, - inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3, - r5xx_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3, - (inst >> 19) & 0x3, r5xx_fs_swiz[(inst >> 21) & 0x7], - (inst >> 24) & 0x3, (inst >> 31) & 0x1); - - inst = fs->instructions[i].inst5; - debug_printf(" 5: RGBA_INST 0x%08x:", inst); - debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d " - "alp_C_src:%d %s %d\n", - r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f, - inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3, - r5xx_fs_swiz[(inst >> 14) & 0x7], - r5xx_fs_swiz[(inst >> 17) & 0x7], - r5xx_fs_swiz[(inst >> 20) & 0x7], - (inst >> 23) & 0x3, (inst >> 25) & 0x3, - r5xx_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3); - break; - case R500_INST_TYPE_FC: - /* XXX don't even bother yet */ - break; - case R500_INST_TYPE_TEX: - inst = fs->instructions[i].inst1; - debug_printf(" 1: TEX_INST 0x%08x: id: %d " - "op:%s, %s, %s %s\n", - inst, (inst >> 16) & 0xf, - r5xx_fs_tex[(inst >> 22) & 0x7], - (inst & (1 << 25)) ? "ACQ" : "", - (inst & (1 << 26)) ? "IGNUNC" : "", - (inst & (1 << 27)) ? "UNSCALED" : "SCALED"); - - inst = fs->instructions[i].inst2; - debug_printf(" 2: TEX_ADDR 0x%08x: " - "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n", - inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "", - r5xx_fs_swiz[(inst >> 8) & 0x3], - r5xx_fs_swiz[(inst >> 10) & 0x3], - r5xx_fs_swiz[(inst >> 12) & 0x3], - r5xx_fs_swiz[(inst >> 14) & 0x3], - (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "", - r5xx_fs_swiz[(inst >> 24) & 0x3], - r5xx_fs_swiz[(inst >> 26) & 0x3], - r5xx_fs_swiz[(inst >> 28) & 0x3], - r5xx_fs_swiz[(inst >> 30) & 0x3]); - - inst = fs->instructions[i].inst3; - debug_printf(" 3: TEX_DXDY 0x%08x\n", inst); - break; - } - } -} - -static void r300_vs_op_dump(uint32_t op) -{ - debug_printf(" dst: %d%s op: ", - (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]); - if (op & 0x80) { - if (op & 0x1) { - debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n"); - } else { - debug_printf(" PVS_MACRO_OP_2CLK_MADD\n"); - } - } else if (op & 0x40) { - debug_printf("%s\n", r300_vs_me_ops[op & 0x1f]); - } else { - debug_printf("%s\n", r300_vs_ve_ops[op & 0x1f]); - } -} - -void r300_vs_src_dump(uint32_t src) -{ - debug_printf(" reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n", - (src >> 5) & 0x7f, r300_vs_src_debug[src & 0x3], - src & (1 << 25) ? "-" : " ", - r300_vs_swiz_debug[(src >> 13) & 0x7], - src & (1 << 26) ? "-" : " ", - r300_vs_swiz_debug[(src >> 16) & 0x7], - src & (1 << 27) ? "-" : " ", - r300_vs_swiz_debug[(src >> 19) & 0x7], - src & (1 << 28) ? "-" : " ", - r300_vs_swiz_debug[(src >> 22) & 0x7]); -} - -void r300_vs_dump(struct r300_vertex_shader* vs) -{ - int i; - - for (i = 0; i < vs->instruction_count; i++) { - debug_printf("%d: op: 0x%08x", i, vs->instructions[i].inst0); - r300_vs_op_dump(vs->instructions[i].inst0); - debug_printf(" src0: 0x%08x", vs->instructions[i].inst1); - r300_vs_src_dump(vs->instructions[i].inst1); - debug_printf(" src1: 0x%08x", vs->instructions[i].inst2); - r300_vs_src_dump(vs->instructions[i].inst2); - debug_printf(" src2: 0x%08x", vs->instructions[i].inst3); - r300_vs_src_dump(vs->instructions[i].inst3); - } -} diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h deleted file mode 100644 index 6b58c1e250..0000000000 --- a/src/gallium/drivers/r300/r300_debug.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef R300_DEBUG_H -#define R300_DEBUG_H - -#include "r300_reg.h" -#include "r300_fs.h" -#include "r300_vs.h" - -static char* r5xx_fs_swiz[] = { - " R", - " G", - " B", - " A", - " 0", - ".5", - " 1", - " U", -}; - -static char* r5xx_fs_op_rgb[] = { - "MAD", - "DP3", - "DP4", - "D2A", - "MIN", - "MAX", - "---", - "CND", - "CMP", - "FRC", - "SOP", - "MDH", - "MDV", -}; - -static char* r5xx_fs_op_alpha[] = { - "MAD", - " DP", - "MIN", - "MAX", - "---", - "CND", - "CMP", - "FRC", - "EX2", - "LN2", - "RCP", - "RSQ", - "SIN", - "COS", - "MDH", - "MDV", -}; - -static char* r5xx_fs_mask[] = { - "NONE", - "R ", - " G ", - "RG ", - " B ", - "R B ", - " GB ", - "RGB ", - " A", - "R A", - " G A", - "RG A", - " BA", - "R BA", - " GBA", - "RGBA", -}; - -static char* r5xx_fs_tex[] = { - " NOP", - " LD", - "TEXKILL", - " PROJ", - "LODBIAS", - " LOD", - " DXDY", -}; - -static char* r300_vs_ve_ops[] = { - /* R300 vector ops */ - " VE_NO_OP", - " VE_DOT_PRODUCT", - " VE_MULTIPLY", - " VE_ADD", - " VE_MULTIPLY_ADD", - " VE_DISTANCE_FACTOR", - " VE_FRACTION", - " VE_MAXIMUM", - " VE_MINIMUM", - "VE_SET_GREATER_THAN_EQUAL", - " VE_SET_LESS_THAN", - " VE_MULTIPLYX2_ADD", - " VE_MULTIPLY_CLAMP", - " VE_FLT2FIX_DX", - " VE_FLT2FIX_DX_RND", - /* R500 vector ops */ - " VE_PRED_SET_EQ_PUSH", - " VE_PRED_SET_GT_PUSH", - " VE_PRED_SET_GTE_PUSH", - " VE_PRED_SET_NEQ_PUSH", - " VE_COND_WRITE_EQ", - " VE_COND_WRITE_GT", - " VE_COND_WRITE_GTE", - " VE_COND_WRITE_NEQ", - " VE_SET_GREATER_THAN", - " VE_SET_EQUAL", - " VE_SET_NOT_EQUAL", - " (reserved)", - " (reserved)", - " (reserved)", -}; - -static char* r300_vs_me_ops[] = { - /* R300 math ops */ - " ME_NO_OP", - " ME_EXP_BASE2_DX", - " ME_LOG_BASE2_DX", - " ME_EXP_BASEE_FF", - " ME_LIGHT_COEFF_DX", - " ME_POWER_FUNC_FF", - " ME_RECIP_DX", - " ME_RECIP_FF", - " ME_RECIP_SQRT_DX", - " ME_RECIP_SQRT_FF", - " ME_MULTIPLY", - " ME_EXP_BASE2_FULL_DX", - " ME_LOG_BASE2_FULL_DX", - " ME_POWER_FUNC_FF_CLAMP_B", - "ME_POWER_FUNC_FF_CLAMP_B1", - "ME_POWER_FUNC_FF_CLAMP_01", - " ME_SIN", - " ME_COS", - /* R500 math ops */ - " ME_LOG_BASE2_IEEE", - " ME_RECIP_IEEE", - " ME_RECIP_SQRT_IEEE", - " ME_PRED_SET_EQ", - " ME_PRED_SET_GT", - " ME_PRED_SET_GTE", - " ME_PRED_SET_NEQ", - " ME_PRED_SET_CLR", - " ME_PRED_SET_INV", - " ME_PRED_SET_POP", - " ME_PRED_SET_RESTORE", - " (reserved)", - " (reserved)", - " (reserved)", -}; - -/* XXX refactor to avoid clashing symbols */ -static char* r300_vs_src_debug[] = { - "t", - "i", - "c", - "a", -}; - -static char* r300_vs_dst_debug[] = { - "t", - "a0", - "o", - "ox", - "a", - "i", - "u", - "u", -}; - -static char* r300_vs_swiz_debug[] = { - "X", - "Y", - "Z", - "W", - "0", - "1", - "U", - "U", -}; - -void r5xx_fs_dump(struct r5xx_fragment_shader* fs); -void r3xx_dump_fs(struct r3xx_fragment_shader* fs); - -void r300_vs_dump(struct r300_vertex_shader* vs); - -#endif /* R300_DEBUG_H */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 7ba56cdc1d..53256fc6dd 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -24,6 +24,9 @@ #include "r300_emit.h" +#include "r300_fs.h" +#include "r300_vs.h" + void r300_emit_blend_state(struct r300_context* r300, struct r300_blend_state* blend) { @@ -109,73 +112,158 @@ void r300_emit_dsa_state(struct r300_context* r300, END_CS; } -void r300_emit_fragment_shader(struct r300_context* r300, - struct r3xx_fragment_shader* fs) +static const float * get_shader_constant( + struct r300_context * r300, + struct rc_constant * constant, + struct r300_constant_buffer * externals) +{ + static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 }; + switch(constant->Type) { + case RC_CONSTANT_EXTERNAL: + return externals->constants[constant->u.External]; + + case RC_CONSTANT_IMMEDIATE: + return constant->u.Immediate; + + default: + debug_printf("r300: Implementation error: Unhandled constant type %i\n", + constant->Type); + return zero; + } +} + +/* Convert a normal single-precision float into the 7.16 format + * used by the R300 fragment shader. + */ +static uint32_t pack_float24(float f) { + union { + float fl; + uint32_t u; + } u; + float mantissa; + int exponent; + uint32_t float24 = 0; + + if (f == 0.0) + return 0; + + u.fl = f; + + mantissa = frexpf(f, &exponent); + + /* Handle -ve */ + if (mantissa < 0) { + float24 |= (1 << 23); + mantissa = mantissa * -1.0; + } + /* Handle exponent, bias of 63 */ + exponent += 62; + float24 |= (exponent << 16); + /* Kill 7 LSB of mantissa */ + float24 |= (u.u & 0x7FFFFF) >> 7; + + return float24; +} + +void r300_emit_fragment_program_code(struct r300_context* r300, + struct rX00_fragment_program_code* generic_code, + struct r300_constant_buffer* externals) +{ + struct r300_fragment_program_code * code = &generic_code->code.r300; + struct rc_constant_list * constants = &generic_code->constants; int i; CS_LOCALS(r300); - BEGIN_CS(22); - - OUT_CS_REG(R300_US_CONFIG, fs->indirections); - OUT_CS_REG(R300_US_PIXSIZE, fs->shader.stack_size); - /* XXX figure out exactly how big the sizes are on this reg */ - OUT_CS_REG(R300_US_CODE_OFFSET, 0x40); - /* XXX figure these ones out a bit better kthnx */ - OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); - OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); - OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); - OUT_CS_REG(R300_US_CODE_ADDR_3, 0x40 | R300_RGBA_OUT); - - for (i = 0; i < fs->alu_instruction_count; i++) { - OUT_CS_REG(R300_US_ALU_RGB_INST_0 + (4 * i), - fs->instructions[i].alu_rgb_inst); - OUT_CS_REG(R300_US_ALU_RGB_ADDR_0 + (4 * i), - fs->instructions[i].alu_rgb_addr); - OUT_CS_REG(R300_US_ALU_ALPHA_INST_0 + (4 * i), - fs->instructions[i].alu_alpha_inst); - OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0 + (4 * i), - fs->instructions[i].alu_alpha_addr); + BEGIN_CS(15 + + code->alu.length * 4 + + (code->tex.length ? (1 + code->tex.length) : 0) + + (constants->Count ? (1 + constants->Count * 4) : 0)); + + OUT_CS_REG(R300_US_CONFIG, code->config); + OUT_CS_REG(R300_US_PIXSIZE, code->pixsize); + OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset); + + OUT_CS_REG_SEQ(R300_US_CODE_ADDR_0, 4); + for(i = 0; i < 4; ++i) + OUT_CS(code->code_addr[i]); + + OUT_CS_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) + OUT_CS(code->alu.inst[i].rgb_inst); + + OUT_CS_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) + OUT_CS(code->alu.inst[i].rgb_addr); + + OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) + OUT_CS(code->alu.inst[i].alpha_inst); + + OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) + OUT_CS(code->alu.inst[i].alpha_addr); + + if (code->tex.length) { + OUT_CS_REG_SEQ(R300_US_TEX_INST_0, code->tex.length); + for(i = 0; i < code->tex.length; ++i) + OUT_CS(code->tex.inst[i]); + } + + if (constants->Count) { + OUT_CS_ONE_REG(R300_PFS_PARAM_0_X, constants->Count * 4); + for(i = 0; i < constants->Count; ++i) { + const float * data = get_shader_constant(r300, &constants->Constants[i], externals); + OUT_CS(pack_float24(data[0])); + OUT_CS(pack_float24(data[1])); + OUT_CS(pack_float24(data[2])); + OUT_CS(pack_float24(data[3])); + } } END_CS; } -void r500_emit_fragment_shader(struct r300_context* r300, - struct r5xx_fragment_shader* fs) +void r500_emit_fragment_program_code(struct r300_context* r300, + struct rX00_fragment_program_code* generic_code, + struct r300_constant_buffer* externals) { + struct r500_fragment_program_code * code = &generic_code->code.r500; + struct rc_constant_list * constants = &generic_code->constants; int i; - struct r300_constant_buffer* constants = - &r300->shader_constants[PIPE_SHADER_FRAGMENT]; CS_LOCALS(r300); - BEGIN_CS(9 + (fs->instruction_count * 6) + (constants->count ? 3 : 0) + - (constants->count * 4)); - OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); - OUT_CS_REG(R500_US_PIXSIZE, fs->shader.stack_size); - OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) | - R500_US_CODE_END_ADDR(fs->instruction_count)); + BEGIN_CS(13 + + ((code->inst_end + 1) * 6) + + (constants->Count ? (3 + (constants->Count * 4)) : 0)); + OUT_CS_REG(R500_US_CONFIG, 0); + OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx); + OUT_CS_REG(R500_US_CODE_RANGE, + R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end)); + OUT_CS_REG(R500_US_CODE_OFFSET, 0); + OUT_CS_REG(R500_US_CODE_ADDR, + R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(code->inst_end)); OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_INSTR); - OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, fs->instruction_count * 6); - for (i = 0; i < fs->instruction_count; i++) { - OUT_CS(fs->instructions[i].inst0); - OUT_CS(fs->instructions[i].inst1); - OUT_CS(fs->instructions[i].inst2); - OUT_CS(fs->instructions[i].inst3); - OUT_CS(fs->instructions[i].inst4); - OUT_CS(fs->instructions[i].inst5); - } - - if (constants->count) { - OUT_CS_REG(R500_GA_US_VECTOR_INDEX, - R500_GA_US_VECTOR_INDEX_TYPE_CONST); - OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->count * 4); - for (i = 0; i < constants->count; i++) { - OUT_CS_32F(constants->constants[i][0]); - OUT_CS_32F(constants->constants[i][1]); - OUT_CS_32F(constants->constants[i][2]); - OUT_CS_32F(constants->constants[i][3]); + OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, (code->inst_end + 1) * 6); + for (i = 0; i <= code->inst_end; i++) { + OUT_CS(code->inst[i].inst0); + OUT_CS(code->inst[i].inst1); + OUT_CS(code->inst[i].inst2); + OUT_CS(code->inst[i].inst3); + OUT_CS(code->inst[i].inst4); + OUT_CS(code->inst[i].inst5); + } + + if (constants->Count) { + OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST); + OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4); + for (i = 0; i < constants->Count; i++) { + const float * data = get_shader_constant(r300, &constants->Constants[i], externals); + OUT_CS_32F(data[0]); + OUT_CS_32F(data[1]); + OUT_CS_32F(data[2]); + OUT_CS_32F(data[3]); } } @@ -190,7 +278,7 @@ void r300_emit_fb_state(struct r300_context* r300, int i; CS_LOCALS(r300); - BEGIN_CS((8 * fb->nr_cbufs) + (fb->zsbuf ? 8 : 0) + 4); + BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4); for (i = 0; i < fb->nr_cbufs; i++) { tex = (struct r300_texture*)fb->cbufs[i]->texture; assert(tex && tex->buffer && "cbuf is marked, but NULL!"); @@ -199,8 +287,10 @@ void r300_emit_fb_state(struct r300_context* r300, OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); - OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), pixpitch | - r300_translate_colorformat(tex->tex.format)); + OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); + OUT_CS_RELOC(tex->buffer, pixpitch | + r300_translate_colorformat(tex->tex.format), 0, + RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), r300_translate_out_fmt(fb->cbufs[i]->format)); @@ -216,7 +306,8 @@ void r300_emit_fb_state(struct r300_context* r300, OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format)); - OUT_CS_REG(R300_ZB_DEPTHPITCH, pixpitch); + OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); + OUT_CS_RELOC(tex->buffer, pixpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0); } OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, @@ -380,13 +471,13 @@ void r300_emit_vertex_format_state(struct r300_context* r300) END_CS; } -void r300_emit_vertex_shader(struct r300_context* r300, - struct r300_vertex_shader* vs) +void r300_emit_vertex_program_code(struct r300_context* r300, + struct r300_vertex_program_code* code, + struct r300_constant_buffer* constants) { int i; struct r300_screen* r300screen = r300_screen(r300->context.screen); - struct r300_constant_buffer* constants = - &r300->shader_constants[PIPE_SHADER_VERTEX]; + unsigned instruction_count = code->length / 4; CS_LOCALS(r300); if (!r300screen->caps->has_tcl) { @@ -395,10 +486,10 @@ void r300_emit_vertex_shader(struct r300_context* r300, return; } - if (constants->count) { - BEGIN_CS(14 + (vs->instruction_count * 4) + (constants->count * 4)); + if (code->constants.Count) { + BEGIN_CS(14 + code->length + (code->constants.Count * 4)); } else { - BEGIN_CS(11 + (vs->instruction_count * 4)); + BEGIN_CS(11 + code->length); } /* R300_VAP_PVS_CODE_CNTL_0 @@ -408,30 +499,27 @@ void r300_emit_vertex_shader(struct r300_context* r300, * XXX these could be optimized to select better values... */ OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3); OUT_CS(R300_PVS_FIRST_INST(0) | - R300_PVS_XYZW_VALID_INST(vs->instruction_count - 1) | - R300_PVS_LAST_INST(vs->instruction_count - 1)); - OUT_CS(R300_PVS_MAX_CONST_ADDR(constants->count - 1)); - OUT_CS(vs->instruction_count - 1); + R300_PVS_XYZW_VALID_INST(instruction_count - 1) | + R300_PVS_LAST_INST(instruction_count - 1)); + OUT_CS(R300_PVS_MAX_CONST_ADDR(code->constants.Count - 1)); + OUT_CS(instruction_count - 1); OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0); - OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4); - for (i = 0; i < vs->instruction_count; i++) { - OUT_CS(vs->instructions[i].inst0); - OUT_CS(vs->instructions[i].inst1); - OUT_CS(vs->instructions[i].inst2); - OUT_CS(vs->instructions[i].inst3); - } + OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length); + for (i = 0; i < code->length; i++) + OUT_CS(code->body.d[i]); - if (constants->count) { + if (code->constants.Count) { OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, (r300screen->caps->is_r500 ? R500_PVS_CONST_START : R300_PVS_CONST_START)); - OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->count * 4); - for (i = 0; i < constants->count; i++) { - OUT_CS_32F(constants->constants[i][0]); - OUT_CS_32F(constants->constants[i][1]); - OUT_CS_32F(constants->constants[i][2]); - OUT_CS_32F(constants->constants[i][3]); + OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4); + for (i = 0; i < code->constants.Count; i++) { + const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants); + OUT_CS_32F(data[0]); + OUT_CS_32F(data[1]); + OUT_CS_32F(data[2]); + OUT_CS_32F(data[3]); } } @@ -443,6 +531,12 @@ void r300_emit_vertex_shader(struct r300_context* r300, END_CS; } +void r300_emit_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs) +{ + r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]); +} + void r300_emit_viewport_state(struct r300_context* r300, struct r300_viewport_state* viewport) { @@ -531,10 +625,11 @@ validate: } else { debug_printf("No VBO while emitting dirty state!\n"); } - if (r300->winsys->validate(r300->winsys)) { + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { /* Well, hell. */ + debug_printf("r300: Stuck in validation loop, gonna quit now."); exit(1); } invalid = TRUE; @@ -563,11 +658,9 @@ validate: if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) { if (r300screen->caps->is_r500) { - r500_emit_fragment_shader(r300, - (struct r5xx_fragment_shader*)r300->fs); + r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]); } else { - r300_emit_fragment_shader(r300, - (struct r3xx_fragment_shader*)r300->fs); + r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]); } r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER; } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index fda26f3948..350691d592 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -30,6 +30,9 @@ #include "r300_screen.h" #include "r300_state_inlines.h" +struct rX00_fragment_program_code; +struct r300_vertex_program_code; + void r300_emit_blend_state(struct r300_context* r300, struct r300_blend_state* blend); @@ -42,11 +45,13 @@ void r300_emit_clip_state(struct r300_context* r300, void r300_emit_dsa_state(struct r300_context* r300, struct r300_dsa_state* dsa); -void r300_emit_fragment_shader(struct r300_context* r300, - struct r3xx_fragment_shader* fs); +void r300_emit_fragment_program_code(struct r300_context* r300, + struct rX00_fragment_program_code* generic_code, + struct r300_constant_buffer* externals); -void r500_emit_fragment_shader(struct r300_context* r300, - struct r5xx_fragment_shader* fs); +void r500_emit_fragment_program_code(struct r300_context* r300, + struct rX00_fragment_program_code* generic_code, + struct r300_constant_buffer* externals); void r300_emit_fb_state(struct r300_context* r300, struct pipe_framebuffer_state* fb); @@ -68,6 +73,10 @@ void r300_emit_vertex_buffer(struct r300_context* r300); void r300_emit_vertex_format_state(struct r300_context* r300); +void r300_emit_vertex_program_code(struct r300_context* r300, + struct r300_vertex_program_code* code, + struct r300_constant_buffer* constants); + void r300_emit_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 4b304306d0..36463b9a2e 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -23,87 +23,115 @@ #include "r300_fs.h" -void r300_translate_fragment_shader(struct r300_context* r300, - struct r300_fragment_shader* fs) +#include "r300_tgsi_to_rc.h" + +#include "radeon_compiler.h" + +static void find_output_registers(struct r300_fragment_program_compiler * compiler, + struct r300_fragment_shader * fs) { - struct tgsi_parse_context parser; - int i; - boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; - struct r300_constant_buffer* consts = - &r300->shader_constants[PIPE_SHADER_FRAGMENT]; + unsigned i; - struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm); - if (assembler == NULL) { - return; - } - /* Setup starting offset for immediates. */ - assembler->imm_offset = consts->user_count; - /* Enable depth writes, if needed. */ - assembler->writes_depth = fs->info.writes_z; - - /* Make sure we start at the beginning of the shader. */ - if (is_r500) { - ((struct r5xx_fragment_shader*)fs)->instruction_count = 0; - } + /* Mark the outputs as not present initially */ + compiler->OutputColor = fs->info.num_outputs; + compiler->OutputDepth = fs->info.num_outputs; - tgsi_parse_init(&parser, fs->state.tokens); + /* Now see where they really are. */ + for(i = 0; i < fs->info.num_outputs; ++i) { + switch(fs->info.output_semantic_name[i]) { + case TGSI_SEMANTIC_COLOR: + compiler->OutputColor = i; + break; + case TGSI_SEMANTIC_POSITION: + compiler->OutputDepth = i; + break; + } + } +} - while (!tgsi_parse_end_of_tokens(&parser)) { - tgsi_parse_token(&parser); +static void allocate_hardware_inputs( + struct r300_fragment_program_compiler * c, + void (*allocate)(void * data, unsigned input, unsigned hwreg), + void * mydata) +{ + struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info; + int total_colors = 0; + int colors = 0; + int total_generic = 0; + int generic = 0; + int i; - /* This is seriously the lamest way to create fragment programs ever. - * I blame TGSI. */ - switch (parser.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - /* Allocated registers sitting at the beginning - * of the program. */ - r300_fs_declare(assembler, &parser.FullToken.FullDeclaration); + for (i = 0; i < info->num_inputs; i++) { + switch (info->input_semantic_name[i]) { + case TGSI_SEMANTIC_COLOR: + total_colors++; break; - case TGSI_TOKEN_TYPE_IMMEDIATE: - debug_printf("r300: Emitting immediate to constant buffer, " - "position %d\n", - assembler->imm_offset + assembler->imm_count); - /* I am not amused by the length of these. */ - for (i = 0; i < 4; i++) { - consts->constants[assembler->imm_offset + - assembler->imm_count][i] = - parser.FullToken.FullImmediate.u.ImmediateFloat32[i] - .Float; - } - assembler->imm_count++; + case TGSI_SEMANTIC_FOG: + case TGSI_SEMANTIC_GENERIC: + total_generic++; break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - if (is_r500) { - r5xx_fs_instruction((struct r5xx_fragment_shader*)fs, - assembler, &parser.FullToken.FullInstruction); - } else { - r3xx_fs_instruction((struct r3xx_fragment_shader*)fs, - assembler, &parser.FullToken.FullInstruction); - } + } + } + + for(i = 0; i < info->num_inputs; i++) { + switch (info->input_semantic_name[i]) { + case TGSI_SEMANTIC_COLOR: + allocate(mydata, i, colors); + colors++; + break; + case TGSI_SEMANTIC_FOG: + case TGSI_SEMANTIC_GENERIC: + allocate(mydata, i, total_colors + generic); + generic++; break; } } +} + +void r300_translate_fragment_shader(struct r300_context* r300, + struct r300_fragment_shader* fs) +{ + struct r300_fragment_program_compiler compiler; + struct tgsi_to_rc ttr; + + memset(&compiler, 0, sizeof(compiler)); + rc_init(&compiler.Base); + compiler.Base.Debug = 1; + + compiler.code = &fs->code; + compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500; + compiler.AllocateHwInputs = &allocate_hardware_inputs; + compiler.UserData = fs; + + /* TODO: Program compilation depends on texture compare modes, + * which are sampler state. Therefore, programs need to be recompiled + * depending on this state as in the classic Mesa driver. + * + * This is not yet handled correctly. + */ - debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n", - assembler->tex_count, assembler->color_count, - assembler->tex_count + assembler->color_count); - - consts->count = consts->user_count + assembler->imm_count; - fs->uses_imms = assembler->imm_count; - debug_printf("r300: fs: %d total constants, " - "%d from user and %d from immediates\n", consts->count, - consts->user_count, assembler->imm_count); - r3xx_fs_finalize(fs, assembler); - if (is_r500) { - r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler); + find_output_registers(&compiler, fs); + + if (compiler.Base.Debug) { + debug_printf("r300: Initial fragment program\n"); + tgsi_dump(fs->state.tokens, 0); } - tgsi_dump(fs->state.tokens, 0); - /* XXX finish r300 dumper too */ - if (is_r500) { - r5xx_fs_dump((struct r5xx_fragment_shader*)fs); + /* Translate TGSI to our internal representation */ + ttr.compiler = &compiler.Base; + ttr.info = &fs->info; + + r300_tgsi_to_rc(&ttr, fs->state.tokens); + + /* Invoke the compiler */ + r3xx_compile_fragment_program(&compiler); + if (compiler.Base.Error) { + /* Todo: Fail gracefully */ + fprintf(stderr, "r300 FP: Compiler error\n"); + abort(); } - tgsi_parse_free(&parser); - FREE(assembler); + /* And, finally... */ + rc_destroy(&compiler.Base); + fs->translated = TRUE; } diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h index 18deb7a05e..9fab789402 100644 --- a/src/gallium/drivers/r300/r300_fs.h +++ b/src/gallium/drivers/r300/r300_fs.h @@ -30,6 +30,21 @@ #include "r3xx_fs.h" #include "r5xx_fs.h" +#include "radeon_code.h" + +struct r300_fragment_shader { + /* Parent class */ + struct pipe_shader_state state; + struct tgsi_shader_info info; + + /* Has this shader been translated yet? */ + boolean translated; + + /* Compiled code */ + struct rX00_fragment_program_code code; +}; + + void r300_translate_fragment_shader(struct r300_context* r300, struct r300_fragment_shader* fs); diff --git a/src/gallium/drivers/r300/r300_fs_inlines.h b/src/gallium/drivers/r300/r300_fs_inlines.h deleted file mode 100644 index be4be9465e..0000000000 --- a/src/gallium/drivers/r300/r300_fs_inlines.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> - * Joakim Sindholt <opensource@zhasha.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef R300_FS_INLINES_H -#define R300_FS_INLINES_H - -#include "tgsi/tgsi_parse.h" - -#include "r300_context.h" -#include "r300_debug.h" -#include "r300_reg.h" -#include "r300_screen.h" -#include "r300_shader_inlines.h" - -/* Temporary struct used to hold assembly state while putting together - * fragment programs. */ -struct r300_fs_asm { - /* Pipe context. */ - struct r300_context* r300; - /* Number of colors. */ - unsigned color_count; - /* Number of texcoords. */ - unsigned tex_count; - /* Offset for temporary registers. Inputs and temporaries have no - * distinguishing markings, so inputs start at 0 and the first usable - * temporary register is after all inputs. */ - unsigned temp_offset; - /* Number of requested temporary registers. */ - unsigned temp_count; - /* Offset for immediate constants. Neither R300 nor R500 can do four - * inline constants per source, so instead we copy immediates into the - * constant buffer. */ - unsigned imm_offset; - /* Number of immediate constants. */ - unsigned imm_count; - /* Are depth writes enabled? */ - boolean writes_depth; - /* Depth write offset. This is the TGSI output that corresponds to - * depth writes. */ - unsigned depth_output; -}; - -static INLINE void r300_fs_declare(struct r300_fs_asm* assembler, - struct tgsi_full_declaration* decl) -{ - switch (decl->Declaration.File) { - case TGSI_FILE_INPUT: - switch (decl->Semantic.SemanticName) { - case TGSI_SEMANTIC_COLOR: - assembler->color_count++; - break; - case TGSI_SEMANTIC_FOG: - case TGSI_SEMANTIC_GENERIC: - assembler->tex_count++; - break; - default: - debug_printf("r300: fs: Bad semantic declaration %d\n", - decl->Semantic.SemanticName); - break; - } - break; - case TGSI_FILE_OUTPUT: - /* Depth write. Mark the position of the output so we can - * identify it later. */ - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { - assembler->depth_output = decl->DeclarationRange.First; - } - break; - case TGSI_FILE_CONSTANT: - break; - case TGSI_FILE_TEMPORARY: - assembler->temp_count++; - break; - default: - debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File); - break; - } - - assembler->temp_offset = assembler->color_count + assembler->tex_count; -} - -static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler, - struct tgsi_src_register* src) -{ - switch (src->File) { - case TGSI_FILE_NULL: - return 0; - case TGSI_FILE_INPUT: - /* XXX may be wrong */ - return src->Index; - break; - case TGSI_FILE_TEMPORARY: - return src->Index + assembler->temp_offset; - break; - case TGSI_FILE_IMMEDIATE: - return (src->Index + assembler->imm_offset) | (1 << 8); - break; - case TGSI_FILE_CONSTANT: - /* XXX magic */ - return src->Index | (1 << 8); - break; - default: - debug_printf("r300: fs: Unimplemented src %d\n", src->File); - break; - } - return 0; -} - -static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler, - struct tgsi_dst_register* dst) -{ - switch (dst->File) { - case TGSI_FILE_NULL: - /* This happens during KIL instructions. */ - return 0; - break; - case TGSI_FILE_OUTPUT: - return 0; - break; - case TGSI_FILE_TEMPORARY: - return dst->Index + assembler->temp_offset; - break; - default: - debug_printf("r300: fs: Unimplemented dst %d\n", dst->File); - break; - } - return 0; -} - -static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler, - struct tgsi_dst_register* dst) -{ - return (assembler->writes_depth && - (dst->File == TGSI_FILE_OUTPUT) && - (dst->Index == assembler->depth_output)); -} - -#endif /* R300_FS_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index da1d5ffe2f..96a7304621 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -147,6 +147,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) case PIPE_CAP_TGSI_CONT_SUPPORTED: /* XXX */ return 0; + case PIPE_CAP_BLEND_EQUATION_SEPARATE: + return 1; default: debug_printf("r300: Implementation error: Bad param %d\n", param); @@ -320,13 +322,14 @@ r300_get_tex_transfer(struct pipe_screen *screen, trans = CALLOC_STRUCT(r300_transfer); if (trans) { pipe_texture_reference(&trans->transfer.texture, texture); - trans->transfer.format = trans->transfer.format; + trans->transfer.format = texture->format; trans->transfer.width = w; trans->transfer.height = h; trans->transfer.block = texture->block; trans->transfer.nblocksx = texture->nblocksx[level]; trans->transfer.nblocksy = texture->nblocksy[level]; - trans->transfer.stride = tex->stride; + trans->transfer.stride = align(pf_get_stride(&trans->transfer.block, + texture->width[level]), 32); trans->transfer.usage = usage; trans->offset = offset; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 68da0aa4cb..a02fb34b2a 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -32,6 +32,7 @@ #include "r300_reg.h" #include "r300_state_inlines.h" #include "r300_fs.h" +#include "r300_vs.h" /* r300_state: Functions used to intialize state context by translating * Gallium state objects into semi-native r300 state objects. */ @@ -137,7 +138,6 @@ static void const struct pipe_constant_buffer* buffer) { struct r300_context* r300 = r300_context(pipe); - int i = r300->shader_constants[shader].user_count; /* This entire chunk of code seems ever-so-slightly baked. * It's as if I've got pipe_buffer* matryoshkas... */ @@ -148,26 +148,13 @@ static void map, buffer->buffer->size); pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer); - r300->shader_constants[shader].user_count = + r300->shader_constants[shader].count = buffer->buffer->size / (sizeof(float) * 4); } else { - r300->shader_constants[shader].user_count = 0; + r300->shader_constants[shader].count = 0; } r300->dirty_state |= R300_NEW_CONSTANTS; - - /* If the number of constants have changed, invalidate the shader. */ - if (r300->shader_constants[shader].user_count != i) { - if (shader == PIPE_SHADER_FRAGMENT && r300->fs && - r300->fs->uses_imms) { - r300->fs->translated = FALSE; - r300_translate_fragment_shader(r300, r300->fs); - } else if (shader == PIPE_SHADER_VERTEX && r300->vs && - r300->vs->uses_imms) { - r300->vs->translated = FALSE; - r300_translate_vertex_shader(r300, r300->vs); - } - } } /* Create a new depth, stencil, and alpha state based on the CSO dsa state. @@ -284,14 +271,9 @@ static void static void* r300_create_fs_state(struct pipe_context* pipe, const struct pipe_shader_state* shader) { - struct r300_context* r300 = r300_context(pipe); struct r300_fragment_shader* fs = NULL; - if (r300_screen(r300->context.screen)->caps->is_r500) { - fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader); - } else { - fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader); - } + fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader); /* Copy state directly into shader. */ fs->state = *shader; @@ -315,7 +297,6 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300_translate_fragment_shader(r300, fs); } - fs->translated = TRUE; r300->fs = fs; r300->dirty_state |= R300_NEW_FRAGMENT_SHADER; @@ -325,6 +306,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) { struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; + rc_constants_destroy(&fs->code.constants); FREE(fs->state.tokens); FREE(shader); } @@ -688,6 +670,7 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) if (r300_screen(pipe->screen)->caps->has_tcl) { struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; + rc_constants_destroy(&vs->code.constants); draw_delete_vertex_shader(r300->draw, vs->draw); FREE(vs->state.tokens); FREE(shader); diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 2477b30822..ea670f41fb 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -22,6 +22,9 @@ #include "r300_state_derived.h" +#include "r300_fs.h" +#include "r300_vs.h" + /* r300_state_derived: Various bits of state which are dependent upon * currently bound CSO data. */ diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index 430129d5bd..1e92374a4e 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -34,7 +34,7 @@ void r300_emit_invariant_state(struct r300_context* r300) struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; CS_LOCALS(r300); - BEGIN_CS(22 + (caps->has_tcl ? 2: 0)); + BEGIN_CS(24 + (caps->has_tcl ? 2: 0)); /*** Graphics Backend (GB) ***/ /* Various GB enables */ @@ -56,6 +56,7 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x0); OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x0); OUT_CS_REG(R300_FG_DEPTH_SRC, 0x0); + OUT_CS_REG(R300_US_W_FMT, 0x0); /*** VAP ***/ /* Max and min vertex index clamp. */ @@ -72,7 +73,7 @@ void r300_emit_invariant_state(struct r300_context* r300) END_CS; /* XXX unsorted stuff from surface_fill */ - BEGIN_CS(71 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0)); + BEGIN_CS(64 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0)); /* Flush PVS. */ OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); @@ -132,11 +133,5 @@ void r300_emit_invariant_state(struct r300_context* r300) /* XXX */ OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa); - OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4); - OUT_CS(R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A); - OUT_CS(R300_US_OUT_FMT_UNUSED); - OUT_CS(R300_US_OUT_FMT_UNUSED); - OUT_CS(R300_US_OUT_FMT_UNUSED); - OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0); END_CS; } diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index fdabe4d9cf..a093f83945 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -37,7 +37,7 @@ static void r300_surface_setup(struct r300_context* r300, r300_emit_dsa_state(r300, &dsa_clear_state); r300_emit_rs_state(r300, &rs_clear_state); - BEGIN_CS(24); + BEGIN_CS(26); /* Viewport setup */ OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); @@ -78,8 +78,10 @@ static void r300_surface_setup(struct r300_context* r300, /* Setup colorbuffer. */ OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1); OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); - OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch | - r300_translate_colorformat(dest->tex.format)); + OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0, 1); + OUT_CS_RELOC(dest->buffer, pixpitch | + r300_translate_colorformat(dest->tex.format), 0, + RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf); END_CS; @@ -125,9 +127,10 @@ validate: r300->context.flush(&r300->context, 0, NULL); goto validate; } - if (r300->winsys->validate(r300->winsys)) { + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { + debug_printf("r300: Stuck in validation loop, gonna fallback."); goto fallback; } invalid = TRUE; @@ -138,10 +141,14 @@ validate: /* Vertex shader setup */ if (caps->has_tcl) { - r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader); + r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0); } else { BEGIN_CS(4); - OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); + OUT_CS_REG(R300_VAP_CNTL_STATUS, +#ifdef PIPE_ARCH_BIG_ENDIAN + R300_VC_32BIT_SWAP | +#endif + R300_VAP_TCL_BYPASS); OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) | R300_PVS_NUM_CNTLRS(5) | R300_PVS_NUM_FPUS(caps->num_vert_fpus) | @@ -151,10 +158,10 @@ validate: /* Fragment shader setup */ if (caps->is_r500) { - r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader); + r500_emit_fragment_program_code(r300, &r5xx_passthrough_fragment_shader, 0); r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state); } else { - r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader); + r300_emit_fragment_program_code(r300, &r3xx_passthrough_fragment_shader, 0); r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state); } @@ -256,9 +263,10 @@ validate: r300->context.flush(&r300->context, 0, NULL); goto validate; } - if (r300->winsys->validate(r300->winsys)) { + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { + debug_printf("r300: Stuck in validation loop, gonna fallback."); goto fallback; } invalid = TRUE; @@ -275,10 +283,14 @@ validate: /* Vertex shader setup */ if (caps->has_tcl) { - r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader); + r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0); } else { BEGIN_CS(4); - OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); + OUT_CS_REG(R300_VAP_CNTL_STATUS, +#ifdef PIPE_ARCH_BIG_ENDIAN + R300_VC_32BIT_SWAP | +#endif + R300_VAP_TCL_BYPASS); OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) | R300_PVS_NUM_CNTLRS(5) | R300_PVS_NUM_FPUS(caps->num_vert_fpus) | @@ -288,10 +300,10 @@ validate: /* Fragment shader setup */ if (caps->is_r500) { - r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader); + r500_emit_fragment_program_code(r300, &r5xx_texture_fragment_shader, 0); r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state); } else { - r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader); + r300_emit_fragment_program_code(r300, &r3xx_texture_fragment_shader, 0); r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state); } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 11c7858d42..590052509c 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -22,13 +22,6 @@ #include "r300_texture.h" -/* XXX maths need to go to util */ - -static int minify(int i) -{ - return MAX2(1, i >> 1); -} - static void r300_setup_texture_state(struct r300_texture* tex, unsigned width, unsigned height, @@ -55,6 +48,9 @@ static void r300_setup_texture_state(struct r300_texture* tex, if (height > 2048) { state->format2 |= R500_TXHEIGHT_BIT11; } + + debug_printf("r300: Set texture state (%dx%d, pitch %d, %d levels)\n", + width, height, pitch, levels); } static void r300_setup_miptree(struct r300_texture* tex) @@ -71,19 +67,23 @@ static void r300_setup_miptree(struct r300_texture* tex) } base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]); - base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]); + base->nblocksy[i] = pf_get_nblocksy(&base->block, base->height[i]); /* Radeons enjoy things in multiples of 64. * * XXX * POT, uncompressed, unmippmapped textures can be aligned to 32, * instead of 64. */ - stride = align(base->nblocksx[i] * base->block.size, 64); + stride = align(pf_get_stride(&base->block, base->width[i]), 32); size = stride * base->nblocksy[i] * base->depth[i]; - tex->offset[i] = align(tex->size, 64); + tex->offset[i] = align(tex->size, 32); tex->size = tex->offset[i] + size; + debug_printf("r300: Texture miptree: Level %d " + "(%dx%dx%d px, pitch %d bytes)\n", + i, base->width[i], base->height[i], base->depth[i], + stride); /* Save stride of first level to the texture. */ if (i == 0) { tex->stride = stride; @@ -111,7 +111,7 @@ static struct pipe_texture* r300_setup_texture_state(tex, template->width[0], template->height[0], template->width[0], template->last_level); - tex->buffer = screen->buffer_create(screen, 64, + tex->buffer = screen->buffer_create(screen, 1024, PIPE_BUFFER_USAGE_PIXEL, tex->size); diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c new file mode 100644 index 0000000000..3adbb715f3 --- /dev/null +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -0,0 +1,337 @@ +/* + * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "r300_tgsi_to_rc.h" + +#include "radeon_compiler.h" +#include "radeon_program.h" + +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_scan.h" +#include "tgsi/tgsi_util.h" + + +static unsigned translate_opcode(unsigned opcode) +{ + switch(opcode) { + case TGSI_OPCODE_ARL: return OPCODE_ARL; + case TGSI_OPCODE_MOV: return OPCODE_MOV; + case TGSI_OPCODE_LIT: return OPCODE_LIT; + case TGSI_OPCODE_RCP: return OPCODE_RCP; + case TGSI_OPCODE_RSQ: return OPCODE_RSQ; + case TGSI_OPCODE_EXP: return OPCODE_EXP; + case TGSI_OPCODE_LOG: return OPCODE_LOG; + case TGSI_OPCODE_MUL: return OPCODE_MUL; + case TGSI_OPCODE_ADD: return OPCODE_ADD; + case TGSI_OPCODE_DP3: return OPCODE_DP3; + case TGSI_OPCODE_DP4: return OPCODE_DP4; + case TGSI_OPCODE_DST: return OPCODE_DST; + case TGSI_OPCODE_MIN: return OPCODE_MIN; + case TGSI_OPCODE_MAX: return OPCODE_MAX; + case TGSI_OPCODE_SLT: return OPCODE_SLT; + case TGSI_OPCODE_SGE: return OPCODE_SGE; + case TGSI_OPCODE_MAD: return OPCODE_MAD; + case TGSI_OPCODE_SUB: return OPCODE_SUB; + case TGSI_OPCODE_LRP: return OPCODE_LRP; + /* case TGSI_OPCODE_CND: return OPCODE_CND; */ + /* case TGSI_OPCODE_CND0: return OPCODE_CND0; */ + case TGSI_OPCODE_DP2A: return OPCODE_DP2A; + /* gap */ + case TGSI_OPCODE_FRC: return OPCODE_FRC; + /* case TGSI_OPCODE_CLAMP: return OPCODE_CLAMP; */ + case TGSI_OPCODE_FLR: return OPCODE_FLR; + /* case TGSI_OPCODE_ROUND: return OPCODE_ROUND; */ + case TGSI_OPCODE_EX2: return OPCODE_EX2; + case TGSI_OPCODE_LG2: return OPCODE_LG2; + case TGSI_OPCODE_POW: return OPCODE_POW; + case TGSI_OPCODE_XPD: return OPCODE_XPD; + /* gap */ + case TGSI_OPCODE_ABS: return OPCODE_ABS; + case TGSI_OPCODE_RCC: return OPCODE_RCC; + case TGSI_OPCODE_DPH: return OPCODE_DPH; + case TGSI_OPCODE_COS: return OPCODE_COS; + case TGSI_OPCODE_DDX: return OPCODE_DDX; + case TGSI_OPCODE_DDY: return OPCODE_DDY; + /* case TGSI_OPCODE_KILP: return OPCODE_KILP; */ + case TGSI_OPCODE_PK2H: return OPCODE_PK2H; + case TGSI_OPCODE_PK2US: return OPCODE_PK2US; + case TGSI_OPCODE_PK4B: return OPCODE_PK4B; + case TGSI_OPCODE_PK4UB: return OPCODE_PK4UB; + case TGSI_OPCODE_RFL: return OPCODE_RFL; + case TGSI_OPCODE_SEQ: return OPCODE_SEQ; + case TGSI_OPCODE_SFL: return OPCODE_SFL; + case TGSI_OPCODE_SGT: return OPCODE_SGT; + case TGSI_OPCODE_SIN: return OPCODE_SIN; + case TGSI_OPCODE_SLE: return OPCODE_SLE; + case TGSI_OPCODE_SNE: return OPCODE_SNE; + case TGSI_OPCODE_STR: return OPCODE_STR; + case TGSI_OPCODE_TEX: return OPCODE_TEX; + case TGSI_OPCODE_TXD: return OPCODE_TXD; + case TGSI_OPCODE_TXP: return OPCODE_TXP; + case TGSI_OPCODE_UP2H: return OPCODE_UP2H; + case TGSI_OPCODE_UP2US: return OPCODE_UP2US; + case TGSI_OPCODE_UP4B: return OPCODE_UP4B; + case TGSI_OPCODE_UP4UB: return OPCODE_UP4UB; + case TGSI_OPCODE_X2D: return OPCODE_X2D; + case TGSI_OPCODE_ARA: return OPCODE_ARA; + case TGSI_OPCODE_ARR: return OPCODE_ARR; + case TGSI_OPCODE_BRA: return OPCODE_BRA; + case TGSI_OPCODE_CAL: return OPCODE_CAL; + case TGSI_OPCODE_RET: return OPCODE_RET; + case TGSI_OPCODE_SSG: return OPCODE_SSG; + case TGSI_OPCODE_CMP: return OPCODE_CMP; + case TGSI_OPCODE_SCS: return OPCODE_SCS; + case TGSI_OPCODE_TXB: return OPCODE_TXB; + /* case TGSI_OPCODE_NRM: return OPCODE_NRM; */ + /* case TGSI_OPCODE_DIV: return OPCODE_DIV; */ + case TGSI_OPCODE_DP2: return OPCODE_DP2; + case TGSI_OPCODE_TXL: return OPCODE_TXL; + case TGSI_OPCODE_BRK: return OPCODE_BRK; + case TGSI_OPCODE_IF: return OPCODE_IF; + /* case TGSI_OPCODE_LOOP: return OPCODE_LOOP; */ + /* case TGSI_OPCODE_REP: return OPCODE_REP; */ + case TGSI_OPCODE_ELSE: return OPCODE_ELSE; + case TGSI_OPCODE_ENDIF: return OPCODE_ENDIF; + case TGSI_OPCODE_ENDLOOP: return OPCODE_ENDLOOP; + /* case TGSI_OPCODE_ENDREP: return OPCODE_ENDREP; */ + case TGSI_OPCODE_PUSHA: return OPCODE_PUSHA; + case TGSI_OPCODE_POPA: return OPCODE_POPA; + /* case TGSI_OPCODE_CEIL: return OPCODE_CEIL; */ + /* case TGSI_OPCODE_I2F: return OPCODE_I2F; */ + case TGSI_OPCODE_NOT: return OPCODE_NOT; + case TGSI_OPCODE_TRUNC: return OPCODE_TRUNC; + /* case TGSI_OPCODE_SHL: return OPCODE_SHL; */ + /* case TGSI_OPCODE_SHR: return OPCODE_SHR; */ + case TGSI_OPCODE_AND: return OPCODE_AND; + case TGSI_OPCODE_OR: return OPCODE_OR; + /* case TGSI_OPCODE_MOD: return OPCODE_MOD; */ + case TGSI_OPCODE_XOR: return OPCODE_XOR; + /* case TGSI_OPCODE_SAD: return OPCODE_SAD; */ + /* case TGSI_OPCODE_TXF: return OPCODE_TXF; */ + /* case TGSI_OPCODE_TXQ: return OPCODE_TXQ; */ + case TGSI_OPCODE_CONT: return OPCODE_CONT; + /* case TGSI_OPCODE_EMIT: return OPCODE_EMIT; */ + /* case TGSI_OPCODE_ENDPRIM: return OPCODE_ENDPRIM; */ + /* case TGSI_OPCODE_BGNLOOP2: return OPCODE_BGNLOOP2; */ + case TGSI_OPCODE_BGNSUB: return OPCODE_BGNSUB; + /* case TGSI_OPCODE_ENDLOOP2: return OPCODE_ENDLOOP2; */ + case TGSI_OPCODE_ENDSUB: return OPCODE_ENDSUB; + case TGSI_OPCODE_NOISE1: return OPCODE_NOISE1; + case TGSI_OPCODE_NOISE2: return OPCODE_NOISE2; + case TGSI_OPCODE_NOISE3: return OPCODE_NOISE3; + case TGSI_OPCODE_NOISE4: return OPCODE_NOISE4; + case TGSI_OPCODE_NOP: return OPCODE_NOP; + /* gap */ + case TGSI_OPCODE_NRM4: return OPCODE_NRM4; + /* case TGSI_OPCODE_CALLNZ: return OPCODE_CALLNZ; */ + /* case TGSI_OPCODE_IFC: return OPCODE_IFC; */ + /* case TGSI_OPCODE_BREAKC: return OPCODE_BREAKC; */ + case TGSI_OPCODE_KIL: return OPCODE_KIL; + case TGSI_OPCODE_END: return OPCODE_END; + case TGSI_OPCODE_SWZ: return OPCODE_SWZ; + } + + fprintf(stderr, "Unknown opcode: %i\n", opcode); + abort(); +} + +static unsigned translate_saturate(unsigned saturate) +{ + switch(saturate) { + case TGSI_SAT_NONE: return SATURATE_OFF; + case TGSI_SAT_ZERO_ONE: return SATURATE_ZERO_ONE; + case TGSI_SAT_MINUS_PLUS_ONE: return SATURATE_PLUS_MINUS_ONE; + } + + fprintf(stderr, "Unknown saturate mode: %i\n", saturate); + abort(); +} + +static unsigned translate_register_file(unsigned file) +{ + switch(file) { + case TGSI_FILE_CONSTANT: return PROGRAM_CONSTANT; + case TGSI_FILE_IMMEDIATE: return PROGRAM_CONSTANT; + case TGSI_FILE_INPUT: return PROGRAM_INPUT; + case TGSI_FILE_OUTPUT: return PROGRAM_OUTPUT; + case TGSI_FILE_TEMPORARY: return PROGRAM_TEMPORARY; + case TGSI_FILE_ADDRESS: return PROGRAM_ADDRESS; + } + + fprintf(stderr, "Unhandled register file: %i\n", file); + abort(); +} + +static int translate_register_index( + struct tgsi_to_rc * ttr, + unsigned file, + int index) +{ + if (file == TGSI_FILE_IMMEDIATE) + return ttr->immediate_offset + index; + + return index; +} + +static void transform_dstreg( + struct tgsi_to_rc * ttr, + struct prog_dst_register * dst, + struct tgsi_full_dst_register * src) +{ + dst->File = translate_register_file(src->DstRegister.File); + dst->Index = translate_register_index(ttr, src->DstRegister.File, src->DstRegister.Index); + dst->WriteMask = src->DstRegister.WriteMask; + dst->RelAddr = src->DstRegister.Indirect; +} + +static void transform_srcreg( + struct tgsi_to_rc * ttr, + struct prog_src_register * dst, + struct tgsi_full_src_register * src) +{ + dst->File = translate_register_file(src->SrcRegister.File); + dst->Index = translate_register_index(ttr, src->SrcRegister.File, src->SrcRegister.Index); + dst->RelAddr = src->SrcRegister.Indirect; + dst->Swizzle = tgsi_util_get_full_src_register_extswizzle(src, 0); + dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 1) << 3; + dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 2) << 6; + dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 3) << 9; + dst->Abs = src->SrcRegisterExtMod.Absolute; + dst->Negate = + src->SrcRegisterExtSwz.NegateX | + (src->SrcRegisterExtSwz.NegateY << 1) | + (src->SrcRegisterExtSwz.NegateZ << 2) | + (src->SrcRegisterExtSwz.NegateW << 3); + dst->Negate ^= src->SrcRegister.Negate ? NEGATE_XYZW : 0; +} + +static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_ext_texture src) +{ + switch(src.Texture) { + case TGSI_TEXTURE_1D: + dst->I.TexSrcTarget = TEXTURE_1D_INDEX; + break; + case TGSI_TEXTURE_2D: + dst->I.TexSrcTarget = TEXTURE_2D_INDEX; + break; + case TGSI_TEXTURE_3D: + dst->I.TexSrcTarget = TEXTURE_3D_INDEX; + break; + case TGSI_TEXTURE_CUBE: + dst->I.TexSrcTarget = TEXTURE_CUBE_INDEX; + break; + case TGSI_TEXTURE_RECT: + dst->I.TexSrcTarget = TEXTURE_RECT_INDEX; + break; + case TGSI_TEXTURE_SHADOW1D: + dst->I.TexSrcTarget = TEXTURE_1D_INDEX; + dst->I.TexShadow = 1; + break; + case TGSI_TEXTURE_SHADOW2D: + dst->I.TexSrcTarget = TEXTURE_2D_INDEX; + dst->I.TexShadow = 1; + break; + case TGSI_TEXTURE_SHADOWRECT: + dst->I.TexSrcTarget = TEXTURE_RECT_INDEX; + dst->I.TexShadow = 1; + break; + } +} + +static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src) +{ + if (src->Instruction.Opcode == TGSI_OPCODE_END) + return; + + struct rc_instruction * dst = rc_insert_new_instruction(ttr->compiler, ttr->compiler->Program.Instructions.Prev); + int i; + + dst->I.Opcode = translate_opcode(src->Instruction.Opcode); + dst->I.SaturateMode = translate_saturate(src->Instruction.Saturate); + + if (src->Instruction.NumDstRegs) + transform_dstreg(ttr, &dst->I.DstReg, &src->FullDstRegisters[0]); + + for(i = 0; i < src->Instruction.NumSrcRegs; ++i) { + if (src->FullSrcRegisters[i].SrcRegister.File == TGSI_FILE_SAMPLER) + dst->I.TexSrcUnit = src->FullSrcRegisters[i].SrcRegister.Index; + else + transform_srcreg(ttr, &dst->I.SrcReg[i], &src->FullSrcRegisters[i]); + } + + /* Texturing. */ + transform_texture(dst, src->InstructionExtTexture); +} + +static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm) +{ + struct rc_constant constant; + int i; + + constant.Type = RC_CONSTANT_IMMEDIATE; + constant.Size = 4; + for(i = 0; i < 4; ++i) + constant.u.Immediate[i] = imm->u[i].Float; + rc_constants_add(&ttr->compiler->Program.Constants, &constant); +} + +void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) +{ + struct tgsi_parse_context parser; + int i; + + /* Allocate constants placeholders. + * + * Note: What if declared constants are not contiguous? */ + for(i = 0; i <= ttr->info->file_max[TGSI_FILE_CONSTANT]; ++i) { + struct rc_constant constant; + memset(&constant, 0, sizeof(constant)); + constant.Type = RC_CONSTANT_EXTERNAL; + constant.Size = 4; + constant.u.External = i; + rc_constants_add(&ttr->compiler->Program.Constants, &constant); + } + + ttr->immediate_offset = ttr->compiler->Program.Constants.Count; + + tgsi_parse_init(&parser, tokens); + + while (!tgsi_parse_end_of_tokens(&parser)) { + tgsi_parse_token(&parser); + + switch (parser.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + handle_immediate(ttr, &parser.FullToken.FullImmediate); + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + transform_instruction(ttr, &parser.FullToken.FullInstruction); + break; + } + } + + tgsi_parse_free(&parser); + + rc_calculate_inputs_outputs(ttr->compiler); +} + diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.h b/src/gallium/drivers/r300/r300_tgsi_to_rc.h new file mode 100644 index 0000000000..93e90ec6d2 --- /dev/null +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.h @@ -0,0 +1,41 @@ +/* + * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_TGSI_TO_RC_H +#define R300_TGSI_TO_RC_H + +struct radeon_compiler; + +struct tgsi_full_declaration; +struct tgsi_shader_info; +struct tgsi_token; + +struct tgsi_to_rc { + struct radeon_compiler * compiler; + const struct tgsi_shader_info * info; + + int immediate_offset; +}; + +void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens); + +#endif /* R300_TGSI_TO_RC_H */ diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index f87435f9f0..2cb903bba2 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -22,391 +22,213 @@ #include "r300_vs.h" -static void r300_vs_declare(struct r300_vs_asm* assembler, - struct tgsi_full_declaration* decl) -{ - switch (decl->Declaration.File) { - case TGSI_FILE_INPUT: - break; - case TGSI_FILE_OUTPUT: - switch (decl->Semantic.SemanticName) { - case TGSI_SEMANTIC_POSITION: - assembler->tab[decl->DeclarationRange.First] = 0; - break; - case TGSI_SEMANTIC_COLOR: - assembler->tab[decl->DeclarationRange.First] = - (assembler->point_size ? 1 : 0) + - assembler->out_colors; - break; - case TGSI_SEMANTIC_FOG: - case TGSI_SEMANTIC_GENERIC: - /* XXX multiple? */ - assembler->tab[decl->DeclarationRange.First] = - (assembler->point_size ? 1 : 0) + - assembler->out_colors + - assembler->out_texcoords; - break; - case TGSI_SEMANTIC_PSIZE: - assembler->tab[decl->DeclarationRange.First] = 1; - break; - default: - debug_printf("r300: vs: Bad semantic declaration %d\n", - decl->Semantic.SemanticName); - break; - } - break; - case TGSI_FILE_CONSTANT: - break; - case TGSI_FILE_TEMPORARY: - assembler->temp_count++; - break; - default: - debug_printf("r300: vs: Bad file %d\n", decl->Declaration.File); - break; - } -} +#include "r300_context.h" +#include "r300_tgsi_to_rc.h" -static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler, - struct tgsi_src_register* src) -{ - switch (src->File) { - case TGSI_FILE_NULL: - case TGSI_FILE_INPUT: - /* Probably a zero or one swizzle */ - return R300_PVS_SRC_REG_INPUT; - case TGSI_FILE_TEMPORARY: - return R300_PVS_SRC_REG_TEMPORARY; - case TGSI_FILE_CONSTANT: - case TGSI_FILE_IMMEDIATE: - return R300_PVS_SRC_REG_CONSTANT; - default: - debug_printf("r300: vs: Unimplemented src type %d\n", src->File); - break; - } - return 0; -} +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_parse.h" -static INLINE unsigned r300_vs_src(struct r300_vs_asm* assembler, - struct tgsi_src_register* src) -{ - switch (src->File) { - case TGSI_FILE_NULL: - case TGSI_FILE_INPUT: - case TGSI_FILE_TEMPORARY: - case TGSI_FILE_CONSTANT: - return src->Index; - case TGSI_FILE_IMMEDIATE: - return src->Index + assembler->imm_offset; - default: - debug_printf("r300: vs: Unimplemented src type %d\n", src->File); - break; - } - return 0; -} +#include "radeon_compiler.h" -static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler, - struct tgsi_dst_register* dst) -{ - switch (dst->File) { - case TGSI_FILE_TEMPORARY: - return R300_PVS_DST_REG_TEMPORARY; - case TGSI_FILE_OUTPUT: - return R300_PVS_DST_REG_OUT; - default: - debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File); - break; - } - return 0; -} -static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler, - struct tgsi_dst_register* dst) +static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) { - switch (dst->File) { - case TGSI_FILE_TEMPORARY: - return dst->Index; - case TGSI_FILE_OUTPUT: - return assembler->tab[dst->Index]; - default: - debug_printf("r300: vs: Unimplemented dst %d\n", dst->File); - break; - } - return 0; -} + struct r300_vertex_shader * vs = c->UserData; + struct tgsi_shader_info* info = &vs->info; + boolean pointsize = false; + int out_colors = 0; + int colors = 0; + int out_generic = 0; + int generic = 0; + int i; -static uint32_t r300_vs_op(unsigned op) -{ - switch (op) { - case TGSI_OPCODE_DP3: - case TGSI_OPCODE_DP4: - return R300_VE_DOT_PRODUCT; - case TGSI_OPCODE_MUL: - return R300_VE_MULTIPLY; - case TGSI_OPCODE_ADD: - case TGSI_OPCODE_MOV: - case TGSI_OPCODE_SUB: - case TGSI_OPCODE_SWZ: - return R300_VE_ADD; - case TGSI_OPCODE_MAX: - return R300_VE_MAXIMUM; - case TGSI_OPCODE_SLT: - return R300_VE_SET_LESS_THAN; - case TGSI_OPCODE_RSQ: - return R300_PVS_DST_MATH_INST | R300_ME_RECIP_DX; - case TGSI_OPCODE_MAD: - return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD; - default: - break; - } - return 0; -} + /* Fill in the input mapping */ + for (i = 0; i < info->num_inputs; i++) + c->code->inputs[i] = i; -static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg) -{ - if (reg->SrcRegister.Extended) { - return (reg->SrcRegister.Negate ? (0xf << 12) : 0) | - reg->SrcRegisterExtSwz.ExtSwizzleX | - (reg->SrcRegisterExtSwz.ExtSwizzleY << 3) | - (reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) | - (reg->SrcRegisterExtSwz.ExtSwizzleW << 9); - } else { - return (reg->SrcRegister.Negate ? (0xf << 12) : 0) | - reg->SrcRegister.SwizzleX | - (reg->SrcRegister.SwizzleY << 3) | - (reg->SrcRegister.SwizzleZ << 6) | - (reg->SrcRegister.SwizzleW << 9); + /* Fill in the output mapping */ + for (i = 0; i < info->num_outputs; i++) { + switch (info->output_semantic_name[i]) { + case TGSI_SEMANTIC_PSIZE: + pointsize = true; + break; + case TGSI_SEMANTIC_COLOR: + out_colors++; + break; + case TGSI_SEMANTIC_FOG: + case TGSI_SEMANTIC_GENERIC: + out_generic++; + break; + } } -} -/* XXX icky icky icky icky */ -static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg) -{ - if (reg->SrcRegister.Extended) { - return (reg->SrcRegister.Negate ? (0xf << 12) : 0) | - reg->SrcRegisterExtSwz.ExtSwizzleX | - (reg->SrcRegisterExtSwz.ExtSwizzleX << 3) | - (reg->SrcRegisterExtSwz.ExtSwizzleX << 6) | - (reg->SrcRegisterExtSwz.ExtSwizzleX << 9); - } else { - return (reg->SrcRegister.Negate ? (0xf << 12) : 0) | - reg->SrcRegister.SwizzleX | - (reg->SrcRegister.SwizzleX << 3) | - (reg->SrcRegister.SwizzleX << 6) | - (reg->SrcRegister.SwizzleX << 9); - } -} + struct tgsi_parse_context parser; -/* XXX scalar stupidity */ -static void r300_vs_emit_inst(struct r300_vertex_shader* vs, - struct r300_vs_asm* assembler, - struct tgsi_full_src_register* src, - struct tgsi_full_dst_register* dst, - unsigned op, - unsigned count, - boolean is_scalar) -{ - int i = vs->instruction_count; - vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) | - R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) | - R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) | - R300_PVS_DST_WE(dst->DstRegister.WriteMask); - switch (count) { - case 3: - vs->instructions[i].inst3 = - R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, - &src[2].SrcRegister)) | - R300_PVS_SRC_OFFSET(r300_vs_src(assembler, - &src[2].SrcRegister)) | - R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2])); - /* Fall through */ - case 2: - vs->instructions[i].inst2 = - R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, - &src[1].SrcRegister)) | - R300_PVS_SRC_OFFSET(r300_vs_src(assembler, - &src[1].SrcRegister)) | - R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1])); - /* Fall through */ - case 1: - vs->instructions[i].inst1 = - R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, - &src[0].SrcRegister)) | - R300_PVS_SRC_OFFSET(r300_vs_src(assembler, - &src[0].SrcRegister)) | - /* XXX the icky, it burns */ - R300_PVS_SRC_SWIZZLE(is_scalar ? r300_vs_scalar_swiz(&src[0]) - : r300_vs_swiz(&src[0])); - break; - } - vs->instruction_count++; -} + tgsi_parse_init(&parser, vs->state.tokens); -static void r300_vs_instruction(struct r300_vertex_shader* vs, - struct r300_vs_asm* assembler, - struct tgsi_full_instruction* inst) -{ - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_RSQ: - r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 1, TRUE); - break; - case TGSI_OPCODE_SUB: - inst->FullSrcRegisters[1].SrcRegister.Negate = - !inst->FullSrcRegisters[1].SrcRegister.Negate; - /* Fall through */ - case TGSI_OPCODE_ADD: - case TGSI_OPCODE_MUL: - case TGSI_OPCODE_MAX: - case TGSI_OPCODE_SLT: - r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 2, FALSE); - break; - case TGSI_OPCODE_DP3: - /* Set alpha swizzle to zero for src0 and src1 */ - if (!inst->FullSrcRegisters[0].SrcRegister.Extended) { - inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE; - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX = - inst->FullSrcRegisters[0].SrcRegister.SwizzleX; - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY = - inst->FullSrcRegisters[0].SrcRegister.SwizzleY; - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ = - inst->FullSrcRegisters[0].SrcRegister.SwizzleZ; - } - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = - TGSI_EXTSWIZZLE_ZERO; - if (!inst->FullSrcRegisters[1].SrcRegister.Extended) { - inst->FullSrcRegisters[1].SrcRegister.Extended = TRUE; - inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleX = - inst->FullSrcRegisters[1].SrcRegister.SwizzleX; - inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleY = - inst->FullSrcRegisters[1].SrcRegister.SwizzleY; - inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleZ = - inst->FullSrcRegisters[1].SrcRegister.SwizzleZ; - } - inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleW = - TGSI_EXTSWIZZLE_ZERO; - /* Fall through */ - case TGSI_OPCODE_DP4: - r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 2, FALSE); - break; - case TGSI_OPCODE_MOV: - case TGSI_OPCODE_SWZ: - inst->FullSrcRegisters[1] = r300_constant_zero; - r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 2, FALSE); - break; - case TGSI_OPCODE_MAD: - r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 3, FALSE); - break; - case TGSI_OPCODE_END: - break; - default: - debug_printf("r300: vs: Bad opcode %d\n", - inst->Instruction.Opcode); - break; - } -} + while (!tgsi_parse_end_of_tokens(&parser)) { + tgsi_parse_token(&parser); -static void r300_vs_init(struct r300_vertex_shader* vs, - struct r300_vs_asm* assembler) -{ - struct tgsi_shader_info* info = &vs->info; - int i; + if (parser.FullToken.Token.Type != TGSI_TOKEN_TYPE_DECLARATION) + continue; - for (i = 0; i < info->num_outputs; i++) { - switch (info->output_semantic_name[i]) { + struct tgsi_full_declaration * decl = &parser.FullToken.FullDeclaration; + + if (decl->Declaration.File != TGSI_FILE_OUTPUT) + continue; + + switch (decl->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + c->code->outputs[decl->DeclarationRange.First] = 0; + break; case TGSI_SEMANTIC_PSIZE: - assembler->point_size = TRUE; + c->code->outputs[decl->DeclarationRange.First] = 1; break; case TGSI_SEMANTIC_COLOR: - assembler->out_colors++; + c->code->outputs[decl->DeclarationRange.First] = 1 + + (pointsize ? 1 : 0) + + colors++; break; case TGSI_SEMANTIC_FOG: case TGSI_SEMANTIC_GENERIC: - assembler->out_texcoords++; + c->code->outputs[decl->DeclarationRange.First] = 1 + + (pointsize ? 1 : 0) + + out_colors + + generic++; + break; + default: + debug_printf("r300: vs: Bad semantic declaration %d\n", + decl->Semantic.SemanticName); break; } } - vs->instruction_count = 0; + tgsi_parse_free(&parser); } + void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs) { - struct tgsi_parse_context parser; - int i; - struct r300_constant_buffer* consts = - &r300->shader_constants[PIPE_SHADER_VERTEX]; + struct r300_vertex_program_compiler compiler; + struct tgsi_to_rc ttr; - struct r300_vs_asm* assembler = CALLOC_STRUCT(r300_vs_asm); - if (assembler == NULL) { - return; - } + /* Setup the compiler */ + rc_init(&compiler.Base); - /* Init assembler. */ - r300_vs_init(vs, assembler); + compiler.Base.Debug = 1; + compiler.code = &vs->code; + compiler.UserData = vs; - /* Setup starting offset for immediates. */ - assembler->imm_offset = consts->user_count; + if (compiler.Base.Debug) { + debug_printf("r300: Initial vertex program\n"); + tgsi_dump(vs->state.tokens, 0); + } - tgsi_parse_init(&parser, vs->state.tokens); + /* Translate TGSI to our internal representation */ + ttr.compiler = &compiler.Base; + ttr.info = &vs->info; - while (!tgsi_parse_end_of_tokens(&parser)) { - tgsi_parse_token(&parser); + r300_tgsi_to_rc(&ttr, vs->state.tokens); - /* This is seriously the lamest way to create fragment programs ever. - * I blame TGSI. */ - switch (parser.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - /* Allocated registers sitting at the beginning - * of the program. */ - r300_vs_declare(assembler, &parser.FullToken.FullDeclaration); - break; - case TGSI_TOKEN_TYPE_IMMEDIATE: - debug_printf("r300: Emitting immediate to constant buffer, " - "position %d\n", - assembler->imm_offset + assembler->imm_count); - /* I am not amused by the length of these. */ - for (i = 0; i < 4; i++) { - consts->constants[assembler->imm_offset + - assembler->imm_count][i] = - parser.FullToken.FullImmediate.u.ImmediateFloat32[i] - .Float; - } - assembler->imm_count++; - break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - r300_vs_instruction(vs, assembler, - &parser.FullToken.FullInstruction); - break; - } - } + compiler.RequiredOutputs = ~(~0 << vs->info.num_outputs); + compiler.SetHwInputOutput = &set_vertex_inputs_outputs; - debug_printf("r300: vs: %d texs and %d colors, first free reg is %d\n", - assembler->tex_count, assembler->color_count, - assembler->tex_count + assembler->color_count); + /* Invoke the compiler */ + r3xx_compile_vertex_program(&compiler); + if (compiler.Base.Error) { + /* Todo: Fail gracefully */ + fprintf(stderr, "r300 VP: Compiler error\n"); + abort(); + } - consts->count = consts->user_count + assembler->imm_count; - vs->uses_imms = assembler->imm_count; - debug_printf("r300: vs: %d total constants, " - "%d from user and %d from immediates\n", consts->count, - consts->user_count, assembler->imm_count); + /* And, finally... */ + rc_destroy(&compiler.Base); + vs->translated = TRUE; +} - debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0], - assembler->tab[1], assembler->tab[2], assembler->tab[3]); - tgsi_dump(vs->state.tokens, 0); - /* XXX finish r300 vertex shader dumper */ - r300_vs_dump(vs); +/* XXX get these to r300_reg */ +#define R300_PVS_DST_OPCODE(x) ((x) << 0) +# define R300_VE_DOT_PRODUCT 1 +# define R300_VE_MULTIPLY 2 +# define R300_VE_ADD 3 +# define R300_VE_MAXIMUM 7 +# define R300_VE_SET_LESS_THAN 10 +#define R300_PVS_DST_MATH_INST (1 << 6) +# define R300_ME_RECIP_DX 6 +#define R300_PVS_DST_MACRO_INST (1 << 7) +# define R300_PVS_MACRO_OP_2CLK_MADD 0 +#define R300_PVS_DST_REG_TYPE(x) ((x) << 8) +# define R300_PVS_DST_REG_TEMPORARY 0 +# define R300_PVS_DST_REG_A0 1 +# define R300_PVS_DST_REG_OUT 2 +# define R300_PVS_DST_REG_OUT_REPL_X 3 +# define R300_PVS_DST_REG_ALT_TEMPORARY 4 +# define R300_PVS_DST_REG_INPUT 5 +#define R300_PVS_DST_OFFSET(x) ((x) << 13) +#define R300_PVS_DST_WE(x) ((x) << 20) +#define R300_PVS_DST_WE_XYZW (0xf << 20) + +#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0) +# define R300_PVS_SRC_REG_TEMPORARY 0 +# define R300_PVS_SRC_REG_INPUT 1 +# define R300_PVS_SRC_REG_CONSTANT 2 +# define R300_PVS_SRC_REG_ALT_TEMPORARY 3 +#define R300_PVS_SRC_OFFSET(x) ((x) << 5) +#define R300_PVS_SRC_SWIZZLE(x) ((x) << 13) +# define R300_PVS_SRC_SELECT_X 0 +# define R300_PVS_SRC_SELECT_Y 1 +# define R300_PVS_SRC_SELECT_Z 2 +# define R300_PVS_SRC_SELECT_W 3 +# define R300_PVS_SRC_SELECT_FORCE_0 4 +# define R300_PVS_SRC_SELECT_FORCE_1 5 +# define R300_PVS_SRC_SWIZZLE_XYZW \ + ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \ + (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13) +# define R300_PVS_SRC_SWIZZLE_ZERO \ + ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \ + (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \ + (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13) +# define R300_PVS_SRC_SWIZZLE_ONE \ + ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \ + (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \ + (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13) +#define R300_PVS_MODIFIER_X (1 << 25) +#define R300_PVS_MODIFIER_Y (1 << 26) +#define R300_PVS_MODIFIER_Z (1 << 27) +#define R300_PVS_MODIFIER_W (1 << 28) +#define R300_PVS_NEGATE_XYZW \ + (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \ + R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W) + +struct r300_vertex_program_code r300_passthrough_vertex_shader = { + .length = 8, /* two instructions */ + + /* MOV out[0], in[0] */ + .body.d[0] = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, + .body.d[1] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, + .body.d[2] = R300_PVS_SRC_SWIZZLE_ZERO, + .body.d[3] = 0x0, + + /* MOV out[1], in[1] */ + .body.d[4] = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW, + .body.d[5] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, + .body.d[6] = R300_PVS_SRC_SWIZZLE_ZERO, + .body.d[7] = 0x0, + + .inputs[0] = 0, + .inputs[1] = 1, + .outputs[0] = 0, + .outputs[1] = 1, + + .InputsRead = 3, + .OutputsWritten = 3 +}; - tgsi_parse_free(&parser); - FREE(assembler); -} diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h index 165d717812..2a4ce315e3 100644 --- a/src/gallium/drivers/r300/r300_vs.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -23,134 +23,31 @@ #ifndef R300_VS_H #define R300_VS_H -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_dump.h" +#include "pipe/p_state.h" +#include "tgsi/tgsi_scan.h" -#include "r300_context.h" -#include "r300_debug.h" -#include "r300_reg.h" -#include "r300_screen.h" -#include "r300_shader_inlines.h" +#include "radeon_code.h" -/* XXX get these to r300_reg */ -#define R300_PVS_DST_OPCODE(x) ((x) << 0) -# define R300_VE_DOT_PRODUCT 1 -# define R300_VE_MULTIPLY 2 -# define R300_VE_ADD 3 -# define R300_VE_MAXIMUM 7 -# define R300_VE_SET_LESS_THAN 10 -#define R300_PVS_DST_MATH_INST (1 << 6) -# define R300_ME_RECIP_DX 6 -#define R300_PVS_DST_MACRO_INST (1 << 7) -# define R300_PVS_MACRO_OP_2CLK_MADD 0 -#define R300_PVS_DST_REG_TYPE(x) ((x) << 8) -# define R300_PVS_DST_REG_TEMPORARY 0 -# define R300_PVS_DST_REG_A0 1 -# define R300_PVS_DST_REG_OUT 2 -# define R300_PVS_DST_REG_OUT_REPL_X 3 -# define R300_PVS_DST_REG_ALT_TEMPORARY 4 -# define R300_PVS_DST_REG_INPUT 5 -#define R300_PVS_DST_OFFSET(x) ((x) << 13) -#define R300_PVS_DST_WE(x) ((x) << 20) -#define R300_PVS_DST_WE_XYZW (0xf << 20) +struct r300_context; -#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0) -# define R300_PVS_SRC_REG_TEMPORARY 0 -# define R300_PVS_SRC_REG_INPUT 1 -# define R300_PVS_SRC_REG_CONSTANT 2 -# define R300_PVS_SRC_REG_ALT_TEMPORARY 3 -#define R300_PVS_SRC_OFFSET(x) ((x) << 5) -#define R300_PVS_SRC_SWIZZLE(x) ((x) << 13) -# define R300_PVS_SRC_SELECT_X 0 -# define R300_PVS_SRC_SELECT_Y 1 -# define R300_PVS_SRC_SELECT_Z 2 -# define R300_PVS_SRC_SELECT_W 3 -# define R300_PVS_SRC_SELECT_FORCE_0 4 -# define R300_PVS_SRC_SELECT_FORCE_1 5 -# define R300_PVS_SRC_SWIZZLE_XYZW \ - ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \ - (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13) -# define R300_PVS_SRC_SWIZZLE_ZERO \ - ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \ - (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \ - (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13) -# define R300_PVS_SRC_SWIZZLE_ONE \ - ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \ - (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \ - (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13) -#define R300_PVS_MODIFIER_X (1 << 25) -#define R300_PVS_MODIFIER_Y (1 << 26) -#define R300_PVS_MODIFIER_Z (1 << 27) -#define R300_PVS_MODIFIER_W (1 << 28) -#define R300_PVS_NEGATE_XYZW \ - (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \ - R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W) +struct r300_vertex_shader { + /* Parent class */ + struct pipe_shader_state state; + struct tgsi_shader_info info; -/* Temporary struct used to hold assembly state while putting together - * fragment programs. */ -struct r300_vs_asm { - /* Pipe context. */ - struct r300_context* r300; - /* Number of colors. */ - unsigned color_count; - /* Number of texcoords. */ - unsigned tex_count; - /* Number of requested temporary registers. */ - unsigned temp_count; - /* Offset for immediate constants. Neither R300 nor R500 can do four - * inline constants per source, so instead we copy immediates into the - * constant buffer. */ - unsigned imm_offset; - /* Number of immediate constants. */ - unsigned imm_count; - /* Number of colors to write. */ - unsigned out_colors; - /* Number of texcoords to write. */ - unsigned out_texcoords; - /* Whether to emit point size. */ - boolean point_size; - /* Tab of declared outputs to OVM outputs. */ - unsigned tab[16]; -}; + /* Fallback shader, because Draw has issues */ + struct draw_vertex_shader* draw; -static struct r300_vertex_shader r300_passthrough_vertex_shader = { - /* XXX translate these back into normal instructions */ - .instruction_count = 2, - .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | - R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | - R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, - .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | - R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, - .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, - .instructions[0].inst3 = 0x0, - .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | - R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | - R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW, - .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | - R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, - .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, - .instructions[1].inst3 = 0x0, -}; + /* Has this shader been translated yet? */ + boolean translated; -static struct r300_vertex_shader r300_texture_vertex_shader = { - /* XXX translate these back into normal instructions */ - .instruction_count = 2, - .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | - R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | - R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, - .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | - R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, - .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, - .instructions[0].inst3 = 0x0, - .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | - R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | - R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW, - .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | - R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, - .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, - .instructions[1].inst3 = 0x0, + /* Machine code (if translated) */ + struct r300_vertex_program_code code; }; + +extern struct r300_vertex_program_code r300_passthrough_vertex_shader; + void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/r300/r3xx_fs.c b/src/gallium/drivers/r300/r3xx_fs.c index 6e05d76977..c1c1194d58 100644 --- a/src/gallium/drivers/r300/r3xx_fs.c +++ b/src/gallium/drivers/r300/r3xx_fs.c @@ -23,74 +23,52 @@ #include "r3xx_fs.h" -static INLINE uint32_t r3xx_rgb_op(unsigned op) -{ - switch (op) { - case TGSI_OPCODE_MOV: - return R300_ALU_OUTC_CMP; - default: - return 0; - } -} +#include "r300_reg.h" -static INLINE uint32_t r3xx_alpha_op(unsigned op) -{ - switch (op) { - case TGSI_OPCODE_MOV: - return R300_ALU_OUTA_CMP; - default: - return 0; - } -} +struct rX00_fragment_program_code r3xx_passthrough_fragment_shader = { + .code.r300.alu.length = 1, + .code.r300.tex.length = 0, -static INLINE void r3xx_emit_maths(struct r3xx_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_src_register* src, - struct tgsi_full_dst_register* dst, - unsigned op, - unsigned count) -{ - int i = fs->alu_instruction_count; + .code.r300.config = 0, + .code.r300.pixsize = 0, + .code.r300.code_offset = 0, + .code.r300.code_addr[3] = R300_RGBA_OUT, - fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | - r3xx_rgb_op(op); - fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | - R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; - fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALU_OUTC_CMP, + .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, + .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | - r3xx_alpha_op(op); - fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | - R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; + R300_ALU_OUTA_CMP, + .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; - fs->alu_instruction_count++; -} +struct rX00_fragment_program_code r3xx_texture_fragment_shader = { + .code.r300.alu.length = 1, + .code.r300.tex.length = 1, -void r3xx_fs_finalize(struct r300_fragment_shader* fs, - struct r300_fs_asm* assembler) -{ - fs->stack_size = assembler->temp_count + assembler->temp_offset + 1; -} + .code.r300.config = R300_PFS_CNTL_FIRST_NODE_HAS_TEX, + .code.r300.pixsize = 0, + .code.r300.code_offset = 0, + .code.r300.code_addr[3] = R300_RGBA_OUT, -void r3xx_fs_instruction(struct r3xx_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_instruction* inst) -{ - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_MOV: - /* src0 -> src1 and src2 forced to zero */ - inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; - inst->FullSrcRegisters[2] = r300_constant_zero; - r3xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); - break; - case TGSI_OPCODE_END: - break; - default: - debug_printf("r300: fs: Bad opcode %d\n", - inst->Instruction.Opcode); - break; - } -} + .code.r300.tex.inst[0] = R300_TEX_OP_LD << R300_TEX_INST_SHIFT, + + .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | + R300_ALU_OUTC_CMP, + .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, + .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | + R300_ALU_OUTA_CMP, + .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; diff --git a/src/gallium/drivers/r300/r3xx_fs.h b/src/gallium/drivers/r300/r3xx_fs.h index 3da39ec252..51cd245724 100644 --- a/src/gallium/drivers/r300/r3xx_fs.h +++ b/src/gallium/drivers/r300/r3xx_fs.h @@ -24,53 +24,9 @@ #ifndef R3XX_FS_H #define R3XX_FS_H -#include "r300_fs_inlines.h" +#include "radeon_code.h" -static struct r3xx_fragment_shader r3xx_passthrough_fragment_shader = { - .alu_instruction_count = 1, - .tex_instruction_count = 0, - .indirections = 0, - .shader.stack_size = 1, - - .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | - R300_ALU_OUTC_CMP, - .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | - R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, - .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | - R300_ALU_OUTA_CMP, - .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | - R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -static struct r3xx_fragment_shader r3xx_texture_fragment_shader = { - .alu_instruction_count = 1, - .tex_instruction_count = 0, - .indirections = 0, - .shader.stack_size = 1, - - .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | - R300_ALU_OUTC_CMP, - .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | - R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, - .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | - R300_ALU_OUTA_CMP, - .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | - R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -void r3xx_fs_finalize(struct r300_fragment_shader* fs, - struct r300_fs_asm* assembler); - -void r3xx_fs_instruction(struct r3xx_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_instruction* inst); +struct rX00_fragment_program_code r3xx_passthrough_fragment_shader; +struct rX00_fragment_program_code r3xx_texture_fragment_shader; #endif /* R3XX_FS_H */ diff --git a/src/gallium/drivers/r300/r5xx_fs.c b/src/gallium/drivers/r300/r5xx_fs.c index 99d826278c..f072deab0d 100644 --- a/src/gallium/drivers/r300/r5xx_fs.c +++ b/src/gallium/drivers/r300/r5xx_fs.c @@ -23,445 +23,103 @@ #include "r5xx_fs.h" -static INLINE unsigned r5xx_fix_swiz(unsigned s) -{ - /* For historical reasons, the swizzle values x, y, z, w, and 0 are - * equivalent to the actual machine code, but 1 is not. Thus, we just - * adjust it a bit... */ - if (s == TGSI_EXTSWIZZLE_ONE) { - return R500_SWIZZLE_ONE; - } else { - return s; - } -} - -static uint32_t r5xx_rgba_swiz(struct tgsi_full_src_register* reg) -{ - if (reg->SrcRegister.Extended) { - return r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) | - (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) | - (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) | - (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9); - } else { - return reg->SrcRegister.SwizzleX | - (reg->SrcRegister.SwizzleY << 3) | - (reg->SrcRegister.SwizzleZ << 6) | - (reg->SrcRegister.SwizzleW << 9); - } -} - -static uint32_t r5xx_strq_swiz(struct tgsi_full_src_register* reg) -{ - return reg->SrcRegister.SwizzleX | - (reg->SrcRegister.SwizzleY << 2) | - (reg->SrcRegister.SwizzleZ << 4) | - (reg->SrcRegister.SwizzleW << 6); -} - -static INLINE uint32_t r5xx_rgb_swiz(struct tgsi_full_src_register* reg) -{ - /* Only the first 9 bits... */ - return (r5xx_rgba_swiz(reg) & 0x1ff) | - (reg->SrcRegister.Negate ? (1 << 9) : 0) | - (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); -} - -static INLINE uint32_t r5xx_alpha_swiz(struct tgsi_full_src_register* reg) -{ - /* Only the last 3 bits... */ - return (r5xx_rgba_swiz(reg) >> 9) | - (reg->SrcRegister.Negate ? (1 << 9) : 0) | - (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); -} - -static INLINE uint32_t r5xx_rgba_op(unsigned op) -{ - switch (op) { - case TGSI_OPCODE_COS: - case TGSI_OPCODE_EX2: - case TGSI_OPCODE_LG2: - case TGSI_OPCODE_RCP: - case TGSI_OPCODE_RSQ: - case TGSI_OPCODE_SIN: - return R500_ALU_RGBA_OP_SOP; - case TGSI_OPCODE_DDX: - return R500_ALU_RGBA_OP_MDH; - case TGSI_OPCODE_DDY: - return R500_ALU_RGBA_OP_MDV; - case TGSI_OPCODE_FRC: - return R500_ALU_RGBA_OP_FRC; - case TGSI_OPCODE_DP3: - return R500_ALU_RGBA_OP_DP3; - case TGSI_OPCODE_DP4: - case TGSI_OPCODE_DPH: - return R500_ALU_RGBA_OP_DP4; - case TGSI_OPCODE_ABS: - case TGSI_OPCODE_CMP: - case TGSI_OPCODE_MOV: - case TGSI_OPCODE_SWZ: - return R500_ALU_RGBA_OP_CMP; - case TGSI_OPCODE_ADD: - case TGSI_OPCODE_MAD: - case TGSI_OPCODE_MUL: - case TGSI_OPCODE_SUB: - return R500_ALU_RGBA_OP_MAD; - default: - return 0; - } -} - -static INLINE uint32_t r5xx_alpha_op(unsigned op) -{ - switch (op) { - case TGSI_OPCODE_COS: - return R500_ALPHA_OP_COS; - case TGSI_OPCODE_EX2: - return R500_ALPHA_OP_EX2; - case TGSI_OPCODE_LG2: - return R500_ALPHA_OP_LN2; - case TGSI_OPCODE_RCP: - return R500_ALPHA_OP_RCP; - case TGSI_OPCODE_RSQ: - return R500_ALPHA_OP_RSQ; - case TGSI_OPCODE_FRC: - return R500_ALPHA_OP_FRC; - case TGSI_OPCODE_SIN: - return R500_ALPHA_OP_SIN; - case TGSI_OPCODE_DDX: - return R500_ALPHA_OP_MDH; - case TGSI_OPCODE_DDY: - return R500_ALPHA_OP_MDV; - case TGSI_OPCODE_DP3: - case TGSI_OPCODE_DP4: - case TGSI_OPCODE_DPH: - return R500_ALPHA_OP_DP; - case TGSI_OPCODE_ABS: - case TGSI_OPCODE_CMP: - case TGSI_OPCODE_MOV: - case TGSI_OPCODE_SWZ: - return R500_ALPHA_OP_CMP; - case TGSI_OPCODE_ADD: - case TGSI_OPCODE_MAD: - case TGSI_OPCODE_MUL: - case TGSI_OPCODE_SUB: - return R500_ALPHA_OP_MAD; - default: - return 0; - } -} - -static INLINE uint32_t r5xx_tex_op(unsigned op) -{ - switch (op) { - case TGSI_OPCODE_KIL: - return R500_TEX_INST_TEXKILL; - case TGSI_OPCODE_TEX: - return R500_TEX_INST_LD; - case TGSI_OPCODE_TXB: - return R500_TEX_INST_LODBIAS; - case TGSI_OPCODE_TXP: - return R500_TEX_INST_PROJ; - default: - return 0; - } -} - -/* Setup an ALU operation. */ -static INLINE void r5xx_emit_maths(struct r5xx_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_src_register* src, - struct tgsi_full_dst_register* dst, - unsigned op, - unsigned count) -{ - int i = fs->instruction_count; - - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - fs->instructions[i].inst0 = R500_INST_TYPE_OUT; - if (r300_fs_is_depr(assembler, dst)) { - fs->instructions[i].inst4 = R500_W_OMASK; - } else { - fs->instructions[i].inst0 |= - R500_ALU_OMASK(dst->DstRegister.WriteMask); - } - } else { - fs->instructions[i].inst0 = R500_INST_TYPE_ALU | - R500_ALU_WMASK(dst->DstRegister.WriteMask); - } - - fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT; - - fs->instructions[i].inst4 |= - R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister)); - fs->instructions[i].inst5 = - R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister)); - - switch (count) { - case 3: - fs->instructions[i].inst1 = - R500_RGB_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister)); - fs->instructions[i].inst2 = - R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister)); - fs->instructions[i].inst5 |= - R500_ALU_RGBA_SEL_C_SRC2 | - R500_SWIZ_RGBA_C(r5xx_rgb_swiz(&src[2])) | - R500_ALU_RGBA_ALPHA_SEL_C_SRC2 | - R500_SWIZ_ALPHA_C(r5xx_alpha_swiz(&src[2])); - case 2: - fs->instructions[i].inst1 |= - R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister)); - fs->instructions[i].inst2 |= - R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister)); - fs->instructions[i].inst3 = - R500_ALU_RGB_SEL_B_SRC1 | - R500_SWIZ_RGB_B(r5xx_rgb_swiz(&src[1])); - fs->instructions[i].inst4 |= - R500_ALPHA_SEL_B_SRC1 | - R500_SWIZ_ALPHA_B(r5xx_alpha_swiz(&src[1])); - case 1: - case 0: - default: - fs->instructions[i].inst1 |= - R500_RGB_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister)); - fs->instructions[i].inst2 |= - R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister)); - fs->instructions[i].inst3 |= - R500_ALU_RGB_SEL_A_SRC0 | - R500_SWIZ_RGB_A(r5xx_rgb_swiz(&src[0])); - fs->instructions[i].inst4 |= - R500_ALPHA_SEL_A_SRC0 | - R500_SWIZ_ALPHA_A(r5xx_alpha_swiz(&src[0])); - break; - } - - fs->instructions[i].inst4 |= r5xx_alpha_op(op); - fs->instructions[i].inst5 |= r5xx_rgba_op(op); - - fs->instruction_count++; -} - -static INLINE void r5xx_emit_tex(struct r5xx_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_src_register* src, - struct tgsi_full_dst_register* dst, - uint32_t op) -{ - int i = fs->instruction_count; - - fs->instructions[i].inst0 = R500_INST_TYPE_TEX | - R500_TEX_WMASK(dst->DstRegister.WriteMask) | - R500_INST_TEX_SEM_WAIT; - fs->instructions[i].inst1 = R500_TEX_ID(0) | - R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED | - r5xx_tex_op(op); - fs->instructions[i].inst2 = - R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) | - R500_SWIZ_TEX_STRQ(r5xx_strq_swiz(src)) | - R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) | +#include "r300_reg.h" + +/* XXX this all should find its way back to r300_reg */ +/* Swizzle tools */ +#define R500_SWIZZLE_ZERO 4 +#define R500_SWIZZLE_HALF 5 +#define R500_SWIZZLE_ONE 6 +#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6)) +#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6)) +#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6)) +#define R500_SWIZ_MOD_NEG 1 +#define R500_SWIZ_MOD_ABS 2 +#define R500_SWIZ_MOD_NEG_ABS 3 +/* Swizzles for inst2 */ +#define R500_SWIZ_TEX_STRQ(x) ((x) << 8) +#define R500_SWIZ_TEX_RGBA(x) ((x) << 24) +/* Swizzles for inst3 */ +#define R500_SWIZ_RGB_A(x) ((x) << 2) +#define R500_SWIZ_RGB_B(x) ((x) << 15) +/* Swizzles for inst4 */ +#define R500_SWIZ_ALPHA_A(x) ((x) << 14) +#define R500_SWIZ_ALPHA_B(x) ((x) << 21) +/* Swizzle for inst5 */ +#define R500_SWIZ_RGBA_C(x) ((x) << 14) +#define R500_SWIZ_ALPHA_C(x) ((x) << 27) +/* Writemasks */ +#define R500_TEX_WMASK(x) ((x) << 11) +#define R500_ALU_WMASK(x) ((x) << 11) +#define R500_ALU_OMASK(x) ((x) << 15) +#define R500_W_OMASK (1 << 31) + +struct rX00_fragment_program_code r5xx_passthrough_fragment_shader = { + .code.r500.max_temp_idx = 0, + .code.r500.inst_end = 0, + + .code.r500.inst[0].inst0 = R500_INST_TYPE_OUT | + R500_INST_TEX_SEM_WAIT | R500_INST_LAST | + R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | + R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, + .code.r500.inst[0].inst1 = + R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | + R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, + .code.r500.inst[0].inst2 = + R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | + R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, + .code.r500.inst[0].inst3 = + R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | + R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | + R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | + R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, + .code.r500.inst[0].inst4 = + R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, + .code.r500.inst[0].inst5 = + R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | + R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | + R500_ALU_RGBA_A_SWIZ_0, +}; + +struct rX00_fragment_program_code r5xx_texture_fragment_shader = { + .code.r500.max_temp_idx = 0, + .code.r500.inst_end = 1, + + .code.r500.inst[0].inst0 = R500_INST_TYPE_TEX | + R500_INST_TEX_SEM_WAIT | + R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK | + R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, + .code.r500.inst[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD | + R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, + .code.r500.inst[0].inst2 = R500_TEX_SRC_ADDR(0) | + R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G | + R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A | + R500_TEX_DST_ADDR(0) | R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | - R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; - - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - fs->instructions[i].inst2 |= - R500_TEX_DST_ADDR(assembler->temp_count + - assembler->temp_offset); - - fs->instruction_count++; - - /* Setup and emit a MOV. */ - src[0].SrcRegister.Index = assembler->temp_count; - src[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - - src[1] = src[0]; - src[2] = r300_constant_zero; - r5xx_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3); - } else { - fs->instruction_count++; - } -} - -void r5xx_fs_finalize(struct r5xx_fragment_shader* fs, - struct r300_fs_asm* assembler) -{ - /* XXX should this just go with OPCODE_END? */ - fs->instructions[fs->instruction_count - 1].inst0 |= - R500_INST_LAST; -} - -void r5xx_fs_instruction(struct r5xx_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_instruction* inst) -{ - /* Switch between opcodes. When possible, prefer using the official - * AMD/ATI names for opcodes, please, as it facilitates using the - * documentation. */ - switch (inst->Instruction.Opcode) { - /* XXX trig needs extra prep */ - case TGSI_OPCODE_COS: - case TGSI_OPCODE_SIN: - /* The simple scalar ops. */ - case TGSI_OPCODE_EX2: - case TGSI_OPCODE_LG2: - case TGSI_OPCODE_RCP: - case TGSI_OPCODE_RSQ: - /* Copy red swizzle to alpha for src0 */ - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX; - inst->FullSrcRegisters[0].SrcRegister.SwizzleW = - inst->FullSrcRegisters[0].SrcRegister.SwizzleX; - /* Fall through */ - case TGSI_OPCODE_DDX: - case TGSI_OPCODE_DDY: - case TGSI_OPCODE_FRC: - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1); - break; - - /* The dot products. */ - case TGSI_OPCODE_DPH: - /* Set alpha swizzle to one for src0 */ - if (!inst->FullSrcRegisters[0].SrcRegister.Extended) { - inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE; - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX = - inst->FullSrcRegisters[0].SrcRegister.SwizzleX; - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY = - inst->FullSrcRegisters[0].SrcRegister.SwizzleY; - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ = - inst->FullSrcRegisters[0].SrcRegister.SwizzleZ; - } - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = - TGSI_EXTSWIZZLE_ONE; - /* Fall through */ - case TGSI_OPCODE_DP3: - case TGSI_OPCODE_DP4: - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2); - break; - - /* Simple three-source operations. */ - case TGSI_OPCODE_CMP: - /* Swap src0 and src2 */ - inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2]; - inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0]; - inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3]; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); - break; - - /* The MAD variants. */ - case TGSI_OPCODE_SUB: - /* Just like ADD, but flip the negation on src1 first */ - inst->FullSrcRegisters[1].SrcRegister.Negate = - !inst->FullSrcRegisters[1].SrcRegister.Negate; - /* Fall through */ - case TGSI_OPCODE_ADD: - /* Force src0 to one, move all registers over */ - inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1]; - inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; - inst->FullSrcRegisters[0] = r300_constant_one; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); - break; - case TGSI_OPCODE_MUL: - /* Force our src2 to zero */ - inst->FullSrcRegisters[2] = r300_constant_zero; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); - break; - case TGSI_OPCODE_MAD: - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); - break; - - /* The MOV variants. */ - case TGSI_OPCODE_ABS: - /* Set absolute value modifiers. */ - inst->FullSrcRegisters[0].SrcRegisterExtMod.Absolute = TRUE; - /* Fall through */ - case TGSI_OPCODE_MOV: - case TGSI_OPCODE_SWZ: - /* src0 -> src1 and src2 forced to zero */ - inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; - inst->FullSrcRegisters[2] = r300_constant_zero; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); - break; - - /* The compound and hybrid insts. */ - case TGSI_OPCODE_LRP: - /* LRP DST A, B, C -> MAD TMP -A, C, C; MAD DST A, B, TMP */ - inst->FullSrcRegisters[3] = inst->FullSrcRegisters[1]; - inst->FullSrcRegisters[1] = inst->FullSrcRegisters[2]; - inst->FullSrcRegisters[0].SrcRegister.Negate = - !(inst->FullSrcRegisters[0].SrcRegister.Negate); - inst->FullDstRegisters[1] = inst->FullDstRegisters[0]; - inst->FullDstRegisters[0].DstRegister.Index = - assembler->temp_count; - inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3); - inst->FullSrcRegisters[2].SrcRegister.Index = - assembler->temp_count; - inst->FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst->FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst->FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - inst->FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; - inst->FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; - inst->FullSrcRegisters[1] = inst->FullSrcRegisters[3]; - inst->FullSrcRegisters[0].SrcRegister.Negate = - !(inst->FullSrcRegisters[0].SrcRegister.Negate); - inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3); - break; - case TGSI_OPCODE_POW: - /* POW DST A, B -> LG2 TMP A; MUL TMP TMP, B; EX2 DST TMP */ - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = - inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX; - inst->FullSrcRegisters[0].SrcRegister.SwizzleW = - inst->FullSrcRegisters[0].SrcRegister.SwizzleX; - inst->FullDstRegisters[1] = inst->FullDstRegisters[0]; - inst->FullDstRegisters[0].DstRegister.Index = - assembler->temp_count; - inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1); - inst->FullSrcRegisters[0].SrcRegister.Index = - assembler->temp_count; - inst->FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst->FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; - inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; - inst->FullSrcRegisters[2] = r300_constant_zero; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3); - inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; - r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1); - break; - - /* The texture instruction set. */ - case TGSI_OPCODE_KIL: - case TGSI_OPCODE_TEX: - case TGSI_OPCODE_TXB: - case TGSI_OPCODE_TXP: - r5xx_emit_tex(fs, assembler, &inst->FullSrcRegisters[0], - &inst->FullDstRegisters[0], inst->Instruction.Opcode); - break; - - /* This is the end. My only friend, the end. */ - case TGSI_OPCODE_END: - break; - default: - debug_printf("r300: fs: Bad opcode %d\n", - inst->Instruction.Opcode); - break; - } - - /* Clamp, if saturation flags are set. */ - if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) { - fs->instructions[fs->instruction_count - 1].inst0 |= - R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP; - } -} + R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A, + .code.r500.inst[0].inst3 = 0x0, + .code.r500.inst[0].inst4 = 0x0, + .code.r500.inst[0].inst5 = 0x0, + + .code.r500.inst[1].inst0 = R500_INST_TYPE_OUT | + R500_INST_TEX_SEM_WAIT | R500_INST_LAST | + R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | + R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, + .code.r500.inst[1].inst1 = + R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | + R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, + .code.r500.inst[1].inst2 = + R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | + R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, + .code.r500.inst[1].inst3 = + R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | + R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | + R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | + R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, + .code.r500.inst[1].inst4 = + R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, + .code.r500.inst[1].inst5 = + R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | + R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | + R500_ALU_RGBA_A_SWIZ_0, +}; diff --git a/src/gallium/drivers/r300/r5xx_fs.h b/src/gallium/drivers/r300/r5xx_fs.h index 629e587be4..a4addde32b 100644 --- a/src/gallium/drivers/r300/r5xx_fs.h +++ b/src/gallium/drivers/r300/r5xx_fs.h @@ -24,109 +24,9 @@ #ifndef R5XX_FS_H #define R5XX_FS_H -#include "r300_fs_inlines.h" +#include "radeon_code.h" -/* XXX this all should find its way back to r300_reg */ -/* Swizzle tools */ -#define R500_SWIZZLE_ZERO 4 -#define R500_SWIZZLE_HALF 5 -#define R500_SWIZZLE_ONE 6 -#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6)) -#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6)) -#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6)) -#define R500_SWIZ_MOD_NEG 1 -#define R500_SWIZ_MOD_ABS 2 -#define R500_SWIZ_MOD_NEG_ABS 3 -/* Swizzles for inst2 */ -#define R500_SWIZ_TEX_STRQ(x) ((x) << 8) -#define R500_SWIZ_TEX_RGBA(x) ((x) << 24) -/* Swizzles for inst3 */ -#define R500_SWIZ_RGB_A(x) ((x) << 2) -#define R500_SWIZ_RGB_B(x) ((x) << 15) -/* Swizzles for inst4 */ -#define R500_SWIZ_ALPHA_A(x) ((x) << 14) -#define R500_SWIZ_ALPHA_B(x) ((x) << 21) -/* Swizzle for inst5 */ -#define R500_SWIZ_RGBA_C(x) ((x) << 14) -#define R500_SWIZ_ALPHA_C(x) ((x) << 27) -/* Writemasks */ -#define R500_TEX_WMASK(x) ((x) << 11) -#define R500_ALU_WMASK(x) ((x) << 11) -#define R500_ALU_OMASK(x) ((x) << 15) -#define R500_W_OMASK (1 << 31) - -static struct r5xx_fragment_shader r5xx_passthrough_fragment_shader = { - .shader.stack_size = 0, - .instruction_count = 1, - .instructions[0].inst0 = R500_INST_TYPE_OUT | - R500_INST_TEX_SEM_WAIT | R500_INST_LAST | - R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | - R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, - .instructions[0].inst1 = - R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | - R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, - .instructions[0].inst2 = - R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | - R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, - .instructions[0].inst3 = - R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | - R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | - R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | - R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, - .instructions[0].inst4 = - R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, - .instructions[0].inst5 = - R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | - R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | - R500_ALU_RGBA_A_SWIZ_0, -}; - -static struct r5xx_fragment_shader r5xx_texture_fragment_shader = { - .shader.stack_size = 1, - .instruction_count = 2, - .instructions[0].inst0 = R500_INST_TYPE_TEX | - R500_INST_TEX_SEM_WAIT | - R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK | - R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, - .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD | - R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, - .instructions[0].inst2 = R500_TEX_SRC_ADDR(0) | - R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G | - R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A | - R500_TEX_DST_ADDR(0) | - R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | - R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A, - .instructions[0].inst3 = 0x0, - .instructions[0].inst4 = 0x0, - .instructions[0].inst5 = 0x0, - .instructions[1].inst0 = R500_INST_TYPE_OUT | - R500_INST_TEX_SEM_WAIT | R500_INST_LAST | - R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | - R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, - .instructions[1].inst1 = - R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | - R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, - .instructions[1].inst2 = - R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | - R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, - .instructions[1].inst3 = - R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | - R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | - R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | - R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, - .instructions[1].inst4 = - R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, - .instructions[1].inst5 = - R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | - R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | - R500_ALU_RGBA_A_SWIZ_0, -}; - -void r5xx_fs_finalize(struct r5xx_fragment_shader* fs, - struct r300_fs_asm* assembler); - -void r5xx_fs_instruction(struct r5xx_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_instruction* inst); +struct rX00_fragment_program_code r5xx_passthrough_fragment_shader; +struct rX00_fragment_program_code r5xx_texture_fragment_shader; #endif /* R5XX_FS_H */ diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 7a533dad9f..70f0932431 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -48,11 +48,6 @@ /* Simple, maximally packed layout. */ -static unsigned minify( unsigned d ) -{ - return MAX2(1, d>>1); -} - /* Conventional allocation path for non-display textures: */ @@ -100,6 +95,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, { unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE | PIPE_BUFFER_USAGE_GPU_READ_WRITE); + unsigned tex_usage = spt->base.tex_usage; spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); @@ -109,6 +105,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, spt->base.height[0], spt->base.format, usage, + tex_usage, &spt->stride[0]); return spt->buffer != NULL; @@ -130,7 +127,8 @@ softpipe_texture_create(struct pipe_screen *screen, pipe_reference_init(&spt->base.reference, 1); spt->base.screen = screen; - if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_PRIMARY)) { if (!softpipe_displaytarget_layout(screen, spt)) goto fail; } @@ -224,12 +222,6 @@ softpipe_get_tex_surface(struct pipe_screen *screen, if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; - if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_WRITE)) { - /* Mark the surface as dirty. The tile cache will look for this. */ - spt->modified = TRUE; - } - ps->face = face; ps->level = level; ps->zslice = zslice; @@ -376,6 +368,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen, spt = softpipe_texture(transfer->texture); pipe_buffer_unmap( screen, spt->buffer ); + + if (transfer->usage != PIPE_TRANSFER_READ) { + /* Mark the texture as dirty to expire the tile caches. */ + spt->modified = TRUE; + } } diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c index 98ac75e3fa..93c569c73a 100644 --- a/src/gallium/drivers/trace/tr_drm.c +++ b/src/gallium/drivers/trace/tr_drm.c @@ -63,7 +63,7 @@ trace_drm_create_screen(struct drm_api *_api, int fd, screen = api->create_screen(api, fd, arg); return trace_screen_create(screen); -}; +} static struct pipe_context * trace_drm_create_context(struct drm_api *_api, @@ -82,7 +82,7 @@ trace_drm_create_context(struct drm_api *_api, pipe = trace_context_create(_screen, pipe); return pipe; -}; +} static boolean trace_drm_buffer_from_texture(struct drm_api *_api, @@ -102,7 +102,7 @@ trace_drm_buffer_from_texture(struct drm_api *_api, result = api->buffer_from_texture(api, texture, &buffer, stride); if (result && _buffer) - buffer = trace_buffer_create(trace_screen(texture->screen), buffer); + buffer = trace_buffer_create(trace_screen(_texture->screen), buffer); if (_buffer) *_buffer = buffer; diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 5b1e26a52d..26f1c04594 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -462,6 +462,7 @@ trace_screen_surface_buffer_create(struct pipe_screen *_screen, unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *pstride) { struct trace_screen *tr_scr = trace_screen(_screen); @@ -476,11 +477,13 @@ trace_screen_surface_buffer_create(struct pipe_screen *_screen, trace_dump_arg(uint, height); trace_dump_arg(format, format); trace_dump_arg(uint, usage); + trace_dump_arg(uint, tex_usage); result = screen->surface_buffer_create(screen, width, height, format, usage, + tex_usage, pstride); stride = *pstride; diff --git a/src/gallium/include/pipe/internal/p_winsys_screen.h b/src/gallium/include/pipe/internal/p_winsys_screen.h index f4a29e63c7..a1542dada7 100644 --- a/src/gallium/include/pipe/internal/p_winsys_screen.h +++ b/src/gallium/include/pipe/internal/p_winsys_screen.h @@ -140,6 +140,7 @@ struct pipe_winsys unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride); diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index bc4bc70759..b01ab6d137 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -191,9 +191,9 @@ enum pipe_texture_target { * Transfer object usage flags */ enum pipe_transfer_usage { - PIPE_TRANSFER_READ, - PIPE_TRANSFER_WRITE, - PIPE_TRANSFER_READ_WRITE /**< Read/modify/write */ + PIPE_TRANSFER_READ = (1 << 0), + PIPE_TRANSFER_WRITE = (1 << 1), + PIPE_TRANSFER_READ_WRITE = PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE /**< Read/modify/write */ }; diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 6cbdd75943..3f30c52a16 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -194,6 +194,7 @@ struct pipe_screen { unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride); diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index b00cfe3423..f0ba4fb308 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -78,6 +78,7 @@ enum tgsi_file_type { TGSI_FILE_SAMPLER =5, TGSI_FILE_ADDRESS =6, TGSI_FILE_IMMEDIATE =7, + TGSI_FILE_LOOP =8, TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */ }; @@ -152,13 +153,16 @@ struct tgsi_immediate unsigned Extended : 1; /**< BOOL */ }; -struct tgsi_immediate_float32 +union tgsi_immediate_data { float Float; }; -/* - * GL_NV_vertex_program +/* TGSI opcodes. + * + * For more information on semantics of opcodes and + * which APIs are known to use which opcodes, see + * auxiliary/tgsi/tgsi-instruction-set.txt */ #define TGSI_OPCODE_ARL 0 #define TGSI_OPCODE_MOV 1 @@ -177,62 +181,32 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_SLT 14 #define TGSI_OPCODE_SGE 15 #define TGSI_OPCODE_MAD 16 - -/* - * GL_ATI_fragment_shader - */ #define TGSI_OPCODE_SUB 17 -#define TGSI_OPCODE_DOT3 TGSI_OPCODE_DP3 -#define TGSI_OPCODE_DOT4 TGSI_OPCODE_DP4 -#define TGSI_OPCODE_LERP 18 +#define TGSI_OPCODE_LRP 18 #define TGSI_OPCODE_CND 19 #define TGSI_OPCODE_CND0 20 -#define TGSI_OPCODE_DOT2ADD 21 - -/* - * GL_EXT_vertex_shader - */ -#define TGSI_OPCODE_INDEX 22 /* considered for removal */ -#define TGSI_OPCODE_NEGATE 23 /* considered for removal */ -#define TGSI_OPCODE_MADD TGSI_OPCODE_MAD -#define TGSI_OPCODE_FRAC 24 -#define TGSI_OPCODE_SETGE TGSI_OPCODE_SGE -#define TGSI_OPCODE_SETLT TGSI_OPCODE_SLT +#define TGSI_OPCODE_DP2A 21 + /* gap */ +#define TGSI_OPCODE_FRC 24 #define TGSI_OPCODE_CLAMP 25 -#define TGSI_OPCODE_FLOOR 26 +#define TGSI_OPCODE_FLR 26 #define TGSI_OPCODE_ROUND 27 -#define TGSI_OPCODE_EXPBASE2 28 -#define TGSI_OPCODE_LOGBASE2 29 -#define TGSI_OPCODE_POWER 30 -#define TGSI_OPCODE_RECIP TGSI_OPCODE_RCP -#define TGSI_OPCODE_RECIPSQRT TGSI_OPCODE_RSQ -#define TGSI_OPCODE_CROSSPRODUCT 31 -#define TGSI_OPCODE_MULTIPLYMATRIX 32 /* considered for removal */ - -/* - * GL_NV_vertex_program1_1 - */ +#define TGSI_OPCODE_EX2 28 +#define TGSI_OPCODE_LG2 29 +#define TGSI_OPCODE_POW 30 +#define TGSI_OPCODE_XPD 31 + /* gap */ #define TGSI_OPCODE_ABS 33 #define TGSI_OPCODE_RCC 34 #define TGSI_OPCODE_DPH 35 - -/* - * GL_NV_fragment_program - */ #define TGSI_OPCODE_COS 36 #define TGSI_OPCODE_DDX 37 #define TGSI_OPCODE_DDY 38 -#define TGSI_OPCODE_EX2 TGSI_OPCODE_EXPBASE2 -#define TGSI_OPCODE_FLR TGSI_OPCODE_FLOOR -#define TGSI_OPCODE_FRC TGSI_OPCODE_FRAC #define TGSI_OPCODE_KILP 39 /* predicated kill */ -#define TGSI_OPCODE_LG2 TGSI_OPCODE_LOGBASE2 -#define TGSI_OPCODE_LRP TGSI_OPCODE_LERP #define TGSI_OPCODE_PK2H 40 #define TGSI_OPCODE_PK2US 41 #define TGSI_OPCODE_PK4B 42 #define TGSI_OPCODE_PK4UB 43 -#define TGSI_OPCODE_POW TGSI_OPCODE_POWER #define TGSI_OPCODE_RFL 44 #define TGSI_OPCODE_SEQ 45 #define TGSI_OPCODE_SFL 46 @@ -249,66 +223,29 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_UP4B 57 #define TGSI_OPCODE_UP4UB 58 #define TGSI_OPCODE_X2D 59 - -/* - * GL_NV_vertex_program2 - */ #define TGSI_OPCODE_ARA 60 #define TGSI_OPCODE_ARR 61 #define TGSI_OPCODE_BRA 62 #define TGSI_OPCODE_CAL 63 #define TGSI_OPCODE_RET 64 -#define TGSI_OPCODE_SSG 65 - -/* - * GL_ARB_vertex_program - */ -#define TGSI_OPCODE_SWZ 118 -#define TGSI_OPCODE_XPD TGSI_OPCODE_CROSSPRODUCT - -/* - * GL_ARB_fragment_program - */ +#define TGSI_OPCODE_SSG 65 /* SGN */ #define TGSI_OPCODE_CMP 66 -#define TGSI_OPCODE_KIL 116 /* conditional kill */ #define TGSI_OPCODE_SCS 67 #define TGSI_OPCODE_TXB 68 - -/* - * GL_NV_fragment_program_option - */ -/* No new opcode */ - -/* - * GL_NV_fragment_program2 - */ #define TGSI_OPCODE_NRM 69 #define TGSI_OPCODE_DIV 70 #define TGSI_OPCODE_DP2 71 -#define TGSI_OPCODE_DP2A TGSI_OPCODE_DOT2ADD #define TGSI_OPCODE_TXL 72 #define TGSI_OPCODE_BRK 73 #define TGSI_OPCODE_IF 74 -#define TGSI_OPCODE_LOOP 75 +#define TGSI_OPCODE_BGNFOR 75 #define TGSI_OPCODE_REP 76 #define TGSI_OPCODE_ELSE 77 #define TGSI_OPCODE_ENDIF 78 -#define TGSI_OPCODE_ENDLOOP 79 +#define TGSI_OPCODE_ENDFOR 79 #define TGSI_OPCODE_ENDREP 80 - -/* - * GL_NV_vertex_program2_option - */ - -/* - * GL_NV_vertex_program3 - */ #define TGSI_OPCODE_PUSHA 81 #define TGSI_OPCODE_POPA 82 - -/* - * GL_NV_gpu_program4 - */ #define TGSI_OPCODE_CEIL 83 #define TGSI_OPCODE_I2F 84 #define TGSI_OPCODE_NOT 85 @@ -323,103 +260,25 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_TXF 94 #define TGSI_OPCODE_TXQ 95 #define TGSI_OPCODE_CONT 96 - -/* - * GL_NV_vertex_program4 - */ -/* Same as GL_NV_gpu_program4 */ - -/* - * GL_NV_fragment_program4 - */ -/* Same as GL_NV_gpu_program4 */ - -/* - * GL_NV_geometry_program4 - */ -/* Same as GL_NV_gpu_program4 */ #define TGSI_OPCODE_EMIT 97 #define TGSI_OPCODE_ENDPRIM 98 - -/* - * GLSL - */ -#define TGSI_OPCODE_BGNLOOP2 99 +#define TGSI_OPCODE_BGNLOOP 99 #define TGSI_OPCODE_BGNSUB 100 -#define TGSI_OPCODE_ENDLOOP2 101 +#define TGSI_OPCODE_ENDLOOP 101 #define TGSI_OPCODE_ENDSUB 102 -#define TGSI_OPCODE_INT TGSI_OPCODE_TRUNC #define TGSI_OPCODE_NOISE1 103 #define TGSI_OPCODE_NOISE2 104 #define TGSI_OPCODE_NOISE3 105 #define TGSI_OPCODE_NOISE4 106 #define TGSI_OPCODE_NOP 107 - -/* - * ps_1_1 - */ -#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KIL - -/* - * ps_1_2 - */ -/* CMP - use TGSI_OPCODE_CND0 */ - -/* - * ps_1_3 - */ -/* CMP - use TGSI_OPCODE_CND0 */ - -/* - * ps_1_4 - */ -#define TGSI_OPCODE_TEXLD TGSI_OPCODE_TEX - -/* - * ps_2_0 - */ -#define TGSI_OPCODE_M4X4 TGSI_OPCODE_MULTIPLYMATRIX -#define TGSI_OPCODE_M4X3 108 -#define TGSI_OPCODE_M3X4 109 -#define TGSI_OPCODE_M3X3 110 -#define TGSI_OPCODE_M3X2 111 -#define TGSI_OPCODE_CRS TGSI_OPCODE_XPD + /* gap */ #define TGSI_OPCODE_NRM4 112 -#define TGSI_OPCODE_SINCOS TGSI_OPCODE_SCS -#define TGSI_OPCODE_TEXLDB TGSI_OPCODE_TXB -#define TGSI_OPCODE_DP2ADD TGSI_OPCODE_DP2A - -/* - * ps_2_x - */ -#define TGSI_OPCODE_CALL TGSI_OPCODE_CAL #define TGSI_OPCODE_CALLNZ 113 #define TGSI_OPCODE_IFC 114 -#define TGSI_OPCODE_BREAK TGSI_OPCODE_BRK #define TGSI_OPCODE_BREAKC 115 -#define TGSI_OPCODE_DSX TGSI_OPCODE_DDX -#define TGSI_OPCODE_DSY TGSI_OPCODE_DDY -#define TGSI_OPCODE_TEXLDD TGSI_OPCODE_TXD - -/* - * vs_1_1 - */ -#define TGSI_OPCODE_EXPP TGSI_OPCODE_EXP -#define TGSI_OPCODE_LOGP TGSI_OPCODE_LG2 - -/* - * vs_2_0 - */ -#define TGSI_OPCODE_SGN TGSI_OPCODE_SSG -#define TGSI_OPCODE_MOVA TGSI_OPCODE_ARR -/* EXPP - use TGSI_OPCODE_EX2 */ - -/* - * vs_2_x - */ - +#define TGSI_OPCODE_KIL 116 /* conditional kill */ #define TGSI_OPCODE_END 117 /* aka HALT */ - +#define TGSI_OPCODE_SWZ 118 #define TGSI_OPCODE_LAST 119 #define TGSI_SAT_NONE 0 /* do not saturate */ diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 6c617197ec..830e511fef 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -109,9 +109,6 @@ dri_destroy_context(__DRIcontextPrivate * cPriv) */ st_flush(ctx->st, 0, NULL); - if (screen->dummyContext == ctx) - screen->dummyContext = NULL; - /* Also frees ctx->pipe? */ st_destroy_context(ctx->st); @@ -153,11 +150,6 @@ dri_make_current(__DRIcontextPrivate * cPriv, ++ctx->bind_count; - /* This is for situations in which we need a rendering context but - * there may not be any currently bound. - */ - screen->dummyContext = ctx; - if (ctx->dPriv != driDrawPriv) { ctx->dPriv = driDrawPriv; ctx->d_stamp = driDrawPriv->lastStamp - 1; diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 1d91fbb89f..0a952f7b28 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -204,6 +204,30 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv) st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h); } +/** + * These are used for GLX_EXT_texture_from_pixmap + */ +void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target, + GLint format, __DRIdrawable *dPriv) +{ + struct dri_drawable *drawable = dri_drawable(dPriv); + struct pipe_surface *ps; + + dri_get_buffers(drawable->dPriv); + st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps); + + st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D : + ST_TEXTURE_RECT, 0, + format == GLX_TEXTURE_FORMAT_RGBA_EXT ? + PIPE_FORMAT_R8G8B8A8_UNORM : PIPE_FORMAT_R8G8B8X8_UNORM); +} + +void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, + __DRIdrawable *dPriv) +{ + dri2_set_tex_buffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); +} + void dri_flush_frontbuffer(struct pipe_screen *screen, struct pipe_surface *surf, void *context_private) diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index 2fbd5f1eb7..dfd0b8766d 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -91,6 +91,12 @@ void dri_get_buffers(__DRIdrawablePrivate * dPriv); void dri_destroy_buffer(__DRIdrawablePrivate * dPriv); +void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target, + GLint glx_texture_format, __DRIdrawable *dPriv); + +void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, + __DRIdrawable *dPriv); + void dri1_update_drawables(struct dri_context *ctx, struct dri_drawable *draw, struct dri_drawable *read); diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 5f78b7264a..25555128f9 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -57,12 +57,19 @@ PUBLIC const char __driConfigOptions[] = const uint __driNConfigOptions = 3; +static const __DRItexBufferExtension dri2TexBufferExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + dri2_set_tex_buffer, + dri2_set_tex_buffer2, +}; + static const __DRIextension *dri_screen_extensions[] = { &driReadDrawableExtension, &driCopySubBufferExtension.base, &driSwapControlExtension.base, &driFrameTrackingExtension.base, &driMediaStreamCounterExtension.base, + &dri2TexBufferExtension.base, NULL }; diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index f3335bb09f..f6c56d0f0c 100644 --- a/src/gallium/state_trackers/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -49,12 +49,6 @@ struct dri_screen */ driOptionCache optionCache; - /** - * Temporary(?) context to use for SwapBuffers or other situations in - * which we need a rendering context, but none is currently bound. - */ - struct dri_context *dummyContext; - /* drm */ int fd; drmLock *drmLock; diff --git a/src/gallium/state_trackers/egl/egl_context.c b/src/gallium/state_trackers/egl/egl_context.c index e2da2180f7..2c8f51cf38 100644 --- a/src/gallium/state_trackers/egl/egl_context.c +++ b/src/gallium/state_trackers/egl/egl_context.c @@ -148,7 +148,7 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) { struct drm_context *c = lookup_drm_context(context); _eglUnlinkContext(&c->base); - if (!c->base.IsBound) { + if (!_eglIsContextBound(&c->base)) { st_destroy_context(c->st); c->pipe->destroy(c->pipe); free(c); diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c index 86f2ea97e5..d4cd2d3c74 100644 --- a/src/gallium/state_trackers/egl/egl_surface.c +++ b/src/gallium/state_trackers/egl/egl_surface.c @@ -98,8 +98,8 @@ drm_create_texture(_EGLDriver *drv, goto err_buf; memset(&templat, 0, sizeof(templat)); - templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; - templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; + templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; templat.depth[0] = 1; @@ -366,7 +366,7 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) struct drm_surface *surf = lookup_drm_surface(surface); _eglUnlinkSurface(&surf->base); - if (!surf->base.IsBound) { + if (!_eglIsSurfaceBound(&surf->base)) { if (surf->screen) drm_takedown_shown_screen(drv, surf->screen); st_unreference_framebuffer(surf->stfb); diff --git a/src/gallium/state_trackers/glx/xlib/Makefile b/src/gallium/state_trackers/glx/xlib/Makefile index 6d10b090aa..7b2adc62c3 100644 --- a/src/gallium/state_trackers/glx/xlib/Makefile +++ b/src/gallium/state_trackers/glx/xlib/Makefile @@ -5,13 +5,12 @@ LIBNAME = xlib LIBRARY_INCLUDES = \ -I$(TOP)/include \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main + -I$(TOP)/src/mesa C_SOURCES = \ - glxapi.c \ - fakeglx.c \ - fakeglx_fonts.c \ + glx_api.c \ + glx_getproc.c \ + glx_usefont.c \ xm_api.c include ../../../Makefile.template diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript index 0dbe341397..04a44c3067 100644 --- a/src/gallium/state_trackers/glx/xlib/SConscript +++ b/src/gallium/state_trackers/glx/xlib/SConscript @@ -18,9 +18,10 @@ if env['platform'] == 'linux' \ st_xlib = env.ConvenienceLibrary( target = 'st_xlib', - source = [ 'glxapi.c', - 'fakeglx.c', - 'fakeglx_fonts.c', + source = [ + 'glx_api.c', + 'glx_getproc.c', + 'glx_usefont.c', 'xm_api.c', ] ) diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.h b/src/gallium/state_trackers/glx/xlib/fakeglx.h deleted file mode 100644 index e5fd960072..0000000000 --- a/src/gallium/state_trackers/glx/xlib/fakeglx.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2000 Brian Paul 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, 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 - * BRIAN PAUL 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 FAKEGLX_H -#define FAKEGLX_H - - -#include <X11/Xlib.h> - -struct _glxapi_table; - -extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); - -extern void Fake_glXUseXFont( Font font, int first, int count, int listbase ); - - -#endif - diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.c b/src/gallium/state_trackers/glx/xlib/glx_api.c index 23777c76f6..96490dbeda 100644 --- a/src/gallium/state_trackers/glx/xlib/fakeglx.c +++ b/src/gallium/state_trackers/glx/xlib/glx_api.c @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.6 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright (C) 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"), @@ -23,31 +24,21 @@ */ -/* - * This is an emulation of the GLX API which allows Mesa/GLX-based programs - * to run on X servers which do not have the real GLX extension. - * - * Thanks to the contributors: - * - * Initial version: Philip Brown (phil@bolthole.com) - * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu) - * Further visual-handling refinements: Wolfram Gloger - * (wmglo@Dent.MED.Uni-Muenchen.DE). - * - * Notes: - * Don't be fooled, stereo isn't supported yet. +/** + * "Fake" GLX API implemented in terms of the XMesa*() functions. */ -#include "glxapi.h" +#define GLX_GLXEXT_PROTOTYPES +#include "GL/glx.h" + #include "xm_api.h" -#include "context.h" -#include "config.h" -#include "macros.h" -#include "imports.h" -#include "version.h" -#include "fakeglx.h" +#include "main/context.h" +#include "main/config.h" +#include "main/macros.h" +#include "main/imports.h" +#include "main/version.h" #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" @@ -80,24 +71,55 @@ "GLX_SGIX_fbconfig " \ "GLX_SGIX_pbuffer " -/* - * Our fake GLX context will contain a "real" GLX context and an XMesa context. - * - * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context, - * and vice versa. - * - * We really just need this structure in order to make the libGL functions - * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay() - * work correctly. +#define DEFAULT_DIRECT GL_TRUE + + + +/** + * The GLXContext typedef is defined as a pointer to this structure. */ -struct fake_glx_context { - __GLXcontext glxContext; /* this MUST be first! */ +struct __GLXcontextRec +{ + Display *currentDpy; + GLboolean isDirect; + GLXDrawable currentDrawable; + GLXDrawable currentReadable; + XID xid; + XMesaContext xmesaContext; }; -#define DEFAULT_DIRECT GL_TRUE +static pipe_tsd ContextTSD; + +/** Set current context for calling thread */ +static void +SetCurrentContext(GLXContext c) +{ + pipe_tsd_set(&ContextTSD, c); +} + +/** Get current context for calling thread */ +static GLXContext +GetCurrentContext(void) +{ + return pipe_tsd_get(&ContextTSD); +} + + + +/**********************************************************************/ +/*** Debug helper code ***/ +/**********************************************************************/ + +extern void _kw_ungrab_all( Display *dpy ); +void _kw_ungrab_all( Display *dpy ) +{ + XUngrabPointer( dpy, CurrentTime ); + XUngrabKeyboard( dpy, CurrentTime ); +} + /**********************************************************************/ @@ -366,10 +388,6 @@ find_glx_visual( Display *dpy, XVisualInfo *vinfo ) } - - - - /** * Try to get an X visual which matches the given arguments. */ @@ -418,7 +436,6 @@ get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) } - /* * Retrieve the value of the given environment variable and find * the X visual which matches it. @@ -1002,8 +1019,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) } -static XVisualInfo * -Fake_glXChooseVisual( Display *dpy, int screen, int *list ) +XVisualInfo * +glXChooseVisual( Display *dpy, int screen, int *list ) { XMesaVisual xmvis; @@ -1024,18 +1041,18 @@ Fake_glXChooseVisual( Display *dpy, int screen, int *list ) } -static GLXContext -Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, - GLXContext share_list, Bool direct ) +GLXContext +glXCreateContext( Display *dpy, XVisualInfo *visinfo, + GLXContext share_list, Bool direct ) { XMesaVisual xmvis; - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + GLXContext glxCtx; + GLXContext shareCtx = share_list; if (!dpy || !visinfo) return 0; - glxCtx = CALLOC_STRUCT(fake_glx_context); + glxCtx = CALLOC_STRUCT(__GLXcontextRec); if (!glxCtx) return 0; @@ -1062,13 +1079,11 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, return NULL; } - glxCtx->glxContext.isDirect = DEFAULT_DIRECT; - glxCtx->glxContext.currentDpy = dpy; - glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ - - assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + glxCtx->isDirect = DEFAULT_DIRECT; + glxCtx->currentDpy = dpy; + glxCtx->xid = (XID) glxCtx; /* self pointer */ - return (GLXContext) glxCtx; + return glxCtx; } @@ -1081,11 +1096,11 @@ static XMesaBuffer MakeCurrent_PrevReadBuffer = 0; /* GLX 1.3 and later */ -static Bool -Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext ctx ) +Bool +glXMakeContextCurrent( Display *dpy, GLXDrawable draw, + GLXDrawable read, GLXContext ctx ) { - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + GLXContext glxCtx = ctx; static boolean firsttime = 1, no_rast = 0; if (firsttime) { @@ -1093,7 +1108,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, firsttime = 0; } - if (ctx && draw && read) { XMesaBuffer drawBuffer, readBuffer; XMesaContext xmctx = glxCtx->xmesaContext; @@ -1148,9 +1162,10 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, /* Now make current! */ if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { - ((__GLXcontext *) ctx)->currentDpy = dpy; - ((__GLXcontext *) ctx)->currentDrawable = draw; - ((__GLXcontext *) ctx)->currentReadable = read; + ctx->currentDpy = dpy; + ctx->currentDrawable = draw; + ctx->currentReadable = read; + SetCurrentContext(ctx); return True; } else { @@ -1165,6 +1180,7 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, MakeCurrent_PrevReadable = 0; MakeCurrent_PrevDrawBuffer = 0; MakeCurrent_PrevReadBuffer = 0; + SetCurrentContext(NULL); return True; } else { @@ -1176,15 +1192,61 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, } -static Bool -Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) +Bool +glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) { - return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx ); + return glXMakeContextCurrent( dpy, drawable, drawable, ctx ); } -static GLXPixmap -Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) +GLXContext +glXGetCurrentContext(void) +{ + return GetCurrentContext(); +} + + +Display * +glXGetCurrentDisplay(void) +{ + GLXContext glxCtx = glXGetCurrentContext(); + + return glxCtx ? glxCtx->currentDpy : NULL; +} + + +Display * +glXGetCurrentDisplayEXT(void) +{ + return glXGetCurrentDisplay(); +} + + +GLXDrawable +glXGetCurrentDrawable(void) +{ + GLXContext gc = glXGetCurrentContext(); + return gc ? gc->currentDrawable : 0; +} + + +GLXDrawable +glXGetCurrentReadDrawable(void) +{ + GLXContext gc = glXGetCurrentContext(); + return gc ? gc->currentReadable : 0; +} + + +GLXDrawable +glXGetCurrentReadDrawableSGI(void) +{ + return glXGetCurrentReadDrawable(); +} + + +GLXPixmap +glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) { XMesaVisual v; XMesaBuffer b; @@ -1208,9 +1270,9 @@ Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) /*** GLX_MESA_pixmap_colormap ***/ -static GLXPixmap -Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, - Pixmap pixmap, Colormap cmap ) +GLXPixmap +glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, + Pixmap pixmap, Colormap cmap ) { XMesaVisual v; XMesaBuffer b; @@ -1232,8 +1294,8 @@ Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, } -static void -Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) +void +glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) { XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); if (b) { @@ -1245,12 +1307,12 @@ Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) } -static void -Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, - unsigned long mask ) +void +glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, + unsigned long mask ) { - struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src; - struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst; + GLXContext fakeSrc = src; + GLXContext fakeDst = dst; XMesaContext xm_src = fakeSrc->xmesaContext; XMesaContext xm_dst = fakeDst->xmesaContext; (void) dpy; @@ -1261,8 +1323,8 @@ Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, } -static Bool -Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) +Bool +glXQueryExtension( Display *dpy, int *errorb, int *event ) { /* Mesa's GLX isn't really an X extension but we try to act like one. */ (void) dpy; @@ -1272,18 +1334,10 @@ Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) } -extern void _kw_ungrab_all( Display *dpy ); -void _kw_ungrab_all( Display *dpy ) -{ - XUngrabPointer( dpy, CurrentTime ); - XUngrabKeyboard( dpy, CurrentTime ); -} - - -static void -Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) +void +glXDestroyContext( Display *dpy, GLXContext ctx ) { - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + GLXContext glxCtx = ctx; (void) dpy; MakeCurrent_PrevContext = 0; MakeCurrent_PrevDrawable = 0; @@ -1296,18 +1350,18 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) } -static Bool -Fake_glXIsDirect( Display *dpy, GLXContext ctx ) +Bool +glXIsDirect( Display *dpy, GLXContext ctx ) { - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + GLXContext glxCtx = ctx; (void) ctx; - return glxCtx->glxContext.isDirect; + return glxCtx->isDirect; } -static void -Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) +void +glXSwapBuffers( Display *dpy, GLXDrawable drawable ) { XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); static boolean firsttime = 1, no_rast = 0; @@ -1333,8 +1387,8 @@ Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) /*** GLX_MESA_copy_sub_buffer ***/ -static void -Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, +void +glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, int x, int y, int width, int height ) { XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); @@ -1347,8 +1401,8 @@ Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, } -static Bool -Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) +Bool +glXQueryVersion( Display *dpy, int *maj, int *min ) { (void) dpy; /* Return GLX version, not Mesa version */ @@ -1564,8 +1618,8 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) } -static int -Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, +int +glXGetConfig( Display *dpy, XVisualInfo *visinfo, int attrib, int *value ) { XMesaVisual xmvis; @@ -1594,8 +1648,8 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, } -static void -Fake_glXWaitGL( void ) +void +glXWaitGL( void ) { XMesaContext xmesa = XMesaGetCurrentContext(); XMesaFlush( xmesa ); @@ -1603,8 +1657,8 @@ Fake_glXWaitGL( void ) -static void -Fake_glXWaitX( void ) +void +glXWaitX( void ) { XMesaContext xmesa = XMesaGetCurrentContext(); XMesaFlush( xmesa ); @@ -1620,8 +1674,8 @@ get_extensions( void ) /* GLX 1.1 and later */ -static const char * -Fake_glXQueryExtensionsString( Display *dpy, int screen ) +const char * +glXQueryExtensionsString( Display *dpy, int screen ) { (void) dpy; (void) screen; @@ -1631,8 +1685,8 @@ Fake_glXQueryExtensionsString( Display *dpy, int screen ) /* GLX 1.1 and later */ -static const char * -Fake_glXQueryServerString( Display *dpy, int screen, int name ) +const char * +glXQueryServerString( Display *dpy, int screen, int name ) { static char version[1000]; _mesa_sprintf(version, "%d.%d %s", @@ -1656,8 +1710,8 @@ Fake_glXQueryServerString( Display *dpy, int screen, int name ) /* GLX 1.1 and later */ -static const char * -Fake_glXGetClientString( Display *dpy, int name ) +const char * +glXGetClientString( Display *dpy, int name ) { static char version[1000]; _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, @@ -1684,8 +1738,8 @@ Fake_glXGetClientString( Display *dpy, int name ) */ -static int -Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, +int +glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, int attribute, int *value ) { XMesaVisual v = (XMesaVisual) config; @@ -1699,8 +1753,8 @@ Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, } -static GLXFBConfig * -Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) +GLXFBConfig * +glXGetFBConfigs( Display *dpy, int screen, int *nelements ) { XVisualInfo *visuals, visTemplate; const long visMask = VisualScreenMask; @@ -1725,15 +1779,15 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) } -static GLXFBConfig * -Fake_glXChooseFBConfig( Display *dpy, int screen, +GLXFBConfig * +glXChooseFBConfig( Display *dpy, int screen, const int *attribList, int *nitems ) { XMesaVisual xmvis; if (!attribList || !attribList[0]) { /* return list of all configs (per GLX_SGIX_fbconfig spec) */ - return Fake_glXGetFBConfigs(dpy, screen, nitems); + return glXGetFBConfigs(dpy, screen, nitems); } xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); @@ -1754,8 +1808,8 @@ Fake_glXChooseFBConfig( Display *dpy, int screen, } -static XVisualInfo * -Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) +XVisualInfo * +glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) { if (dpy && config) { XMesaVisual xmvis = (XMesaVisual) config; @@ -1776,8 +1830,8 @@ Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) } -static GLXWindow -Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, +GLXWindow +glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, const int *attribList ) { XMesaVisual xmvis = (XMesaVisual) config; @@ -1796,8 +1850,8 @@ Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, } -static void -Fake_glXDestroyWindow( Display *dpy, GLXWindow window ) +void +glXDestroyWindow( Display *dpy, GLXWindow window ) { XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window); if (b) @@ -1807,8 +1861,8 @@ Fake_glXDestroyWindow( Display *dpy, GLXWindow window ) /* XXX untested */ -static GLXPixmap -Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, +GLXPixmap +glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList ) { XMesaVisual v = (XMesaVisual) config; @@ -1917,8 +1971,8 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, } -static void -Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) +void +glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) { XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap); if (b) @@ -1927,8 +1981,8 @@ Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) } -static GLXPbuffer -Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, +GLXPbuffer +glXCreatePbuffer( Display *dpy, GLXFBConfig config, const int *attribList ) { XMesaVisual xmvis = (XMesaVisual) config; @@ -1980,8 +2034,8 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, } -static void -Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) +void +glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) { XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); if (b) { @@ -1990,8 +2044,8 @@ Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) } -static void -Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, +void +glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, unsigned int *value ) { XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); @@ -2032,19 +2086,19 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, } -static GLXContext -Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, +GLXContext +glXCreateNewContext( Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct ) { - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList; + GLXContext glxCtx; + GLXContext shareCtx = shareList; XMesaVisual xmvis = (XMesaVisual) config; if (!dpy || !config || (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE)) return 0; - glxCtx = CALLOC_STRUCT(fake_glx_context); + glxCtx = CALLOC_STRUCT(__GLXcontextRec); if (!glxCtx) return 0; @@ -2058,20 +2112,18 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, return NULL; } - glxCtx->glxContext.isDirect = DEFAULT_DIRECT; - glxCtx->glxContext.currentDpy = dpy; - glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ - - assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + glxCtx->isDirect = DEFAULT_DIRECT; + glxCtx->currentDpy = dpy; + glxCtx->xid = (XID) glxCtx; /* self pointer */ - return (GLXContext) glxCtx; + return glxCtx; } -static int -Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) +int +glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) { - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + GLXContext glxCtx = ctx; XMesaContext xmctx = glxCtx->xmesaContext; (void) dpy; @@ -2097,8 +2149,8 @@ Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) } -static void -Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) +void +glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) { XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); if (xmbuf) @@ -2106,8 +2158,8 @@ Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) } -static void -Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, +void +glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, unsigned long *mask ) { XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); @@ -2121,8 +2173,8 @@ Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, /*** GLX_SGI_swap_control ***/ -static int -Fake_glXSwapIntervalSGI(int interval) +int +glXSwapIntervalSGI(int interval) { (void) interval; return 0; @@ -2134,16 +2186,16 @@ Fake_glXSwapIntervalSGI(int interval) static unsigned int FrameCounter = 0; -static int -Fake_glXGetVideoSyncSGI(unsigned int *count) +int +glXGetVideoSyncSGI(unsigned int *count) { /* this is a bogus implementation */ *count = FrameCounter++; return 0; } -static int -Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +int +glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { if (divisor <= 0 || remainder < 0) return GLX_BAD_VALUE; @@ -2159,15 +2211,15 @@ Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) /*** GLX_SGI_make_current_read ***/ -static Bool -Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +Bool +glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) { - return Fake_glXMakeContextCurrent( dpy, draw, read, ctx ); + return glXMakeContextCurrent( dpy, draw, read, ctx ); } /* not used static GLXDrawable -Fake_glXGetCurrentReadDrawableSGI(void) +glXGetCurrentReadDrawableSGI(void) { return 0; } @@ -2177,8 +2229,8 @@ Fake_glXGetCurrentReadDrawableSGI(void) /*** GLX_SGIX_video_source ***/ #if defined(_VL_H) -static GLXVideoSourceSGIX -Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) +GLXVideoSourceSGIX +glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) { (void) dpy; (void) screen; @@ -2189,8 +2241,8 @@ Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPa return 0; } -static void -Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) +void +glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) { (void) dpy; (void) src; @@ -2201,30 +2253,30 @@ Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) /*** GLX_EXT_import_context ***/ -static void -Fake_glXFreeContextEXT(Display *dpy, GLXContext context) +void +glXFreeContextEXT(Display *dpy, GLXContext context) { (void) dpy; (void) context; } -static GLXContextID -Fake_glXGetContextIDEXT(const GLXContext context) +GLXContextID +glXGetContextIDEXT(const GLXContext context) { (void) context; return 0; } -static GLXContext -Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID) +GLXContext +glXImportContextEXT(Display *dpy, GLXContextID contextID) { (void) dpy; (void) contextID; return 0; } -static int -Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) +int +glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) { (void) dpy; (void) context; @@ -2237,21 +2289,21 @@ Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int /*** GLX_SGIX_fbconfig ***/ -static int -Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) +int +glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) { - return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value); + return glXGetFBConfigAttrib(dpy, config, attribute, value); } -static GLXFBConfigSGIX * -Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) +GLXFBConfigSGIX * +glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) { - return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements); + return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements); } -static GLXPixmap -Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) +GLXPixmap +glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) { XMesaVisual xmvis = (XMesaVisual) config; XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); @@ -2259,14 +2311,14 @@ Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixm } -static GLXContext -Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) +GLXContext +glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) { XMesaVisual xmvis = (XMesaVisual) config; - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + GLXContext glxCtx; + GLXContext shareCtx = share_list; - glxCtx = CALLOC_STRUCT(fake_glx_context); + glxCtx = CALLOC_STRUCT(__GLXcontextRec); if (!glxCtx) return 0; @@ -2280,25 +2332,23 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re return NULL; } - glxCtx->glxContext.isDirect = DEFAULT_DIRECT; - glxCtx->glxContext.currentDpy = dpy; - glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ - - assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + glxCtx->isDirect = DEFAULT_DIRECT; + glxCtx->currentDpy = dpy; + glxCtx->xid = (XID) glxCtx; /* self pointer */ - return (GLXContext) glxCtx; + return glxCtx; } -static XVisualInfo * -Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) +XVisualInfo * +glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) { - return Fake_glXGetVisualFromFBConfig(dpy, config); + return glXGetVisualFromFBConfig(dpy, config); } -static GLXFBConfigSGIX -Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) +GLXFBConfigSGIX +glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) { XMesaVisual xmvis = find_glx_visual(dpy, vis); if (!xmvis) { @@ -2313,8 +2363,8 @@ Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) /*** GLX_SGIX_pbuffer ***/ -static GLXPbufferSGIX -Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, +GLXPbufferSGIX +glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attribList) { @@ -2352,8 +2402,8 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, } -static void -Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) +void +glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) { XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); if (xmbuf) { @@ -2362,8 +2412,8 @@ Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) } -static int -Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) +int +glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) { const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); @@ -2395,8 +2445,8 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un } -static void -Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) +void +glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) { XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); if (xmbuf) { @@ -2406,8 +2456,8 @@ Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) } -static void -Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) +void +glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) { XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); if (xmbuf) { @@ -2422,8 +2472,8 @@ Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long * /*** GLX_SGI_cushion ***/ -static void -Fake_glXCushionSGI(Display *dpy, Window win, float cushion) +void +glXCushionSGI(Display *dpy, Window win, float cushion) { (void) dpy; (void) win; @@ -2434,8 +2484,8 @@ Fake_glXCushionSGI(Display *dpy, Window win, float cushion) /*** GLX_SGIX_video_resize ***/ -static int -Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) +int +glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) { (void) dpy; (void) screen; @@ -2444,8 +2494,8 @@ Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window w return 0; } -static int -Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) +int +glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) { (void) dpy; (void) screen; @@ -2457,8 +2507,8 @@ Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int return 0; } -static int -Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) +int +glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) { (void) dpy; (void) screen; @@ -2470,8 +2520,8 @@ Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int return 0; } -static int -Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) +int +glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) { (void) dpy; (void) screen; @@ -2483,8 +2533,8 @@ Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, i return 0; } -static int -Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) +int +glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) { (void) dpy; (void) screen; @@ -2498,8 +2548,8 @@ Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum syncty /*** GLX_SGIX_dmbuffer **/ #if defined(_DM_BUFFER_H_) -static Bool -Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) +Bool +glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) { (void) dpy; (void) pbuffer; @@ -2512,8 +2562,8 @@ Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *p /*** GLX_SGIX_swap_group ***/ -static void -Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) +void +glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) { (void) dpy; (void) drawable; @@ -2524,16 +2574,16 @@ Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member /*** GLX_SGIX_swap_barrier ***/ -static void -Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) +void +glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) { (void) dpy; (void) drawable; (void) barrier; } -static Bool -Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) +Bool +glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) { (void) dpy; (void) screen; @@ -2545,8 +2595,8 @@ Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) /*** GLX_SUN_get_transparent_index ***/ -static Status -Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +Status +glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) { (void) dpy; (void) overlay; @@ -2563,8 +2613,8 @@ Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, lo * Release the depth, stencil, accum buffers attached to a GLXDrawable * (a window or pixmap) prior to destroying the GLXDrawable. */ -static Bool -Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) +Bool +glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) { XMesaBuffer b = XMesaFindBuffer(dpy, d); if (b) { @@ -2576,8 +2626,8 @@ Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) /*** GLX_EXT_texture_from_pixmap ***/ -static void -Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, +void +glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list) { XMesaBuffer b = XMesaFindBuffer(dpy, drawable); @@ -2585,162 +2635,10 @@ Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, XMesaBindTexImage(dpy, b, buffer, attrib_list); } -static void -Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +void +glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) { XMesaBuffer b = XMesaFindBuffer(dpy, drawable); if (b) XMesaReleaseTexImage(dpy, b, buffer); } - - - -/** - * Create a new GLX API dispatch table with its function pointers - * initialized to point to Mesa's "fake" GLX API functions. - * - * Note: there used to be a similar function - * (_real_GetGLXDispatchTable) that returns a new dispatch table with - * all pointers initalized to point to "real" GLX functions (which - * understand GLX wire protocol, etc). - */ -struct _glxapi_table * -_mesa_GetGLXDispatchTable(void) -{ - static struct _glxapi_table glx; - - /* be sure our dispatch table size <= libGL's table */ - { - GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); - (void) size; - assert(_glxapi_get_dispatch_table_size() >= size); - } - - /* initialize the whole table to no-ops */ - _glxapi_set_no_op_table(&glx); - - /* now initialize the table with the functions I implement */ - glx.ChooseVisual = Fake_glXChooseVisual; - glx.CopyContext = Fake_glXCopyContext; - glx.CreateContext = Fake_glXCreateContext; - glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap; - glx.DestroyContext = Fake_glXDestroyContext; - glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; - glx.GetConfig = Fake_glXGetConfig; - /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/ - /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ - glx.IsDirect = Fake_glXIsDirect; - glx.MakeCurrent = Fake_glXMakeCurrent; - glx.QueryExtension = Fake_glXQueryExtension; - glx.QueryVersion = Fake_glXQueryVersion; - glx.SwapBuffers = Fake_glXSwapBuffers; - glx.UseXFont = Fake_glXUseXFont; - glx.WaitGL = Fake_glXWaitGL; - glx.WaitX = Fake_glXWaitX; - - /*** GLX_VERSION_1_1 ***/ - glx.GetClientString = Fake_glXGetClientString; - glx.QueryExtensionsString = Fake_glXQueryExtensionsString; - glx.QueryServerString = Fake_glXQueryServerString; - - /*** GLX_VERSION_1_2 ***/ - /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/ - - /*** GLX_VERSION_1_3 ***/ - glx.ChooseFBConfig = Fake_glXChooseFBConfig; - glx.CreateNewContext = Fake_glXCreateNewContext; - glx.CreatePbuffer = Fake_glXCreatePbuffer; - glx.CreatePixmap = Fake_glXCreatePixmap; - glx.CreateWindow = Fake_glXCreateWindow; - glx.DestroyPbuffer = Fake_glXDestroyPbuffer; - glx.DestroyPixmap = Fake_glXDestroyPixmap; - glx.DestroyWindow = Fake_glXDestroyWindow; - /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/ - glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib; - glx.GetFBConfigs = Fake_glXGetFBConfigs; - glx.GetSelectedEvent = Fake_glXGetSelectedEvent; - glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig; - glx.MakeContextCurrent = Fake_glXMakeContextCurrent; - glx.QueryContext = Fake_glXQueryContext; - glx.QueryDrawable = Fake_glXQueryDrawable; - glx.SelectEvent = Fake_glXSelectEvent; - - /*** GLX_SGI_swap_control ***/ - glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI; - - /*** GLX_SGI_video_sync ***/ - glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI; - glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI; - - /*** GLX_SGI_make_current_read ***/ - glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI; - /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/ - -/*** GLX_SGIX_video_source ***/ -#if defined(_VL_H) - glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX; - glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX; -#endif - - /*** GLX_EXT_import_context ***/ - glx.FreeContextEXT = Fake_glXFreeContextEXT; - glx.GetContextIDEXT = Fake_glXGetContextIDEXT; - /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/ - glx.ImportContextEXT = Fake_glXImportContextEXT; - glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT; - - /*** GLX_SGIX_fbconfig ***/ - glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX; - glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX; - glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX; - glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX; - glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX; - glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX; - - /*** GLX_SGIX_pbuffer ***/ - glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX; - glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX; - glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX; - glx.SelectEventSGIX = Fake_glXSelectEventSGIX; - glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX; - - /*** GLX_SGI_cushion ***/ - glx.CushionSGI = Fake_glXCushionSGI; - - /*** GLX_SGIX_video_resize ***/ - glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX; - glx.ChannelRectSGIX = Fake_glXChannelRectSGIX; - glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX; - glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX; - glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX; - - /*** GLX_SGIX_dmbuffer **/ -#if defined(_DM_BUFFER_H_) - glx.AssociateDMPbufferSGIX = NULL; -#endif - - /*** GLX_SGIX_swap_group ***/ - glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX; - - /*** GLX_SGIX_swap_barrier ***/ - glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX; - glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX; - - /*** GLX_SUN_get_transparent_index ***/ - glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; - - /*** GLX_MESA_copy_sub_buffer ***/ - glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA; - - /*** GLX_MESA_release_buffers ***/ - glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA; - - /*** GLX_MESA_pixmap_colormap ***/ - glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; - - /*** GLX_EXT_texture_from_pixmap ***/ - glx.BindTexImageEXT = Fake_glXBindTexImageEXT; - glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; - - return &glx; -} diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c new file mode 100644 index 0000000000..ca7d88c922 --- /dev/null +++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c @@ -0,0 +1,214 @@ +/* + * Mesa 3-D graphics library + * Version: 7.6 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 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, 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 + * BRIAN PAUL 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. + */ + + +/** + * glXGetProcAddress() + */ + + +#define GLX_GLXEXT_PROTOTYPES + +#include <string.h> +#include "GL/glx.h" +#include "glapi/glapi.h" + + +struct name_address_pair { + const char *Name; + __GLXextFuncPtr Address; +}; + + +static struct name_address_pair GLX_functions[] = { + /*** GLX_VERSION_1_0 ***/ + { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual }, + { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext }, + { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext }, + { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap }, + { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext }, + { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap }, + { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig }, + { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext }, + { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable }, + { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect }, + { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent }, + { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension }, + { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion }, + { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers }, + { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont }, + { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL }, + { "glXWaitX", (__GLXextFuncPtr) glXWaitX }, + + /*** GLX_VERSION_1_1 ***/ + { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString }, + { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString }, + { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString }, + + /*** GLX_VERSION_1_2 ***/ + { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay }, + + /*** GLX_VERSION_1_3 ***/ + { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig }, + { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext }, + { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer }, + { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap }, + { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow }, + { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer }, + { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap }, + { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow }, + { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable }, + { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib }, + { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs }, + { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent }, + { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig }, + { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent }, + { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext }, + { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable }, + { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent }, + + /*** GLX_VERSION_1_4 ***/ + { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress }, + + /*** GLX_SGI_swap_control ***/ + { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI }, + + /*** GLX_SGI_video_sync ***/ + { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI }, + { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI }, + + /*** GLX_SGI_make_current_read ***/ + { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI }, + { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI }, + + /*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX }, + { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX }, +#endif + + /*** GLX_EXT_import_context ***/ + { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT }, + { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT }, + { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT }, + { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT }, + { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT }, + + /*** GLX_SGIX_fbconfig ***/ + { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX }, + { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX }, + { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX }, + { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX }, + { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX }, + { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX }, + + /*** GLX_SGIX_pbuffer ***/ + { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX }, + { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX }, + { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX }, + { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX }, + { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX }, + + /*** GLX_SGI_cushion ***/ + { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI }, + + /*** GLX_SGIX_video_resize ***/ + { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX }, + { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX }, + { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX }, + { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX }, + { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX }, + + /*** GLX_SGIX_dmbuffer **/ +#if defined(_DM_BUFFER_H_) + { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX }, +#endif + + /*** GLX_SGIX_swap_group ***/ + { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX }, + + /*** GLX_SGIX_swap_barrier ***/ + { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX }, + { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX }, + + /*** GLX_SUN_get_transparent_index ***/ + { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN }, + + /*** GLX_MESA_copy_sub_buffer ***/ + { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA }, + + /*** GLX_MESA_pixmap_colormap ***/ + { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA }, + + /*** GLX_MESA_release_buffers ***/ + { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA }, + + /*** GLX_ARB_get_proc_address ***/ + { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB }, + + /*** GLX_EXT_texture_from_pixmap ***/ + { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT }, + { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT }, + + { NULL, NULL } /* end of list */ +}; + + + +/** + * Return address of named glX function, or NULL if not found. + */ +static __GLXextFuncPtr +_glxapi_get_proc_address(const char *funcName) +{ + GLuint i; + for (i = 0; GLX_functions[i].Name; i++) { + if (strcmp(GLX_functions[i].Name, funcName) == 0) + return GLX_functions[i].Address; + } + return NULL; +} + + +__GLXextFuncPtr +glXGetProcAddressARB(const GLubyte *procName) +{ + __GLXextFuncPtr f; + + f = _glxapi_get_proc_address((const char *) procName); + if (f) { + return f; + } + + f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName); + return f; +} + + +/* GLX 1.4 */ +void (*glXGetProcAddress(const GLubyte *procName))() +{ + return glXGetProcAddressARB(procName); +} diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx_fonts.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c index e359046756..acc64df62b 100644 --- a/src/gallium/state_trackers/glx/xlib/fakeglx_fonts.c +++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c @@ -1,9 +1,10 @@ - /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 7.6 * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 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"), @@ -24,13 +25,13 @@ */ -/* xfonts.c -- glXUseXFont() for Mesa written by - * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de +/** + * Fake implementation of glXUseXFont(). */ -#include "context.h" -#include "imports.h" -#include "fakeglx.h" + +#include "main/context.h" +#include "main/imports.h" #include <GL/glx.h> @@ -210,7 +211,7 @@ isvalid(XFontStruct * fs, unsigned int which) void -Fake_glXUseXFont(Font font, int first, int count, int listbase) +glXUseXFont(Font font, int first, int count, int listbase) { Display *dpy; Window win; @@ -228,7 +229,8 @@ Fake_glXUseXFont(Font font, int first, int count, int listbase) dpy = glXGetCurrentDisplay(); if (!dpy) return; /* I guess glXMakeCurrent wasn't called */ - win = RootWindow(dpy, DefaultScreen(dpy)); + i = DefaultScreen(dpy); + win = RootWindow(dpy, i); fs = XQueryFont(dpy, font); if (!fs) { diff --git a/src/gallium/state_trackers/glx/xlib/glxapi.c b/src/gallium/state_trackers/glx/xlib/glxapi.c deleted file mode 100644 index c2cb34d7cf..0000000000 --- a/src/gallium/state_trackers/glx/xlib/glxapi.c +++ /dev/null @@ -1,1254 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2007 Brian Paul 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, 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 - * BRIAN PAUL 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. - */ - - -/* - * This is the GLX API dispatcher. Calls to the glX* functions are - * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions. - * See the glxapi.h file for more details. - */ - - -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "glapi/glapi.h" -#include "glxapi.h" -#include "fakeglx.h" -#include "pipe/p_thread.h" - - -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 -# define PUBLIC __attribute__((visibility("default"))) -# define USED __attribute__((used)) -#else -# define PUBLIC -# define USED -#endif - - -struct display_dispatch { - Display *Dpy; - struct _glxapi_table *Table; - struct display_dispatch *Next; -}; - -static struct display_dispatch *DispatchList = NULL; - - -/* Display -> Dispatch caching */ -static Display *prevDisplay = NULL; -static struct _glxapi_table *prevTable = NULL; - - -static struct _glxapi_table * -get_dispatch(Display *dpy) -{ - if (!dpy) - return NULL; - - /* search list of display/dispatch pairs for this display */ - { - const struct display_dispatch *d = DispatchList; - while (d) { - if (d->Dpy == dpy) { - prevDisplay = dpy; - prevTable = d->Table; - return d->Table; /* done! */ - } - d = d->Next; - } - } - - /* A new display, determine if we should use real GLX - * or Mesa's pseudo-GLX. - */ - { - struct _glxapi_table *t = _mesa_GetGLXDispatchTable(); - - if (t) { - struct display_dispatch *d; - d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch)); - if (d) { - d->Dpy = dpy; - d->Table = t; - /* insert at head of list */ - d->Next = DispatchList; - DispatchList = d; - /* update cache */ - prevDisplay = dpy; - prevTable = t; - return t; - } - } - } - - /* If we get here that means we can't use real GLX on this display - * and the Mesa pseudo-GLX software renderer wasn't compiled in. - * Or, we ran out of memory! - */ - return NULL; -} - - -/* Don't use the GET_DISPATCH defined in glthread.h */ -#undef GET_DISPATCH - -#define GET_DISPATCH(DPY, TABLE) \ - if (DPY == prevDisplay) { \ - TABLE = prevTable; \ - } \ - else if (!DPY) { \ - TABLE = NULL; \ - } \ - else { \ - TABLE = get_dispatch(DPY); \ - } - - - - -/** - * GLX API current context. - */ -pipe_tsd ContextTSD; - - -static void -SetCurrentContext(GLXContext c) -{ - pipe_tsd_set(&ContextTSD, c); -} - - -/* - * GLX API entrypoints - */ - -/*** GLX_VERSION_1_0 ***/ - -XVisualInfo PUBLIC * -glXChooseVisual(Display *dpy, int screen, int *list) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->ChooseVisual)(dpy, screen, list); -} - - -void PUBLIC -glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->CopyContext)(dpy, src, dst, mask); -} - - -GLXContext PUBLIC -glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateContext)(dpy, visinfo, shareList, direct); -} - - -GLXPixmap PUBLIC -glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXPixmap)(dpy, visinfo, pixmap); -} - - -void PUBLIC -glXDestroyContext(Display *dpy, GLXContext ctx) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - if (glXGetCurrentContext() == ctx) - SetCurrentContext(NULL); - (t->DestroyContext)(dpy, ctx); -} - - -void PUBLIC -glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyGLXPixmap)(dpy, pixmap); -} - - -int PUBLIC -glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return GLX_NO_EXTENSION; - return (t->GetConfig)(dpy, visinfo, attrib, value); -} - - -GLXContext PUBLIC -glXGetCurrentContext(void) -{ - return (GLXContext) pipe_tsd_get(&ContextTSD); -} - - -GLXDrawable PUBLIC -glXGetCurrentDrawable(void) -{ - __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); - return gc ? gc->currentDrawable : 0; -} - - -Bool PUBLIC -glXIsDirect(Display *dpy, GLXContext ctx) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->IsDirect)(dpy, ctx); -} - - -Bool PUBLIC -glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) -{ - Bool b; - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) { - return False; - } - b = (*t->MakeCurrent)(dpy, drawable, ctx); - if (b) { - SetCurrentContext(ctx); - } - return b; -} - - -Bool PUBLIC -glXQueryExtension(Display *dpy, int *errorb, int *event) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->QueryExtension)(dpy, errorb, event); -} - - -Bool PUBLIC -glXQueryVersion(Display *dpy, int *maj, int *min) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->QueryVersion)(dpy, maj, min); -} - - -void PUBLIC -glXSwapBuffers(Display *dpy, GLXDrawable drawable) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->SwapBuffers)(dpy, drawable); -} - - -void PUBLIC -glXUseXFont(Font font, int first, int count, int listBase) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->UseXFont)(font, first, count, listBase); -} - - -void PUBLIC -glXWaitGL(void) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->WaitGL)(); -} - - -void PUBLIC -glXWaitX(void) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->WaitX)(); -} - - - -/*** GLX_VERSION_1_1 ***/ - -const char PUBLIC * -glXGetClientString(Display *dpy, int name) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->GetClientString)(dpy, name); -} - - -const char PUBLIC * -glXQueryExtensionsString(Display *dpy, int screen) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->QueryExtensionsString)(dpy, screen); -} - - -const char PUBLIC * -glXQueryServerString(Display *dpy, int screen, int name) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->QueryServerString)(dpy, screen, name); -} - - -/*** GLX_VERSION_1_2 ***/ - -Display PUBLIC * -glXGetCurrentDisplay(void) -{ - /* Same code as in libGL's glxext.c */ - __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); - if (NULL == gc) return NULL; - return gc->currentDpy; -} - - - -/*** GLX_VERSION_1_3 ***/ - -GLXFBConfig PUBLIC * -glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ChooseFBConfig)(dpy, screen, attribList, nitems); -} - - -GLXContext PUBLIC -glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateNewContext)(dpy, config, renderType, shareList, direct); -} - - -GLXPbuffer PUBLIC -glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreatePbuffer)(dpy, config, attribList); -} - - -GLXPixmap PUBLIC -glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreatePixmap)(dpy, config, pixmap, attribList); -} - - -GLXWindow PUBLIC -glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateWindow)(dpy, config, win, attribList); -} - - -void PUBLIC -glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyPbuffer)(dpy, pbuf); -} - - -void PUBLIC -glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyPixmap)(dpy, pixmap); -} - - -void PUBLIC -glXDestroyWindow(Display *dpy, GLXWindow window) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyWindow)(dpy, window); -} - - -GLXDrawable PUBLIC -glXGetCurrentReadDrawable(void) -{ - __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); - return gc ? gc->currentReadable : 0; -} - - -int PUBLIC -glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return GLX_NO_EXTENSION; - return (t->GetFBConfigAttrib)(dpy, config, attribute, value); -} - - -GLXFBConfig PUBLIC * -glXGetFBConfigs(Display *dpy, int screen, int *nelements) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->GetFBConfigs)(dpy, screen, nelements); -} - -void PUBLIC -glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->GetSelectedEvent)(dpy, drawable, mask); -} - - -XVisualInfo PUBLIC * -glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->GetVisualFromFBConfig)(dpy, config); -} - - -Bool PUBLIC -glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) -{ - Bool b; - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - b = (t->MakeContextCurrent)(dpy, draw, read, ctx); - if (b) { - SetCurrentContext(ctx); - } - return b; -} - - -int PUBLIC -glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - assert(t); - if (!t) - return 0; /* XXX correct? */ - return (t->QueryContext)(dpy, ctx, attribute, value); -} - - -void PUBLIC -glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->QueryDrawable)(dpy, draw, attribute, value); -} - - -void PUBLIC -glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->SelectEvent)(dpy, drawable, mask); -} - - - -/*** GLX_SGI_swap_control ***/ - -int PUBLIC -glXSwapIntervalSGI(int interval) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->SwapIntervalSGI)(interval); -} - - - -/*** GLX_SGI_video_sync ***/ - -int PUBLIC -glXGetVideoSyncSGI(unsigned int *count) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t || !glXGetCurrentContext()) - return GLX_BAD_CONTEXT; - return (t->GetVideoSyncSGI)(count); -} - -int PUBLIC -glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t || !glXGetCurrentContext()) - return GLX_BAD_CONTEXT; - return (t->WaitVideoSyncSGI)(divisor, remainder, count); -} - - - -/*** GLX_SGI_make_current_read ***/ - -Bool PUBLIC -glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx); -} - -GLXDrawable PUBLIC -glXGetCurrentReadDrawableSGI(void) -{ - return glXGetCurrentReadDrawable(); -} - - -#if defined(_VL_H) - -GLXVideoSourceSGIX PUBLIC -glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode); -} - -void PUBLIC -glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->DestroyGLXVideoSourceSGIX)(dpy, src); -} - -#endif - - -/*** GLX_EXT_import_context ***/ - -void PUBLIC -glXFreeContextEXT(Display *dpy, GLXContext context) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->FreeContextEXT)(dpy, context); -} - -GLXContextID PUBLIC -glXGetContextIDEXT(const GLXContext context) -{ - return ((__GLXcontext *) context)->xid; -} - -Display PUBLIC * -glXGetCurrentDisplayEXT(void) -{ - return glXGetCurrentDisplay(); -} - -GLXContext PUBLIC -glXImportContextEXT(Display *dpy, GLXContextID contextID) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ImportContextEXT)(dpy, contextID); -} - -int PUBLIC -glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; /* XXX ok? */ - return (t->QueryContextInfoEXT)(dpy, context, attribute, value); -} - - - -/*** GLX_SGIX_fbconfig ***/ - -int PUBLIC -glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value); -} - -GLXFBConfigSGIX PUBLIC * -glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements); -} - -GLXPixmap PUBLIC -glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap); -} - -GLXContext PUBLIC -glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct); -} - -XVisualInfo PUBLIC * -glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->GetVisualFromFBConfigSGIX)(dpy, config); -} - -GLXFBConfigSGIX PUBLIC -glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->GetFBConfigFromVisualSGIX)(dpy, vis); -} - - - -/*** GLX_SGIX_pbuffer ***/ - -GLXPbufferSGIX PUBLIC -glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list); -} - -void PUBLIC -glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyGLXPbufferSGIX)(dpy, pbuf); -} - -int PUBLIC -glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value); -} - -void PUBLIC -glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->SelectEventSGIX)(dpy, drawable, mask); -} - -void PUBLIC -glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->GetSelectedEventSGIX)(dpy, drawable, mask); -} - - - -/*** GLX_SGI_cushion ***/ - -void PUBLIC -glXCushionSGI(Display *dpy, Window win, float cushion) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->CushionSGI)(dpy, win, cushion); -} - - - -/*** GLX_SGIX_video_resize ***/ - -int PUBLIC -glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window); -} - -int PUBLIC -glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h); -} - -int PUBLIC -glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h); -} - -int PUBLIC -glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh); -} - -int PUBLIC -glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype); -} - - - -#if defined(_DM_BUFFER_H_) - -Bool PUBLIC -glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer); -} - -#endif - - -/*** GLX_SGIX_swap_group ***/ - -void PUBLIC -glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (*t->JoinSwapGroupSGIX)(dpy, drawable, member); -} - - -/*** GLX_SGIX_swap_barrier ***/ - -void PUBLIC -glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier); -} - -Bool PUBLIC -glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max); -} - - - -/*** GLX_SUN_get_transparent_index ***/ - -Status PUBLIC -glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent); -} - - - -/*** GLX_MESA_copy_sub_buffer ***/ - -void PUBLIC -glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height); -} - - - -/*** GLX_MESA_release_buffers ***/ - -Bool PUBLIC -glXReleaseBuffersMESA(Display *dpy, Window w) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->ReleaseBuffersMESA)(dpy, w); -} - - - -/*** GLX_MESA_pixmap_colormap ***/ - -GLXPixmap PUBLIC -glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap); -} - -/*** GLX_EXT_texture_from_pixmap */ - -void -glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, - const int *attrib_list) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (t) - t->BindTexImageEXT(dpy, drawable, buffer, attrib_list); -} - -void -glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (t) - t->ReleaseTexImageEXT(dpy, drawable, buffer); -} - - -/**********************************************************************/ -/* GLX API management functions */ -/**********************************************************************/ - - -const char * -_glxapi_get_version(void) -{ - return "1.3"; -} - - - -/* - * Return size of the GLX dispatch table, in entries, not bytes. - */ -GLuint -_glxapi_get_dispatch_table_size(void) -{ - return sizeof(struct _glxapi_table) / sizeof(void *); -} - - -static int -generic_no_op_func(void) -{ - return 0; -} - - -/* - * Initialize all functions in given dispatch table to be no-ops - */ -void -_glxapi_set_no_op_table(struct _glxapi_table *t) -{ - typedef int (*nop_func)(void); - nop_func *dispatch = (nop_func *) t; - GLuint n = _glxapi_get_dispatch_table_size(); - GLuint i; - for (i = 0; i < n; i++) { - dispatch[i] = generic_no_op_func; - } -} - - -struct name_address_pair { - const char *Name; - __GLXextFuncPtr Address; -}; - -static struct name_address_pair GLX_functions[] = { - /*** GLX_VERSION_1_0 ***/ - { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual }, - { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext }, - { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext }, - { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap }, - { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext }, - { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap }, - { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig }, - { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext }, - { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable }, - { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect }, - { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent }, - { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension }, - { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion }, - { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers }, - { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont }, - { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL }, - { "glXWaitX", (__GLXextFuncPtr) glXWaitX }, - - /*** GLX_VERSION_1_1 ***/ - { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString }, - { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString }, - { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString }, - - /*** GLX_VERSION_1_2 ***/ - { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay }, - - /*** GLX_VERSION_1_3 ***/ - { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig }, - { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext }, - { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer }, - { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap }, - { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow }, - { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer }, - { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap }, - { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow }, - { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable }, - { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib }, - { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs }, - { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent }, - { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig }, - { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent }, - { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext }, - { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable }, - { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent }, - - /*** GLX_VERSION_1_4 ***/ - { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress }, - - /*** GLX_SGI_swap_control ***/ - { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI }, - - /*** GLX_SGI_video_sync ***/ - { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI }, - { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI }, - - /*** GLX_SGI_make_current_read ***/ - { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI }, - { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI }, - - /*** GLX_SGIX_video_source ***/ -#if defined(_VL_H) - { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX }, - { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX }, -#endif - - /*** GLX_EXT_import_context ***/ - { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT }, - { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT }, - { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT }, - { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT }, - { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT }, - - /*** GLX_SGIX_fbconfig ***/ - { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX }, - { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX }, - { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX }, - { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX }, - { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX }, - { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX }, - - /*** GLX_SGIX_pbuffer ***/ - { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX }, - { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX }, - { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX }, - { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX }, - { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX }, - - /*** GLX_SGI_cushion ***/ - { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI }, - - /*** GLX_SGIX_video_resize ***/ - { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX }, - { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX }, - { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX }, - { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX }, - { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX }, - - /*** GLX_SGIX_dmbuffer **/ -#if defined(_DM_BUFFER_H_) - { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX }, -#endif - - /*** GLX_SGIX_swap_group ***/ - { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX }, - - /*** GLX_SGIX_swap_barrier ***/ - { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX }, - { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX }, - - /*** GLX_SUN_get_transparent_index ***/ - { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN }, - - /*** GLX_MESA_copy_sub_buffer ***/ - { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA }, - - /*** GLX_MESA_pixmap_colormap ***/ - { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA }, - - /*** GLX_MESA_release_buffers ***/ - { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA }, - - /*** GLX_ARB_get_proc_address ***/ - { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB }, - - /*** GLX_EXT_texture_from_pixmap ***/ - { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT }, - { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT }, - - { NULL, NULL } /* end of list */ -}; - - - -/* - * Return address of named glX function, or NULL if not found. - */ -__GLXextFuncPtr -_glxapi_get_proc_address(const char *funcName) -{ - GLuint i; - for (i = 0; GLX_functions[i].Name; i++) { - if (strcmp(GLX_functions[i].Name, funcName) == 0) - return GLX_functions[i].Address; - } - return NULL; -} - - - -/* - * This function does not get dispatched through the dispatch table - * since it's really a "meta" function. - */ -__GLXextFuncPtr -glXGetProcAddressARB(const GLubyte *procName) -{ - __GLXextFuncPtr f; - - f = _glxapi_get_proc_address((const char *) procName); - if (f) { - return f; - } - - f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName); - return f; -} - - -/* GLX 1.4 */ -void (*glXGetProcAddress(const GLubyte *procName))() -{ - return glXGetProcAddressARB(procName); -} diff --git a/src/gallium/state_trackers/glx/xlib/glxapi.h b/src/gallium/state_trackers/glx/xlib/glxapi.h deleted file mode 100644 index b4e12b4162..0000000000 --- a/src/gallium/state_trackers/glx/xlib/glxapi.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2004 Brian Paul 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, 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 - * BRIAN PAUL 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 _glxapi_h_ -#define _glxapi_h_ - - -#define GLX_GLXEXT_PROTOTYPES -#include "GL/glx.h" - - -/* The GLX API dispatcher (i.e. this code) is being built into stand-alone - * Mesa. We don't know anything about XFree86 or real GLX so we define a - * minimal __GLXContextRec here so some of the functions in this file can - * work properly. - */ -typedef struct __GLXcontextRec { - Display *currentDpy; - GLboolean isDirect; - GLXDrawable currentDrawable; - GLXDrawable currentReadable; - XID xid; -} __GLXcontext; - - -/* - * Almost all the GLX API functions get routed through this dispatch table. - * The exceptions are the glXGetCurrentXXX() functions. - * - * This dispatch table allows multiple GLX client-side modules to coexist. - * Specifically, a real GLX library (like SGI's or the Utah GLX) and Mesa's - * pseudo-GLX can be present at the same time. The former being used on - * GLX-enabled X servers and the later on non-GLX X servers. - * - * Red Hat has been using this since Red Hat Linux 7.0 (I think). - * This'll be a standard feature in XFree86 4.3. It basically allows one - * libGL to do both DRI-rendering and "fake GLX" rendering to X displays - * that lack the GLX extension. - */ -struct _glxapi_table { - /*** GLX_VERSION_1_0 ***/ - XVisualInfo *(*ChooseVisual)(Display *dpy, int screen, int *list); - void (*CopyContext)(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask); - GLXContext (*CreateContext)(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct); - GLXPixmap (*CreateGLXPixmap)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap); - void (*DestroyContext)(Display *dpy, GLXContext ctx); - void (*DestroyGLXPixmap)(Display *dpy, GLXPixmap pixmap); - int (*GetConfig)(Display *dpy, XVisualInfo *visinfo, int attrib, int *value); - /*GLXContext (*GetCurrentContext)(void);*/ - /*GLXDrawable (*GetCurrentDrawable)(void);*/ - Bool (*IsDirect)(Display *dpy, GLXContext ctx); - Bool (*MakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx); - Bool (*QueryExtension)(Display *dpy, int *errorb, int *event); - Bool (*QueryVersion)(Display *dpy, int *maj, int *min); - void (*SwapBuffers)(Display *dpy, GLXDrawable drawable); - void (*UseXFont)(Font font, int first, int count, int listBase); - void (*WaitGL)(void); - void (*WaitX)(void); - - /*** GLX_VERSION_1_1 ***/ - const char *(*GetClientString)(Display *dpy, int name); - const char *(*QueryExtensionsString)(Display *dpy, int screen); - const char *(*QueryServerString)(Display *dpy, int screen, int name); - - /*** GLX_VERSION_1_2 ***/ - /*Display *(*GetCurrentDisplay)(void);*/ - - /*** GLX_VERSION_1_3 ***/ - GLXFBConfig *(*ChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems); - GLXContext (*CreateNewContext)(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct); - GLXPbuffer (*CreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attribList); - GLXPixmap (*CreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList); - GLXWindow (*CreateWindow)(Display *dpy, GLXFBConfig config, Window win, const int *attribList); - void (*DestroyPbuffer)(Display *dpy, GLXPbuffer pbuf); - void (*DestroyPixmap)(Display *dpy, GLXPixmap pixmap); - void (*DestroyWindow)(Display *dpy, GLXWindow window); - /*GLXDrawable (*GetCurrentReadDrawable)(void);*/ - int (*GetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value); - GLXFBConfig *(*GetFBConfigs)(Display *dpy, int screen, int *nelements); - void (*GetSelectedEvent)(Display *dpy, GLXDrawable drawable, unsigned long *mask); - XVisualInfo *(*GetVisualFromFBConfig)(Display *dpy, GLXFBConfig config); - Bool (*MakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); - int (*QueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value); - void (*QueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); - void (*SelectEvent)(Display *dpy, GLXDrawable drawable, unsigned long mask); - - /*** GLX_SGI_swap_control ***/ - int (*SwapIntervalSGI)(int); - - /*** GLX_SGI_video_sync ***/ - int (*GetVideoSyncSGI)(unsigned int *count); - int (*WaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count); - - /*** GLX_SGI_make_current_read ***/ - Bool (*MakeCurrentReadSGI)(Display *, GLXDrawable, GLXDrawable, GLXContext); - /*GLXDrawable (*GetCurrentReadDrawableSGI)(void);*/ - - /*** GLX_SGIX_video_source (needs video library) ***/ -#if defined(_VL_H_) - GLXVideoSourceSGIX (*CreateGLXVideoSourceSGIX)(Display *, int, VLServer, VLPath, int, VLNode); - void (*DestroyGLXVideoSourceSGIX)(Display *, GLXVideoSourceSGIX); -#else - void *CreateGLXVideoSourceSGIX; - void *DestroyGLXVideoSourceSGIX; -#endif - - /*** GLX_EXT_import_context ***/ - void (*FreeContextEXT)(Display *dpy, GLXContext context); - GLXContextID (*GetContextIDEXT)(const GLXContext context); - /*Display *(*GetCurrentDisplayEXT)(void);*/ - GLXContext (*ImportContextEXT)(Display *dpy, GLXContextID contextID); - int (*QueryContextInfoEXT)(Display *dpy, GLXContext context, int attribute,int *value); - - /*** GLX_SGIX_fbconfig ***/ - int (*GetFBConfigAttribSGIX)(Display *, GLXFBConfigSGIX, int, int *); - GLXFBConfigSGIX * (*ChooseFBConfigSGIX)(Display *, int, int *, int *); - GLXPixmap (*CreateGLXPixmapWithConfigSGIX)(Display *, GLXFBConfigSGIX, Pixmap); - GLXContext (*CreateContextWithConfigSGIX)(Display *, GLXFBConfigSGIX, int, GLXContext, Bool); - XVisualInfo * (*GetVisualFromFBConfigSGIX)(Display *, GLXFBConfigSGIX); - GLXFBConfigSGIX (*GetFBConfigFromVisualSGIX)(Display *, XVisualInfo *); - - /*** GLX_SGIX_pbuffer ***/ - GLXPbufferSGIX (*CreateGLXPbufferSGIX)(Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); - void (*DestroyGLXPbufferSGIX)(Display *, GLXPbufferSGIX); - int (*QueryGLXPbufferSGIX)(Display *, GLXPbufferSGIX, int, unsigned int *); - void (*SelectEventSGIX)(Display *, GLXDrawable, unsigned long); - void (*GetSelectedEventSGIX)(Display *, GLXDrawable, unsigned long *); - - /*** GLX_SGI_cushion ***/ - void (*CushionSGI)(Display *, Window, float); - - /*** GLX_SGIX_video_resize ***/ - int (*BindChannelToWindowSGIX)(Display *, int, int, Window); - int (*ChannelRectSGIX)(Display *, int, int, int, int, int, int); - int (*QueryChannelRectSGIX)(Display *, int, int, int *, int *, int *, int *); - int (*QueryChannelDeltasSGIX)(Display *, int, int, int *, int *, int *, int *); - int (*ChannelRectSyncSGIX)(Display *, int, int, GLenum); - - /*** GLX_SGIX_dmbuffer (needs dmedia library) ***/ -#if defined (_DM_BUFFER_H_) - Bool (*AssociateDMPbufferSGIX)(Display *, GLXPbufferSGIX, DMparams *, DMbuffer); -#else - void *AssociciateDMPbufferSGIX; -#endif - - /*** GLX_SGIX_swap_group ***/ - void (*JoinSwapGroupSGIX)(Display *, GLXDrawable, GLXDrawable); - - /*** GLX_SGIX_swap_barrier ***/ - void (*BindSwapBarrierSGIX)(Display *, GLXDrawable, int); - Bool (*QueryMaxSwapBarriersSGIX)(Display *, int, int *); - - /*** GLX_SUN_get_transparent_index ***/ - Status (*GetTransparentIndexSUN)(Display *, Window, Window, long *); - - /*** GLX_MESA_copy_sub_buffer ***/ - void (*CopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); - - /*** GLX_MESA_release_buffers ***/ - Bool (*ReleaseBuffersMESA)(Display *dpy, Window w); - - /*** GLX_MESA_pixmap_colormap ***/ - GLXPixmap (*CreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap); - - /*** GLX_EXT_texture_from_pixmap ***/ - void (*BindTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer, - const int *attrib_list); - void (*ReleaseTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer); -}; - - - -extern const char * -_glxapi_get_version(void); - - - - -extern GLuint -_glxapi_get_dispatch_table_size(void); - - -extern void -_glxapi_set_no_op_table(struct _glxapi_table *t); - - -extern __GLXextFuncPtr -_glxapi_get_proc_address(const char *funcName); - - -#endif diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h index bdd434cd36..ce97a3ec76 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.h +++ b/src/gallium/state_trackers/glx/xlib/xm_api.h @@ -57,7 +57,7 @@ and create a window, you must do the following to use the X/Mesa interface: #define XMESA_H -#include "mtypes.h" +#include "main/mtypes.h" #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" #include "pipe/p_thread.h" diff --git a/src/gallium/state_trackers/vega/asm_filters.h b/src/gallium/state_trackers/vega/asm_filters.h index 49807b9ab4..9a49f2e12d 100644 --- a/src/gallium/state_trackers/vega/asm_filters.h +++ b/src/gallium/state_trackers/vega/asm_filters.h @@ -60,7 +60,7 @@ static const char convolution_asm[] = "DCL SAMP[0], CONSTANT\n" "0: MOV TEMP[0], CONST[0].xxxx\n" "1: MOV TEMP[1], CONST[0].xxxx\n" - "2: BGNLOOP2 :14\n" + "2: BGNLOOP :14\n" "3: SGE TEMP[0].z, TEMP[0].yyyy, CONST[1].xxxx\n" "4: IF TEMP[0].zzzz :7\n" "5: BRK\n" @@ -72,7 +72,7 @@ static const char convolution_asm[] = "11: MOV TEMP[3], CONST[ADDR[0]+%d]\n" "12: MAD TEMP[1], TEMP[2], TEMP[3], TEMP[1]\n" "13: ADD TEMP[0].y, TEMP[0].yyyy, CONST[0].yyyy\n" - "14: ENDLOOP2 :2\n" + "14: ENDLOOP :2\n" "15: MAD OUT[0], TEMP[1], CONST[1].yyyy, CONST[1].zzzz\n" "16: END\n"; diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c index c262ce08fa..56cc60aebe 100644 --- a/src/gallium/state_trackers/vega/vg_tracker.c +++ b/src/gallium/state_trackers/vega/vg_tracker.c @@ -367,6 +367,11 @@ void st_make_current(struct vg_context *st, } } +struct vg_context *st_get_current(void) +{ + return vg_current_context(); +} + void st_flush(struct vg_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence) { @@ -399,8 +404,13 @@ void st_notify_swapbuffers_complete(struct st_framebuffer *stfb) { } -int -st_set_teximage(struct pipe_texture *pt, int target) +int st_bind_texture_surface(struct pipe_surface *ps, int target, int level, + enum pipe_format format) +{ + return 0; +} + +int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level) { return 0; } diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h index 805c58ccc7..5457631106 100644 --- a/src/gallium/state_trackers/vega/vg_tracker.h +++ b/src/gallium/state_trackers/vega/vg_tracker.h @@ -70,7 +70,10 @@ void st_set_framebuffer_surface(struct st_framebuffer *stfb, void st_get_framebuffer_dimensions( struct st_framebuffer *stfb, uint *width, uint *height); -int st_set_teximage(struct pipe_texture *pt, int target); +int st_bind_texture_surface(struct pipe_surface *ps, int target, int level, + enum pipe_format format); + +int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level); int st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surf); @@ -86,6 +89,8 @@ void st_make_current(struct vg_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); +struct vg_context *st_get_current(void); + void st_flush(struct vg_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence); void st_finish(struct vg_context *st); diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index ae3338ffef..3fbab4dc51 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -39,10 +39,13 @@ #include "pipe/p_state.h" #include "pipe/p_inlines.h" +#include "util/u_rect.h" + typedef struct { PixmapPtr pPixmap; struct pipe_texture *tex; struct pipe_buffer *buf; + struct pipe_fence_handle *fence; } *BufferPrivatePtr; static DRI2BufferPtr @@ -83,7 +86,6 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) pipe_texture_reference(&tex, depth); } else if (attachments[i] == DRI2BufferDepth) { struct pipe_texture template; - memset(&template, 0, sizeof(template)); template.target = PIPE_TEXTURE_2D; template.format = PIPE_FORMAT_S8Z24_UNORM; @@ -92,22 +94,20 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) template.height[0] = pDraw->height; template.depth[0] = 1; template.last_level = 0; - template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; tex = ms->screen->texture_create(ms->screen, &template); + depth = tex; } else { - struct pipe_texture template; - memset(&template, 0, sizeof(template)); - template.target = PIPE_TEXTURE_2D; - template.format = PIPE_FORMAT_A8R8G8B8_UNORM; - pf_get_block(template.format, &template.block); - template.width[0] = pDraw->width; - template.height[0] = pDraw->height; - template.depth[0] = 1; - template.last_level = 0; - template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; - tex = ms->screen->texture_create(ms->screen, &template); + pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width, + pDraw->height, + pDraw->depth, + 0); + tex = xorg_exa_get_texture(pPixmap); } + if (!tex) + FatalError("NO TEXTURE IN DRI2\n"); + ms->api->buffer_from_texture(ms->api, tex, &buf, &stride); ms->api->global_handle_from_buffer(ms->api, ms->screen, buf, &handle); @@ -138,15 +138,17 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) modesettingPtr ms = modesettingPTR(pScrn); BufferPrivatePtr private; int i; + (void)ms; for (i = 0; i < count; i++) { private = buffers[i].driverPrivate; - if (private->pPixmap) - (*pScreen->DestroyPixmap)(private->pPixmap); - pipe_texture_reference(&private->tex, NULL); pipe_buffer_reference(&private->buf, NULL); + ms->screen->fence_reference(ms->screen, &private->fence, NULL); + + if (private->pPixmap) + (*pScreen->DestroyPixmap)(private->pPixmap); } if (buffers) { @@ -164,19 +166,42 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, modesettingPtr ms = modesettingPTR(pScrn); BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate; BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate; + PixmapPtr src_pixmap; + PixmapPtr dst_pixmap; + GCPtr gc; + RegionPtr copy_clip; + + src_pixmap = src_priv->pPixmap; + dst_pixmap = dst_priv->pPixmap; + if (pSrcBuffer->attachment == DRI2BufferFrontLeft) + src_pixmap = (PixmapPtr)pDraw; + if (pDestBuffer->attachment == DRI2BufferFrontLeft) + dst_pixmap = (PixmapPtr)pDraw; + gc = GetScratchGC(pDraw->depth, pScreen); + copy_clip = REGION_CREATE(pScreen, NULL, 0); + REGION_COPY(pScreen, copy_clip, pRegion); + (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0); + ValidateGC(&dst_pixmap->drawable, gc); + + /* If this is a full buffer swap, throttle on the previous one */ + if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) { + BoxPtr extents = REGION_EXTENTS(pScreen, pRegion); + + if (extents->x1 == 0 && extents->y1 == 0 && + extents->x2 == pDraw->width && extents->y2 == pDraw->height) { + ms->screen->fence_finish(ms->screen, dst_priv->fence, 0); + ms->screen->fence_reference(ms->screen, &dst_priv->fence, NULL); + } + } - struct pipe_surface *dst_surf = - ms->screen->get_tex_surface(ms->screen, dst_priv->tex, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - struct pipe_surface *src_surf = - ms->screen->get_tex_surface(ms->screen, src_priv->tex, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_READ); + (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc, + 0, 0, pDraw->width, pDraw->height, 0, 0); - ms->ctx->surface_copy(ms->ctx, dst_surf, 0, 0, src_surf, - 0, 0, pDraw->width, pDraw->height); + FreeScratchGC(gc); - pipe_surface_reference(&dst_surf, NULL); - pipe_surface_reference(&src_surf, NULL); + ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, + pDestBuffer->attachment == DRI2BufferFrontLeft ? + &dst_priv->fence : NULL); } Bool diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index e01e5294b1..53d1a33095 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -179,8 +179,10 @@ CreateFrontBuffer(ScrnInfoPtr pScrn) modesettingPtr ms = modesettingPTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + unsigned handle, stride; ms->noEvict = TRUE; + xorg_exa_set_displayed_usage(rootPixmap); pScreen->ModifyPixmapHeader(rootPixmap, pScrn->virtualX, pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel, @@ -188,13 +190,16 @@ CreateFrontBuffer(ScrnInfoPtr pScrn) NULL); ms->noEvict = FALSE; + handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride); + drmModeAddFB(ms->fd, pScrn->virtualX, pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel, - pScrn->displayWidth * pScrn->bitsPerPixel / 8, - xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id); + stride, + handle, + &ms->fb_id); pScrn->frameX0 = 0; pScrn->frameY0 = 0; @@ -426,6 +431,7 @@ CreateScreenResources(ScreenPtr pScreen) modesettingPtr ms = modesettingPTR(pScrn); PixmapPtr rootPixmap; Bool ret; + unsigned handle, stride; ms->noEvict = TRUE; @@ -435,18 +441,22 @@ CreateScreenResources(ScreenPtr pScreen) rootPixmap = pScreen->GetScreenPixmap(pScreen); + xorg_exa_set_displayed_usage(rootPixmap); if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) FatalError("Couldn't adjust screen pixmap\n"); ms->noEvict = FALSE; + handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride); + drmModeAddFB(ms->fd, pScrn->virtualX, pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel, - pScrn->displayWidth * pScrn->bitsPerPixel / 8, - xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id); + stride, + handle, + &ms->fb_id); AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); @@ -623,6 +633,10 @@ LeaveVT(int scrnIndex, int flags) RestoreHWState(pScrn); + if (drmDropMaster(ms->fd)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "drmDropMaster failed: %s\n", strerror(errno)); + pScrn->vtSema = FALSE; } @@ -635,6 +649,17 @@ EnterVT(int scrnIndex, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); + if (drmSetMaster(ms->fd)) { + if (errno == EINVAL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "drmSetMaster failed: 2.6.29 or newer kernel required for " + "multi-server DRI\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "drmSetMaster failed: %s\n", strerror(errno)); + } + } + /* * Only save state once per server generation since that's what most * drivers do. Could change this to save state at each VT enter. diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 2c4291aa4e..f2dac73e90 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -359,8 +359,48 @@ ExaPixmapIsOffscreen(PixmapPtr pPixmap) return FALSE; } +int +xorg_exa_set_displayed_usage(PixmapPtr pPixmap) +{ + struct exa_pixmap_priv *priv; + priv = exaGetPixmapDriverPrivate(pPixmap); + + if (!priv) { + FatalError("NO PIXMAP PRIVATE\n"); + return 0; + } + + if (priv->flags & ~PIPE_TEXTURE_USAGE_PRIMARY) { + FatalError("BAD FLAGS\n"); + return 0; + } + priv->flags = PIPE_TEXTURE_USAGE_PRIMARY; + + return 0; +} + +int +xorg_exa_set_shared_usage(PixmapPtr pPixmap) +{ + struct exa_pixmap_priv *priv; + priv = exaGetPixmapDriverPrivate(pPixmap); + + if (!priv) { + FatalError("NO PIXMAP PRIVATE\n"); + return 0; + } + + if (priv->flags & ~PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + FatalError("BAD FLAGS\n"); + return 0; + } + priv->flags = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + + return 0; +} + unsigned -xorg_exa_get_pixmap_handle(PixmapPtr pPixmap) +xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -385,6 +425,9 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap) ms->api->buffer_from_texture(ms->api, priv->tex, &buffer, &stride); ms->api->handle_from_buffer(ms->api, ms->screen, buffer, &handle); pipe_buffer_reference(&buffer, NULL); + if (stride_out) + *stride_out = stride; + return handle; } @@ -421,7 +464,9 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, bitsPerPixel, devKind, NULL); /* Deal with screen resize */ - if (priv->tex && (priv->tex->width[0] != width || priv->tex->height[0] != height)) { + if (priv->tex && (priv->tex->width[0] != width || + priv->tex->height[0] != height || + priv->tex_flags != priv->flags)) { pipe_texture_reference(&priv->tex, NULL); } @@ -436,7 +481,8 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, template.height[0] = height; template.depth[0] = 1; template.last_level = 0; - template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; + priv->tex_flags = priv->flags; priv->tex = exa->scrn->texture_create(exa->scrn, &template); } diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h index 650997aec6..f0508eb2d5 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.h +++ b/src/gallium/state_trackers/xorg/xorg_exa.h @@ -14,6 +14,8 @@ struct exa_context struct exa_pixmap_priv { int flags; + int tex_flags; + struct pipe_texture *tex; unsigned int color; struct pipe_surface *src_surf; /* for copies */ diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h index b4742bdbf5..910782dbc4 100644 --- a/src/gallium/state_trackers/xorg/xorg_tracker.h +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -31,6 +31,7 @@ #ifndef _XORG_TRACKER_H_ #define _XORG_TRACKER_H_ +#include <stddef.h> #include <stdint.h> #include <errno.h> #include <drm.h> @@ -98,7 +99,13 @@ struct pipe_texture * xorg_exa_get_texture(PixmapPtr pPixmap); unsigned -xorg_exa_get_pixmap_handle(PixmapPtr pPixmap); +xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride); + +int +xorg_exa_set_displayed_usage(PixmapPtr pPixmap); + +int +xorg_exa_set_shared_usage(PixmapPtr pPixmap); void * xorg_exa_init(ScrnInfoPtr pScrn); diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template index 985e5a861f..9635c3c50e 100644 --- a/src/gallium/winsys/drm/Makefile.template +++ b/src/gallium/winsys/drm/Makefile.template @@ -83,7 +83,9 @@ default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME) $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template $(MKLIB) -noprefix -o $@ \ - $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) + $(OBJECTS) $(PIPE_DRIVERS) \ + -Wl,--start-group $(MESA_MODULES) -Wl,--end-group \ + $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) $(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) $(MKLIB) -o $(LIBNAME_EGL) \ diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript index e14e96e32f..6c00861f51 100644 --- a/src/gallium/winsys/drm/intel/dri/SConscript +++ b/src/gallium/winsys/drm/intel/dri/SConscript @@ -2,11 +2,14 @@ Import('*') env = drienv.Clone() +env.ParseConfig('pkg-config --cflags --libs libdrm_intel') + drivers = [ + st_dri, + inteldrm, softpipe, i915simple, trace, - inteldrm ] env.SharedLibrary( diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile index c5217ad2d6..490baded66 100644 --- a/src/gallium/winsys/drm/intel/egl/Makefile +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -8,6 +8,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ $(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/i915simple/libi915simple.a DRIVER_SOURCES = diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index d5e63c3bae..c4a79586e6 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -21,12 +21,10 @@ intel_be_batchbuffer_alloc(struct intel_be_context *intel) batch->base.size = 0; batch->base.actual_size = intel->device->max_batch_size; batch->base.relocs = 0; - batch->base.max_relocs = 500;/*INTEL_DEFAULT_RELOCS;*/ + batch->base.max_relocs = 100;/*INTEL_DEFAULT_RELOCS;*/ - batch->base.map = malloc(batch->base.actual_size); - memset(batch->base.map, 0, batch->base.actual_size); - - batch->base.ptr = batch->base.map; + batch->intel = intel; + batch->device = intel->device; intel_be_batchbuffer_reset(batch); @@ -41,16 +39,17 @@ intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch) if (batch->bo) drm_intel_bo_unreference(batch->bo); + batch->bo = drm_intel_bo_alloc(dev->pools.gem, + "gallium3d_batch_buffer", + batch->base.actual_size, + 4096); + drm_intel_bo_map(batch->bo, TRUE); + batch->base.map = batch->bo->virtual; memset(batch->base.map, 0, batch->base.actual_size); batch->base.ptr = batch->base.map; batch->base.size = batch->base.actual_size - BATCH_RESERVED; - batch->base.relocs = 0; - - batch->bo = drm_intel_bo_alloc(dev->pools.gem, - "gallium3d_batch_buffer", - batch->base.actual_size, 0); } int @@ -88,6 +87,7 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch, struct i915_batchbuffer *i915 = &batch->base; unsigned used = 0; int ret = 0; + int i; assert(i915_batchbuffer_space(i915) >= 0); @@ -105,11 +105,29 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch, used = batch->base.ptr - batch->base.map; - drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map); - ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0); + drm_intel_bo_unmap(batch->bo); + /* Do the sending to HW */ + ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0); assert(ret == 0); + if (batch->device->dump_cmd) { + unsigned *ptr; + drm_intel_bo_map(batch->bo, FALSE); + ptr = (unsigned*)batch->bo->virtual; + + debug_printf("%s:\n", __func__); + for (i = 0; i < used / 4; i++, ptr++) { + debug_printf("\t%08x: %08x\n", i*4, *ptr); + } + + drm_intel_bo_unmap(batch->bo); + } else { + /* TODO figgure out why the gpu hangs if we don't run sync */ + drm_intel_bo_map(batch->bo, FALSE); + drm_intel_bo_unmap(batch->bo); + } + intel_be_batchbuffer_reset(batch); if (fence) { @@ -134,6 +152,5 @@ intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch) if (batch->bo) drm_intel_bo_unreference(batch->bo); - free(batch->base.map); free(batch); } diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c index db84f9af51..629987c6f9 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c @@ -36,7 +36,7 @@ intel_be_batch_reloc(struct i915_winsys *sws, } if (access_flags & I915_BUFFER_ACCESS_READ) { - read |= I915_GEM_DOMAIN_VERTEX; + read |= I915_GEM_DOMAIN_SAMPLER; } ret = intel_be_offset_relocation(intel->batch, diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c index e3630f5d12..5312865a03 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c @@ -7,6 +7,7 @@ #include "pipe/p_inlines.h" #include "util/u_memory.h" #include "util/u_debug.h" +#include "util/u_math.h" #include "intel_be_fence.h" @@ -16,6 +17,8 @@ #include "intel_be_api.h" #include <stdio.h> +#define I915_TILING_X 1 + /* * Buffer */ @@ -25,9 +28,10 @@ intel_be_buffer_map(struct pipe_winsys *winsys, struct pipe_buffer *buf, unsigned flags) { + struct intel_be_buffer *buffer = intel_be_buffer(buf); drm_intel_bo *bo = intel_bo(buf); int write = 0; - int ret; + int ret = 0; if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { /* Remove this when drm_intel_bo_map supports DONTBLOCK @@ -38,19 +42,37 @@ intel_be_buffer_map(struct pipe_winsys *winsys, if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) write = 1; - ret = drm_intel_bo_map(bo, write); + if (buffer->map_count) + goto out; + + if (buffer->map_gtt) + ret = drm_intel_gem_bo_map_gtt(bo); + else + ret = drm_intel_bo_map(bo, write); + + buffer->ptr = bo->virtual; +out: if (ret) return NULL; - return bo->virtual; + buffer->map_count++; + return buffer->ptr; } static void intel_be_buffer_unmap(struct pipe_winsys *winsys, struct pipe_buffer *buf) { - drm_intel_bo_unmap(intel_bo(buf)); + struct intel_be_buffer *buffer = intel_be_buffer(buf); + + if (--buffer->map_count) + return; + + if (buffer->map_gtt) + drm_intel_gem_bo_unmap_gtt(intel_bo(buf)); + else + drm_intel_bo_unmap(intel_bo(buf)); } static void @@ -80,8 +102,13 @@ intel_be_buffer_create(struct pipe_winsys *winsys, buffer->base.size = size; buffer->flinked = FALSE; buffer->flink = 0; + buffer->map_gtt = FALSE; - if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { + if (usage & I915_BUFFER_USAGE_SCANOUT) { + /* Scanout buffer */ + name = "gallium3d_scanout"; + pool = dev->pools.gem; + } else if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { /* Local buffer */ name = "gallium3d_local"; pool = dev->pools.gem; @@ -96,6 +123,12 @@ intel_be_buffer_create(struct pipe_winsys *winsys, } buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment); + if (usage & I915_BUFFER_USAGE_SCANOUT) { + unsigned tiling = I915_TILING_X; + unsigned stride = 2048 * 4; /* TODO do something smarter here */ + drm_intel_bo_set_tiling(buffer->bo, &tiling, stride); + buffer->map_gtt = TRUE; + } if (!buffer->bo) goto err; @@ -142,6 +175,40 @@ err: return NULL; } +static struct pipe_buffer * +intel_be_surface_buffer_create(struct pipe_winsys *winsys, + unsigned width, unsigned height, + enum pipe_format format, + unsigned usage, + unsigned tex_usage, + unsigned *stride) +{ + struct pipe_format_block block; + unsigned buf_usage = 0; + unsigned buf_stride = 0; + unsigned buf_size = 0; + + pf_get_block(format, &block); + buf_stride = pf_get_stride(&block, width); + buf_stride = align(buf_stride, 64); + + if (tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) { + /* TODO more checks */ + assert(buf_stride <= 2048*4); + assert(height % 8 == 0); + buf_stride = 2048 * 4; + buf_usage |= I915_BUFFER_USAGE_SCANOUT; + } + + buf_size = buf_stride * height; + *stride = buf_stride; + + return intel_be_buffer_create(winsys, + 0, + buf_usage, + buf_size); +} + boolean intel_be_get_texture_buffer(struct drm_api *api, struct pipe_texture *texture, @@ -225,6 +292,7 @@ intel_be_global_handle_from_buffer(struct drm_api *api, *handle = buf->flink; return TRUE; } + /* * Fence */ @@ -296,8 +364,8 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) dev->base.buffer_unmap = intel_be_buffer_unmap; dev->base.buffer_destroy = intel_be_buffer_destroy; - /* Not used anymore */ - dev->base.surface_buffer_create = NULL; + /* Used by softpipe */ + dev->base.surface_buffer_create = intel_be_surface_buffer_create; dev->base.fence_reference = intel_be_fence_refunref; dev->base.fence_signalled = intel_be_fence_signalled; @@ -308,6 +376,7 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size); dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", FALSE); + dev->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE); return true; } diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h index 56d95bd7fe..c397048f8c 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h @@ -19,6 +19,7 @@ struct intel_be_device struct pipe_winsys base; boolean softpipe; + boolean dump_cmd; int fd; /**< Drm file discriptor */ @@ -47,6 +48,10 @@ intel_be_init_device(struct intel_be_device *device, int fd, unsigned id); struct intel_be_buffer { struct pipe_buffer base; + void *ptr; + unsigned map_count; + boolean map_gtt; + drm_intel_bo *bo; boolean flinked; unsigned flink; diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile index d51cca8d21..9e56853b02 100644 --- a/src/gallium/winsys/drm/intel/xorg/Makefile +++ b/src/gallium/winsys/drm/intel/xorg/Makefile @@ -19,6 +19,7 @@ LIBS = \ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \ $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(GALLIUM_AUXILIARIES) diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 684a487f24..775bda8308 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -72,6 +72,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, alignment, domain, 0); if (radeon_buffer->bo == NULL) { FREE(radeon_buffer); + return NULL; } return &radeon_buffer->base; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index 8c8b61fa10..f5153b06af 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -61,11 +61,6 @@ struct radeon_winsys_priv { /* Radeon BO manager. */ struct radeon_bo_manager* bom; - /* Radeon BO space checker. */ - struct radeon_cs_space_check sc[RADEON_MAX_BOS]; - /* Current BO count. */ - unsigned bo_count; - /* Radeon CS manager. */ struct radeon_cs_manager* csm; diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index da2010184a..8d818cf830 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -29,7 +29,6 @@ */ #include "radeon_drm.h" -#include "trace/tr_drm.h" /* Create a pipe_screen. */ struct pipe_screen* radeon_create_screen(struct drm_api* api, @@ -54,7 +53,8 @@ struct pipe_context* radeon_create_context(struct drm_api* api, if (getenv("RADEON_SOFTPIPE")) { return radeon_create_softpipe(screen->winsys); } else { - return r300_create_context(screen, screen->winsys); + return r300_create_context(screen, + (struct r300_winsys*)screen->winsys); } } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index 8560f71db6..88a5c82b28 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -30,8 +30,13 @@ #ifndef RADEON_DRM_H #define RADEON_DRM_H +#include <sys/ioctl.h> + +#include "xf86drm.h" + #include "pipe/p_screen.h" +#include "trace/tr_drm.h" #include "util/u_memory.h" #include "state_tracker/drm_api.h" @@ -40,6 +45,9 @@ #include "radeon_r300.h" #include "radeon_winsys_softpipe.h" +/* XXX */ +#include "r300_screen.h" + struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB, struct drm_create_screen_arg *arg); diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index 8c5f756ddf..4e9a2ddd16 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -27,66 +27,25 @@ static boolean radeon_r300_add_buffer(struct r300_winsys* winsys, uint32_t rd, uint32_t wd) { - int i; struct radeon_winsys_priv* priv = (struct radeon_winsys_priv*)winsys->radeon_winsys; - struct radeon_cs_space_check* sc = priv->sc; struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo; - /* Check to see if this BO is already in line for validation; - * find a slot for it otherwise. */ - for (i = 0; i < priv->bo_count; i++) { - if (sc[i].bo == bo) { - sc[i].read_domains |= rd; - sc[i].write_domain |= wd; - return TRUE; - } - } - - if (priv->bo_count >= RADEON_MAX_BOS) { - /* Dohoho. Not falling for that one again. Request a flush. */ - return FALSE; - } - - sc[priv->bo_count].bo = bo; - sc[priv->bo_count].read_domains = rd; - sc[priv->bo_count].write_domain = wd; - priv->bo_count++; - + radeon_cs_space_add_persistent_bo(priv->cs, bo, rd, wd); return TRUE; } static boolean radeon_r300_validate(struct r300_winsys* winsys) { - int retval, i; struct radeon_winsys_priv* priv = (struct radeon_winsys_priv*)winsys->radeon_winsys; - struct radeon_cs_space_check* sc = priv->sc; - - retval = radeon_cs_space_check(priv->cs, sc, priv->bo_count); - - if (retval == RADEON_CS_SPACE_OP_TO_BIG) { - /* We might as well HCF, since this is not going to fit in the card, - * period. */ - /* XXX just drop it on the floor instead */ - exit(1); - } else if (retval == RADEON_CS_SPACE_FLUSH) { - /* We must flush before more rendering can commence. */ - return TRUE; - } - /* XXX should probably be its own function */ - for (i = 0; i < priv->bo_count; i++) { - if (sc[i].read_domains && sc[i].write_domain) { - /* Cute, cute. We need to flush first. */ - debug_printf("radeon: BO %p can't be read and written; " - "requesting flush.\n", sc[i].bo); - return TRUE; - } + if (radeon_cs_space_check(priv->cs) < 0) { + return FALSE; } /* Things are fine, we can proceed as normal. */ - return FALSE; + return TRUE; } static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size) @@ -151,8 +110,7 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys) { struct radeon_winsys_priv* priv = (struct radeon_winsys_priv*)winsys->radeon_winsys; - struct radeon_cs_space_check* sc = priv->sc; - int retval = 1; + int retval; /* Emit the CS. */ retval = radeon_cs_emit(priv->cs); @@ -160,40 +118,34 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys) debug_printf("radeon: Bad CS, dumping...\n"); radeon_cs_print(priv->cs, stderr); } - radeon_cs_erase(priv->cs); /* Clean out BOs. */ - memset(sc, 0, sizeof(struct radeon_cs_space_check) * RADEON_MAX_BOS); - priv->bo_count = 0; + radeon_cs_space_reset_bos(priv->cs); + + /* Reset CS. + * Someday, when we care about performance, we should really find a way + * to rotate between two or three CS objects so that the GPU can be + * spinning through one CS while another one is being filled. */ + radeon_cs_erase(priv->cs); } /* Helper function to do the ioctls needed for setup and init. */ static void do_ioctls(struct r300_winsys* winsys, int fd) { struct drm_radeon_gem_info gem_info = {0}; - drm_radeon_getparam_t gp = {0}; struct drm_radeon_info info = {0}; int target = 0; int retval; info.value = ⌖ - gp.value = ⌖ /* First, get PCI ID */ info.request = RADEON_INFO_DEVICE_ID; retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); if (retval) { - fprintf(stderr, "%s: New ioctl for PCI ID failed " - "(error number %d), trying classic ioctl...\n", - __FUNCTION__, retval); - gp.param = RADEON_PARAM_DEVICE_ID; - retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, - sizeof(gp)); - if (retval) { - fprintf(stderr, "%s: Failed to get PCI ID, " - "error number %d\n", __FUNCTION__, retval); - exit(1); - } + fprintf(stderr, "%s: Failed to get PCI ID, " + "error number %d\n", __FUNCTION__, retval); + exit(1); } winsys->pci_id = target; diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index a2e0e58248..741c137188 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -20,6 +20,9 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifndef RADEON_R300_H +#define RADEON_R300_H + /* XXX WTF is this! I shouldn't have to include those first three! FUCK! */ #include <stdint.h> #include <stdlib.h> @@ -31,18 +34,9 @@ #include "radeon_buffer.h" -/* protect us from bonghits */ -#ifndef RADEON_INFO_DEVICE_ID -#define RADEON_INFO_DEVICE_ID 0 -#endif -#ifndef DRM_RADEON_INFO -#define DRM_RADEON_INFO 0x1 -struct drm_radeon_info { - uint32_t request; - uint32_t pad; - uint64_t value; -}; -#endif +struct radeon_winsys; struct r300_winsys* radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys); + +#endif /* RADEON_R300_H */ diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index e1ddcae97b..f409a3fd6b 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -82,6 +82,7 @@ struct xlib_egl_surface { _EGLSurface Base; /**< base class */ + /* These are set for window surface */ Display *Dpy; /**< The X Display of the window */ Window Win; /**< The user-created window ID */ GC Gc; @@ -101,7 +102,7 @@ xlib_egl_driver(_EGLDriver *drv) } -static struct xlib_egl_surface * +static INLINE struct xlib_egl_surface * lookup_surface(EGLSurface surf) { _EGLSurface *surface = _eglLookupSurface(surf); @@ -109,10 +110,10 @@ lookup_surface(EGLSurface surf) } -static struct xlib_egl_context * -lookup_context(EGLContext surf) +static INLINE struct xlib_egl_context * +lookup_context(EGLContext ctx) { - _EGLContext *context = _eglLookupContext(surf); + _EGLContext *context = _eglLookupContext(ctx); return (struct xlib_egl_context *) context; } @@ -180,7 +181,9 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy) SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE); SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis); SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis); - SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT); + SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); + SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE); + SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE); _eglAddConfig(disp, config); } @@ -264,7 +267,13 @@ static void check_and_update_buffer_size(struct xlib_egl_surface *surface) { uint width, height; - get_drawable_size(surface->Dpy, surface->Win, &width, &height); + if (surface->Base.Type == EGL_PBUFFER_BIT) { + width = surface->Base.Width; + height = surface->Base.Height; + } + else { + get_drawable_size(surface->Dpy, surface->Win, &width, &height); + } st_resize_framebuffer(surface->Framebuffer, width, height); surface->Base.Width = width; surface->Base.Height = height; @@ -281,6 +290,9 @@ display_surface(struct pipe_winsys *pws, XImage *ximage; void *data; + if (xsurf->Base.Type == EGL_PBUFFER_BIT) + return; + ximage = XCreateImage(xsurf->Dpy, xsurf->VisInfo.visual, xsurf->VisInfo.depth, @@ -382,7 +394,7 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) struct xlib_egl_context *context = lookup_context(ctx); if (context) { _eglUnlinkContext(&context->Base); - if (!context->Base.IsBound) { + if (!_eglIsContextBound(&context->Base)) { /* API-dependent clean-up */ switch (context->Base.ClientAPI) { case EGL_OPENGL_ES_API: @@ -415,10 +427,14 @@ xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, struct xlib_egl_context *context = lookup_context(ctx); struct xlib_egl_surface *draw_surf = lookup_surface(draw); struct xlib_egl_surface *read_surf = lookup_surface(read); + struct st_context *oldctx = st_get_current(); if (!_eglMakeCurrent(drv, dpy, draw, read, context)) return EGL_FALSE; + /* Flush before switching context. Check client API? */ + if (oldctx) + st_flush(oldctx, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); st_make_current((context ? context->Context : NULL), (draw_surf ? draw_surf->Framebuffer : NULL), (read_surf ? read_surf->Framebuffer : NULL)); @@ -527,14 +543,92 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, } +static EGLSurface +xlib_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) +{ + struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); + struct xlib_egl_surface *surf; + __GLcontextModes visual; + uint width, height; + EGLBoolean bind_texture; + + if (!disp) { + _eglError(EGL_BAD_DISPLAY, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + + surf = CALLOC_STRUCT(xlib_egl_surface); + if (!surf) { + _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + + if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT, + conf, attrib_list)) { + free(surf); + return EGL_NO_SURFACE; + } + if (surf->Base.Width < 0 || surf->Base.Height < 0) { + _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferSurface"); + free(surf); + return EGL_NO_SURFACE; + } + + bind_texture = (surf->Base.TextureFormat != EGL_NO_TEXTURE); + width = (uint) surf->Base.Width; + height = (uint) surf->Base.Height; + if ((surf->Base.TextureTarget == EGL_NO_TEXTURE && bind_texture) || + (surf->Base.TextureTarget != EGL_NO_TEXTURE && !bind_texture)) { + _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface"); + free(surf); + return EGL_NO_SURFACE; + } + /* a framebuffer of zero width or height confuses st */ + if (width == 0 || height == 0) { + _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface"); + free(surf); + return EGL_NO_SURFACE; + } + /* no mipmap generation */ + if (surf->Base.MipmapTexture) { + _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface"); + free(surf); + return EGL_NO_SURFACE; + } + + surf->winsys = xdrv->winsys; + + _eglConfigToContextModesRec(conf, &visual); + + /* Create GL statetracker framebuffer */ + surf->Framebuffer = st_create_framebuffer(&visual, + choose_color_format(&visual), + choose_depth_format(&visual), + choose_stencil_format(&visual), + width, height, + (void *) surf); + st_resize_framebuffer(surf->Framebuffer, width, height); + + return _eglLinkSurface(&surf->Base, disp); +} + + static EGLBoolean xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) { struct xlib_egl_surface *surf = lookup_surface(surface); if (surf) { _eglUnlinkSurface(&surf->Base); - if (!surf->Base.IsBound) { - XFreeGC(surf->Dpy, surf->Gc); + if (!_eglIsSurfaceBound(&surf->Base)) { + if (surf->Base.Type != EGL_PBUFFER_BIT) + XFreeGC(surf->Dpy, surf->Gc); st_unreference_framebuffer(surf->Framebuffer); free(surf); } @@ -548,6 +642,86 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) static EGLBoolean +xlib_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, + EGLSurface surface, EGLint buffer) +{ + struct xlib_egl_surface *xsurf = lookup_surface(surface); + struct xlib_egl_context *xctx; + struct pipe_surface *psurf; + enum pipe_format format; + int target; + + if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT) + return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); + if (buffer != EGL_BACK_BUFFER) + return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); + if (xsurf->Base.BoundToTexture) + return _eglError(EGL_BAD_ACCESS, "eglBindTexImage"); + + /* this should be updated when choose_color_format is */ + switch (xsurf->Base.TextureFormat) { + case EGL_TEXTURE_RGB: + format = PIPE_FORMAT_R8G8B8_UNORM; + break; + case EGL_TEXTURE_RGBA: + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + default: + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); + } + + switch (xsurf->Base.TextureTarget) { + case EGL_TEXTURE_2D: + target = ST_TEXTURE_2D; + break; + default: + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); + } + + /* flush properly */ + if (eglGetCurrentSurface(EGL_DRAW) == surface) { + xctx = lookup_context(eglGetCurrentContext()); + st_flush(xctx->Context, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, + NULL); + } + else if (_eglIsSurfaceBound(&xsurf->Base)) { + xctx = lookup_context(_eglGetContextHandle(xsurf->Base.Binding)); + if (xctx) + st_finish(xctx->Context); + } + + st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT, + &psurf); + st_bind_texture_surface(psurf, target, xsurf->Base.MipmapLevel, format); + xsurf->Base.BoundToTexture = EGL_TRUE; + + return EGL_TRUE; +} + + +static EGLBoolean +xlib_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, + EGLint buffer) +{ + struct xlib_egl_surface *xsurf = lookup_surface(surface); + struct pipe_surface *psurf; + + if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT || + !xsurf->Base.BoundToTexture) + return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); + if (buffer != EGL_BACK_BUFFER) + return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); + + st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT, + &psurf); + st_unbind_texture_surface(psurf, ST_TEXTURE_2D, xsurf->Base.MipmapLevel); + xsurf->Base.BoundToTexture = EGL_FALSE; + + return EGL_TRUE; +} + + +static EGLBoolean xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) { /* error checking step: */ @@ -631,7 +805,10 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->Base.API.CreateContext = xlib_eglCreateContext; xdrv->Base.API.DestroyContext = xlib_eglDestroyContext; xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface; + xdrv->Base.API.CreatePbufferSurface = xlib_eglCreatePbufferSurface; xdrv->Base.API.DestroySurface = xlib_eglDestroySurface; + xdrv->Base.API.BindTexImage = xlib_eglBindTexImage; + xdrv->Base.API.ReleaseTexImage = xlib_eglReleaseTexImage; xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index aa1bfa8e88..79ff2cc985 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -166,6 +166,7 @@ surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride) { const unsigned alignment = 64; diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c index fe8dfff767..6f3861e2cd 100644 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -249,6 +249,7 @@ aub_i915_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride) { const unsigned alignment = 64; diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 44b8464518..277e724d2a 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -375,6 +375,7 @@ xm_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride) { const unsigned alignment = 64; |