dri/nouveau: Support rectangle textures.
authorFrancisco Jerez <currojerez@riseup.net>
Thu, 25 Feb 2010 01:15:54 +0000 (02:15 +0100)
committerFrancisco Jerez <currojerez@riseup.net>
Thu, 25 Feb 2010 17:37:38 +0000 (18:37 +0100)
src/mesa/drivers/dri/nouveau/nouveau_texture.c
src/mesa/drivers/dri/nouveau/nv10_context.c
src/mesa/drivers/dri/nouveau/nv10_state_tex.c
src/mesa/drivers/dri/nouveau/nv20_context.c
src/mesa/drivers/dri/nouveau/nv20_state_tex.c

index 5b788042959db64a8fe448d1d9fd400eb599d33d..840bd6fe838f16b988cdf824b111bd757c10c153 100644 (file)
@@ -118,9 +118,6 @@ nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat,
                return MESA_FORMAT_ARGB8888;
        case GL_RGB5_A1:
                return MESA_FORMAT_ARGB1555;
-       case GL_RGBA2:
-       case GL_RGBA4:
-               return MESA_FORMAT_ARGB4444;
 
        case 3:
        case GL_R3_G3_B2:
@@ -180,9 +177,10 @@ teximage_fits(struct gl_texture_object *t, int level,
 {
        struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level];
 
-       return s->bo && s->width == ti->Width &&
-               s->height == ti->Height &&
-               s->format == ti->TexFormat;
+       return t->Target == GL_TEXTURE_RECTANGLE ||
+               (s->bo && s->width == ti->Width &&
+                s->height == ti->Height &&
+                s->format == ti->TexFormat);
 }
 
 static GLboolean
@@ -196,9 +194,12 @@ validate_teximage(GLcontext *ctx, struct gl_texture_object *t,
                struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
                struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
 
-               context_drv(ctx)->surface_copy(ctx, &ss[level], s,
-                                              x, y, x, y,
-                                              width, height);
+               if (t->Target == GL_TEXTURE_RECTANGLE)
+                       nouveau_surface_ref(s, &ss[level]);
+               else
+                       context_drv(ctx)->surface_copy(ctx, &ss[level], s,
+                                                      x, y, x, y,
+                                                      width, height);
 
                return GL_TRUE;
        }
@@ -223,7 +224,7 @@ relayout_texture(GLcontext *ctx, struct gl_texture_object *t)
 {
        struct gl_texture_image *base = t->Image[0][t->BaseLevel];
 
-       if (base) {
+       if (base && t->Target != GL_TEXTURE_RECTANGLE) {
                struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
                struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
                int i, ret, last = get_last_level(t);
index d80d99caa80454dd284245028aa604f2e620af02..8e70c419ede849d84a1a8b6eea4efaae1e4d6385 100644 (file)
 #include "nv04_driver.h"
 #include "nv10_driver.h"
 
+static const struct dri_extension nv10_extensions[] = {
+       { "GL_EXT_texture_rectangle",   NULL },
+       { NULL,                         NULL }
+};
+
 static void
 nv10_clear(GLcontext *ctx, GLbitfield buffers)
 {
@@ -301,6 +306,8 @@ nv10_context_create(struct nouveau_screen *screen, const GLvisual *visual,
        if (!nouveau_context_init(ctx, screen, visual, share_ctx))
                goto fail;
 
+       driInitExtensions(ctx, nv10_extensions, GL_FALSE);
+
        /* GL constants. */
        ctx->Const.MaxTextureLevels = 12;
        ctx->Const.MaxTextureCoordUnits = NV10_TEXTURE_UNITS;
index d732a5335bc3a8c9eaa7fd2b7facf011da5d9599..f45f6c949ee384bb6a13f4340a476f6f7091663c 100644 (file)
@@ -38,7 +38,7 @@ nv10_emit_tex_gen(GLcontext *ctx, int emit)
 }
 
 static uint32_t
-get_tex_format(struct gl_texture_image *ti)
+get_tex_format_pot(struct gl_texture_image *ti)
 {
        switch (ti->TexFormat) {
        case MESA_FORMAT_ARGB8888:
@@ -67,6 +67,29 @@ get_tex_format(struct gl_texture_image *ti)
        }
 }
 
+static uint32_t
+get_tex_format_rect(struct gl_texture_image *ti)
+{
+       switch (ti->TexFormat) {
+       case MESA_FORMAT_ARGB1555:
+               return NV10TCL_TX_FORMAT_FORMAT_A1R5G5B5_RECT;
+
+       case MESA_FORMAT_RGB565:
+               return NV10TCL_TX_FORMAT_FORMAT_R5G6B5_RECT;
+
+       case MESA_FORMAT_ARGB8888:
+               return NV10TCL_TX_FORMAT_FORMAT_A8R8G8B8_RECT;
+
+       case MESA_FORMAT_A8:
+       case MESA_FORMAT_L8:
+       case MESA_FORMAT_I8:
+               return NV10TCL_TX_FORMAT_FORMAT_A8_RECT;
+
+       default:
+               assert(0);
+       }
+}
+
 void
 nv10_emit_tex_obj(GLcontext *ctx, int emit)
 {
@@ -98,7 +121,6 @@ nv10_emit_tex_obj(GLcontext *ctx, int emit)
                | nvgl_wrap_mode(t->WrapS) << 24
                | ti->HeightLog2 << 20
                | ti->WidthLog2 << 16
-               | get_tex_format(ti)
                | 5 << 4 | 1 << 12;
 
        tx_filter = nvgl_filter_mode(t->MagFilter) << 28
@@ -107,6 +129,17 @@ nv10_emit_tex_obj(GLcontext *ctx, int emit)
        tx_enable = NV10TCL_TX_ENABLE_ENABLE
                | log2i(t->MaxAnisotropy) << 4;
 
+       if (t->Target == GL_TEXTURE_RECTANGLE) {
+               BEGIN_RING(chan, celsius, NV10TCL_TX_NPOT_PITCH(i), 1);
+               OUT_RING(chan, s->pitch << 16);
+               BEGIN_RING(chan, celsius, NV10TCL_TX_NPOT_SIZE(i), 1);
+               OUT_RING(chan, align(s->width, 2) << 16 | s->height);
+
+               tx_format |= get_tex_format_rect(ti);
+       } else {
+               tx_format |= get_tex_format_pot(ti);
+       }
+
        if (t->MinFilter != GL_NEAREST &&
            t->MinFilter != GL_LINEAR) {
                int lod_min = t->MinLod;
index a80062f5f1e50dacab46e912c40f8462dfdb26dc..635b5c09968621402d15f285851a4d264248a034 100644 (file)
 #include "nv10_driver.h"
 #include "nv20_driver.h"
 
+static const struct dri_extension nv20_extensions[] = {
+       { "GL_EXT_texture_rectangle",   NULL },
+       { NULL,                         NULL }
+};
+
 static void
 nv20_hwctx_init(GLcontext *ctx)
 {
@@ -394,6 +399,8 @@ nv20_context_create(struct nouveau_screen *screen, const GLvisual *visual,
        if (!nouveau_context_init(ctx, screen, visual, share_ctx))
                goto fail;
 
+       driInitExtensions(ctx, nv20_extensions, GL_FALSE);
+
        /* GL constants. */
        ctx->Const.MaxTextureCoordUnits = NV20_TEXTURE_UNITS;
        ctx->Const.MaxTextureImageUnits = NV20_TEXTURE_UNITS;
index 2bf760d3b08bf0fab5acd50823896e7e3fa7b7b8..4627799809b2bc698ce4ae3196fc49161e37e37c 100644 (file)
@@ -33,7 +33,7 @@
 #include "nv20_driver.h"
 
 static uint32_t
-get_tex_format(struct gl_texture_image *ti)
+get_tex_format_pot(struct gl_texture_image *ti)
 {
        switch (ti->TexFormat) {
        case MESA_FORMAT_ARGB8888:
@@ -62,6 +62,34 @@ get_tex_format(struct gl_texture_image *ti)
        }
 }
 
+static uint32_t
+get_tex_format_rect(struct gl_texture_image *ti)
+{
+       switch (ti->TexFormat) {
+       case MESA_FORMAT_ARGB1555:
+               return NV20TCL_TX_FORMAT_FORMAT_A1R5G5B5_RECT;
+
+       case MESA_FORMAT_RGB565:
+               return NV20TCL_TX_FORMAT_FORMAT_R5G6B5_RECT;
+
+       case MESA_FORMAT_ARGB8888:
+               return NV20TCL_TX_FORMAT_FORMAT_A8R8G8B8_RECT;
+
+       case MESA_FORMAT_L8:
+               return NV20TCL_TX_FORMAT_FORMAT_L8_RECT;
+
+       case MESA_FORMAT_A8:
+       case MESA_FORMAT_I8:
+               return NV20TCL_TX_FORMAT_FORMAT_A8_RECT;
+
+       case MESA_FORMAT_ARGB4444:
+               return NV20TCL_TX_FORMAT_FORMAT_A4R4G4B4_RECT;
+
+       default:
+               assert(0);
+       }
+}
+
 void
 nv20_emit_tex_obj(GLcontext *ctx, int emit)
 {
@@ -94,7 +122,6 @@ nv20_emit_tex_obj(GLcontext *ctx, int emit)
        tx_format = ti->DepthLog2 << 28
                | ti->HeightLog2 << 24
                | ti->WidthLog2 << 20
-               | get_tex_format(ti)
                | NV20TCL_TX_FORMAT_DIMS_2D
                | NV20TCL_TX_FORMAT_NO_BORDER
                | 1 << 16;
@@ -109,6 +136,17 @@ nv20_emit_tex_obj(GLcontext *ctx, int emit)
        tx_enable = NV20TCL_TX_ENABLE_ENABLE
                | log2i(t->MaxAnisotropy) << 4;
 
+       if (t->Target == GL_TEXTURE_RECTANGLE) {
+               BEGIN_RING(chan, kelvin, NV20TCL_TX_NPOT_PITCH(i), 1);
+               OUT_RING(chan, s->pitch << 16);
+               BEGIN_RING(chan, kelvin, NV20TCL_TX_NPOT_SIZE(i), 1);
+               OUT_RING(chan, s->width << 16 | s->height);
+
+               tx_format |= get_tex_format_rect(ti);
+       } else {
+               tx_format |= get_tex_format_pot(ti);
+       }
+
        if (t->MinFilter != GL_NEAREST &&
            t->MinFilter != GL_LINEAR) {
                int lod_min = t->MinLod;