Add basic sceleton for vertex programs + some other fixes
authorAapo Tahkola <aet@rasterburn.org>
Fri, 28 Jan 2005 09:57:06 +0000 (09:57 +0000)
committerAapo Tahkola <aet@rasterburn.org>
Fri, 28 Jan 2005 09:57:06 +0000 (09:57 +0000)
src/mesa/drivers/dri/r300/Makefile
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_render.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_texstate.c
src/mesa/drivers/dri/r300/r300_vertexprog.c [new file with mode: 0644]

index fdd5b73..1ea0758 100644 (file)
@@ -35,6 +35,7 @@ DRIVER_SOURCES = \
                 r300_texmem.c \
                 r300_tex.c \
                 r300_texstate.c \
+                r300_vertexprog.c \
                 \
                 r200_context.c \
                 r200_ioctl.c \
index 760b6b3..22d1c43 100644 (file)
@@ -32,7 +32,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Keith Whitwell <keith@tungstengraphics.com>
  *   Nicolai Haehnle <prefect_@gmx.net>
  */
-
 #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() */
index af9ef41..fd076a3 100644 (file)
@@ -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__ */
index 35b67ae..d1dd82a 100644 (file)
@@ -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.. */
 
index 5266c4f..1592961 100644 (file)
@@ -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);
index c7b5e7d..366767b 100644 (file)
@@ -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 (file)
index 0000000..c4292da
--- /dev/null
@@ -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 
+}