From: Aapo Tahkola Date: Fri, 28 Jan 2005 09:57:06 +0000 (+0000) Subject: Add basic sceleton for vertex programs + some other fixes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f856b3f10f5c0feb5243d3f78c733099f47e1c54;p=mesa.git Add basic sceleton for vertex programs + some other fixes --- diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index fdd5b732f2a..1ea07584aa5 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -35,6 +35,7 @@ DRIVER_SOURCES = \ r300_texmem.c \ r300_tex.c \ r300_texstate.c \ + r300_vertexprog.c \ \ r200_context.c \ r200_ioctl.c \ diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 760b6b3061a..22d1c43db84 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -32,7 +32,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Keith Whitwell * Nicolai Haehnle */ - #include "glheader.h" #include "api_arrayelt.h" #include "context.h" @@ -78,6 +77,7 @@ static const char *const card_extensions[] = { "GL_ARB_texture_mirrored_repeat", "GL_ARB_vertex_buffer_object", "GL_ARB_vertex_program", + //"GL_ARB_fragment_program", "GL_EXT_blend_equation_separate", "GL_EXT_blend_func_separate", "GL_EXT_blend_minmax", @@ -136,7 +136,6 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = { 0, }; - /* Create the device specific rendering context. */ GLboolean r300CreateContext(const __GLcontextModes * glVisual, @@ -173,7 +172,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, r300InitIoctlFuncs(&functions); r300InitStateFuncs(&functions); r300InitTextureFuncs(&functions); - + r300InitVertexProgFuncs(&functions); + if (!radeonInitContext(&r300->radeon, &functions, glVisual, driContextPriv, sharedContextPrivate)) { FREE(r300); @@ -261,11 +261,26 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, _tnl_allow_pixel_fog(ctx, GL_FALSE); _tnl_allow_vertex_fog(ctx, GL_TRUE); +#if 0 + //if(driQueryOptionb(&rmesa->optionCache, "arb_vertex_program")) + _mesa_enable_extension( ctx, "GL_ARB_vertex_program"); + //if(driQueryOptionb(&rmesa->optionCache, "nv_vertex_program")) + _mesa_enable_extension( ctx, "GL_NV_vertex_program"); +#endif + /* currently bogus data */ + ctx->Const.MaxVertexProgramInstructions=128; + ctx->Const.MaxVertexProgramAttribs=64; + ctx->Const.MaxVertexProgramTemps=64; + ctx->Const.MaxVertexProgramLocalParams=64; + ctx->Const.MaxVertexProgramEnvParams=64; + ctx->Const.MaxVertexProgramAddressRegs=8; + driInitExtensions(ctx, card_extensions, GL_TRUE); - + radeonInitSpanFuncs(ctx); r300InitCmdBuf(r300); r300InitState(r300); + #if 0 /* plug in a few more device driver functions */ /* XXX these should really go right after _mesa_init_driver_functions() */ diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index af9ef419d1c..fd076a38ec7 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -518,6 +518,12 @@ struct r300_vertex_shader_state { int unknown_ptr2; /* pointer within program space */ int unknown_ptr3; /* pointer within program space */ }; + +struct r300_vertex_program { + struct vertex_program mesa_program; /* Must be first */ + int translated; + +}; /* 64 appears to be the maximum */ #define PSF_MAX_PROGRAM_LENGTH 64 @@ -662,5 +668,6 @@ extern void r300DestroyContext(__DRIcontextPrivate * driContextPriv); extern GLboolean r300CreateContext(const __GLcontextModes * glVisual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); +extern void r300InitVertexProgFuncs(struct dd_function_table *functions); #endif /* __R300_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 35b67aeaa05..d1dd82ad919 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -206,7 +206,12 @@ static void r300_render_immediate_primitive(r300ContextPtr rmesa, #endif if(type<0)return; - + + if(!VB->ObjPtr){ + fprintf(stderr, "FIXME: Dont know how to handle GL_ARB_vertex_buffer_object " + "correctly\n"); + return; + } /* A packet cannot have more than 16383 data words.. */ if(((end-start)*8+4*rmesa->state.texture.tc_count)>16380){ fprintf(stderr, "%s:%s: Too many vertices to paint. Fix me !\n"); @@ -274,7 +279,7 @@ static GLboolean r300_run_immediate_render(GLcontext *ctx, r300TexObjPtr t=to->DriverData; LOCAL_VARS - + /* Update texture state - needs to be done only when actually changed.. All the time for now.. */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 5266c4f90aa..1592961d454 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -500,6 +500,9 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) case GL_CULL_FACE: r300UpdateCulling(ctx); break; + case GL_VERTEX_PROGRAM_ARB: + //TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, state); + break; default: radeonEnable(ctx, cap, state); diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index c7b5e7d2a98..366767bc227 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -289,7 +289,7 @@ static void r300SetTexImages(r300ContextPtr rmesa, t->format_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT); t->format_x |= R200_TEXCOORD_VOLUME; } else if (tObj->Target == GL_TEXTURE_CUBE_MAP) { - ASSERT(log2Width == log2height); + ASSERT(log2Width == log2Height); t->format |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) | (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) | (R200_TXFORMAT_CUBIC_MAP_ENABLE)); diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c new file mode 100644 index 00000000000..c4292da6fe5 --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c @@ -0,0 +1,302 @@ +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "program.h" +#include "r300_context.h" +#include "nvvertprog.h" + +static void r300BindProgram(GLcontext *ctx, GLenum target, struct program *prog) +{ + fprintf(stderr, "r300BindProgram\n"); +} + + +static struct program *r300NewProgram(GLcontext *ctx, GLenum target, GLuint id) +{ +r300ContextPtr rmesa = R300_CONTEXT(ctx); +struct r300_vertex_program *vp; +struct fragment_program *fp; +struct ati_fragment_shader *afs; + + fprintf(stderr, "r300NewProgram, target=%d, id=%d\n", target, id); + + switch(target){ + case GL_VERTEX_PROGRAM_ARB: + fprintf(stderr, "vertex prog\n"); + vp=malloc(sizeof(*vp)); + memset(vp, 0, sizeof(*vp)); + + /* note that vp points to mesa_program since its first on the struct + */ + return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id); + + case GL_FRAGMENT_PROGRAM_ARB: + fprintf(stderr, "fragment prog\n"); + fp=malloc(sizeof(*fp)); + memset(fp, 0, sizeof(*fp)); + + return _mesa_init_fragment_program(ctx, fp, target, id); + case GL_FRAGMENT_PROGRAM_NV: + fprintf(stderr, "nv fragment prog\n"); + fp=malloc(sizeof(*fp)); + memset(fp, 0, sizeof(*fp)); + + return _mesa_init_fragment_program(ctx, fp, target, id); + + case GL_FRAGMENT_SHADER_ATI: + fprintf(stderr, "ati fragment prog\n"); + afs=malloc(sizeof(*afs)); + memset(afs, 0, sizeof(*afs)); + + return _mesa_init_ati_fragment_shader(ctx, afs, target, id); + + default: + return NULL; + } + +} + + +static void r300DeleteProgram(GLcontext *ctx, struct program *prog) +{ + fprintf(stderr, "r300DeleteProgram\n"); + + /* check that not active */ + _mesa_delete_program(ctx, prog); +} + +static void r300ProgramStringNotify(GLcontext *ctx, GLenum target, + struct program *prog) +{ + struct r300_vertex_program *vp=(void *)prog; + + fprintf(stderr, "r300ProgramStringNotify\n"); + r300IsProgramNative(ctx, target, prog); + + switch(target) { + case GL_VERTEX_PROGRAM_ARB: + vp->translated=GL_FALSE; + break; + } + +} + +#define SCALAR_FLAG (1<<31) +#define FLAG_MASK (1<<31) +#define OPN(operator, ip, op) {#operator, VP_OPCODE_##operator, ip, op} +struct{ + char *name; + int opcode; + unsigned long ip; /* input reg index */ + unsigned long op; /* output reg index */ +}op_names[]={ + OPN(ABS, 1, 1), + OPN(ADD, 2, 1), + OPN(ARL, 1, 1|SCALAR_FLAG), + OPN(DP3, 2, 3|SCALAR_FLAG), + OPN(DP4, 2, 3|SCALAR_FLAG), + OPN(DPH, 2, 3|SCALAR_FLAG), + OPN(DST, 2, 1), + OPN(EX2, 1|SCALAR_FLAG, 4|SCALAR_FLAG), + OPN(EXP, 1|SCALAR_FLAG, 1), + OPN(FLR, 1, 1), + OPN(FRC, 1, 1), + OPN(LG2, 1|SCALAR_FLAG, 4|SCALAR_FLAG), + OPN(LIT, 1, 1), + OPN(LOG, 1|SCALAR_FLAG, 1), + OPN(MAD, 3, 1), + OPN(MAX, 2, 1), + OPN(MIN, 2, 1), + OPN(MOV, 1, 1), + OPN(MUL, 2, 1), + OPN(POW, 2|SCALAR_FLAG, 4|SCALAR_FLAG), + OPN(RCP, 1|SCALAR_FLAG, 4|SCALAR_FLAG), + OPN(RSQ, 1|SCALAR_FLAG, 4|SCALAR_FLAG), + OPN(SGE, 2, 1), + OPN(SLT, 2, 1), + OPN(SUB, 2, 1), + OPN(SWZ, 1, 1), + OPN(XPD, 2, 1), + OPN(RCC, 0, 0), //extra + OPN(PRINT, 0, 0), + OPN(END, 0, 0), +}; +#undef OPN +#define OPN(rf) {#rf, PROGRAM_##rf} + +struct{ + char *name; + int id; +}register_file_names[]={ + OPN(TEMPORARY), + OPN(INPUT), + OPN(OUTPUT), + OPN(LOCAL_PARAM), + OPN(ENV_PARAM), + OPN(NAMED_PARAM), + OPN(STATE_VAR), + OPN(WRITE_ONLY), + OPN(ADDRESS), +}; + +char *dst_mask_names[4]={ "X", "Y", "Z", "W" }; + +/* from vertex program spec: + Instruction Inputs Output Description + ----------- ------ ------ -------------------------------- + ABS v v absolute value + ADD v,v v add + ARL v a address register load + DP3 v,v ssss 3-component dot product + DP4 v,v ssss 4-component dot product + DPH v,v ssss homogeneous dot product + DST v,v v distance vector + EX2 s ssss exponential base 2 + EXP s v exponential base 2 (approximate) + FLR v v floor + FRC v v fraction + LG2 s ssss logarithm base 2 + LIT v v compute light coefficients + LOG s v logarithm base 2 (approximate) + MAD v,v,v v multiply and add + MAX v,v v maximum + MIN v,v v minimum + MOV v v move + MUL v,v v multiply + POW s,s ssss exponentiate + RCP s ssss reciprocal + RSQ s ssss reciprocal square root + SGE v,v v set on greater than or equal + SLT v,v v set on less than + SUB v,v v subtract + SWZ v v extended swizzle + XPD v,v v cross product +*/ + +void dump_program_params(struct vertex_program *vp){ + int i; + int pi; + + fprintf(stderr, "NumInstructions=%d\n", vp->Base.NumInstructions); + fprintf(stderr, "NumTemporaries=%d\n", vp->Base.NumTemporaries); + fprintf(stderr, "NumParameters=%d\n", vp->Base.NumParameters); + fprintf(stderr, "NumAttributes=%d\n", vp->Base.NumAttributes); + fprintf(stderr, "NumAddressRegs=%d\n", vp->Base.NumAddressRegs); + + for(pi=0; pi < vp->Base.NumParameters; pi++){ + fprintf(stderr, "{ "); + for(i=0; i < 4; i++) + fprintf(stderr, "%f ", vp->Base.LocalParams[pi][i]); + fprintf(stderr, "}\n"); + } + + for(pi=0; pi < vp->Parameters->NumParameters; pi++){ + fprintf(stderr, "param %02d:", pi); + + switch(vp->Parameters->Parameters[pi].Type){ + + case NAMED_PARAMETER: + fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name); + fprintf(stderr, "(NAMED_PARAMETER)"); + break; + + case CONSTANT: + fprintf(stderr, "(CONSTANT)"); + break; + + case STATE: + fprintf(stderr, "(STATE)\n"); + /* fetch state info */ + continue; + break; + + } + + fprintf(stderr, "{ "); + for(i=0; i < 4; i++) + fprintf(stderr, "%f ", vp->Parameters->Parameters[pi].Values[i]); + fprintf(stderr, "}\n"); + + } +} + +static GLboolean r300IsProgramNative(GLcontext *ctx, GLenum target, + struct program *prog) +{ + struct vertex_program *vp=(void *)prog; + struct vp_instruction *vpi; + int i, operand_index; + int operator_index; + + fprintf(stderr, "r300IsProgramNative\n"); + //exit(0); + + dump_program_params(vp); + + vpi=vp->Instructions; + + for(;; vpi++){ + if(vpi->Opcode == VP_OPCODE_END) + break; + + for(i=0; i < sizeof(op_names) / sizeof(*op_names); i++){ + if(vpi->Opcode == op_names[i].opcode){ + fprintf(stderr, "%s ", op_names[i].name); + break; + } + } + operator_index=i; + + for(i=0; i < sizeof(register_file_names) / sizeof(*register_file_names); i++){ + if(vpi->DstReg.File == register_file_names[i].id){ + fprintf(stderr, "%s ", register_file_names[i].name); + break; + } + } + + fprintf(stderr, "%d.", vpi->DstReg.Index); + + for(i=0; i < 4; i++) + if(vpi->DstReg.WriteMask[i]) + fprintf(stderr, "%s", dst_mask_names[i]); + fprintf(stderr, " "); + + for(operand_index=0; operand_index < op_names[operator_index].ip & (~FLAG_MASK); + operand_index++){ + + if(vpi->SrcReg[operand_index].Negate) + fprintf(stderr, "-"); + + for(i=0; i < sizeof(register_file_names) / sizeof(*register_file_names); i++){ + if(vpi->SrcReg[operand_index].File == register_file_names[i].id){ + fprintf(stderr, "%s ", register_file_names[i].name); + break; + } + } + fprintf(stderr, "%d.", vpi->SrcReg[operand_index].Index); + + for(i=0; i < 4; i++) + fprintf(stderr, "%s", dst_mask_names[vpi->SrcReg[operand_index].Swizzle[i]]); + + if(operand_index+1 < op_names[operator_index].ip & (~FLAG_MASK) ) + fprintf(stderr, ","); + } + fprintf(stderr, "\n"); + //op_names[i].ip + //op_names[i].op + } + return 1; +} + +/* This is misnamed and shouldnt be here since fragment programs use these functions too */ +void r300InitVertexProgFuncs(struct dd_function_table *functions) +{ +#if 1 + functions->NewProgram=r300NewProgram; + functions->BindProgram=r300BindProgram; + functions->DeleteProgram=r300DeleteProgram; + functions->ProgramStringNotify=r300ProgramStringNotify; + functions->IsProgramNative=r300IsProgramNative; +#endif +}