summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAapo Tahkola <[email protected]>2005-01-28 09:57:06 +0000
committerAapo Tahkola <[email protected]>2005-01-28 09:57:06 +0000
commitf856b3f10f5c0feb5243d3f78c733099f47e1c54 (patch)
tree942422d4e34537e067c1f72f86dc5dbb00be6545
parent6398a97affb8d2dde90dd77cb65aef8e9827e63d (diff)
Add basic sceleton for vertex programs + some other fixes
-rw-r--r--src/mesa/drivers/dri/r300/Makefile1
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c23
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h7
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c9
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c3
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertexprog.c302
7 files changed, 340 insertions, 7 deletions
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 <[email protected]>
* Nicolai Haehnle <[email protected]>
*/
-
#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
+}