nouveau: add hw-dependent function to update modelview*projection matrix
authorPatrice Mandin <pmandin@caramail.com>
Fri, 31 Aug 2007 17:43:16 +0000 (19:43 +0200)
committerPatrice Mandin <pmandin@caramail.com>
Fri, 31 Aug 2007 17:46:39 +0000 (19:46 +0200)
src/mesa/drivers/dri/nouveau/nouveau_context.c
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nouveau_state.c
src/mesa/drivers/dri/nouveau/nv10_state.c
src/mesa/drivers/dri/nouveau/nv20_state.c
src/mesa/drivers/dri/nouveau/nv30_state.c
src/mesa/drivers/dri/nouveau/nv50_state.c

index 1e13324b9837eb0d6ceaa6dd763b32e84c2f2d0b..ae0a6d5c9e7b56651ee58d8f5ca8cbb6aaba882c 100644 (file)
@@ -210,6 +210,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
        _swsetup_CreateContext( ctx );
 
        _math_matrix_ctr(&nmesa->viewport);
+       _math_matrix_ctr(&nmesa->model_proj);
 
        nouveauDDInitStateFuncs( ctx );
        nouveauSpanInitFunctions( ctx );
index 778c4401e428d1bab1bd6ef438782ee8e63d23dc..94d729daef1036bf252487832460b96e7fc37d94 100644 (file)
@@ -86,6 +86,9 @@ typedef struct nouveau_hw_func_t {
                                 nouveau_renderbuffer_t *depth);
        /* Update anything that depends on the window position/size */
        void      (*WindowMoved)(struct nouveau_context *);
+
+       /* Update projection matrix */
+       void    (*UpdateModelProjMatrix)(struct nouveau_context *);
 } nouveau_hw_func;
 
 typedef struct nouveau_context {
@@ -117,6 +120,9 @@ typedef struct nouveau_context {
        GLuint color_offset;
        GLuint specular_offset;
 
+       /* Projection*modelview matrix */
+       GLmatrix model_proj;
+
        /* Vertex state */
        GLuint vertex_size;
        GLubyte *verts;
index f618dcfc99b5b5f079c5551c8cd72bade8d6c045..6c63b12c4695e0ab856f745d62ac329af9ce7fc7 100644 (file)
@@ -100,6 +100,16 @@ static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far)
     nouveauCalcViewport(ctx);
 }
 
+static void nouveauUpdateModelProjMatrix(GLcontext *ctx)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+       _math_matrix_mul_matrix(&(nmesa->model_proj), &(ctx->_ModelProjectMatrix),
+               ctx->ModelviewMatrixStack.Top);
+
+       nmesa->hw_func.UpdateModelProjMatrix(nmesa);
+}
+
 static void nouveauDDUpdateHWState(GLcontext *ctx)
 {
     nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
@@ -141,6 +151,13 @@ static void nouveauDDUpdateHWState(GLcontext *ctx)
 
 static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state)
 {
+       if ( new_state & _NEW_PROJECTION ) {
+               nouveauUpdateModelProjMatrix(ctx);
+       }
+        if ( new_state & _NEW_MODELVIEW ) {
+               nouveauUpdateModelProjMatrix(ctx);
+       }
+
     _swrast_InvalidateState( ctx, new_state );
     _swsetup_InvalidateState( ctx, new_state );
     _vbo_InvalidateState( ctx, new_state );
index 79d567b25d725b4486bd89fabcd8549575a073d0..9c63bd118a42dce0c497a952627a60e864a09f31 100644 (file)
@@ -750,6 +750,51 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
         OUT_RING_CACHEp(mat->m, 16);
 }
 
+static void nv10UpdateModelProjMatrix(nouveauContextPtr nmesa)
+{
+       GLcontext *ctx = nmesa->glCtx;
+       GLfloat w = ((GLfloat) ctx->Viewport.Width) * 0.5;
+       GLfloat h = ((GLfloat) ctx->Viewport.Height) * 0.5;
+       GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5;
+       GLfloat projection[16];
+       int i;
+
+       if (ctx->DrawBuffer) {
+               if (ctx->DrawBuffer->_DepthBuffer) {
+                       switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) {
+                               case 16:
+                                       max_depth *= 32767.0;
+                                       break;
+                               case 24:
+                                       max_depth *= 16777215.0;
+                                       break;
+                       }
+               }
+       }
+
+       /* Rescale for viewport */
+       for (i=0; i<4; i++) {
+               projection[i] = w * nmesa->model_proj.m[i];
+       }
+       for (i=0; i<4; i++) {
+               projection[i+4] = -h * nmesa->model_proj.m[i+4];
+       }
+       for (i=0; i<4; i++) {
+               projection[i+8] = max_depth * nmesa->model_proj.m[i+8];
+       }
+       for (i=0; i<4; i++) {
+               projection[i+12] = nmesa->model_proj.m[i+12];
+       }
+
+       for (i=0; i<16; i++) {
+               printf("%d\t%.3f\t%.3f\n", i,
+                       nmesa->model_proj.m[i], projection[i]);
+       }
+
+       BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16);
+       OUT_RINGp(projection, 16);
+}
+
 /* Update anything that depends on the window position/size */
 static void nv10WindowMoved(nouveauContextPtr nmesa)
 {
@@ -1011,4 +1056,5 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
        nmesa->hw_func.InitCard         = nv10InitCard;
        nmesa->hw_func.BindBuffers      = nv10BindBuffers;
        nmesa->hw_func.WindowMoved      = nv10WindowMoved;
+       nmesa->hw_func.UpdateModelProjMatrix = nv10UpdateModelProjMatrix;
 }
index 6b583980a49975e50a2978fcfc8de660ba5e080e..c6efa6b72c9f7a1eaa10cbaf5b26bcaeb0698292 100644 (file)
@@ -636,6 +636,10 @@ static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
         OUT_RING_CACHEp(mat->m, 16);
 }
 
+static void nv20UpdateModelProjMatrix(nouveauContextPtr nmesa)
+{
+}
+
 /* Update anything that depends on the window position/size */
 static void nv20WindowMoved(nouveauContextPtr nmesa)
 {
@@ -820,5 +824,6 @@ void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
        nmesa->hw_func.InitCard         = nv20InitCard;
        nmesa->hw_func.BindBuffers      = nv20BindBuffers;
        nmesa->hw_func.WindowMoved      = nv20WindowMoved;
+       nmesa->hw_func.UpdateModelProjMatrix = nv20UpdateModelProjMatrix;
 }
 
index cd3ee9868805f8cab3c84f55391276caac72c541..ebd9e1c51454c45f2ae901c489e4bae446293443 100644 (file)
@@ -767,6 +767,10 @@ static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
        }
 }
 
+static void nv30UpdateModelProjMatrix(nouveauContextPtr nmesa)
+{
+}
+
 static void nv30WindowMoved(nouveauContextPtr nmesa)
 {
        GLcontext *ctx = nmesa->glCtx;
@@ -998,5 +1002,6 @@ void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
           nmesa->hw_func.InitCard      = nv30InitCard;
        nmesa->hw_func.BindBuffers      = nv30BindBuffers;
        nmesa->hw_func.WindowMoved      = nv30WindowMoved;
+       nmesa->hw_func.UpdateModelProjMatrix = nv30UpdateModelProjMatrix;
 }
 
index a9236f093c34adb06337139bd5cf0503341fdd5f..66a18c4a156f3ee0aa1b15ffccfae3a5a3dc9b5e 100644 (file)
@@ -520,6 +520,10 @@ static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
        /* Only with shaders */
 }
 
+static void nv50UpdateModelProjMatrix(nouveauContextPtr nmesa)
+{
+}
+
 static void nv50WindowMoved(nouveauContextPtr nmesa)
 {
        GLcontext *ctx = nmesa->glCtx;
@@ -638,4 +642,5 @@ void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
        nmesa->hw_func.InitCard         = nv50InitCard;
        nmesa->hw_func.BindBuffers      = nv50BindBuffers;
        nmesa->hw_func.WindowMoved      = nv50WindowMoved;
+       nmesa->hw_func.UpdateModelProjMatrix = nv50UpdateModelProjMatrix;
 }