diff options
author | Viktor Novotný <noviktor@seznam.cz> | 2012-05-01 15:23:50 +0200 |
---|---|---|
committer | Francisco Jerez <currojerez@riseup.net> | 2012-05-02 03:13:42 +0200 |
commit | 6d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9 (patch) | |
tree | 2aaf60d6df163f777e7c8abeabff527d0c0274cb | |
parent | b389b608d8d853c1f9383b04a222d96a5a096178 (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.c | 7 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_texture.c | 135 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_util.h | 20 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nv04_surface.c | 9 |
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 | |||
31 | void | 33 | void |
32 | nouveau_surface_alloc(struct gl_context *ctx, struct nouveau_surface *s, | 34 | nouveau_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 | ||
518 | static void | 556 | static 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 | ||
531 | static void | 569 | static 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 | |||
582 | static void | ||
583 | nouveau_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 | ||
544 | static void | 594 | static 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 | ||
593 | static void | 651 | static 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 | ||
606 | static void | 664 | static 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 | |||
676 | static void | ||
677 | nouveau_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 | ||
618 | static void | 689 | static 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 | ||
210 | static inline unsigned | ||
211 | get_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 | |||
220 | static inline unsigned | ||
221 | get_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) { |