From a7b8d105a6efe4056633f7129f80aac1f13cc246 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 25 Feb 2010 02:15:54 +0100 Subject: 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(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c index 5b78804295..840bd6fe83 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 d80d99caa8..8e70c419ed 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 d732a5335b..f45f6c949e 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 a80062f5f1..635b5c0996 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 2bf760d3b0..4627799809 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; -- cgit v1.2.3