r300: Implement SetTexOffset hook.
authorMichel Dänzer <michel@tungstengraphics.com>
Tue, 22 May 2007 12:08:11 +0000 (14:08 +0200)
committerMichel Dänzer <michel@tungstengraphics.com>
Tue, 22 May 2007 12:08:11 +0000 (14:08 +0200)
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_tex.h
src/mesa/drivers/dri/r300/r300_texmem.c
src/mesa/drivers/dri/r300/r300_texstate.c
src/mesa/drivers/dri/radeon/radeon_screen.c

index 261c87f2f0bf97733fc8e08fc37c71a4d90eb35f..01caa6176678c3c51417976bb88e8cb016c1148f 100644 (file)
@@ -191,6 +191,8 @@ struct r300_tex_obj {
        drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
        /* Six, for the cube faces */
 
+       GLboolean image_override;       /* Image overridden by GLX_EXT_tfp */
+
        GLuint pitch;           /* this isn't sent to hardware just used in calculations */
        /* hardware register values */
        /* Note that R200 has 8 registers per texture and R300 only 7 */
index 74fa08e97d952551983a64fe9a5fc0b7d935cf54..f67a8e6ba6536e16c449864921fc8f36c42914cf 100644 (file)
@@ -35,6 +35,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef __r300_TEX_H__
 #define __r300_TEX_H__
 
+extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
+                            unsigned long long offset, GLint depth,
+                            GLuint pitch);
+
 extern void r300UpdateTextureState(GLcontext * ctx);
 
 extern int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t,
index 60e7dc967b18126d8dcbe1435fcf782afbc9dc2c..e2e8355d27582ba0e333b463e3b890140604dbdb 100644 (file)
@@ -508,6 +508,9 @@ int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face)
 {
        const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
 
+       if (t->image_override)
+               return 0;
+
        if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) {
                fprintf(stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
                        (void *)rmesa->radeon.glCtx, (void *)t->base.tObj,
index 705502ebf2b8c7456050b427f0943ffea9839214..8203189b7f4131638943764d364876ab7d2a40b9 100644 (file)
@@ -40,6 +40,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "context.h"
 #include "macros.h"
 #include "texformat.h"
+#include "teximage.h"
+#include "texobj.h"
 #include "enums.h"
 
 #include "r300_context.h"
@@ -66,7 +68,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * identically.  -- paulus
  */
 
-static const struct {
+static const struct tx_table {
        GLuint format, filter, flag;
 } tx_table_be[] = {
        /* *INDENT-OFF* */
@@ -109,15 +111,13 @@ static const struct {
        /* *INDENT-ON* */
 };
 
-static const struct {
-       GLuint format, filter, flag;
-} tx_table_le[] = {
+static const struct tx_table tx_table_le[] = {
        /* *INDENT-OFF* */
        _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
        _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
        _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
        _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
-       _ASSIGN(RGB888, 0xffffffff),
+       _ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
        _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
        _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
        _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
@@ -178,7 +178,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
 
        /* Set the hardware texture format
         */
-       if (VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
+       if (!t->image_override && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
                if (_mesa_little_endian()) {
                        t->format =
                            tx_table_le[baseImage->TexFormat->MesaFormat].
@@ -194,7 +194,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
                            tx_table_be[baseImage->TexFormat->MesaFormat].
                            filter;
                }
-       } else {
+       } else if (!t->image_override) {
                _mesa_problem(NULL, "unexpected texture format in %s",
                              __FUNCTION__);
                return;
@@ -382,9 +382,10 @@ static void r300SetTexImages(r300ContextPtr rmesa,
                t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width *
                             texelBytes) + 63) & ~(63);
                t->size |= R300_TX_SIZE_TXPITCH_EN;
-               t->pitch_reg =
-                   (((tObj->Image[0][t->base.firstLevel]->Width) +
-                     align) & ~align) - 1;
+               if (!t->image_override)
+                       t->pitch_reg =
+                           (((tObj->Image[0][t->base.firstLevel]->Width) +
+                             align) & ~align) - 1;
        } else {
                t->pitch =
                    ((tObj->Image[0][t->base.firstLevel]->Width *
@@ -411,9 +412,10 @@ static GLboolean r300EnableTexture2D(GLcontext * ctx, int unit)
 
        if (t->base.dirty_images[0]) {
                R300_FIREVERTICES(rmesa);
+
                r300SetTexImages(rmesa, tObj);
                r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
-               if (!t->base.memBlock)
+               if (!t->base.memBlock && !t->image_override)
                        return GL_FALSE;
        }
 
@@ -492,9 +494,11 @@ static GLboolean r300EnableTextureRect(GLcontext * ctx, int unit)
 
        if (t->base.dirty_images[0]) {
                R300_FIREVERTICES(rmesa);
+
                r300SetTexImages(rmesa, tObj);
                r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
-               if (!t->base.memBlock && !rmesa->prefer_gart_client_texturing)
+               if (!t->base.memBlock && !t->image_override &&
+                   !rmesa->prefer_gart_client_texturing)
                        return GL_FALSE;
        }
 
@@ -534,6 +538,51 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
        return !t->border_fallback;
 }
 
+void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
+                     unsigned long long offset, GLint depth, GLuint pitch)
+{
+       r300ContextPtr rmesa =
+               (r300ContextPtr)((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
+       struct gl_texture_object *tObj =
+               _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
+       r300TexObjPtr t;
+       int idx;
+
+       if (!tObj)
+               return;
+
+       t = (r300TexObjPtr) tObj->DriverData;
+
+       t->image_override = GL_TRUE;
+
+       if (!offset)
+               return;
+
+       t->offset = offset;
+       t->pitch_reg = pitch;
+
+       switch (depth) {
+       case 32:
+               idx = 2;
+               t->pitch_reg /= 4;
+               break;
+       case 24:
+       default:
+               idx = 4;
+               t->pitch_reg /= 4;
+               break;
+       case 16:
+               idx = 5;
+               t->pitch_reg /= 2;
+               break;
+       }
+
+       t->pitch_reg--;
+
+       t->format = tx_table_le[idx].format;
+       t->filter |= tx_table_le[idx].filter;
+}
+
 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
 {
        struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
index b476864d0353bc7d214b0c77c736ab394579c0d3..aa7fb633dd1a8987457f240fce4b30e59c741758 100644 (file)
@@ -56,6 +56,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
 #include "r300_context.h"
 #include "r300_fragprog.h"
+#include "r300_tex.h"
 #include "radeon_span.h"
 #endif
 
@@ -952,6 +953,9 @@ static struct __DriverAPIRec radeonAPI = {
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL,
    .CopySubBuffer   = radeonCopySubBuffer,
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+   .setTexOffset    = r300SetTexOffset,
+#endif
 };
 #else
 static const struct __DriverAPIRec r200API = {