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
@@ -40,3 +40,3 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
/* common formats supported as both textures and render targets */
-unsigned r200_check_blit(gl_format mesa_format)
+unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch)
{
@@ -60,2 +60,8 @@ unsigned r200_check_blit(gl_format mesa_format)
+ /* Rendering to small buffer doesn't work.
+ * Looks like a hw limitation.
+ */
+ if (dst_pitch < 32)
+ return 0;
+
/* ??? */
@@ -469,3 +475,3 @@ unsigned r200_blit(struct gl_context *ctx,
- if (!r200_check_blit(dst_mesaformat))
+ if (!r200_check_blit(dst_mesaformat, dst_pitch))
return GL_FALSE;
@@ -476,8 +482,2 @@ unsigned r200_blit(struct gl_context *ctx,
- /* Rendering to small buffer doesn't work.
- * Looks like a hw limitation.
- */
- if (dst_pitch < 32)
- return GL_FALSE;
-
/* Need to clamp the region size to make sure
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
@@ -32,3 +32,3 @@ void r200_blit_init(struct r200_context *r200);
-unsigned r200_check_blit(gl_format mesa_format);
+unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch);
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
@@ -40,3 +40,3 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
/* common formats supported as both textures and render targets */
-unsigned r100_check_blit(gl_format mesa_format)
+unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch)
{
@@ -57,2 +57,8 @@ unsigned r100_check_blit(gl_format mesa_format)
+ /* Rendering to small buffer doesn't work.
+ * Looks like a hw limitation.
+ */
+ if (dst_pitch < 32)
+ return 0;
+
/* ??? */
@@ -346,3 +352,3 @@ unsigned r100_blit(struct gl_context *ctx,
- if (!r100_check_blit(dst_mesaformat))
+ if (!r100_check_blit(dst_mesaformat, dst_pitch))
return GL_FALSE;
@@ -353,8 +359,2 @@ unsigned r100_blit(struct gl_context *ctx,
- /* Rendering to small buffer doesn't work.
- * Looks like a hw limitation.
- */
- if (dst_pitch < 32)
- return GL_FALSE;
-
/* Need to clamp the region size to make sure
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
@@ -32,3 +32,3 @@ void r100_blit_init(struct r100_context *r100);
-unsigned r100_check_blit(gl_format mesa_format);
+unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch);
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
@@ -91,2 +91,3 @@ struct radeon_renderbuffer
int map_x, map_y, map_w, map_h;
+ int map_pitch;
@@ -176,2 +177,3 @@ struct _radeon_texture_image {
struct radeon_bo *bo;
+ GLboolean used_as_render_target;
};
@@ -483,3 +485,3 @@ struct radeon_context {
void (*update_scissor)(struct gl_context *ctx);
- unsigned (*check_blit)(gl_format mesa_format);
+ unsigned (*check_blit)(gl_format mesa_format, uint32_t dst_pitch);
unsigned (*blit)(struct gl_context *ctx,
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
@@ -84,14 +84,12 @@ radeon_map_renderbuffer(struct gl_context *ctx,
GLboolean ok;
- int stride, ret;
-
- assert(rrb && rrb->bo);
-
- /* Make a temporary buffer and blit the current contents of the renderbuffer
- * out to it. This gives us linear access to the buffer, instead of having
- * to do detiling in software.
- */
- assert(!rrb->map_bo);
- rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
- rrb->pitch * h, 4,
- RADEON_GEM_DOMAIN_GTT, 0);
+ int stride, flip_stride;
+ int ret;
+ int src_x, src_y;
+
+ if (!rrb || !rrb->bo) {
+ *out_map = NULL;
+ *out_stride = 0;
+ return;
+ }
+
rrb->map_mode = mode;
@@ -101,31 +99,73 @@ radeon_map_renderbuffer(struct gl_context *ctx,
rrb->map_h = h;
+ rrb->map_pitch = rrb->pitch;
+
+ ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp);
+ if (ok) {
+ if (rb->Name) {
+ src_x = x;
+ src_y = y;
+ } else {
+ src_x = x;
+ src_y = rrb->base.Height - y - h;
+ }
+
+ /* Make a temporary buffer and blit the current contents of the renderbuffer
+ * out to it. This gives us linear access to the buffer, instead of having
+ * to do detiling in software.
+ */
+
+ rrb->map_pitch = rrb->pitch;
+
+ assert(!rrb->map_bo);
+ rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
+ rrb->map_pitch * h, 4,
+ RADEON_GEM_DOMAIN_GTT, 0);
+
+ ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
+ rb->Format, rrb->pitch / rrb->cpp,
+ rb->Width, rb->Height,
+ src_x, src_y,
+ rrb->map_bo, 0,
+ rb->Format, rrb->map_pitch / rrb->cpp,
+ w, h,
+ 0, 0,
+ w, h,
+ GL_FALSE);
+ assert(ok);
+
+ ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
+ assert(!ret);
+
+ map = rrb->map_bo->ptr;
+
+ if (rb->Name) {
+ *out_map = map;
+ *out_stride = rrb->map_pitch;
+ } else {
+ *out_map = map + (h - 1) * rrb->map_pitch;
+ *out_stride = -rrb->map_pitch;
+ }
+ return;
+ }
+
+ /* sw fallback flush stuff */
+ if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) {
+ radeon_firevertices(rmesa);
+ }
- ok = rmesa->vtbl.check_blit(rb->Format);
- assert(ok);
-
- ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
- rb->Format, rrb->pitch / rrb->cpp,
- rb->Width, rb->Height,
- x, y,
- rrb->map_bo, 0,
- rb->Format, rrb->pitch / rrb->cpp,
- w, h,
- 0, 0,
- w, h,
- GL_FALSE);
- assert(ok);
-
- radeon_bo_wait(rrb->map_bo);
- ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
+ ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
assert(!ret);
- map = rrb->map_bo->ptr;
- stride = rrb->pitch;
+ map = rrb->bo->ptr;
+ stride = rrb->map_pitch;
if (rb->Name == 0) {
- map += stride * (rb->Height - 1);
- stride = -stride;
+ y = rb->Height - 1 - y;
+ flip_stride = -stride;
+ } else {
+ flip_stride = stride;
+ map += rrb->draw_offset;
}
- map += x * _mesa_get_format_bytes(rb->Format);
+ map += x * rrb->cpp;
map += (int)y * stride;
@@ -133,3 +173,3 @@ radeon_map_renderbuffer(struct gl_context *ctx,
*out_map = map;
- *out_stride = stride;
+ *out_stride = flip_stride;
}
@@ -144,2 +184,8 @@ radeon_unmap_renderbuffer(struct gl_context *ctx,
+ if (!rrb->map_bo) {
+ if (rrb->bo)
+ radeon_bo_unmap(rrb->bo);
+ return;
+ }
+
radeon_bo_unmap(rrb->map_bo);
@@ -148,3 +194,3 @@ radeon_unmap_renderbuffer(struct gl_context *ctx,
ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0,
- rb->Format, rrb->pitch / rrb->cpp,
+ rb->Format, rrb->map_pitch / rrb->cpp,
rrb->map_w, rrb->map_h,
@@ -629,3 +675,3 @@ radeon_render_texture(struct gl_context * ctx,
- if (!radeon_image->mt || newImage->Border != 0) {
+ if (!radeon_image->mt) {
/* Fallback on drawing to a texture without a miptree.
@@ -683,2 +729,3 @@ radeon_render_texture(struct gl_context * ctx,
rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride;
+ radeon_image->used_as_render_target = GL_TRUE;
@@ -692,3 +739,12 @@ radeon_finish_render_texture(struct gl_context * ctx,
{
-
+ struct gl_texture_object *tex_obj = att->Texture;
+ struct gl_texture_image *image =
+ tex_obj->Image[att->CubeMapFace][att->TextureLevel];
+ radeon_texture_image *radeon_image = (radeon_texture_image *)image;
+
+ if (radeon_image)
+ radeon_image->used_as_render_target = GL_FALSE;
+
+ if (ctx->Driver.Flush)
+ ctx->Driver.Flush(ctx); /* +r6/r7 */
}
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
@@ -187,5 +187,5 @@ static void calculate_miptree_layout(radeonContextPtr rmesa, radeon_mipmap_tree
*/
-static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa,
- GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
- GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits)
+radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa,
+ GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
+ GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits)
{
@@ -300,9 +300,6 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj,
GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
- struct gl_texture_image *texImage, GLuint face, GLuint level)
+ struct gl_texture_image *texImage)
{
radeon_mipmap_level *lvl;
-
- if (face >= mt->faces)
- return GL_FALSE;
-
+ GLuint level = texImage->Level;
if (texImage->TexFormat != mt->mesaFormat)
@@ -334,3 +331,3 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g
firstImage = texObj->Image[0][texObj->BaseLevel];
- numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1);
+ numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1);
@@ -374,3 +371,2 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t)
GLuint numLevels;
-
assert(!t->mt);
@@ -546,2 +542,3 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
radeonTexObj *t = radeon_tex_obj(texObj);
+ radeon_mipmap_tree *dst_miptree;
@@ -551,10 +548,2 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
- if (texObj->Image[0][texObj->BaseLevel]->Border > 0)
- return GL_FALSE;
-
- _mesa_test_texobj_completeness(rmesa->glCtx, texObj);
- if (!texObj->_Complete) {
- return GL_FALSE;
- }
-
calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod);
@@ -565,4 +554,3 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
- radeon_mipmap_tree *dst_miptree;
- dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base.MaxLevel);
+ dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base._MaxLevel);
@@ -593,3 +581,3 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
- if (img->mt != t->mt) {
+ if (img->mt != t->mt && !img->used_as_render_target) {
radeon_print(RADEON_TEXTURE, RADEON_TRACE,
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
@@ -86,3 +86,4 @@ void radeon_miptree_unreference(radeon_mipmap_tree **ptr);
GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
- struct gl_texture_image *texImage, GLuint face, GLuint level);
+ struct gl_texture_image *texImage);
+
void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t);
@@ -100,2 +101,6 @@ unsigned get_texture_image_size(
unsigned tiling);
+
+radeon_mipmap_tree *radeon_miptree_create(radeonContextPtr rmesa,
+ GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
+ GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits);
#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
@@ -107,3 +107,3 @@ do_blit_readpixels(struct gl_context * ctx,
if (dst_format == MESA_FORMAT_NONE ||
- !radeon->vtbl.check_blit(dst_format) || !radeon->vtbl.blit) {
+ !radeon->vtbl.check_blit(dst_format, rrb->pitch / rrb->cpp) || !radeon->vtbl.blit) {
return GL_FALSE;
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
@@ -218,4 +218,2 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
struct radeon_renderbuffer *rrb = (void *) rb; \
- const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \
- const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
int minx = 0, miny = 0; \
@@ -223,2 +221,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
int maxy = rb->Height; \
+ void *buf = rb->Data; \
+ int pitch = rb->RowStride * rrb->cpp; \
GLuint p; \
@@ -228,5 +228,5 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
struct radeon_renderbuffer *rrb = (void *) rb; \
- const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \
- const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
int minx = 0, miny = 0; \
+ const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \
+ const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1; \
int maxx = rb->Width; \
@@ -236,3 +236,3 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
-#define Y_FLIP(_y) ((_y) * yScale + yBias)
+#define Y_FLIP(_y) (_y)
@@ -251,6 +251,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
-
#define TAG(x) radeon##x##_RGB565
#define TAG2(x,y) radeon##x##_RGB565##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
#include "spantmp2.h"
@@ -259,6 +257,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV
-
#define TAG(x) radeon##x##_RGB565_REV
#define TAG2(x,y) radeon##x##_RGB565_REV##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
#include "spantmp2.h"
@@ -269,6 +265,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
-
#define TAG(x) radeon##x##_ARGB1555
#define TAG2(x,y) radeon##x##_ARGB1555##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
#include "spantmp2.h"
@@ -277,6 +271,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5
-
#define TAG(x) radeon##x##_ARGB1555_REV
#define TAG2(x,y) radeon##x##_ARGB1555_REV##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
#include "spantmp2.h"
@@ -287,6 +279,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
-
#define TAG(x) radeon##x##_ARGB4444
#define TAG2(x,y) radeon##x##_ARGB4444##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
#include "spantmp2.h"
@@ -295,6 +285,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4
-
#define TAG(x) radeon##x##_ARGB4444_REV
#define TAG2(x,y) radeon##x##_ARGB4444_REV##y
-#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y))
#include "spantmp2.h"
@@ -305,10 +293,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
-
#define TAG(x) radeon##x##_xRGB8888
#define TAG2(x,y) radeon##x##_xRGB8888##y
-#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)) | 0xff000000))
-#define PUT_VALUE(_x, _y, d) { \
- GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \
- *_ptr = d; \
-} while (0)
#include "spantmp2.h"
@@ -319,10 +301,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
-
#define TAG(x) radeon##x##_ARGB8888
#define TAG2(x,y) radeon##x##_ARGB8888##y
-#define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)))
-#define PUT_VALUE(_x, _y, d) { \
- GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \
- *_ptr = d; \
-} while (0)
#include "spantmp2.h"
@@ -333,10 +309,4 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
-
#define TAG(x) radeon##x##_BGRx8888
#define TAG2(x,y) radeon##x##_BGRx8888##y
-#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)) | 0x000000ff))
-#define PUT_VALUE(_x, _y, d) { \
- GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \
- *_ptr = d; \
-} while (0)
#include "spantmp2.h"
@@ -347,8 +317,8 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
-
#define TAG(x) radeon##x##_BGRA8888
#define TAG2(x,y) radeon##x##_BGRA8888##y
-#define GET_PTR(X,Y) radeon_ptr_4byte(rrb, (X), (Y))
#include "spantmp2.h"
+#undef Y_FLIP
+#define Y_FLIP(_y) ((_y) * yScale + yBias)
/* ================================================================
@@ -511,29 +481,35 @@ do { \
-
-static void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
+static void
+radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb)
{
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
- int r;
+ GLubyte *map;
+ int stride;
- if (rrb == NULL || !rrb->bo)
+ if (!rb || !rrb)
return;
- radeon_print(RADEON_MEMORY, RADEON_TRACE,
- "%s( rb %p, flag %s )\n",
- __func__, rb, flag ? "true":"false");
-
- if (flag) {
- radeon_bo_wait(rrb->bo);
- r = radeon_bo_map(rrb->bo, 1);
- if (r) {
- fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
- __FUNCTION__, r);
- }
+ ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height,
+ GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
+ &map, &stride);
- radeonSetSpanFunctions(rrb);
- } else {
- radeon_bo_unmap(rrb->bo);
- rb->GetRow = NULL;
- rb->PutRow = NULL;
- }
+ rb->Data = map;
+ rb->RowStride = stride / _mesa_get_format_bytes(rb->Format);
+
+ radeonSetSpanFunctions(rrb);
+}
+
+static void
+radeon_renderbuffer_unmap(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+ struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+ if (!rb || !rrb)
+ return;
+
+ ctx->Driver.UnmapRenderbuffer(ctx, rb);
+
+ rb->GetRow = NULL;
+ rb->PutRow = NULL;
+ rb->Data = NULL;
+ rb->RowStride = 0;
}
@@ -541,4 +517,3 @@ static void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
static void
-radeon_map_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
- GLboolean map)
+radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
{
@@ -547,37 +522,24 @@ radeon_map_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
radeon_print(RADEON_MEMORY, RADEON_TRACE,
- "%s( %p , fb %p, map %s )\n",
- __func__, ctx, fb, map ? "true":"false");
+ "%s( %p , fb %p )\n",
+ __func__, ctx, fb);
- /* color draw buffers */
- for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++)
- map_unmap_rb(fb->_ColorDrawBuffers[j], map);
+ /* check for render to textures */
+ for (i = 0; i < BUFFER_COUNT; i++)
+ radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer);
- map_unmap_rb(fb->_ColorReadBuffer, map);
+ radeon_check_front_buffer_rendering(ctx);
+}
- /* check for render to textures */
- for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att =
- fb->Attachment + i;
- struct gl_texture_object *tex = att->Texture;
- if (tex) {
- /* Render to texture. Note that a mipmapped texture need not
- * be complete for render to texture, so we must restrict to
- * mapping only the attached image.
- */
- radeon_texture_image *image = get_radeon_texture_image(tex->Image[att->CubeMapFace][att->TextureLevel]);
- ASSERT(att->Renderbuffer);
-
- if (map)
- radeon_teximage_map(image, GL_TRUE);
- else
- radeon_teximage_unmap(image);
- }
- }
-
- /* depth buffer (Note wrapper!) */
- if (fb->_DepthBuffer)
- map_unmap_rb(fb->_DepthBuffer->Wrapped, map);
+static void
+radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
+{
+ GLuint i, j;
- if (fb->_StencilBuffer)
- map_unmap_rb(fb->_StencilBuffer->Wrapped, map);
+ radeon_print(RADEON_MEMORY, RADEON_TRACE,
+ "%s( %p , fb %p)\n",
+ __func__, ctx, fb);
+
+ /* check for render to textures */
+ for (i = 0; i < BUFFER_COUNT; i++)
+ radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer);
@@ -593,9 +555,12 @@ static void radeonSpanRenderStart(struct gl_context * ctx)
- for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
- if (ctx->Texture.Unit[i]._ReallyEnabled)
- radeonMapTexture(ctx, ctx->Texture.Unit[i]._Current);
-
- radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_TRUE);
+ for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ radeon_validate_texture_miptree(ctx, ctx->Texture.Unit[i]._Current);
+ radeon_swrast_map_texture_images(ctx, ctx->Texture.Unit[i]._Current);
+ }
+ }
+
+ radeon_map_framebuffer(ctx, ctx->DrawBuffer);
if (ctx->ReadBuffer != ctx->DrawBuffer)
- radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_TRUE);
+ radeon_map_framebuffer(ctx, ctx->ReadBuffer);
}
@@ -610,7 +575,7 @@ static void radeonSpanRenderFinish(struct gl_context * ctx)
if (ctx->Texture.Unit[i]._ReallyEnabled)
- radeonUnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
+ radeon_swrast_unmap_texture_images(ctx, ctx->Texture.Unit[i]._Current);
- radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_FALSE);
+ radeon_unmap_framebuffer(ctx, ctx->DrawBuffer);
if (ctx->ReadBuffer != ctx->DrawBuffer)
- radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_FALSE);
+ radeon_unmap_framebuffer(ctx, ctx->ReadBuffer);
}
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
@@ -103,3 +103,3 @@ do_copy_texsubimage(struct gl_context *ctx,
dst_bpp = _mesa_get_format_bytes(dst_mesaformat);
- if (!radeon->vtbl.check_blit(dst_mesaformat)) {
+ if (!radeon->vtbl.check_blit(dst_mesaformat, rrb->pitch / rrb->cpp)) {
/* depth formats tend to be special */
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
@@ -50,2 +50,9 @@
+static void teximage_assign_miptree(radeonContextPtr rmesa,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
@@ -96,2 +103,29 @@ radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img)
+static GLboolean
+radeonAllocTextureImageBuffer(struct gl_context *ctx,
+ struct gl_texture_image *timage,
+ gl_format format, GLsizei width,
+ GLsizei height, GLsizei depth)
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeon_texture_image *image = get_radeon_texture_image(timage);
+ struct gl_texture_object *texobj = timage->TexObject;
+ int slices;
+
+ ctx->Driver.FreeTextureImageBuffer(ctx, timage);
+
+ switch (texobj->Target) {
+ case GL_TEXTURE_3D:
+ slices = timage->Depth;
+ break;
+ default:
+ slices = 1;
+ }
+ assert(!image->base.ImageOffsets);
+ image->base.ImageOffsets = malloc(slices * sizeof(GLuint));
+ teximage_assign_miptree(rmesa, texobj, timage);
+
+ return GL_TRUE;
+}
+
@@ -106,3 +140,2 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag
radeon_miptree_unreference(&image->mt);
- assert(!image->base.Buffer);
} else {
@@ -175,87 +208,2 @@ void radeon_teximage_unmap(radeon_texture_image *image)
-static void map_override(struct gl_context *ctx, radeonTexObj *t)
-{
- radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
-
- radeon_bo_map(t->bo, GL_FALSE);
-
- img->base.Data = t->bo->ptr;
-}
-
-static void unmap_override(struct gl_context *ctx, radeonTexObj *t)
-{
- radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
-
- radeon_bo_unmap(t->bo);
-
- img->base.Data = NULL;
-}
-
-/**
- * Map a validated texture for reading during software rendering.
- */
-void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
- radeonTexObj* t = radeon_tex_obj(texObj);
- int face, level;
-
- radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
- "%s(%p, tex %p)\n",
- __func__, ctx, texObj);
-
- if (!radeon_validate_texture_miptree(ctx, texObj)) {
- radeon_error("%s(%p, tex %p) Failed to validate miptree for "
- "sw fallback.\n",
- __func__, ctx, texObj);
- return;
- }
-
- if (t->image_override && t->bo) {
- radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
- "%s(%p, tex %p) Work around for missing miptree in r100.\n",
- __func__, ctx, texObj);
-
- map_override(ctx, t);
- }
-
- /* for r100 3D sw fallbacks don't have mt */
- if (!t->mt) {
- radeon_warning("%s(%p, tex %p) No miptree in texture.\n",
- __func__, ctx, texObj);
- return;
- }
-
- radeon_bo_map(t->mt->bo, GL_FALSE);
- for(face = 0; face < t->mt->faces; ++face) {
- for(level = t->minLod; level <= t->maxLod; ++level)
- teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
- }
-}
-
-void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
- radeonTexObj* t = radeon_tex_obj(texObj);
- int face, level;
-
- radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
- "%s(%p, tex %p)\n",
- __func__, ctx, texObj);
-
- if (t->image_override && t->bo)
- unmap_override(ctx, t);
- /* for r100 3D sw fallbacks don't have mt */
- if (!t->mt)
- return;
-
- for(face = 0; face < t->mt->faces; ++face) {
- for(level = t->minLod; level <= t->maxLod; ++level) {
- radeon_texture_image *image =
- get_radeon_texture_image(texObj->Image[face][level]);
- image->base.Data = NULL;
- }
- }
- radeon_bo_unmap(t->mt->bo);
-}
-
-
/**
@@ -288,3 +236,3 @@ radeon_map_texture_image(struct gl_context *ctx,
y /= bh;
- height /= bh;
+ texel_size /= bw;
@@ -304,5 +252,7 @@ radeon_map_texture_image(struct gl_context *ctx,
} else if (likely(mt)) {
- radeon_bo_map(mt->bo, write);
+ void *base;
radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level];
- void *base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset;
+
+ radeon_bo_map(mt->bo, write);
+ base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset;
@@ -596,29 +546,5 @@ gl_format radeonChooseTextureFormat(struct gl_context * ctx,
*/
-static int image_matches_texture_obj(struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- unsigned level)
-{
- const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
-
- if (!baseImage)
- return 0;
-
- if (level < texObj->BaseLevel || level > texObj->MaxLevel)
- return 0;
-
- const unsigned levelDiff = level - texObj->BaseLevel;
- const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
- const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
- const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
-
- return (texImage->Width == refWidth &&
- texImage->Height == refHeight &&
- texImage->Depth == refDepth);
-}
-
static void teximage_assign_miptree(radeonContextPtr rmesa,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- unsigned face,
- unsigned level)
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
{
@@ -627,16 +553,13 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
- /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
- * don't allocate the miptree if the teximage won't fit.
- */
- if (!image_matches_texture_obj(texObj, texImage, level))
- return;
-
/* Try using current miptree, or create new if there isn't any */
- if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+ if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) {
radeon_miptree_unreference(&t->mt);
- radeon_try_alloc_miptree(rmesa, t);
+ t->mt = radeon_miptree_create_for_teximage(rmesa,
+ texObj,
+ texImage);
+
radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
- "%s: texObj %p, texImage %p, face %d, level %d, "
+ "%s: texObj %p, texImage %p, "
"texObj miptree doesn't match, allocated new miptree %p\n",
- __FUNCTION__, texObj, texImage, face, level, t->mt);
+ __FUNCTION__, texObj, texImage, t->mt);
}
@@ -652,97 +575,2 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
-
-/**
- * Update a subregion of the given texture image.
- */
-static void radeon_store_teximage(struct gl_context* ctx, int dims,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- int compressed)
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeonTexObj *t = radeon_tex_obj(texObj);
- radeon_texture_image* image = get_radeon_texture_image(texImage);
- GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat);
-
- GLuint dstRowStride;
- GLuint alignedWidth;
- GLint i;
-
- radeon_print(RADEON_TEXTURE, RADEON_TRACE,
- "%s(%p, tex %p, image %p) compressed %d\n",
- __func__, ctx, texObj, texImage, compressed);
-
- if (image->mt) {
- dstRowStride = image->mt->levels[image->base.Base.Level].rowstride;
- } else if (t->bo) {
- /* TFP case */
- dstRowStride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texObj->Target);
- } else {
- dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
- }
-
- assert(dstRowStride);
-
- /* fill in the ImageOffsets array */
- alignedWidth = dstRowStride / texel_size;
- for (i = 0; i < texImage->Depth; ++i) {
- image->base.ImageOffsets[i] = alignedWidth * texImage->Height * i;
- }
- /* and fill in RowStride (in texels) */
- image->base.RowStride = alignedWidth;
-
- radeon_teximage_map(image, GL_TRUE);
-
- if (compressed) {
- uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
- GLubyte *img_start;
-
- _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
-
- if (!image->mt) {
- dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
- img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
- texImage->TexFormat,
- texImage->Width, image->base.Data);
- }
- else {
- uint32_t offset;
- offset = dstRowStride / texel_size * yoffset / block_height + xoffset / block_width;
- offset *= texel_size;
- img_start = image->base.Data + offset;
- }
- srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
- bytesPerRow = srcRowStride;
- rows = (height + block_height - 1) / block_height;
-
- copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
- }
- else {
- GLubyte *slices[512];
- GLuint i;
- assert(depth <= 512);
- for (i = 0; i < depth; i++) {
- slices[i] = (GLubyte *) image->base.Data
- + image->base.ImageOffsets[i] * texel_size;
- }
- if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
- texImage->TexFormat,
- xoffset, yoffset, zoffset,
- dstRowStride,
- slices,
- width, height, depth,
- format, type, pixels, packing)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
- }
- }
-
- radeon_teximage_unmap(image);
-}
-
/**
@@ -762,68 +590,6 @@ static void radeon_teximage(
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeonTexObj* t = radeon_tex_obj(texObj);
- radeon_texture_image* image = get_radeon_texture_image(texImage);
- GLuint face = _mesa_tex_target_to_face(target);
-
- radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
- "%s %dd: texObj %p, texImage %p, face %d, level %d\n",
- __func__, dims, texObj, texImage, face, level);
-
- t->validated = GL_FALSE;
-
- radeonFreeTextureImageBuffer(ctx, texImage);
-
- if (!t->bo) {
- teximage_assign_miptree(rmesa, texObj, texImage, face, level);
- if (!image->mt) {
- int size = _mesa_format_image_size(texImage->TexFormat,
- texImage->Width,
- texImage->Height,
- texImage->Depth);
- image->base.Buffer = _mesa_align_malloc(size, 512);
-
- radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
- "%s %dd: texObj %p, texImage %p, "
- " no miptree assigned, using local memory %p\n",
- __func__, dims, texObj, texImage, image->base.Buffer);
- }
- }
-
- {
- struct radeon_bo *bo;
- bo = !image->mt ? image->bo : image->mt->bo;
- if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
- radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
- "%s Calling teximage for texture that is "
- "queued for GPU processing.\n",
- __func__);
- radeon_firevertices(rmesa);
- }
- }
-
- image->base.ImageOffsets =
- (GLuint *) malloc(texImage->Depth * sizeof(GLuint));
-
-
- /* Upload texture image; note that the spec allows pixels to be NULL */
- if (compressed) {
- pixels = _mesa_validate_pbo_compressed_teximage(
- ctx, imageSize, pixels, packing, "glCompressedTexImage");
- } else {
- pixels = _mesa_validate_pbo_teximage(
- ctx, dims, width, height, depth,
- format, type, pixels, packing, "glTexImage");
- }
-
- if (pixels) {
- radeon_store_teximage(ctx, dims,
- 0, 0, 0,
- width, height, depth,
- imageSize, format, type,
- pixels, packing,
- texObj, texImage,
- compressed);
- }
-
- _mesa_unmap_teximage_pbo(ctx, packing);
+ _mesa_store_teximage3d(ctx, target, level, internalFormat,
+ width, height, depth, 0,
+ format, type, pixels,
+ packing, texObj, texImage);
}
@@ -855,13 +621,2 @@ void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
-void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target,
- GLint level, GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLsizei imageSize, const GLvoid * data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
- imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
-}
-
void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
@@ -879,112 +634,2 @@ void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
-/**
- * All glTexSubImage calls go through this function.
- */
-static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- int compressed)
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeonTexObj* t = radeon_tex_obj(texObj);
- radeon_texture_image* image = get_radeon_texture_image(texImage);
-
- radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
- "%s %dd: texObj %p, texImage %p, face %d, level %d\n",
- __func__, dims, texObj, texImage,
- _mesa_tex_target_to_face(target), level);
- {
- struct radeon_bo *bo;
- bo = !image->mt ? image->bo : image->mt->bo;
- if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
- radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
- "%s Calling texsubimage for texture that is "
- "queued for GPU processing.\n",
- __func__);
- radeon_firevertices(rmesa);
- }
- }
-
-
- t->validated = GL_FALSE;
- if (compressed) {
- pixels = _mesa_validate_pbo_compressed_teximage(
- ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
- } else {
- pixels = _mesa_validate_pbo_teximage(ctx, dims,
- width, height, depth, format, type, pixels, packing, "glTexSubImage");
- }
-
- if (pixels) {
- radeon_store_teximage(ctx, dims,
- xoffset, yoffset, zoffset,
- width, height, depth,
- imageSize, format, type,
- pixels, packing,
- texObj, texImage,
- compressed);
- }
-
- _mesa_unmap_teximage_pbo(ctx, packing);
-}
-
-void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
- GLint xoffset,
- GLsizei width,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
- format, type, pixels, packing, texObj, texImage, 0);
-}
-
-void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
- 0, format, type, pixels, packing, texObj, texImage,
- 0);
-}
-
-void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target,
- GLint level, GLint xoffset,
- GLint yoffset, GLsizei width,
- GLsizei height, GLenum format,
- GLsizei imageSize, const GLvoid * data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
- imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
-}
-
-
-void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
- format, type, pixels, packing, texObj, texImage, 0);
-}
-
unsigned radeonIsFormatRenderable(gl_format mesa_format)
@@ -1061,4 +706,3 @@ void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
- if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base,
- radeonImage->base.Base.Face, 0))
+ if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base))
fprintf(stderr, "miptree doesn't match image\n");
@@ -1103,5 +747,4 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
functions->DeleteTextureImage = radeonDeleteTextureImage;
+ functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer;
functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
- functions->MapTexture = radeonMapTexture;
- functions->UnmapTexture = radeonUnmapTexture;
functions->MapTextureImage = radeon_map_texture_image;
@@ -1114,7 +757,2 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
functions->TexImage3D = radeonTexImage3D;
- functions->TexSubImage1D = radeonTexSubImage1D;
- functions->TexSubImage2D = radeonTexSubImage2D;
- functions->TexSubImage3D = radeonTexSubImage3D;
- functions->CompressedTexImage2D = radeonCompressedTexImage2D;
- functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
@@ -1129 +767,131 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
}
+
+static void
+radeon_swrast_map_image(radeonContextPtr rmesa,
+ radeon_texture_image *image)
+{
+ GLuint level, face;
+ radeon_mipmap_tree *mt;
+ GLuint texel_size;
+ radeon_mipmap_level *lvl;
+ int rs;
+
+ if (!image || !image->mt)
+ return;
+
+ texel_size = _mesa_get_format_bytes(image->base.Base.TexFormat);
+ level = image->base.Base.Level;
+ face = image->base.Base.Face;
+ mt = image->mt;
+
+ lvl = &image->mt->levels[level];
+
+ rs = lvl->rowstride / texel_size;
+
+ radeon_bo_map(mt->bo, 1);
+
+ image->base.Data = mt->bo->ptr + lvl->faces[face].offset;
+ if (mt->target == GL_TEXTURE_3D) {
+ int i;
+
+ for (i = 0; i < mt->levels[level].depth; i++)
+ image->base.ImageOffsets[i] = rs * lvl->height * i;
+ }
+ image->base.RowStride = rs;
+}
+
+static void
+radeon_swrast_unmap_image(radeonContextPtr rmesa,
+ radeon_texture_image *image)
+{
+ if (image && image->mt) {
+ image->base.Data = NULL;
+ radeon_bo_unmap(image->mt->bo);
+ }
+}
+
+void
+radeon_swrast_map_texture_images(struct gl_context *ctx,
+ struct gl_texture_object *texObj)
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+ int i, face;
+
+ for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) {
+ for (face = 0; face < nr_faces; face++) {
+ radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]);
+ radeon_swrast_map_image(rmesa, image);
+ }
+ }
+}
+
+void
+radeon_swrast_unmap_texture_images(struct gl_context *ctx,
+ struct gl_texture_object *texObj)
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+ int i, face;
+
+ for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) {
+ for (face = 0; face < nr_faces; face++) {
+ radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]);
+ radeon_swrast_unmap_image(rmesa, image);
+ }
+ }
+
+}
+
+static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeonTexObj *t = radeon_tex_obj(texObj);
+ GLuint firstLevel;
+ GLuint lastLevel;
+ int width, height, depth;
+ int i;
+
+ width = texImage->Width;
+ height = texImage->Height;
+ depth = texImage->Depth;
+
+ if (texImage->Level > texObj->BaseLevel &&
+ (width == 1 ||
+ (texObj->Target != GL_TEXTURE_1D && height == 1) ||
+ (texObj->Target == GL_TEXTURE_3D && depth == 1))) {
+ /* For this combination, we're at some lower mipmap level and
+ * some important dimension is 1. We can't extrapolate up to a
+ * likely base level width/height/depth for a full mipmap stack
+ * from this info, so just allocate this one level.
+ */
+ firstLevel = texImage->Level;
+ lastLevel = texImage->Level;
+ } else {
+ if (texImage->Level < texObj->BaseLevel)
+ firstLevel = 0;
+ else
+ firstLevel = texObj->BaseLevel;
+
+ for (i = texImage->Level; i > firstLevel; i--) {
+ width <<= 1;
+ if (height != 1)
+ height <<= 1;
+ if (depth != 1)
+ depth <<= 1;
+ }
+ if ((texObj->Sampler.MinFilter == GL_NEAREST ||
+ texObj->Sampler.MinFilter == GL_LINEAR) &&
+ texImage->Level == firstLevel) {
+ lastLevel = firstLevel;
+ } else {
+ lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth));
+ }
+ }
+
+ return radeon_miptree_create(rmesa, texObj->Target,
+ texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1,
+ width, height, depth,
+ t->tile_bits);
+}
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
@@ -51,6 +51,8 @@ void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable);
void radeon_teximage_unmap(radeon_texture_image *image);
-void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj);
-void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj);
int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_object *texObj);
+
+void radeon_swrast_map_texture_images(struct gl_context *ctx, struct gl_texture_object *texObj);
+void radeon_swrast_unmap_texture_images(struct gl_context *ctx, struct gl_texture_object *texObj);
+
gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx,