Mesa (master): dri/nouveau: Support rectangle textures.

Francisco Jerez currojerez at kemper.freedesktop.org
Thu Feb 25 18:33:39 UTC 2010


Module: Mesa
Branch: master
Commit: a7b8d105a6efe4056633f7129f80aac1f13cc246
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a7b8d105a6efe4056633f7129f80aac1f13cc246

Author: Francisco Jerez <currojerez at riseup.net>
Date:   Thu Feb 25 02:15:54 2010 +0100

dri/nouveau: Support rectangle textures.

---

 src/mesa/drivers/dri/nouveau/nouveau_texture.c |   21 ++++++------
 src/mesa/drivers/dri/nouveau/nv10_context.c    |    7 ++++
 src/mesa/drivers/dri/nouveau/nv10_state_tex.c  |   37 ++++++++++++++++++++-
 src/mesa/drivers/dri/nouveau/nv20_context.c    |    7 ++++
 src/mesa/drivers/dri/nouveau/nv20_state_tex.c  |   42 ++++++++++++++++++++++-
 5 files changed, 100 insertions(+), 14 deletions(-)

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
index 5b78804..840bd6f 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
@@ -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);
diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c
index d80d99c..8e70c41 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_context.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_context.c
@@ -32,6 +32,11 @@
 #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;
diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tex.c b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c
index d732a53..f45f6c9 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_state_tex.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c
@@ -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;
diff --git a/src/mesa/drivers/dri/nouveau/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_context.c
index a80062f..635b5c0 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_context.c
+++ b/src/mesa/drivers/dri/nouveau/nv20_context.c
@@ -31,6 +31,11 @@
 #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;
diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c
index 2bf760d..4627799 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c
+++ b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c
@@ -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;




More information about the mesa-commit mailing list