summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViktor Novotný <noviktor@seznam.cz>2012-05-01 15:23:50 +0200
committerFrancisco Jerez <currojerez@riseup.net>2012-05-02 03:13:42 +0200
commit6d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9 (patch)
tree2aaf60d6df163f777e7c8abeabff527d0c0274cb
parentb389b608d8d853c1f9383b04a222d96a5a096178 (diff)
dri/nouveau: Add general support for compressed formats.
Signed-off-by: Viktor Novotný <noviktor@seznam.cz> Signed-off-by: Francisco Jerez <currojerez@riseup.net>
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_surface.c7
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_texture.c135
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_util.h20
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_surface.c9
4 files changed, 138 insertions, 33 deletions
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_surface.c b/src/mesa/drivers/dri/nouveau/nouveau_surface.c
index f2521149088..ffac309b9ef 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_surface.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_surface.c
@@ -28,6 +28,8 @@
28#include "nouveau_context.h" 28#include "nouveau_context.h"
29#include "nouveau_util.h" 29#include "nouveau_util.h"
30 30
31#include "main/formats.h"
32
31void 33void
32nouveau_surface_alloc(struct gl_context *ctx, struct nouveau_surface *s, 34nouveau_surface_alloc(struct gl_context *ctx, struct nouveau_surface *s,
33 enum nouveau_surface_layout layout, 35 enum nouveau_surface_layout layout,
@@ -45,7 +47,7 @@ nouveau_surface_alloc(struct gl_context *ctx, struct nouveau_surface *s,
45 .width = width, 47 .width = width,
46 .height = height, 48 .height = height,
47 .cpp = cpp, 49 .cpp = cpp,
48 .pitch = width * cpp, 50 .pitch = _mesa_format_row_stride(format, width),
49 }; 51 };
50 52
51 if (layout == TILED) { 53 if (layout == TILED) {
@@ -64,7 +66,8 @@ nouveau_surface_alloc(struct gl_context *ctx, struct nouveau_surface *s,
64 s->pitch = align(s->pitch, 64); 66 s->pitch = align(s->pitch, 64);
65 } 67 }
66 68
67 ret = nouveau_bo_new(context_dev(ctx), flags, 0, s->pitch * height, 69 ret = nouveau_bo_new(context_dev(ctx), flags, 0,
70 get_format_blocksy(format, height) * s->pitch,
68 &config, &s->bo); 71 &config, &s->bo);
69 assert(!ret); 72 assert(!ret);
70} 73}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
index eadbeb45d7a..a2e96aa1684 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
@@ -91,6 +91,7 @@ nouveau_teximage_map(struct gl_context *ctx, struct gl_texture_image *ti,
91 if (s->bo) { 91 if (s->bo) {
92 if (!(access & GL_MAP_READ_BIT) && 92 if (!(access & GL_MAP_READ_BIT) &&
93 nouveau_pushbuf_refd(context_push(ctx), s->bo)) { 93 nouveau_pushbuf_refd(context_push(ctx), s->bo)) {
94 unsigned size;
94 /* 95 /*
95 * Heuristic: use a bounce buffer to pipeline 96 * Heuristic: use a bounce buffer to pipeline
96 * teximage transfers. 97 * teximage transfers.
@@ -104,7 +105,8 @@ nouveau_teximage_map(struct gl_context *ctx, struct gl_texture_image *ti,
104 nti->transfer.x = x; 105 nti->transfer.x = x;
105 nti->transfer.y = y; 106 nti->transfer.y = y;
106 107
107 nti->base.Map = nouveau_get_scratch(ctx, st->pitch * h, 108 size = get_format_blocksy(st->format, h) * st->pitch;
109 nti->base.Map = nouveau_get_scratch(ctx, size,
108 &st->bo, &st->offset); 110 &st->bo, &st->offset);
109 111
110 } else { 112 } else {
@@ -120,7 +122,10 @@ nouveau_teximage_map(struct gl_context *ctx, struct gl_texture_image *ti,
120 assert(!ret); 122 assert(!ret);
121 } 123 }
122 124
123 nti->base.Map = s->bo->map + y * s->pitch + x * s->cpp; 125 nti->base.Map = s->bo->map +
126 get_format_blocksy(s->format, y) * s->pitch +
127 get_format_blocksx(s->format, x) * s->cpp;
128
124 } 129 }
125 } 130 }
126} 131}
@@ -163,6 +168,7 @@ nouveau_map_texture_image(struct gl_context *ctx,
163 if (s->bo) { 168 if (s->bo) {
164 if (!(mode & GL_MAP_READ_BIT) && 169 if (!(mode & GL_MAP_READ_BIT) &&
165 nouveau_pushbuf_refd(context_push(ctx), s->bo)) { 170 nouveau_pushbuf_refd(context_push(ctx), s->bo)) {
171 unsigned size;
166 /* 172 /*
167 * Heuristic: use a bounce buffer to pipeline 173 * Heuristic: use a bounce buffer to pipeline
168 * teximage transfers. 174 * teximage transfers.
@@ -176,8 +182,9 @@ nouveau_map_texture_image(struct gl_context *ctx,
176 nti->transfer.x = x; 182 nti->transfer.x = x;
177 nti->transfer.y = y; 183 nti->transfer.y = y;
178 184
179 *map = nouveau_get_scratch(ctx, st->pitch * h, 185 size = get_format_blocksy(st->format, h) * st->pitch;
180 &st->bo, &st->offset); 186 *map = nouveau_get_scratch(ctx, size,
187 &st->bo, &st->offset);
181 *stride = st->pitch; 188 *stride = st->pitch;
182 } else { 189 } else {
183 int ret, flags = 0; 190 int ret, flags = 0;
@@ -192,11 +199,15 @@ nouveau_map_texture_image(struct gl_context *ctx,
192 assert(!ret); 199 assert(!ret);
193 } 200 }
194 201
195 *map = s->bo->map + y * s->pitch + x * s->cpp; 202 *map = s->bo->map +
203 get_format_blocksy(s->format, y) * s->pitch +
204 get_format_blocksx(s->format, x) * s->cpp;
196 *stride = s->pitch; 205 *stride = s->pitch;
197 } 206 }
198 } else { 207 } else {
199 *map = nti->base.Map + y * s->pitch + x * s->cpp; 208 *map = nti->base.Map +
209 get_format_blocksy(s->format, y) * s->pitch +
210 get_format_blocksx(s->format, x) * s->cpp;
200 *stride = s->pitch; 211 *stride = s->pitch;
201 } 212 }
202} 213}
@@ -286,6 +297,22 @@ nouveau_choose_tex_format(struct gl_context *ctx, GLint internalFormat,
286 case GL_INTENSITY8: 297 case GL_INTENSITY8:
287 return MESA_FORMAT_I8; 298 return MESA_FORMAT_I8;
288 299
300 case GL_RGB_S3TC:
301 case GL_RGB4_S3TC:
302 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
303 return MESA_FORMAT_RGB_DXT1;
304
305 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
306 return MESA_FORMAT_RGBA_DXT1;
307
308 case GL_RGBA_S3TC:
309 case GL_RGBA4_S3TC:
310 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
311 return MESA_FORMAT_RGBA_DXT3;
312
313 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
314 return MESA_FORMAT_RGBA_DXT5;
315
289 default: 316 default:
290 assert(0); 317 assert(0);
291 } 318 }
@@ -353,7 +380,9 @@ relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
353 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces; 380 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
354 struct nouveau_surface *s = &to_nouveau_teximage(base)->surface; 381 struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
355 int i, ret, last = get_last_level(t); 382 int i, ret, last = get_last_level(t);
356 unsigned size, offset = 0, 383 enum nouveau_surface_layout layout =
384 (_mesa_is_format_compressed(s->format) ? LINEAR : SWIZZLED);
385 unsigned size, pitch, offset = 0,
357 width = s->width, 386 width = s->width,
358 height = s->height; 387 height = s->height;
359 388
@@ -363,7 +392,8 @@ relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
363 392
364 /* Relayout the mipmap tree. */ 393 /* Relayout the mipmap tree. */
365 for (i = t->BaseLevel; i <= last; i++) { 394 for (i = t->BaseLevel; i <= last; i++) {
366 size = width * height * s->cpp; 395 pitch = _mesa_format_row_stride(s->format, width);
396 size = get_format_blocksy(s->format, height) * pitch;
367 397
368 /* Images larger than 16B have to be aligned. */ 398 /* Images larger than 16B have to be aligned. */
369 if (size > 16) 399 if (size > 16)
@@ -371,12 +401,12 @@ relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
371 401
372 ss[i] = (struct nouveau_surface) { 402 ss[i] = (struct nouveau_surface) {
373 .offset = offset, 403 .offset = offset,
374 .layout = SWIZZLED, 404 .layout = layout,
375 .format = s->format, 405 .format = s->format,
376 .width = width, 406 .width = width,
377 .height = height, 407 .height = height,
378 .cpp = s->cpp, 408 .cpp = s->cpp,
379 .pitch = width * s->cpp, 409 .pitch = pitch,
380 }; 410 };
381 411
382 offset += size; 412 offset += size;
@@ -453,8 +483,10 @@ nouveau_teximage(struct gl_context *ctx, GLint dims,
453 struct gl_texture_image *ti, 483 struct gl_texture_image *ti,
454 GLint internalFormat, 484 GLint internalFormat,
455 GLint width, GLint height, GLint depth, GLint border, 485 GLint width, GLint height, GLint depth, GLint border,
486 GLsizei imageSize,
456 GLenum format, GLenum type, const GLvoid *pixels, 487 GLenum format, GLenum type, const GLvoid *pixels,
457 const struct gl_pixelstore_attrib *packing) 488 const struct gl_pixelstore_attrib *packing,
489 GLboolean compressed)
458{ 490{
459 struct gl_texture_object *t = ti->TexObject; 491 struct gl_texture_object *t = ti->TexObject;
460 const GLuint level = ti->Level; 492 const GLuint level = ti->Level;
@@ -467,9 +499,15 @@ nouveau_teximage(struct gl_context *ctx, GLint dims,
467 ti->TexFormat, width, height); 499 ti->TexFormat, width, height);
468 nti->base.RowStride = s->pitch / s->cpp; 500 nti->base.RowStride = s->pitch / s->cpp;
469 501
470 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, 502 if (compressed)
471 format, type, pixels, packing, 503 pixels = _mesa_validate_pbo_compressed_teximage(ctx,
472 "glTexImage"); 504 imageSize,
505 pixels, packing, "glCompressedTexImage");
506 else
507 pixels = _mesa_validate_pbo_teximage(ctx,
508 dims, width, height, depth, format, type,
509 pixels, packing, "glTexImage");
510
473 if (pixels) { 511 if (pixels) {
474 /* Store the pixel data. */ 512 /* Store the pixel data. */
475 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT, 513 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT,
@@ -511,8 +549,8 @@ nouveau_teximage_1d(struct gl_context *ctx,
511 const struct gl_pixelstore_attrib *packing) 549 const struct gl_pixelstore_attrib *packing)
512{ 550{
513 nouveau_teximage(ctx, 1, ti, internalFormat, 551 nouveau_teximage(ctx, 1, ti, internalFormat,
514 width, 1, 1, border, format, type, pixels, 552 width, 1, 1, border, 0, format, type, pixels,
515 packing); 553 packing, GL_FALSE);
516} 554}
517 555
518static void 556static void
@@ -524,8 +562,8 @@ nouveau_teximage_2d(struct gl_context *ctx,
524 const struct gl_pixelstore_attrib *packing) 562 const struct gl_pixelstore_attrib *packing)
525{ 563{
526 nouveau_teximage(ctx, 2, ti, internalFormat, 564 nouveau_teximage(ctx, 2, ti, internalFormat,
527 width, height, 1, border, format, type, pixels, 565 width, height, 1, border, 0, format, type, pixels,
528 packing); 566 packing, GL_FALSE);
529} 567}
530 568
531static void 569static void
@@ -537,8 +575,20 @@ nouveau_teximage_3d(struct gl_context *ctx,
537 const struct gl_pixelstore_attrib *packing) 575 const struct gl_pixelstore_attrib *packing)
538{ 576{
539 nouveau_teximage(ctx, 3, ti, internalFormat, 577 nouveau_teximage(ctx, 3, ti, internalFormat,
540 width, height, depth, border, format, type, pixels, 578 width, height, depth, border, 0, format, type, pixels,
541 packing); 579 packing, GL_FALSE);
580}
581
582static void
583nouveau_compressed_teximage_2d(struct gl_context *ctx,
584 struct gl_texture_image *ti,
585 GLint internalFormat,
586 GLint width, GLint height, GLint border,
587 GLsizei imageSize, const GLvoid *data)
588{
589 nouveau_teximage(ctx, 2, ti, internalFormat,
590 width, height, 1, border, imageSize, 0, 0, data,
591 &ctx->Unpack, GL_TRUE);
542} 592}
543 593
544static void 594static void
@@ -546,21 +596,29 @@ nouveau_texsubimage(struct gl_context *ctx, GLint dims,
546 struct gl_texture_image *ti, 596 struct gl_texture_image *ti,
547 GLint xoffset, GLint yoffset, GLint zoffset, 597 GLint xoffset, GLint yoffset, GLint zoffset,
548 GLint width, GLint height, GLint depth, 598 GLint width, GLint height, GLint depth,
599 GLsizei imageSize,
549 GLenum format, GLenum type, const void *pixels, 600 GLenum format, GLenum type, const void *pixels,
550 const struct gl_pixelstore_attrib *packing) 601 const struct gl_pixelstore_attrib *packing,
602 GLboolean compressed)
551{ 603{
552 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; 604 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
553 struct nouveau_teximage *nti = to_nouveau_teximage(ti); 605 struct nouveau_teximage *nti = to_nouveau_teximage(ti);
554 int ret; 606 int ret;
555 607
556 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, 608 if (compressed)
557 format, type, pixels, packing, 609 pixels = _mesa_validate_pbo_compressed_teximage(ctx,
558 "glTexSubImage"); 610 imageSize,
611 pixels, packing, "glCompressedTexSubImage");
612 else
613 pixels = _mesa_validate_pbo_teximage(ctx,
614 dims, width, height, depth, format, type,
615 pixels, packing, "glTexSubImage");
616
559 if (pixels) { 617 if (pixels) {
560 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT, 618 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT,
561 xoffset, yoffset, width, height); 619 xoffset, yoffset, width, height);
562 620
563 ret = _mesa_texstore(ctx, 3, ti->_BaseFormat, ti->TexFormat, 621 ret = _mesa_texstore(ctx, dims, ti->_BaseFormat, ti->TexFormat,
564 s->pitch, 622 s->pitch,
565 &nti->base.Map, 623 &nti->base.Map,
566 width, height, depth, 624 width, height, depth,
@@ -586,8 +644,8 @@ nouveau_texsubimage_3d(struct gl_context *ctx,
586 const struct gl_pixelstore_attrib *packing) 644 const struct gl_pixelstore_attrib *packing)
587{ 645{
588 nouveau_texsubimage(ctx, 3, ti, xoffset, yoffset, zoffset, 646 nouveau_texsubimage(ctx, 3, ti, xoffset, yoffset, zoffset,
589 width, height, depth, format, type, pixels, 647 width, height, depth, 0, format, type, pixels,
590 packing); 648 packing, GL_FALSE);
591} 649}
592 650
593static void 651static void
@@ -599,8 +657,8 @@ nouveau_texsubimage_2d(struct gl_context *ctx,
599 const struct gl_pixelstore_attrib *packing) 657 const struct gl_pixelstore_attrib *packing)
600{ 658{
601 nouveau_texsubimage(ctx, 2, ti, xoffset, yoffset, 0, 659 nouveau_texsubimage(ctx, 2, ti, xoffset, yoffset, 0,
602 width, height, 1, format, type, pixels, 660 width, height, 1, 0, format, type, pixels,
603 packing); 661 packing, GL_FALSE);
604} 662}
605 663
606static void 664static void
@@ -611,8 +669,21 @@ nouveau_texsubimage_1d(struct gl_context *ctx,
611 const struct gl_pixelstore_attrib *packing) 669 const struct gl_pixelstore_attrib *packing)
612{ 670{
613 nouveau_texsubimage(ctx, 1, ti, xoffset, 0, 0, 671 nouveau_texsubimage(ctx, 1, ti, xoffset, 0, 0,
614 width, 1, 1, format, type, pixels, 672 width, 1, 1, 0, format, type, pixels,
615 packing); 673 packing, GL_FALSE);
674}
675
676static void
677nouveau_compressed_texsubimage_2d(struct gl_context *ctx,
678 struct gl_texture_image *ti,
679 GLint xoffset, GLint yoffset,
680 GLsizei width, GLint height,
681 GLenum format,
682 GLint imageSize, const void *data)
683{
684 nouveau_texsubimage(ctx, 2, ti, xoffset, yoffset, 0,
685 width, height, 1, imageSize, format, 0, data,
686 &ctx->Unpack, GL_TRUE);
616} 687}
617 688
618static void 689static void
@@ -691,6 +762,8 @@ nouveau_texture_functions_init(struct dd_function_table *functions)
691 functions->TexSubImage1D = nouveau_texsubimage_1d; 762 functions->TexSubImage1D = nouveau_texsubimage_1d;
692 functions->TexSubImage2D = nouveau_texsubimage_2d; 763 functions->TexSubImage2D = nouveau_texsubimage_2d;
693 functions->TexSubImage3D = nouveau_texsubimage_3d; 764 functions->TexSubImage3D = nouveau_texsubimage_3d;
765 functions->CompressedTexImage2D = nouveau_compressed_teximage_2d;
766 functions->CompressedTexSubImage2D = nouveau_compressed_texsubimage_2d;
694 functions->BindTexture = nouveau_bind_texture; 767 functions->BindTexture = nouveau_bind_texture;
695 functions->MapTextureImage = nouveau_map_texture_image; 768 functions->MapTextureImage = nouveau_map_texture_image;
696 functions->UnmapTextureImage = nouveau_unmap_texture_image; 769 functions->UnmapTextureImage = nouveau_unmap_texture_image;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_util.h b/src/mesa/drivers/dri/nouveau/nouveau_util.h
index d4cc5c4fb9c..17d6965ee2c 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_util.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_util.h
@@ -207,4 +207,24 @@ get_texgen_coeff(struct gl_texgen *c)
207 return NULL; 207 return NULL;
208} 208}
209 209
210static inline unsigned
211get_format_blocksx(gl_format format,
212 unsigned x)
213{
214 GLuint blockwidth;
215 GLuint blockheight;
216 _mesa_get_format_block_size(format, &blockwidth, &blockheight);
217 return (x + blockwidth - 1) / blockwidth;
218}
219
220static inline unsigned
221get_format_blocksy(gl_format format,
222 unsigned y)
223{
224 GLuint blockwidth;
225 GLuint blockheight;
226 _mesa_get_format_block_size(format, &blockwidth, &blockheight);
227 return (y + blockheight - 1) / blockheight;
228}
229
210#endif 230#endif
diff --git a/src/mesa/drivers/dri/nouveau/nv04_surface.c b/src/mesa/drivers/dri/nouveau/nv04_surface.c
index 522c94819c0..103453f1b9a 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_surface.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_surface.c
@@ -393,6 +393,15 @@ nv04_surface_copy(struct gl_context *ctx,
393 int dx, int dy, int sx, int sy, 393 int dx, int dy, int sx, int sy,
394 int w, int h) 394 int w, int h)
395{ 395{
396 if (_mesa_is_format_compressed(src->format)) {
397 sx = get_format_blocksx(src->format, sx);
398 sy = get_format_blocksy(src->format, sy);
399 dx = get_format_blocksx(dst->format, dx);
400 dy = get_format_blocksy(dst->format, dy);
401 w = get_format_blocksx(src->format, w);
402 h = get_format_blocksy(src->format, h);
403 }
404
396 /* Linear texture copy. */ 405 /* Linear texture copy. */
397 if ((src->layout == LINEAR && dst->layout == LINEAR) || 406 if ((src->layout == LINEAR && dst->layout == LINEAR) ||
398 dst->width <= 2 || dst->height <= 1) { 407 dst->width <= 2 || dst->height <= 1) {