summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,
}
/* 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)
{
/* XXX others? BE/LE? */
switch (mesa_format) {
@@ -58,6 +58,12 @@ unsigned r200_check_blit(gl_format mesa_format)
return 0;
}
+ /* Rendering to small buffer doesn't work.
+ * Looks like a hw limitation.
+ */
+ if (dst_pitch < 32)
+ return 0;
+
/* ??? */
if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
return 0;
@@ -467,19 +473,13 @@ unsigned r200_blit(struct gl_context *ctx,
{
struct r200_context *r200 = R200_CONTEXT(ctx);
- if (!r200_check_blit(dst_mesaformat))
+ if (!r200_check_blit(dst_mesaformat, dst_pitch))
return GL_FALSE;
/* Make sure that colorbuffer has even width - hw limitation */
if (dst_pitch % 2 > 0)
++dst_pitch;
- /* 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
* we don't read outside of the source buffer
* 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 @@
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);
unsigned r200_blit(struct gl_context *ctx,
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,
}
/* 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)
{
/* XXX others? BE/LE? */
switch (mesa_format) {
@@ -55,6 +55,12 @@ unsigned r100_check_blit(gl_format mesa_format)
return 0;
}
+ /* Rendering to small buffer doesn't work.
+ * Looks like a hw limitation.
+ */
+ if (dst_pitch < 32)
+ return 0;
+
/* ??? */
if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
return 0;
@@ -344,19 +350,13 @@ unsigned r100_blit(struct gl_context *ctx,
{
struct r100_context *r100 = R100_CONTEXT(ctx);
- if (!r100_check_blit(dst_mesaformat))
+ if (!r100_check_blit(dst_mesaformat, dst_pitch))
return GL_FALSE;
/* Make sure that colorbuffer has even width - hw limitation */
if (dst_pitch % 2 > 0)
++dst_pitch;
- /* 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
* we don't read outside of the source buffer
* 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 @@
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);
unsigned r100_blit(struct gl_context *ctx,
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
struct radeon_bo *map_bo;
GLbitfield map_mode;
int map_x, map_y, map_w, map_h;
+ int map_pitch;
uint32_t draw_offset; /* FBO */
/* boo Xorg 6.8.2 compat */
@@ -174,6 +175,7 @@ struct _radeon_texture_image {
*/
struct _radeon_mipmap_tree *mt;
struct radeon_bo *bo;
+ GLboolean used_as_render_target;
};
@@ -481,7 +483,7 @@ struct radeon_context {
void (*free_context)(struct gl_context *ctx);
void (*emit_query_finish)(radeonContextPtr radeon);
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,
struct radeon_bo *src_bo,
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,
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
GLubyte *map;
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;
rrb->map_x = x;
rrb->map_y = y;
rrb->map_w = w;
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;
*out_map = map;
- *out_stride = stride;
+ *out_stride = flip_stride;
}
static void
@@ -142,11 +182,17 @@ radeon_unmap_renderbuffer(struct gl_context *ctx,
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
GLboolean ok;
+ if (!rrb->map_bo) {
+ if (rrb->bo)
+ radeon_bo_unmap(rrb->bo);
+ return;
+ }
+
radeon_bo_unmap(rrb->map_bo);
if (rrb->map_mode & GL_MAP_WRITE_BIT) {
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,
0, 0,
rrb->bo, rrb->draw_offset,
@@ -627,7 +673,7 @@ radeon_render_texture(struct gl_context * ctx,
radeon_image = (radeon_texture_image *)newImage;
- if (!radeon_image->mt || newImage->Border != 0) {
+ if (!radeon_image->mt) {
/* Fallback on drawing to a texture without a miptree.
*/
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
@@ -681,6 +727,7 @@ radeon_render_texture(struct gl_context * ctx,
* the image we are rendering to */
rrb->draw_offset = imageOffset;
rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride;
+ radeon_image->used_as_render_target = GL_TRUE;
/* update drawing region, etc */
radeon_draw_buffer(ctx, fb);
@@ -690,7 +737,16 @@ static void
radeon_finish_render_texture(struct gl_context * ctx,
struct gl_renderbuffer_attachment *att)
{
-
+ 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 */
}
static void
radeon_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
/**
* Create a new mipmap tree, calculate its layout and allocate memory.
*/
-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)
{
radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree);
@@ -298,13 +298,10 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj,
* given face and level.
*/
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)
return GL_FALSE;
@@ -332,7 +329,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g
mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel];
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);
if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) {
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)
struct gl_texture_object *texObj = &t->base;
struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];
GLuint numLevels;
-
assert(!t->mt);
if (!texImg) {
@@ -544,27 +540,19 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
radeonTexObj *t = radeon_tex_obj(texObj);
+ radeon_mipmap_tree *dst_miptree;
if (t->validated || t->image_override) {
return GL_TRUE;
}
- 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);
radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
"%s: Validating texture %p now, minLod = %d, maxLod = %d\n",
__FUNCTION__, texObj ,t->minLod, t->maxLod);
- 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);
radeon_miptree_unreference(&t->mt);
if (!dst_miptree) {
@@ -591,7 +579,7 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o
"Checking image level %d, face %d, mt %p ... ",
level, face, img->mt);
- if (img->mt != t->mt) {
+ if (img->mt != t->mt && !img->used_as_render_target) {
radeon_print(RADEON_TEXTURE, RADEON_TRACE,
"MIGRATING\n");
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);
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);
GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt,
GLuint face, GLuint level);
@@ -98,4 +99,8 @@ unsigned get_texture_image_size(
unsigned height,
unsigned depth,
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
@@ -105,7 +105,7 @@ 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
@@ -216,25 +216,25 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
*/
#define LOCAL_VARS \
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; \
int maxx = rb->Width; \
int maxy = rb->Height; \
+ void *buf = rb->Data; \
+ int pitch = rb->RowStride * rrb->cpp; \
GLuint p; \
(void)p;
#define LOCAL_DEPTH_VARS \
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; \
int maxy = rb->Height;
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
-#define Y_FLIP(_y) ((_y) * yScale + yBias)
+#define Y_FLIP(_y) (_y)
#define HW_LOCK()
#define HW_UNLOCK()
@@ -249,108 +249,78 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
*/
#define SPANTMP_PIXEL_FMT GL_RGB
#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"
#define SPANTMP_PIXEL_FMT GL_RGB
#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"
/* 16 bit, ARGB1555 color spanline and pixel functions
*/
#define SPANTMP_PIXEL_FMT GL_BGRA
#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"
#define SPANTMP_PIXEL_FMT GL_BGRA
#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"
/* 16 bit, RGBA4 color spanline and pixel functions
*/
#define SPANTMP_PIXEL_FMT GL_BGRA
#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"
#define SPANTMP_PIXEL_FMT GL_BGRA
#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"
/* 32 bit, xRGB8888 color spanline and pixel functions
*/
#define SPANTMP_PIXEL_FMT GL_BGRA
#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"
/* 32 bit, ARGB8888 color spanline and pixel functions
*/
#define SPANTMP_PIXEL_FMT GL_BGRA
#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"
/* 32 bit, BGRx8888 color spanline and pixel functions
*/
#define SPANTMP_PIXEL_FMT GL_BGRA
#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"
/* 32 bit, BGRA8888 color spanline and pixel functions
*/
#define SPANTMP_PIXEL_FMT GL_BGRA
#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)
/* ================================================================
* Depth buffer
*/
@@ -509,77 +479,69 @@ do { \
#define TAG(x) radeon##x##_s8_z24
#include "stenciltmp.h"
-
-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;
}
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)
{
GLuint i, j;
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);
radeon_check_front_buffer_rendering(ctx);
}
@@ -591,13 +553,16 @@ static void radeonSpanRenderStart(struct gl_context * ctx)
radeon_firevertices(rmesa);
- 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);
}
static void radeonSpanRenderFinish(struct gl_context * ctx)
@@ -608,11 +573,11 @@ static void radeonSpanRenderFinish(struct gl_context * ctx)
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
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);
}
void 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,
dst_mesaformat = timg->base.Base.TexFormat;
src_bpp = _mesa_get_format_bytes(src_mesaformat);
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 */
if (_mesa_get_format_bits(dst_mesaformat, GL_DEPTH_BITS) > 0)
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 @@
#include "radeon_mipmap_tree.h"
+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);
void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
GLuint numrows, GLuint rowsize)
@@ -94,6 +101,33 @@ radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img)
_mesa_delete_texture_image(ctx, 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;
+}
+
/**
* Free memory associated with this texture image.
@@ -104,7 +138,6 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag
if (image->mt) {
radeon_miptree_unreference(&image->mt);
- assert(!image->base.Buffer);
} else {
_swrast_free_texture_image_buffer(ctx, timage);
}
@@ -173,91 +206,6 @@ 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);
-}
-
-
/**
* Map texture memory/buffer into user space.
* Note: the region of interest parameters are ignored here.
@@ -286,7 +234,7 @@ radeon_map_texture_image(struct gl_context *ctx,
_mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
assert(y % bh == 0);
y /= bh;
- height /= bh;
+ texel_size /= bw;
if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
@@ -302,9 +250,11 @@ radeon_map_texture_image(struct gl_context *ctx,
*stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target);
*map = bo->ptr;
} 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;
*stride = lvl->rowstride;
*map = base + (slice * height) * *stride;
@@ -594,51 +544,24 @@ gl_format radeonChooseTextureFormat(struct gl_context * ctx,
/** Check if given image is valid within current texture object.
*/
-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)
{
radeonTexObj *t = radeon_tex_obj(texObj);
radeon_texture_image* image = get_radeon_texture_image(texImage);
- /* 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);
}
/* Miptree alocation may have failed,
@@ -650,101 +573,6 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
"%s Failed to allocate miptree.\n", __func__);
}
-
-/**
- * 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);
-}
-
/**
* All glTexImage calls go through this function.
*/
@@ -760,72 +588,10 @@ static void radeon_teximage(
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 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);
}
void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
@@ -853,17 +619,6 @@ void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
0, format, type, pixels, packing, texObj, texImage, 0);
}
-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,
GLint internalFormat,
GLint width, GLint height, GLint depth,
@@ -877,116 +632,6 @@ void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
0, format, type, pixels, packing, texObj, texImage, 0);
}
-/**
- * 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)
{
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,
radeon_bo_ref(image->bo);
t->mt->bo = image->bo;
- 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");
}
#endif
@@ -1101,9 +745,8 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
{
functions->NewTextureImage = radeonNewTextureImage;
functions->DeleteTextureImage = radeonDeleteTextureImage;
+ functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer;
functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
- functions->MapTexture = radeonMapTexture;
- functions->UnmapTexture = radeonUnmapTexture;
functions->MapTextureImage = radeon_map_texture_image;
functions->UnmapTextureImage = radeon_unmap_texture_image;
@@ -1112,11 +755,6 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
functions->TexImage1D = radeonTexImage1D;
functions->TexImage2D = radeonTexImage2D;
functions->TexImage3D = radeonTexImage3D;
- functions->TexSubImage1D = radeonTexSubImage1D;
- functions->TexSubImage2D = radeonTexSubImage2D;
- functions->TexSubImage3D = radeonTexSubImage3D;
- functions->CompressedTexImage2D = radeonCompressedTexImage2D;
- functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
@@ -1127,3 +765,133 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon,
radeonInitTextureFormats();
}
+
+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
@@ -49,10 +49,12 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag
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,
GLint internalFormat,
GLenum format,