summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-11-11 16:13:06 +0000
committerDave Airlie <airlied@redhat.com>2011-12-05 14:36:19 +0000
commitb2596c36c8f73e8bb7a0b1679b491662aeb2f9d9 (patch)
tree0eff8746b4334dbc6e780e7426031a910335a781
parentfd7fcfcc2dffb73ac3159a04ccd164b527c11a8f (diff)
radeon: texture/renderbuffer overhaul.
This could have been split up better, but the driver is just broken now, so bisecting the brokenness is going to be painful no matter what. This adds renderbuffer mapping/unmapping along with texture image allocation. It drops all the old texture upload paths, some of which could possible be reimplemented with the blitter later. It also redoes the span code paths to use its own set of image mapping handlers, along with removing the tiling decode paths for the color buffers, since we now hope to use the blitter for this. Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--src/mesa/drivers/dri/r200/r200_blit.c16
-rw-r--r--src/mesa/drivers/dri/r200/r200_blit.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_blit.c16
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_blit.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c132
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c30
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h7
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_pixel_read.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_span.c165
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tex_copy.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c600
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.h6
13 files changed, 385 insertions, 599 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_blit.c b/src/mesa/drivers/dri/r200/r200_blit.c
index 487bb5b78e1..04ab6d07def 100644
--- a/src/mesa/drivers/dri/r200/r200_blit.c
+++ b/src/mesa/drivers/dri/r200/r200_blit.c
@@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
38} 38}
39 39
40/* common formats supported as both textures and render targets */ 40/* common formats supported as both textures and render targets */
41unsigned r200_check_blit(gl_format mesa_format) 41unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch)
42{ 42{
43 /* XXX others? BE/LE? */ 43 /* XXX others? BE/LE? */
44 switch (mesa_format) { 44 switch (mesa_format) {
@@ -58,6 +58,12 @@ unsigned r200_check_blit(gl_format mesa_format)
58 return 0; 58 return 0;
59 } 59 }
60 60
61 /* Rendering to small buffer doesn't work.
62 * Looks like a hw limitation.
63 */
64 if (dst_pitch < 32)
65 return 0;
66
61 /* ??? */ 67 /* ??? */
62 if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) 68 if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
63 return 0; 69 return 0;
@@ -467,19 +473,13 @@ unsigned r200_blit(struct gl_context *ctx,
467{ 473{
468 struct r200_context *r200 = R200_CONTEXT(ctx); 474 struct r200_context *r200 = R200_CONTEXT(ctx);
469 475
470 if (!r200_check_blit(dst_mesaformat)) 476 if (!r200_check_blit(dst_mesaformat, dst_pitch))
471 return GL_FALSE; 477 return GL_FALSE;
472 478
473 /* Make sure that colorbuffer has even width - hw limitation */ 479 /* Make sure that colorbuffer has even width - hw limitation */
474 if (dst_pitch % 2 > 0) 480 if (dst_pitch % 2 > 0)
475 ++dst_pitch; 481 ++dst_pitch;
476 482
477 /* Rendering to small buffer doesn't work.
478 * Looks like a hw limitation.
479 */
480 if (dst_pitch < 32)
481 return GL_FALSE;
482
483 /* Need to clamp the region size to make sure 483 /* Need to clamp the region size to make sure
484 * we don't read outside of the source buffer 484 * we don't read outside of the source buffer
485 * or write outside of the destination buffer. 485 * or write outside of the destination buffer.
diff --git a/src/mesa/drivers/dri/r200/r200_blit.h b/src/mesa/drivers/dri/r200/r200_blit.h
index 56018b9c0ea..fb5dacbe870 100644
--- a/src/mesa/drivers/dri/r200/r200_blit.h
+++ b/src/mesa/drivers/dri/r200/r200_blit.h
@@ -30,7 +30,7 @@
30 30
31void r200_blit_init(struct r200_context *r200); 31void r200_blit_init(struct r200_context *r200);
32 32
33unsigned r200_check_blit(gl_format mesa_format); 33unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch);
34 34
35unsigned r200_blit(struct gl_context *ctx, 35unsigned r200_blit(struct gl_context *ctx,
36 struct radeon_bo *src_bo, 36 struct radeon_bo *src_bo,
diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.c b/src/mesa/drivers/dri/radeon/radeon_blit.c
index 330e1abdfe5..b84f2fa9f2b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_blit.c
+++ b/src/mesa/drivers/dri/radeon/radeon_blit.c
@@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
38} 38}
39 39
40/* common formats supported as both textures and render targets */ 40/* common formats supported as both textures and render targets */
41unsigned r100_check_blit(gl_format mesa_format) 41unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch)
42{ 42{
43 /* XXX others? BE/LE? */ 43 /* XXX others? BE/LE? */
44 switch (mesa_format) { 44 switch (mesa_format) {
@@ -55,6 +55,12 @@ unsigned r100_check_blit(gl_format mesa_format)
55 return 0; 55 return 0;
56 } 56 }
57 57
58 /* Rendering to small buffer doesn't work.
59 * Looks like a hw limitation.
60 */
61 if (dst_pitch < 32)
62 return 0;
63
58 /* ??? */ 64 /* ??? */
59 if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) 65 if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
60 return 0; 66 return 0;
@@ -344,19 +350,13 @@ unsigned r100_blit(struct gl_context *ctx,
344{ 350{
345 struct r100_context *r100 = R100_CONTEXT(ctx); 351 struct r100_context *r100 = R100_CONTEXT(ctx);
346 352
347 if (!r100_check_blit(dst_mesaformat)) 353 if (!r100_check_blit(dst_mesaformat, dst_pitch))
348 return GL_FALSE; 354 return GL_FALSE;
349 355
350 /* Make sure that colorbuffer has even width - hw limitation */ 356 /* Make sure that colorbuffer has even width - hw limitation */
351 if (dst_pitch % 2 > 0) 357 if (dst_pitch % 2 > 0)
352 ++dst_pitch; 358 ++dst_pitch;
353 359
354 /* Rendering to small buffer doesn't work.
355 * Looks like a hw limitation.
356 */
357 if (dst_pitch < 32)
358 return GL_FALSE;
359
360 /* Need to clamp the region size to make sure 360 /* Need to clamp the region size to make sure
361 * we don't read outside of the source buffer 361 * we don't read outside of the source buffer
362 * or write outside of the destination buffer. 362 * or write outside of the destination buffer.
diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.h b/src/mesa/drivers/dri/radeon/radeon_blit.h
index 5e5c73481a6..4fac4afe889 100644
--- a/src/mesa/drivers/dri/radeon/radeon_blit.h
+++ b/src/mesa/drivers/dri/radeon/radeon_blit.h
@@ -30,7 +30,7 @@
30 30
31void r100_blit_init(struct r100_context *r100); 31void r100_blit_init(struct r100_context *r100);
32 32
33unsigned r100_check_blit(gl_format mesa_format); 33unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch);
34 34
35unsigned r100_blit(struct gl_context *ctx, 35unsigned r100_blit(struct gl_context *ctx,
36 struct radeon_bo *src_bo, 36 struct radeon_bo *src_bo,
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index 6de9f8a37b5..b8c6bf00ebc 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -89,6 +89,7 @@ struct radeon_renderbuffer
89 struct radeon_bo *map_bo; 89 struct radeon_bo *map_bo;
90 GLbitfield map_mode; 90 GLbitfield map_mode;
91 int map_x, map_y, map_w, map_h; 91 int map_x, map_y, map_w, map_h;
92 int map_pitch;
92 93
93 uint32_t draw_offset; /* FBO */ 94 uint32_t draw_offset; /* FBO */
94 /* boo Xorg 6.8.2 compat */ 95 /* boo Xorg 6.8.2 compat */
@@ -174,6 +175,7 @@ struct _radeon_texture_image {
174 */ 175 */
175 struct _radeon_mipmap_tree *mt; 176 struct _radeon_mipmap_tree *mt;
176 struct radeon_bo *bo; 177 struct radeon_bo *bo;
178 GLboolean used_as_render_target;
177}; 179};
178 180
179 181
@@ -481,7 +483,7 @@ struct radeon_context {
481 void (*free_context)(struct gl_context *ctx); 483 void (*free_context)(struct gl_context *ctx);
482 void (*emit_query_finish)(radeonContextPtr radeon); 484 void (*emit_query_finish)(radeonContextPtr radeon);
483 void (*update_scissor)(struct gl_context *ctx); 485 void (*update_scissor)(struct gl_context *ctx);
484 unsigned (*check_blit)(gl_format mesa_format); 486 unsigned (*check_blit)(gl_format mesa_format, uint32_t dst_pitch);
485 unsigned (*blit)(struct gl_context *ctx, 487 unsigned (*blit)(struct gl_context *ctx,
486 struct radeon_bo *src_bo, 488 struct radeon_bo *src_bo,
487 intptr_t src_offset, 489 intptr_t src_offset,
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index 9967fe5139e..5aad67f1a75 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -82,56 +82,96 @@ radeon_map_renderbuffer(struct gl_context *ctx,
82 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 82 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
83 GLubyte *map; 83 GLubyte *map;
84 GLboolean ok; 84 GLboolean ok;
85 int stride, ret; 85 int stride, flip_stride;
86 86 int ret;
87 assert(rrb && rrb->bo); 87 int src_x, src_y;
88 88
89 /* Make a temporary buffer and blit the current contents of the renderbuffer 89 if (!rrb || !rrb->bo) {
90 * out to it. This gives us linear access to the buffer, instead of having 90 *out_map = NULL;
91 * to do detiling in software. 91 *out_stride = 0;
92 */ 92 return;
93 assert(!rrb->map_bo); 93 }
94 rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0, 94
95 rrb->pitch * h, 4,
96 RADEON_GEM_DOMAIN_GTT, 0);
97 rrb->map_mode = mode; 95 rrb->map_mode = mode;
98 rrb->map_x = x; 96 rrb->map_x = x;
99 rrb->map_y = y; 97 rrb->map_y = y;
100 rrb->map_w = w; 98 rrb->map_w = w;
101 rrb->map_h = h; 99 rrb->map_h = h;
100 rrb->map_pitch = rrb->pitch;
101
102 ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp);
103 if (ok) {
104 if (rb->Name) {
105 src_x = x;
106 src_y = y;
107 } else {
108 src_x = x;
109 src_y = rrb->base.Height - y - h;
110 }
111
112 /* Make a temporary buffer and blit the current contents of the renderbuffer
113 * out to it. This gives us linear access to the buffer, instead of having
114 * to do detiling in software.
115 */
116
117 rrb->map_pitch = rrb->pitch;
118
119 assert(!rrb->map_bo);
120 rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
121 rrb->map_pitch * h, 4,
122 RADEON_GEM_DOMAIN_GTT, 0);
123
124 ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
125 rb->Format, rrb->pitch / rrb->cpp,
126 rb->Width, rb->Height,
127 src_x, src_y,
128 rrb->map_bo, 0,
129 rb->Format, rrb->map_pitch / rrb->cpp,
130 w, h,
131 0, 0,
132 w, h,
133 GL_FALSE);
134 assert(ok);
135
136 ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
137 assert(!ret);
138
139 map = rrb->map_bo->ptr;
140
141 if (rb->Name) {
142 *out_map = map;
143 *out_stride = rrb->map_pitch;
144 } else {
145 *out_map = map + (h - 1) * rrb->map_pitch;
146 *out_stride = -rrb->map_pitch;
147 }
148 return;
149 }
150
151 /* sw fallback flush stuff */
152 if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) {
153 radeon_firevertices(rmesa);
154 }
102 155
103 ok = rmesa->vtbl.check_blit(rb->Format); 156 ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
104 assert(ok);
105
106 ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
107 rb->Format, rrb->pitch / rrb->cpp,
108 rb->Width, rb->Height,
109 x, y,
110 rrb->map_bo, 0,
111 rb->Format, rrb->pitch / rrb->cpp,
112 w, h,
113 0, 0,
114 w, h,
115 GL_FALSE);
116 assert(ok);
117
118 radeon_bo_wait(rrb->map_bo);
119 ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
120 assert(!ret); 157 assert(!ret);
121 158
122 map = rrb->map_bo->ptr; 159 map = rrb->bo->ptr;
123 stride = rrb->pitch; 160 stride = rrb->map_pitch;
124 161
125 if (rb->Name == 0) { 162 if (rb->Name == 0) {
126 map += stride * (rb->Height - 1); 163 y = rb->Height - 1 - y;
127 stride = -stride; 164 flip_stride = -stride;
165 } else {
166 flip_stride = stride;
167 map += rrb->draw_offset;
128 } 168 }
129 169
130 map += x * _mesa_get_format_bytes(rb->Format); 170 map += x * rrb->cpp;
131 map += (int)y * stride; 171 map += (int)y * stride;
132 172
133 *out_map = map; 173 *out_map = map;
134 *out_stride = stride; 174 *out_stride = flip_stride;
135} 175}
136 176
137static void 177static void
@@ -142,11 +182,17 @@ radeon_unmap_renderbuffer(struct gl_context *ctx,
142 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 182 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
143 GLboolean ok; 183 GLboolean ok;
144 184
185 if (!rrb->map_bo) {
186 if (rrb->bo)
187 radeon_bo_unmap(rrb->bo);
188 return;
189 }
190
145 radeon_bo_unmap(rrb->map_bo); 191 radeon_bo_unmap(rrb->map_bo);
146 192
147 if (rrb->map_mode & GL_MAP_WRITE_BIT) { 193 if (rrb->map_mode & GL_MAP_WRITE_BIT) {
148 ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0, 194 ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0,
149 rb->Format, rrb->pitch / rrb->cpp, 195 rb->Format, rrb->map_pitch / rrb->cpp,
150 rrb->map_w, rrb->map_h, 196 rrb->map_w, rrb->map_h,
151 0, 0, 197 0, 0,
152 rrb->bo, rrb->draw_offset, 198 rrb->bo, rrb->draw_offset,
@@ -627,7 +673,7 @@ radeon_render_texture(struct gl_context * ctx,
627 673
628 radeon_image = (radeon_texture_image *)newImage; 674 radeon_image = (radeon_texture_image *)newImage;
629 675
630 if (!radeon_image->mt || newImage->Border != 0) { 676 if (!radeon_image->mt) {
631 /* Fallback on drawing to a texture without a miptree. 677 /* Fallback on drawing to a texture without a miptree.
632 */ 678 */
633 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); 679 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
@@ -681,6 +727,7 @@ radeon_render_texture(struct gl_context * ctx,
681 * the image we are rendering to */ 727 * the image we are rendering to */
682 rrb->draw_offset = imageOffset; 728 rrb->draw_offset = imageOffset;
683 rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride; 729 rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride;
730 radeon_image->used_as_render_target = GL_TRUE;
684 731
685 /* update drawing region, etc */ 732 /* update drawing region, etc */
686 radeon_draw_buffer(ctx, fb); 733 radeon_draw_buffer(ctx, fb);
@@ -690,7 +737,16 @@ static void
690radeon_finish_render_texture(struct gl_context * ctx, 737radeon_finish_render_texture(struct gl_context * ctx,
691 struct gl_renderbuffer_attachment *att) 738 struct gl_renderbuffer_attachment *att)
692{ 739{
693 740 struct gl_texture_object *tex_obj = att->Texture;
741 struct gl_texture_image *image =
742 tex_obj->Image[att->CubeMapFace][att->TextureLevel];
743 radeon_texture_image *radeon_image = (radeon_texture_image *)image;
744
745 if (radeon_image)
746 radeon_image->used_as_render_target = GL_FALSE;
747
748 if (ctx->Driver.Flush)
749 ctx->Driver.Flush(ctx); /* +r6/r7 */
694} 750}
695static void 751static void
696radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) 752radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index 05daf1cec43..23af9aca6ce 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -185,9 +185,9 @@ static void calculate_miptree_layout(radeonContextPtr rmesa, radeon_mipmap_tree
185/** 185/**
186 * Create a new mipmap tree, calculate its layout and allocate memory. 186 * Create a new mipmap tree, calculate its layout and allocate memory.
187 */ 187 */
188static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, 188radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa,
189 GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels, 189 GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
190 GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits) 190 GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits)
191{ 191{
192 radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree); 192 radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree);
193 193
@@ -298,13 +298,10 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj,
298 * given face and level. 298 * given face and level.
299 */ 299 */
300GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, 300GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
301 struct gl_texture_image *texImage, GLuint face, GLuint level) 301 struct gl_texture_image *texImage)
302{ 302{
303 radeon_mipmap_level *lvl; 303 radeon_mipmap_level *lvl;
304 304 GLuint level = texImage->Level;
305 if (face >= mt->faces)
306 return GL_FALSE;
307
308 if (texImage->TexFormat != mt->mesaFormat) 305 if (texImage->TexFormat != mt->mesaFormat)
309 return GL_FALSE; 306 return GL_FALSE;
310 307
@@ -332,7 +329,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g
332 329
333 mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel]; 330 mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel];
334 firstImage = texObj->Image[0][texObj->BaseLevel]; 331 firstImage = texObj->Image[0][texObj->BaseLevel];
335 numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1); 332 numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1);
336 333
337 if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) { 334 if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) {
338 fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj); 335 fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj);
@@ -372,7 +369,6 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t)
372 struct gl_texture_object *texObj = &t->base; 369 struct gl_texture_object *texObj = &t->base;
373 struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; 370 struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];
374 GLuint numLevels; 371 GLuint numLevels;
375
376 assert(!t->mt); 372 assert(!t->mt);
377 373
378 if (!texImg) { 374 if (!texImg) {
@@ -544,27 +540,19 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
544{ 540{
545 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 541 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
546 radeonTexObj *t = radeon_tex_obj(texObj); 542 radeonTexObj *t = radeon_tex_obj(texObj);
543 radeon_mipmap_tree *dst_miptree;
547 544
548 if (t->validated || t->image_override) { 545 if (t->validated || t->image_override) {
549 return GL_TRUE; 546 return GL_TRUE;
550 } 547 }
551 548
552 if (texObj->Image[0][texObj->BaseLevel]->Border > 0)
553 return GL_FALSE;
554
555 _mesa_test_texobj_completeness(rmesa->glCtx, texObj);
556 if (!texObj->_Complete) {
557 return GL_FALSE;
558 }
559
560 calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod); 549 calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod);
561 550
562 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, 551 radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
563 "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", 552 "%s: Validating texture %p now, minLod = %d, maxLod = %d\n",
564 __FUNCTION__, texObj ,t->minLod, t->maxLod); 553 __FUNCTION__, texObj ,t->minLod, t->maxLod);
565 554
566 radeon_mipmap_tree *dst_miptree; 555 dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base._MaxLevel);
567 dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base.MaxLevel);
568 556
569 radeon_miptree_unreference(&t->mt); 557 radeon_miptree_unreference(&t->mt);
570 if (!dst_miptree) { 558 if (!dst_miptree) {
@@ -591,7 +579,7 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
591 "Checking image level %d, face %d, mt %p ... ", 579 "Checking image level %d, face %d, mt %p ... ",
592 level, face, img->mt); 580 level, face, img->mt);
593 581
594 if (img->mt != t->mt) { 582 if (img->mt != t->mt && !img->used_as_render_target) {
595 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 583 radeon_print(RADEON_TEXTURE, RADEON_TRACE,
596 "MIGRATING\n"); 584 "MIGRATING\n");
597 585
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
index c0c52f0ff9a..74007ffdebc 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
@@ -84,7 +84,8 @@ void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr);
84void radeon_miptree_unreference(radeon_mipmap_tree **ptr); 84void radeon_miptree_unreference(radeon_mipmap_tree **ptr);
85 85
86GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, 86GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
87 struct gl_texture_image *texImage, GLuint face, GLuint level); 87 struct gl_texture_image *texImage);
88
88void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t); 89void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t);
89GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, 90GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt,
90 GLuint face, GLuint level); 91 GLuint face, GLuint level);
@@ -98,4 +99,8 @@ unsigned get_texture_image_size(
98 unsigned height, 99 unsigned height,
99 unsigned depth, 100 unsigned depth,
100 unsigned tiling); 101 unsigned tiling);
102
103radeon_mipmap_tree *radeon_miptree_create(radeonContextPtr rmesa,
104 GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
105 GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits);
101#endif /* __RADEON_MIPMAP_TREE_H_ */ 106#endif /* __RADEON_MIPMAP_TREE_H_ */
diff --git a/src/mesa/drivers/dri/radeon/radeon_pixel_read.c b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c
index 9f6124034d9..68e3114989d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_pixel_read.c
+++ b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c
@@ -105,7 +105,7 @@ do_blit_readpixels(struct gl_context * ctx,
105 } 105 }
106 106
107 if (dst_format == MESA_FORMAT_NONE || 107 if (dst_format == MESA_FORMAT_NONE ||
108 !radeon->vtbl.check_blit(dst_format) || !radeon->vtbl.blit) { 108 !radeon->vtbl.check_blit(dst_format, rrb->pitch / rrb->cpp) || !radeon->vtbl.blit) {
109 return GL_FALSE; 109 return GL_FALSE;
110 } 110 }
111 111
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index ecc3befdbfe..b83d152091c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -216,25 +216,25 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
216 */ 216 */
217#define LOCAL_VARS \ 217#define LOCAL_VARS \
218 struct radeon_renderbuffer *rrb = (void *) rb; \ 218 struct radeon_renderbuffer *rrb = (void *) rb; \
219 const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \
220 const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
221 int minx = 0, miny = 0; \ 219 int minx = 0, miny = 0; \
222 int maxx = rb->Width; \ 220 int maxx = rb->Width; \
223 int maxy = rb->Height; \ 221 int maxy = rb->Height; \
222 void *buf = rb->Data; \
223 int pitch = rb->RowStride * rrb->cpp; \
224 GLuint p; \ 224 GLuint p; \
225 (void)p; 225 (void)p;
226 226
227#define LOCAL_DEPTH_VARS \ 227#define LOCAL_DEPTH_VARS \
228 struct radeon_renderbuffer *rrb = (void *) rb; \ 228 struct radeon_renderbuffer *rrb = (void *) rb; \
229 const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \
230 const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
231 int minx = 0, miny = 0; \ 229 int minx = 0, miny = 0; \
230 const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \
231 const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1; \
232 int maxx = rb->Width; \ 232 int maxx = rb->Width; \
233 int maxy = rb->Height; 233 int maxy = rb->Height;
234 234
235#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS 235#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
236 236
237#define Y_FLIP(_y) ((_y) * yScale + yBias) 237#define Y_FLIP(_y) (_y)
238 238
239#define HW_LOCK() 239#define HW_LOCK()
240#define HW_UNLOCK() 240#define HW_UNLOCK()
@@ -249,108 +249,78 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
249 */ 249 */
250#define SPANTMP_PIXEL_FMT GL_RGB 250#define SPANTMP_PIXEL_FMT GL_RGB
251#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 251#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
252
253#define TAG(x) radeon##x##_RGB565 252#define TAG(x) radeon##x##_RGB565
254#define TAG2(x,y) radeon##x##_RGB565##y 253#define TAG2(x,y) radeon##x##_RGB565##y
255#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
256#include "spantmp2.h" 254#include "spantmp2.h"
257 255
258#define SPANTMP_PIXEL_FMT GL_RGB 256#define SPANTMP_PIXEL_FMT GL_RGB
259#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV 257#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV
260
261#define TAG(x) radeon##x##_RGB565_REV 258#define TAG(x) radeon##x##_RGB565_REV
262#define TAG2(x,y) radeon##x##_RGB565_REV##y 259#define TAG2(x,y) radeon##x##_RGB565_REV##y
263#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
264#include "spantmp2.h" 260#include "spantmp2.h"
265 261
266/* 16 bit, ARGB1555 color spanline and pixel functions 262/* 16 bit, ARGB1555 color spanline and pixel functions
267 */ 263 */
268#define SPANTMP_PIXEL_FMT GL_BGRA 264#define SPANTMP_PIXEL_FMT GL_BGRA
269#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV 265#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
270
271#define TAG(x) radeon##x##_ARGB1555 266#define TAG(x) radeon##x##_ARGB1555
272#define TAG2(x,y) radeon##x##_ARGB1555##y 267#define TAG2(x,y) radeon##x##_ARGB1555##y
273#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
274#include "spantmp2.h" 268#include "spantmp2.h"
275 269
276#define SPANTMP_PIXEL_FMT GL_BGRA 270#define SPANTMP_PIXEL_FMT GL_BGRA
277#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5 271#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5
278
279#define TAG(x) radeon##x##_ARGB1555_REV 272#define TAG(x) radeon##x##_ARGB1555_REV
280#define TAG2(x,y) radeon##x##_ARGB1555_REV##y 273#define TAG2(x,y) radeon##x##_ARGB1555_REV##y
281#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
282#include "spantmp2.h" 274#include "spantmp2.h"
283 275
284/* 16 bit, RGBA4 color spanline and pixel functions 276/* 16 bit, RGBA4 color spanline and pixel functions
285 */ 277 */
286#define SPANTMP_PIXEL_FMT GL_BGRA 278#define SPANTMP_PIXEL_FMT GL_BGRA
287#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV 279#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
288
289#define TAG(x) radeon##x##_ARGB4444 280#define TAG(x) radeon##x##_ARGB4444
290#define TAG2(x,y) radeon##x##_ARGB4444##y 281#define TAG2(x,y) radeon##x##_ARGB4444##y
291#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
292#include "spantmp2.h" 282#include "spantmp2.h"
293 283
294#define SPANTMP_PIXEL_FMT GL_BGRA 284#define SPANTMP_PIXEL_FMT GL_BGRA
295#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4 285#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4
296
297#define TAG(x) radeon##x##_ARGB4444_REV 286#define TAG(x) radeon##x##_ARGB4444_REV
298#define TAG2(x,y) radeon##x##_ARGB4444_REV##y 287#define TAG2(x,y) radeon##x##_ARGB4444_REV##y
299#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
300#include "spantmp2.h" 288#include "spantmp2.h"
301 289
302/* 32 bit, xRGB8888 color spanline and pixel functions 290/* 32 bit, xRGB8888 color spanline and pixel functions
303 */ 291 */
304#define SPANTMP_PIXEL_FMT GL_BGRA 292#define SPANTMP_PIXEL_FMT GL_BGRA
305#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV 293#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
306
307#define TAG(x) radeon##x##_xRGB8888 294#define TAG(x) radeon##x##_xRGB8888
308#define TAG2(x,y) radeon##x##_xRGB8888##y 295#define TAG2(x,y) radeon##x##_xRGB8888##y
309#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)) | 0xff000000))
310#define PUT_VALUE(_x, _y, d) { \
311 GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \
312 *_ptr = d; \
313} while (0)
314#include "spantmp2.h" 296#include "spantmp2.h"
315 297
316/* 32 bit, ARGB8888 color spanline and pixel functions 298/* 32 bit, ARGB8888 color spanline and pixel functions
317 */ 299 */
318#define SPANTMP_PIXEL_FMT GL_BGRA 300#define SPANTMP_PIXEL_FMT GL_BGRA
319#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV 301#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
320
321#define TAG(x) radeon##x##_ARGB8888 302#define TAG(x) radeon##x##_ARGB8888
322#define TAG2(x,y) radeon##x##_ARGB8888##y 303#define TAG2(x,y) radeon##x##_ARGB8888##y
323#define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)))
324#define PUT_VALUE(_x, _y, d) { \
325 GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \
326 *_ptr = d; \
327} while (0)
328#include "spantmp2.h" 304#include "spantmp2.h"
329 305
330/* 32 bit, BGRx8888 color spanline and pixel functions 306/* 32 bit, BGRx8888 color spanline and pixel functions
331 */ 307 */
332#define SPANTMP_PIXEL_FMT GL_BGRA 308#define SPANTMP_PIXEL_FMT GL_BGRA
333#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8 309#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
334
335#define TAG(x) radeon##x##_BGRx8888 310#define TAG(x) radeon##x##_BGRx8888
336#define TAG2(x,y) radeon##x##_BGRx8888##y 311#define TAG2(x,y) radeon##x##_BGRx8888##y
337#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)) | 0x000000ff))
338#define PUT_VALUE(_x, _y, d) { \
339 GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \
340 *_ptr = d; \
341} while (0)
342#include "spantmp2.h" 312#include "spantmp2.h"
343 313
344/* 32 bit, BGRA8888 color spanline and pixel functions 314/* 32 bit, BGRA8888 color spanline and pixel functions
345 */ 315 */
346#define SPANTMP_PIXEL_FMT GL_BGRA 316#define SPANTMP_PIXEL_FMT GL_BGRA
347#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8 317#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
348
349#define TAG(x) radeon##x##_BGRA8888 318#define TAG(x) radeon##x##_BGRA8888
350#define TAG2(x,y) radeon##x##_BGRA8888##y 319#define TAG2(x,y) radeon##x##_BGRA8888##y
351#define GET_PTR(X,Y) radeon_ptr_4byte(rrb, (X), (Y))
352#include "spantmp2.h" 320#include "spantmp2.h"
353 321
322#undef Y_FLIP
323#define Y_FLIP(_y) ((_y) * yScale + yBias)
354/* ================================================================ 324/* ================================================================
355 * Depth buffer 325 * Depth buffer
356 */ 326 */
@@ -509,77 +479,69 @@ do { \
509#define TAG(x) radeon##x##_s8_z24 479#define TAG(x) radeon##x##_s8_z24
510#include "stenciltmp.h" 480#include "stenciltmp.h"
511 481
512 482static void
513static void map_unmap_rb(struct gl_renderbuffer *rb, int flag) 483radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb)
514{ 484{
515 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 485 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
516 int r; 486 GLubyte *map;
487 int stride;
517 488
518 if (rrb == NULL || !rrb->bo) 489 if (!rb || !rrb)
519 return; 490 return;
520 491
521 radeon_print(RADEON_MEMORY, RADEON_TRACE, 492 ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height,
522 "%s( rb %p, flag %s )\n", 493 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
523 __func__, rb, flag ? "true":"false"); 494 &map, &stride);
524
525 if (flag) {
526 radeon_bo_wait(rrb->bo);
527 r = radeon_bo_map(rrb->bo, 1);
528 if (r) {
529 fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
530 __FUNCTION__, r);
531 }
532 495
533 radeonSetSpanFunctions(rrb); 496 rb->Data = map;
534 } else { 497 rb->RowStride = stride / _mesa_get_format_bytes(rb->Format);
535 radeon_bo_unmap(rrb->bo); 498
536 rb->GetRow = NULL; 499 radeonSetSpanFunctions(rrb);
537 rb->PutRow = NULL; 500}
538 } 501
502static void
503radeon_renderbuffer_unmap(struct gl_context *ctx, struct gl_renderbuffer *rb)
504{
505 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
506 if (!rb || !rrb)
507 return;
508
509 ctx->Driver.UnmapRenderbuffer(ctx, rb);
510
511 rb->GetRow = NULL;
512 rb->PutRow = NULL;
513 rb->Data = NULL;
514 rb->RowStride = 0;
539} 515}
540 516
541static void 517static void
542radeon_map_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 518radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
543 GLboolean map)
544{ 519{
545 GLuint i, j; 520 GLuint i, j;
546 521
547 radeon_print(RADEON_MEMORY, RADEON_TRACE, 522 radeon_print(RADEON_MEMORY, RADEON_TRACE,
548 "%s( %p , fb %p, map %s )\n", 523 "%s( %p , fb %p )\n",
549 __func__, ctx, fb, map ? "true":"false"); 524 __func__, ctx, fb);
550 525
551 /* color draw buffers */ 526 /* check for render to textures */
552 for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) 527 for (i = 0; i < BUFFER_COUNT; i++)
553 map_unmap_rb(fb->_ColorDrawBuffers[j], map); 528 radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer);
554 529
555 map_unmap_rb(fb->_ColorReadBuffer, map); 530 radeon_check_front_buffer_rendering(ctx);
531}
556 532
557 /* check for render to textures */ 533static void
558 for (i = 0; i < BUFFER_COUNT; i++) { 534radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
559 struct gl_renderbuffer_attachment *att = 535{
560 fb->Attachment + i; 536 GLuint i, j;
561 struct gl_texture_object *tex = att->Texture;
562 if (tex) {
563 /* Render to texture. Note that a mipmapped texture need not
564 * be complete for render to texture, so we must restrict to
565 * mapping only the attached image.
566 */
567 radeon_texture_image *image = get_radeon_texture_image(tex->Image[att->CubeMapFace][att->TextureLevel]);
568 ASSERT(att->Renderbuffer);
569
570 if (map)
571 radeon_teximage_map(image, GL_TRUE);
572 else
573 radeon_teximage_unmap(image);
574 }
575 }
576
577 /* depth buffer (Note wrapper!) */
578 if (fb->_DepthBuffer)
579 map_unmap_rb(fb->_DepthBuffer->Wrapped, map);
580 537
581 if (fb->_StencilBuffer) 538 radeon_print(RADEON_MEMORY, RADEON_TRACE,
582 map_unmap_rb(fb->_StencilBuffer->Wrapped, map); 539 "%s( %p , fb %p)\n",
540 __func__, ctx, fb);
541
542 /* check for render to textures */
543 for (i = 0; i < BUFFER_COUNT; i++)
544 radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer);
583 545
584 radeon_check_front_buffer_rendering(ctx); 546 radeon_check_front_buffer_rendering(ctx);
585} 547}
@@ -591,13 +553,16 @@ static void radeonSpanRenderStart(struct gl_context * ctx)
591 553
592 radeon_firevertices(rmesa); 554 radeon_firevertices(rmesa);
593 555
594 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) 556 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
595 if (ctx->Texture.Unit[i]._ReallyEnabled) 557 if (ctx->Texture.Unit[i]._ReallyEnabled) {
596 radeonMapTexture(ctx, ctx->Texture.Unit[i]._Current); 558 radeon_validate_texture_miptree(ctx, ctx->Texture.Unit[i]._Current);
597 559 radeon_swrast_map_texture_images(ctx, ctx->Texture.Unit[i]._Current);
598 radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_TRUE); 560 }
561 }
562
563 radeon_map_framebuffer(ctx, ctx->DrawBuffer);
599 if (ctx->ReadBuffer != ctx->DrawBuffer) 564 if (ctx->ReadBuffer != ctx->DrawBuffer)
600 radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_TRUE); 565 radeon_map_framebuffer(ctx, ctx->ReadBuffer);
601} 566}
602 567
603static void radeonSpanRenderFinish(struct gl_context * ctx) 568static void radeonSpanRenderFinish(struct gl_context * ctx)
@@ -608,11 +573,11 @@ static void radeonSpanRenderFinish(struct gl_context * ctx)
608 573
609 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) 574 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
610 if (ctx->Texture.Unit[i]._ReallyEnabled) 575 if (ctx->Texture.Unit[i]._ReallyEnabled)
611 radeonUnmapTexture(ctx, ctx->Texture.Unit[i]._Current); 576 radeon_swrast_unmap_texture_images(ctx, ctx->Texture.Unit[i]._Current);
612 577
613 radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_FALSE); 578 radeon_unmap_framebuffer(ctx, ctx->DrawBuffer);
614 if (ctx->ReadBuffer != ctx->DrawBuffer) 579 if (ctx->ReadBuffer != ctx->DrawBuffer)
615 radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_FALSE); 580 radeon_unmap_framebuffer(ctx, ctx->ReadBuffer);
616} 581}
617 582
618void radeonInitSpanFuncs(struct gl_context * ctx) 583void radeonInitSpanFuncs(struct gl_context * ctx)
diff --git a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c
index bc9015e574d..ca0ac161709 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c
@@ -101,7 +101,7 @@ do_copy_texsubimage(struct gl_context *ctx,
101 dst_mesaformat = timg->base.Base.TexFormat; 101 dst_mesaformat = timg->base.Base.TexFormat;
102 src_bpp = _mesa_get_format_bytes(src_mesaformat); 102 src_bpp = _mesa_get_format_bytes(src_mesaformat);
103 dst_bpp = _mesa_get_format_bytes(dst_mesaformat); 103 dst_bpp = _mesa_get_format_bytes(dst_mesaformat);
104 if (!radeon->vtbl.check_blit(dst_mesaformat)) { 104 if (!radeon->vtbl.check_blit(dst_mesaformat, rrb->pitch / rrb->cpp)) {
105 /* depth formats tend to be special */ 105 /* depth formats tend to be special */
106 if (_mesa_get_format_bits(dst_mesaformat, GL_DEPTH_BITS) > 0) 106 if (_mesa_get_format_bits(dst_mesaformat, GL_DEPTH_BITS) > 0)
107 return GL_FALSE; 107 return GL_FALSE;
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index 178ff0925c3..71eff75cc04 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -48,6 +48,13 @@
48 48
49#include "radeon_mipmap_tree.h" 49#include "radeon_mipmap_tree.h"
50 50
51static void teximage_assign_miptree(radeonContextPtr rmesa,
52 struct gl_texture_object *texObj,
53 struct gl_texture_image *texImage);
54
55static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
56 struct gl_texture_object *texObj,
57 struct gl_texture_image *texImage);
51 58
52void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, 59void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
53 GLuint numrows, GLuint rowsize) 60 GLuint numrows, GLuint rowsize)
@@ -94,6 +101,33 @@ radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img)
94 _mesa_delete_texture_image(ctx, img); 101 _mesa_delete_texture_image(ctx, img);
95} 102}
96 103
104static GLboolean
105radeonAllocTextureImageBuffer(struct gl_context *ctx,
106 struct gl_texture_image *timage,
107 gl_format format, GLsizei width,
108 GLsizei height, GLsizei depth)
109{
110 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
111 radeon_texture_image *image = get_radeon_texture_image(timage);
112 struct gl_texture_object *texobj = timage->TexObject;
113 int slices;
114
115 ctx->Driver.FreeTextureImageBuffer(ctx, timage);
116
117 switch (texobj->Target) {
118 case GL_TEXTURE_3D:
119 slices = timage->Depth;
120 break;
121 default:
122 slices = 1;
123 }
124 assert(!image->base.ImageOffsets);
125 image->base.ImageOffsets = malloc(slices * sizeof(GLuint));
126 teximage_assign_miptree(rmesa, texobj, timage);
127
128 return GL_TRUE;
129}
130
97 131
98/** 132/**
99 * Free memory associated with this texture image. 133 * Free memory associated with this texture image.
@@ -104,7 +138,6 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag
104 138
105 if (image->mt) { 139 if (image->mt) {
106 radeon_miptree_unreference(&image->mt); 140 radeon_miptree_unreference(&image->mt);
107 assert(!image->base.Buffer);
108 } else { 141 } else {
109 _swrast_free_texture_image_buffer(ctx, timage); 142 _swrast_free_texture_image_buffer(ctx, timage);
110 } 143 }
@@ -173,91 +206,6 @@ void radeon_teximage_unmap(radeon_texture_image *image)
173 } 206 }
174} 207}
175 208
176static void map_override(struct gl_context *ctx, radeonTexObj *t)
177{
178 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
179
180 radeon_bo_map(t->bo, GL_FALSE);
181
182 img->base.Data = t->bo->ptr;
183}
184
185static void unmap_override(struct gl_context *ctx, radeonTexObj *t)
186{
187 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
188
189 radeon_bo_unmap(t->bo);
190
191 img->base.Data = NULL;
192}
193
194/**
195 * Map a validated texture for reading during software rendering.
196 */
197void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
198{
199 radeonTexObj* t = radeon_tex_obj(texObj);
200 int face, level;
201
202 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
203 "%s(%p, tex %p)\n",
204 __func__, ctx, texObj);
205
206 if (!radeon_validate_texture_miptree(ctx, texObj)) {
207 radeon_error("%s(%p, tex %p) Failed to validate miptree for "
208 "sw fallback.\n",
209 __func__, ctx, texObj);
210 return;
211 }
212
213 if (t->image_override && t->bo) {
214 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
215 "%s(%p, tex %p) Work around for missing miptree in r100.\n",
216 __func__, ctx, texObj);
217
218 map_override(ctx, t);
219 }
220
221 /* for r100 3D sw fallbacks don't have mt */
222 if (!t->mt) {
223 radeon_warning("%s(%p, tex %p) No miptree in texture.\n",
224 __func__, ctx, texObj);
225 return;
226 }
227
228 radeon_bo_map(t->mt->bo, GL_FALSE);
229 for(face = 0; face < t->mt->faces; ++face) {
230 for(level = t->minLod; level <= t->maxLod; ++level)
231 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
232 }
233}
234
235void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
236{
237 radeonTexObj* t = radeon_tex_obj(texObj);
238 int face, level;
239
240 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
241 "%s(%p, tex %p)\n",
242 __func__, ctx, texObj);
243
244 if (t->image_override && t->bo)
245 unmap_override(ctx, t);
246 /* for r100 3D sw fallbacks don't have mt */
247 if (!t->mt)
248 return;
249
250 for(face = 0; face < t->mt->faces; ++face) {
251 for(level = t->minLod; level <= t->maxLod; ++level) {
252 radeon_texture_image *image =
253 get_radeon_texture_image(texObj->Image[face][level]);
254 image->base.Data = NULL;
255 }
256 }
257 radeon_bo_unmap(t->mt->bo);
258}
259
260
261/** 209/**
262 * Map texture memory/buffer into user space. 210 * Map texture memory/buffer into user space.
263 * Note: the region of interest parameters are ignored here. 211 * Note: the region of interest parameters are ignored here.
@@ -286,7 +234,7 @@ radeon_map_texture_image(struct gl_context *ctx,
286 _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); 234 _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
287 assert(y % bh == 0); 235 assert(y % bh == 0);
288 y /= bh; 236 y /= bh;
289 height /= bh; 237 texel_size /= bw;
290 238
291 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 239 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
292 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 240 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
@@ -302,9 +250,11 @@ radeon_map_texture_image(struct gl_context *ctx,
302 *stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target); 250 *stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target);
303 *map = bo->ptr; 251 *map = bo->ptr;
304 } else if (likely(mt)) { 252 } else if (likely(mt)) {
305 radeon_bo_map(mt->bo, write); 253 void *base;
306 radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level]; 254 radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level];
307 void *base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset; 255
256 radeon_bo_map(mt->bo, write);
257 base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset;
308 258
309 *stride = lvl->rowstride; 259 *stride = lvl->rowstride;
310 *map = base + (slice * height) * *stride; 260 *map = base + (slice * height) * *stride;
@@ -594,51 +544,24 @@ gl_format radeonChooseTextureFormat(struct gl_context * ctx,
594 544
595/** Check if given image is valid within current texture object. 545/** Check if given image is valid within current texture object.
596 */ 546 */
597static int image_matches_texture_obj(struct gl_texture_object *texObj,
598 struct gl_texture_image *texImage,
599 unsigned level)
600{
601 const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
602
603 if (!baseImage)
604 return 0;
605
606 if (level < texObj->BaseLevel || level > texObj->MaxLevel)
607 return 0;
608
609 const unsigned levelDiff = level - texObj->BaseLevel;
610 const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
611 const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
612 const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
613
614 return (texImage->Width == refWidth &&
615 texImage->Height == refHeight &&
616 texImage->Depth == refDepth);
617}
618
619static void teximage_assign_miptree(radeonContextPtr rmesa, 547static void teximage_assign_miptree(radeonContextPtr rmesa,
620 struct gl_texture_object *texObj, 548 struct gl_texture_object *texObj,
621 struct gl_texture_image *texImage, 549 struct gl_texture_image *texImage)
622 unsigned face,
623 unsigned level)
624{ 550{
625 radeonTexObj *t = radeon_tex_obj(texObj); 551 radeonTexObj *t = radeon_tex_obj(texObj);
626 radeon_texture_image* image = get_radeon_texture_image(texImage); 552 radeon_texture_image* image = get_radeon_texture_image(texImage);
627 553
628 /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
629 * don't allocate the miptree if the teximage won't fit.
630 */
631 if (!image_matches_texture_obj(texObj, texImage, level))
632 return;
633
634 /* Try using current miptree, or create new if there isn't any */ 554 /* Try using current miptree, or create new if there isn't any */
635 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { 555 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) {
636 radeon_miptree_unreference(&t->mt); 556 radeon_miptree_unreference(&t->mt);
637 radeon_try_alloc_miptree(rmesa, t); 557 t->mt = radeon_miptree_create_for_teximage(rmesa,
558 texObj,
559 texImage);
560
638 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, 561 radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
639 "%s: texObj %p, texImage %p, face %d, level %d, " 562 "%s: texObj %p, texImage %p, "
640 "texObj miptree doesn't match, allocated new miptree %p\n", 563 "texObj miptree doesn't match, allocated new miptree %p\n",
641 __FUNCTION__, texObj, texImage, face, level, t->mt); 564 __FUNCTION__, texObj, texImage, t->mt);
642 } 565 }
643 566
644 /* Miptree alocation may have failed, 567 /* Miptree alocation may have failed,
@@ -650,101 +573,6 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
650 "%s Failed to allocate miptree.\n", __func__); 573 "%s Failed to allocate miptree.\n", __func__);
651} 574}
652 575
653
654/**
655 * Update a subregion of the given texture image.
656 */
657static void radeon_store_teximage(struct gl_context* ctx, int dims,
658 GLint xoffset, GLint yoffset, GLint zoffset,
659 GLsizei width, GLsizei height, GLsizei depth,
660 GLsizei imageSize,
661 GLenum format, GLenum type,
662 const GLvoid * pixels,
663 const struct gl_pixelstore_attrib *packing,
664 struct gl_texture_object *texObj,
665 struct gl_texture_image *texImage,
666 int compressed)
667{
668 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
669 radeonTexObj *t = radeon_tex_obj(texObj);
670 radeon_texture_image* image = get_radeon_texture_image(texImage);
671 GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat);
672
673 GLuint dstRowStride;
674 GLuint alignedWidth;
675 GLint i;
676
677 radeon_print(RADEON_TEXTURE, RADEON_TRACE,
678 "%s(%p, tex %p, image %p) compressed %d\n",
679 __func__, ctx, texObj, texImage, compressed);
680
681 if (image->mt) {
682 dstRowStride = image->mt->levels[image->base.Base.Level].rowstride;
683 } else if (t->bo) {
684 /* TFP case */
685 dstRowStride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texObj->Target);
686 } else {
687 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
688 }
689
690 assert(dstRowStride);
691
692 /* fill in the ImageOffsets array */
693 alignedWidth = dstRowStride / texel_size;
694 for (i = 0; i < texImage->Depth; ++i) {
695 image->base.ImageOffsets[i] = alignedWidth * texImage->Height * i;
696 }
697 /* and fill in RowStride (in texels) */
698 image->base.RowStride = alignedWidth;
699
700 radeon_teximage_map(image, GL_TRUE);
701
702 if (compressed) {
703 uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
704 GLubyte *img_start;
705
706 _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
707
708 if (!image->mt) {
709 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
710 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
711 texImage->TexFormat,
712 texImage->Width, image->base.Data);
713 }
714 else {
715 uint32_t offset;
716 offset = dstRowStride / texel_size * yoffset / block_height + xoffset / block_width;
717 offset *= texel_size;
718 img_start = image->base.Data + offset;
719 }
720 srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
721 bytesPerRow = srcRowStride;
722 rows = (height + block_height - 1) / block_height;
723
724 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
725 }
726 else {
727 GLubyte *slices[512];
728 GLuint i;
729 assert(depth <= 512);
730 for (i = 0; i < depth; i++) {
731 slices[i] = (GLubyte *) image->base.Data
732 + image->base.ImageOffsets[i] * texel_size;
733 }
734 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
735 texImage->TexFormat,
736 xoffset, yoffset, zoffset,
737 dstRowStride,
738 slices,
739 width, height, depth,
740 format, type, pixels, packing)) {
741 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
742 }
743 }
744
745 radeon_teximage_unmap(image);
746}
747
748/** 576/**
749 * All glTexImage calls go through this function. 577 * All glTexImage calls go through this function.
750 */ 578 */
@@ -760,72 +588,10 @@ static void radeon_teximage(
760 struct gl_texture_image *texImage, 588 struct gl_texture_image *texImage,
761 int compressed) 589 int compressed)
762{ 590{
763 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 591 _mesa_store_teximage3d(ctx, target, level, internalFormat,
764 radeonTexObj* t = radeon_tex_obj(texObj); 592 width, height, depth, 0,
765 radeon_texture_image* image = get_radeon_texture_image(texImage); 593 format, type, pixels,
766 GLuint face = _mesa_tex_target_to_face(target); 594 packing, texObj, texImage);
767
768 radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
769 "%s %dd: texObj %p, texImage %p, face %d, level %d\n",
770 __func__, dims, texObj, texImage, face, level);
771
772 t->validated = GL_FALSE;
773
774 radeonFreeTextureImageBuffer(ctx, texImage);
775
776 if (!t->bo) {
777 teximage_assign_miptree(rmesa, texObj, texImage, face, level);
778 if (!image->mt) {
779 int size = _mesa_format_image_size(texImage->TexFormat,
780 texImage->Width,
781 texImage->Height,
782 texImage->Depth);
783 image->base.Buffer = _mesa_align_malloc(size, 512);
784
785 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
786 "%s %dd: texObj %p, texImage %p, "
787 " no miptree assigned, using local memory %p\n",
788 __func__, dims, texObj, texImage, image->base.Buffer);
789 }
790 }
791
792 {
793 struct radeon_bo *bo;
794 bo = !image->mt ? image->bo : image->mt->bo;
795 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
796 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
797 "%s Calling teximage for texture that is "
798 "queued for GPU processing.\n",
799 __func__);
800 radeon_firevertices(rmesa);
801 }
802 }
803
804 image->base.ImageOffsets =
805 (GLuint *) malloc(texImage->Depth * sizeof(GLuint));
806
807
808 /* Upload texture image; note that the spec allows pixels to be NULL */
809 if (compressed) {
810 pixels = _mesa_validate_pbo_compressed_teximage(
811 ctx, imageSize, pixels, packing, "glCompressedTexImage");
812 } else {
813 pixels = _mesa_validate_pbo_teximage(
814 ctx, dims, width, height, depth,
815 format, type, pixels, packing, "glTexImage");
816 }
817
818 if (pixels) {
819 radeon_store_teximage(ctx, dims,
820 0, 0, 0,
821 width, height, depth,
822 imageSize, format, type,
823 pixels, packing,
824 texObj, texImage,
825 compressed);
826 }
827
828 _mesa_unmap_teximage_pbo(ctx, packing);
829} 595}
830 596
831void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level, 597void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
@@ -853,17 +619,6 @@ void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
853 0, format, type, pixels, packing, texObj, texImage, 0); 619 0, format, type, pixels, packing, texObj, texImage, 0);
854} 620}
855 621
856void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target,
857 GLint level, GLint internalFormat,
858 GLint width, GLint height, GLint border,
859 GLsizei imageSize, const GLvoid * data,
860 struct gl_texture_object *texObj,
861 struct gl_texture_image *texImage)
862{
863 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
864 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
865}
866
867void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level, 622void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
868 GLint internalFormat, 623 GLint internalFormat,
869 GLint width, GLint height, GLint depth, 624 GLint width, GLint height, GLint depth,
@@ -877,116 +632,6 @@ void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
877 0, format, type, pixels, packing, texObj, texImage, 0); 632 0, format, type, pixels, packing, texObj, texImage, 0);
878} 633}
879 634
880/**
881 * All glTexSubImage calls go through this function.
882 */
883static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level,
884 GLint xoffset, GLint yoffset, GLint zoffset,
885 GLsizei width, GLsizei height, GLsizei depth,
886 GLsizei imageSize,
887 GLenum format, GLenum type,
888 const GLvoid * pixels,
889 const struct gl_pixelstore_attrib *packing,
890 struct gl_texture_object *texObj,
891 struct gl_texture_image *texImage,
892 int compressed)
893{
894 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
895 radeonTexObj* t = radeon_tex_obj(texObj);
896 radeon_texture_image* image = get_radeon_texture_image(texImage);
897
898 radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
899 "%s %dd: texObj %p, texImage %p, face %d, level %d\n",
900 __func__, dims, texObj, texImage,
901 _mesa_tex_target_to_face(target), level);
902 {
903 struct radeon_bo *bo;
904 bo = !image->mt ? image->bo : image->mt->bo;
905 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
906 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
907 "%s Calling texsubimage for texture that is "
908 "queued for GPU processing.\n",
909 __func__);
910 radeon_firevertices(rmesa);
911 }
912 }
913
914
915 t->validated = GL_FALSE;
916 if (compressed) {
917 pixels = _mesa_validate_pbo_compressed_teximage(
918 ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
919 } else {
920 pixels = _mesa_validate_pbo_teximage(ctx, dims,
921 width, height, depth, format, type, pixels, packing, "glTexSubImage");
922 }
923
924 if (pixels) {
925 radeon_store_teximage(ctx, dims,
926 xoffset, yoffset, zoffset,
927 width, height, depth,
928 imageSize, format, type,
929 pixels, packing,
930 texObj, texImage,
931 compressed);
932 }
933
934 _mesa_unmap_teximage_pbo(ctx, packing);
935}
936
937void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
938 GLint xoffset,
939 GLsizei width,
940 GLenum format, GLenum type,
941 const GLvoid * pixels,
942 const struct gl_pixelstore_attrib *packing,
943 struct gl_texture_object *texObj,
944 struct gl_texture_image *texImage)
945{
946 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
947 format, type, pixels, packing, texObj, texImage, 0);
948}
949
950void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
951 GLint xoffset, GLint yoffset,
952 GLsizei width, GLsizei height,
953 GLenum format, GLenum type,
954 const GLvoid * pixels,
955 const struct gl_pixelstore_attrib *packing,
956 struct gl_texture_object *texObj,
957 struct gl_texture_image *texImage)
958{
959 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
960 0, format, type, pixels, packing, texObj, texImage,
961 0);
962}
963
964void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target,
965 GLint level, GLint xoffset,
966 GLint yoffset, GLsizei width,
967 GLsizei height, GLenum format,
968 GLsizei imageSize, const GLvoid * data,
969 struct gl_texture_object *texObj,
970 struct gl_texture_image *texImage)
971{
972 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
973 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
974}
975
976
977void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
978 GLint xoffset, GLint yoffset, GLint zoffset,
979 GLsizei width, GLsizei height, GLsizei depth,
980 GLenum format, GLenum type,
981 const GLvoid * pixels,
982 const struct gl_pixelstore_attrib *packing,
983 struct gl_texture_object *texObj,
984 struct gl_texture_image *texImage)
985{
986 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
987 format, type, pixels, packing, texObj, texImage, 0);
988}
989
990unsigned radeonIsFormatRenderable(gl_format mesa_format) 635unsigned radeonIsFormatRenderable(gl_format mesa_format)
991{ 636{
992 if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 || 637 if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 ||
@@ -1059,8 +704,7 @@ void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
1059 radeon_bo_ref(image->bo); 704 radeon_bo_ref(image->bo);
1060 t->mt->bo = image->bo; 705 t->mt->bo = image->bo;
1061 706
1062 if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base, 707 if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base))
1063 radeonImage->base.Base.Face, 0))
1064 fprintf(stderr, "miptree doesn't match image\n"); 708 fprintf(stderr, "miptree doesn't match image\n");
1065} 709}
1066#endif 710#endif
@@ -1101,9 +745,8 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
1101{ 745{
1102 functions->NewTextureImage = radeonNewTextureImage; 746 functions->NewTextureImage = radeonNewTextureImage;
1103 functions->DeleteTextureImage = radeonDeleteTextureImage; 747 functions->DeleteTextureImage = radeonDeleteTextureImage;
748 functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer;
1104 functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer; 749 functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
1105 functions->MapTexture = radeonMapTexture;
1106 functions->UnmapTexture = radeonUnmapTexture;
1107 functions->MapTextureImage = radeon_map_texture_image; 750 functions->MapTextureImage = radeon_map_texture_image;
1108 functions->UnmapTextureImage = radeon_unmap_texture_image; 751 functions->UnmapTextureImage = radeon_unmap_texture_image;
1109 752
@@ -1112,11 +755,6 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
1112 functions->TexImage1D = radeonTexImage1D; 755 functions->TexImage1D = radeonTexImage1D;
1113 functions->TexImage2D = radeonTexImage2D; 756 functions->TexImage2D = radeonTexImage2D;
1114 functions->TexImage3D = radeonTexImage3D; 757 functions->TexImage3D = radeonTexImage3D;
1115 functions->TexSubImage1D = radeonTexSubImage1D;
1116 functions->TexSubImage2D = radeonTexSubImage2D;
1117 functions->TexSubImage3D = radeonTexSubImage3D;
1118 functions->CompressedTexImage2D = radeonCompressedTexImage2D;
1119 functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
1120 758
1121 functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; 759 functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
1122 760
@@ -1127,3 +765,133 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
1127 765
1128 radeonInitTextureFormats(); 766 radeonInitTextureFormats();
1129} 767}
768
769static void
770radeon_swrast_map_image(radeonContextPtr rmesa,
771 radeon_texture_image *image)
772{
773 GLuint level, face;
774 radeon_mipmap_tree *mt;
775 GLuint texel_size;
776 radeon_mipmap_level *lvl;
777 int rs;
778
779 if (!image || !image->mt)
780 return;
781
782 texel_size = _mesa_get_format_bytes(image->base.Base.TexFormat);
783 level = image->base.Base.Level;
784 face = image->base.Base.Face;
785 mt = image->mt;
786
787 lvl = &image->mt->levels[level];
788
789 rs = lvl->rowstride / texel_size;
790
791 radeon_bo_map(mt->bo, 1);
792
793 image->base.Data = mt->bo->ptr + lvl->faces[face].offset;
794 if (mt->target == GL_TEXTURE_3D) {
795 int i;
796
797 for (i = 0; i < mt->levels[level].depth; i++)
798 image->base.ImageOffsets[i] = rs * lvl->height * i;
799 }
800 image->base.RowStride = rs;
801}
802
803static void
804radeon_swrast_unmap_image(radeonContextPtr rmesa,
805 radeon_texture_image *image)
806{
807 if (image && image->mt) {
808 image->base.Data = NULL;
809 radeon_bo_unmap(image->mt->bo);
810 }
811}
812
813void
814radeon_swrast_map_texture_images(struct gl_context *ctx,
815 struct gl_texture_object *texObj)
816{
817 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
818 GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
819 int i, face;
820
821 for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) {
822 for (face = 0; face < nr_faces; face++) {
823 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]);
824 radeon_swrast_map_image(rmesa, image);
825 }
826 }
827}
828
829void
830radeon_swrast_unmap_texture_images(struct gl_context *ctx,
831 struct gl_texture_object *texObj)
832{
833 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
834 GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
835 int i, face;
836
837 for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) {
838 for (face = 0; face < nr_faces; face++) {
839 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]);
840 radeon_swrast_unmap_image(rmesa, image);
841 }
842 }
843
844}
845
846static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
847 struct gl_texture_object *texObj,
848 struct gl_texture_image *texImage)
849{
850 radeonTexObj *t = radeon_tex_obj(texObj);
851 GLuint firstLevel;
852 GLuint lastLevel;
853 int width, height, depth;
854 int i;
855
856 width = texImage->Width;
857 height = texImage->Height;
858 depth = texImage->Depth;
859
860 if (texImage->Level > texObj->BaseLevel &&
861 (width == 1 ||
862 (texObj->Target != GL_TEXTURE_1D && height == 1) ||
863 (texObj->Target == GL_TEXTURE_3D && depth == 1))) {
864 /* For this combination, we're at some lower mipmap level and
865 * some important dimension is 1. We can't extrapolate up to a
866 * likely base level width/height/depth for a full mipmap stack
867 * from this info, so just allocate this one level.
868 */
869 firstLevel = texImage->Level;
870 lastLevel = texImage->Level;
871 } else {
872 if (texImage->Level < texObj->BaseLevel)
873 firstLevel = 0;
874 else
875 firstLevel = texObj->BaseLevel;
876
877 for (i = texImage->Level; i > firstLevel; i--) {
878 width <<= 1;
879 if (height != 1)
880 height <<= 1;
881 if (depth != 1)
882 depth <<= 1;
883 }
884 if ((texObj->Sampler.MinFilter == GL_NEAREST ||
885 texObj->Sampler.MinFilter == GL_LINEAR) &&
886 texImage->Level == firstLevel) {
887 lastLevel = firstLevel;
888 } else {
889 lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth));
890 }
891 }
892
893 return radeon_miptree_create(rmesa, texObj->Target,
894 texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1,
895 width, height, depth,
896 t->tile_bits);
897}
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h
index 0fa48bd1091..f1af109707f 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.h
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.h
@@ -49,10 +49,12 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag
49 49
50void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable); 50void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable);
51void radeon_teximage_unmap(radeon_texture_image *image); 51void radeon_teximage_unmap(radeon_texture_image *image);
52void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj);
53void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj);
54int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_object *texObj); 52int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_object *texObj);
55 53
54
55void radeon_swrast_map_texture_images(struct gl_context *ctx, struct gl_texture_object *texObj);
56void radeon_swrast_unmap_texture_images(struct gl_context *ctx, struct gl_texture_object *texObj);
57
56gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx, 58gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx,
57 GLint internalFormat, 59 GLint internalFormat,
58 GLenum format, 60 GLenum format,