diff options
author | Alex Deucher <[email protected]> | 2010-01-18 20:56:11 -0500 |
---|---|---|
committer | Alex Deucher <[email protected]> | 2010-01-18 20:56:58 -0500 |
commit | daccc962a15f333a4759849d7088b0c985189175 (patch) | |
tree | da28643b8b124a6d84c917c7fed1441b2fa600b4 /src/mesa/drivers/dri/radeon | |
parent | 1ced546577745d361ad06577914f44f484656d37 (diff) |
r100: add blit support
Only enabled with KMS.
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
-rw-r--r-- | src/mesa/drivers/dri/radeon/Makefile | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_blit.c | 369 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_blit.h | 54 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.c | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_texcopy.c | 168 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/server/radeon_reg.h | 25 |
7 files changed, 623 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 2b2f2c4aa7a..70b946b2fd5 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -40,6 +40,8 @@ DRIVER_SOURCES = \ radeon_swtcl.c \ radeon_maos.c \ radeon_sanity.c \ + radeon_blit.c \ + radeon_texcopy.c \ $(RADEON_COMMON_SOURCES) C_SOURCES = \ diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.c b/src/mesa/drivers/dri/radeon/radeon_blit.c new file mode 100644 index 00000000000..4abe7a2960d --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_blit.c @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2010 Advanced Micro Devices, Inc. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "radeon_common.h" +#include "radeon_context.h" +#include "radeon_blit.h" + +static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, + int reg, int count) +{ + if (count) + return CP_PACKET0(reg, count - 1); + return CP_PACKET2; +} + +static inline void emit_vtx_state(struct r100_context *r100) +{ + BATCH_LOCALS(&r100->radeon); + + BEGIN_BATCH(8); + if (r100->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + OUT_BATCH_REGVAL(RADEON_SE_CNTL_STATUS, 0); + } else { + OUT_BATCH_REGVAL(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS); + + } + OUT_BATCH_REGVAL(RADEON_SE_COORD_FMT, (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_W0)); + OUT_BATCH_REGVAL(RADEON_SE_VTX_FMT, RADEON_SE_VTX_FMT_XY | RADEON_SE_VTX_FMT_ST0); + OUT_BATCH_REGVAL(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_ROUND | + RADEON_ROUND_PREC_4TH_PIX)); + END_BATCH(); +} + +static void inline emit_tx_setup(struct r100_context *r100, + gl_format mesa_format, + struct radeon_bo *bo, + intptr_t offset, + unsigned width, + unsigned height, + unsigned pitch) +{ + uint32_t txformat = RADEON_TXFORMAT_NON_POWER2; + BATCH_LOCALS(&r100->radeon); + + assert(width <= 2047); + assert(height <= 2047); + assert(offset % 32 == 0); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + txformat |= RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_XRGB8888: + txformat |= RADEON_TXFORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + txformat |= RADEON_TXFORMAT_RGB565; + break; + case MESA_FORMAT_ARGB1555: + txformat |= RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_A8: + txformat |= RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + default: + break; + } + + BEGIN_BATCH(18); + OUT_BATCH_REGVAL(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); + OUT_BATCH_REGVAL(RADEON_PP_TXCBLEND_0, (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX)); + OUT_BATCH_REGVAL(RADEON_PP_TXABLEND_0, (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX)); + OUT_BATCH_REGVAL(RADEON_PP_TXFILTER_0, (RADEON_CLAMP_S_CLAMP_LAST | + RADEON_CLAMP_T_CLAMP_LAST | + RADEON_MAG_FILTER_NEAREST | + RADEON_MIN_FILTER_NEAREST)); + OUT_BATCH_REGVAL(RADEON_PP_TXFORMAT_0, txformat); + OUT_BATCH_REGVAL(RADEON_PP_TEX_SIZE_0, ((width - 1) | + ((height - 1) << RADEON_TEX_VSIZE_SHIFT))); + OUT_BATCH_REGVAL(RADEON_PP_TEX_PITCH_0, pitch - 32); + + OUT_BATCH_REGSEQ(RADEON_PP_TXOFFSET_0, 1); + OUT_BATCH_RELOC(0, bo, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + + END_BATCH(); +} + +static inline void emit_cb_setup(struct r100_context *r100, + struct radeon_bo *bo, + intptr_t offset, + gl_format mesa_format, + unsigned pitch, + unsigned width, + unsigned height) +{ + uint32_t dst_pitch = pitch; + uint32_t dst_format = 0; + BATCH_LOCALS(&r100->radeon); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + dst_format = RADEON_COLOR_FORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + dst_format = RADEON_COLOR_FORMAT_RGB565; + break; + case MESA_FORMAT_ARGB1555: + dst_format = RADEON_COLOR_FORMAT_ARGB1555; + break; + case MESA_FORMAT_A8: + dst_format = RADEON_COLOR_FORMAT_RGB8; + break; + default: + break; + } + + BEGIN_BATCH_NO_AUTOSTATE(18); + OUT_BATCH_REGVAL(RADEON_RE_TOP_LEFT, 0); + OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, ((width << RADEON_RE_WIDTH_SHIFT) | + (height << RADEON_RE_HEIGHT_SHIFT))); + OUT_BATCH_REGVAL(RADEON_RB3D_PLANEMASK, 0xffffffff); + OUT_BATCH_REGVAL(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); + OUT_BATCH_REGVAL(RADEON_RB3D_CNTL, dst_format); + + OUT_BATCH_REGSEQ(RADEON_RB3D_COLOROFFSET, 1); + OUT_BATCH_RELOC(0, bo, 0, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + OUT_BATCH_REGSEQ(RADEON_RB3D_COLORPITCH, 1); + OUT_BATCH_RELOC(dst_pitch, bo, dst_pitch, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + + END_BATCH(); +} + +static GLboolean validate_buffers(struct r100_context *r100, + struct radeon_bo *src_bo, + struct radeon_bo *dst_bo) +{ + int ret; + radeon_cs_space_add_persistent_bo(r100->radeon.cmdbuf.cs, + src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_cs_space_add_persistent_bo(r100->radeon.cmdbuf.cs, + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check_with_bo(r100->radeon.cmdbuf.cs, + first_elem(&r100->radeon.dma.reserved)->bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + return GL_TRUE; +} + +/** + * Calculate texcoords for given image region. + * Output values are [minx, maxx, miny, maxy] + */ +static inline void calc_tex_coords(float img_width, float img_height, + float x, float y, + float reg_width, float reg_height, + unsigned flip_y, float *buf) +{ + buf[0] = x / img_width; + buf[1] = buf[0] + reg_width / img_width; + buf[2] = y / img_height; + buf[3] = buf[2] + reg_height / img_height; + if (flip_y) + { + float tmp = buf[2]; + buf[2] = 1.0 - buf[3]; + buf[3] = 1.0 - tmp; + } +} + +static inline void emit_draw_packet(struct r100_context *r100, + unsigned src_width, unsigned src_height, + unsigned src_x_offset, unsigned src_y_offset, + unsigned dst_x_offset, unsigned dst_y_offset, + unsigned reg_width, unsigned reg_height, + unsigned flip_y) +{ + float texcoords[4]; + float verts[12]; + BATCH_LOCALS(&r100->radeon); + + calc_tex_coords(src_width, src_height, + src_x_offset, src_y_offset, + reg_width, reg_height, + flip_y, texcoords); + + verts[0] = dst_x_offset; + verts[1] = dst_y_offset + reg_height; + verts[2] = texcoords[0]; + verts[3] = texcoords[2]; + + verts[4] = dst_x_offset + reg_width; + verts[5] = dst_y_offset + reg_height; + verts[6] = texcoords[1]; + verts[7] = texcoords[2]; + + verts[8] = dst_x_offset + reg_width; + verts[9] = dst_y_offset; + verts[10] = texcoords[1]; + verts[11] = texcoords[3]; + + BEGIN_BATCH(15); + OUT_BATCH(RADEON_CP_PACKET3_3D_DRAW_IMMD | (13 << 16)); + OUT_BATCH(RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_ST0); + OUT_BATCH(RADEON_CP_VC_CNTL_PRIM_WALK_RING | + RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST | + RADEON_CP_VC_CNTL_MAOS_ENABLE | + RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | + (3 << 16)); + OUT_BATCH_TABLE(verts, 12); + END_BATCH(); +} + +/** + * Copy a region of [@a width x @a height] pixels from source buffer + * to destination buffer. + * @param[in] r100 r100 context + * @param[in] src_bo source radeon buffer object + * @param[in] src_offset offset of the source image in the @a src_bo + * @param[in] src_mesaformat source image format + * @param[in] src_pitch aligned source image width + * @param[in] src_width source image width + * @param[in] src_height source image height + * @param[in] src_x_offset x offset in the source image + * @param[in] src_y_offset y offset in the source image + * @param[in] dst_bo destination radeon buffer object + * @param[in] dst_offset offset of the destination image in the @a dst_bo + * @param[in] dst_mesaformat destination image format + * @param[in] dst_pitch aligned destination image width + * @param[in] dst_width destination image width + * @param[in] dst_height destination image height + * @param[in] dst_x_offset x offset in the destination image + * @param[in] dst_y_offset y offset in the destination image + * @param[in] width region width + * @param[in] height region height + * @param[in] flip_y set if y coords of the source image need to be flipped + */ +GLboolean r100_blit(struct r100_context *r100, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y) +{ + if (_mesa_get_format_bits(src_mesaformat, GL_DEPTH_BITS) > 0) + 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. + */ + if (reg_width + src_x_offset > src_width) + reg_width = src_width - src_x_offset; + if (reg_height + src_y_offset > src_height) + reg_height = src_height - src_y_offset; + if (reg_width + dst_x_offset > dst_width) + reg_width = dst_width - dst_x_offset; + if (reg_height + dst_y_offset > dst_height) + reg_height = dst_height - dst_y_offset; + + if (src_bo == dst_bo) { + return GL_FALSE; + } + + if (0) { + fprintf(stderr, "src: size [%d x %d], pitch %d, " + "offset [%d x %d], format %s, bo %p\n", + src_width, src_height, src_pitch, + src_x_offset, src_y_offset, + _mesa_get_format_name(src_mesaformat), + src_bo); + fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n", + dst_pitch, dst_x_offset, dst_y_offset, + _mesa_get_format_name(dst_mesaformat), dst_bo); + fprintf(stderr, "region: %d x %d\n", reg_width, reg_height); + } + + /* Flush is needed to make sure that source buffer has correct data */ + radeonFlush(r100->radeon.glCtx); + + rcommonEnsureCmdBufSpace(&r100->radeon, 59, __FUNCTION__); + + if (!validate_buffers(r100, src_bo, dst_bo)) + return GL_FALSE; + + /* 8 */ + emit_vtx_state(r100); + /* 18 */ + emit_tx_setup(r100, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch); + /* 18 */ + emit_cb_setup(r100, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height); + /* 15 */ + emit_draw_packet(r100, src_width, src_height, + src_x_offset, src_y_offset, + dst_x_offset, dst_y_offset, + reg_width, reg_height, + flip_y); + + radeonFlush(r100->radeon.glCtx); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.h b/src/mesa/drivers/dri/radeon/radeon_blit.h new file mode 100644 index 00000000000..c0203d0a54d --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_blit.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Advanced Micro Devices, Inc. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RADEON_BLIT_H +#define RADEON_BLIT_H + +void r100_blit_init(struct r100_context *r100); + +GLboolean r100_blit(struct r100_context *r100, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned width, + unsigned height, + unsigned flip_y); + +#endif // RADEON_BLIT_H diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 3cd305b0a25..1182fc7f0d7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -228,6 +228,7 @@ r100CreateContext( const __GLcontextModes *glVisual, if ( !rmesa ) return GL_FALSE; + rmesa->radeon.radeonScreen = screen; r100_init_vtbl(&rmesa->radeon); /* init exp fog table data */ @@ -260,6 +261,10 @@ r100CreateContext( const __GLcontextModes *glVisual, radeonInitTextureFuncs( &functions ); radeonInitQueryObjFunctions(&functions); + if (rmesa->radeon.radeonScreen->kernel_mm) { + r100_init_texcopy_functions(&functions); + } + if (!radeonInitContext(&rmesa->radeon, &functions, glVisual, driContextPriv, sharedContextPrivate)) { diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index dfedc38bfd1..c52eff855f2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -453,7 +453,7 @@ struct r100_context { extern GLboolean r100CreateContext( const __GLcontextModes *glVisual, __DRIcontext *driContextPriv, void *sharedContextPrivate); - +extern void r100_init_texcopy_functions(struct dd_function_table *table); #endif /* __RADEON_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_texcopy.c b/src/mesa/drivers/dri/radeon/radeon_texcopy.c new file mode 100644 index 00000000000..d4328982c3a --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_texcopy.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2009 Maciej Cencora <[email protected]> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "radeon_common.h" +#include "radeon_context.h" + +#include "main/image.h" +#include "main/teximage.h" +#include "main/texstate.h" +#include "drivers/common/meta.h" + +#include "radeon_mipmap_tree.h" +#include "radeon_blit.h" +#include <main/debug.h> + +// TODO: +// need to pass correct pitch for small dst textures! +static GLboolean +do_copy_texsubimage(GLcontext *ctx, + GLenum target, GLint level, + struct radeon_tex_obj *tobj, + radeon_texture_image *timg, + GLint dstx, GLint dsty, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + struct r100_context *r100 = R100_CONTEXT(ctx); + struct radeon_renderbuffer *rrb; + + if (_mesa_get_format_bits(timg->base.TexFormat, GL_DEPTH_BITS) > 0) { + rrb = radeon_get_depthbuffer(&r100->radeon); + } else { + rrb = radeon_get_colorbuffer(&r100->radeon); + } + + if (!timg->mt) { + radeon_validate_texture_miptree(ctx, &tobj->base); + } + + assert(rrb && rrb->bo); + assert(timg->mt->bo); + assert(timg->base.Width >= dstx + width); + assert(timg->base.Height >= dsty + height); + + intptr_t src_offset = rrb->draw_offset; + intptr_t dst_offset = radeon_miptree_image_offset(timg->mt, _mesa_tex_target_to_face(target), level); + + if (src_offset % 32 || dst_offset % 32) { + return GL_FALSE; + } + + if (0) { + fprintf(stderr, "%s: copying to face %d, level %d\n", + __FUNCTION__, _mesa_tex_target_to_face(target), level); + fprintf(stderr, "to: x %d, y %d, offset %d\n", dstx, dsty, (uint32_t) dst_offset); + fprintf(stderr, "from (%dx%d) width %d, height %d, offset %d, pitch %d\n", + x, y, rrb->base.Width, rrb->base.Height, (uint32_t) src_offset, rrb->pitch/rrb->cpp); + fprintf(stderr, "src size %d, dst size %d\n", rrb->bo->size, timg->mt->bo->size); + + } + + /* blit from src buffer to texture */ + return r100_blit(r100, rrb->bo, src_offset, rrb->base.Format, rrb->pitch, + rrb->base.Width, rrb->base.Height, x, y, + timg->mt->bo, dst_offset, timg->base.TexFormat, + timg->base.Width, timg->base.Width, timg->base.Height, + dstx, dsty, width, height, 1); +} + +static void +r100CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) +{ + struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + int srcx, srcy, dstx, dsty; + + if (border) + goto fail; + + /* Setup or redefine the texture object, mipmap tree and texture + * image. Don't populate yet. + */ + ctx->Driver.TexImage2D(ctx, target, level, internalFormat, + width, height, border, + GL_RGBA, GL_UNSIGNED_BYTE, NULL, + &ctx->DefaultPacking, texObj, texImage); + + srcx = x; + srcy = y; + dstx = 0; + dsty = 0; + if (!_mesa_clip_copytexsubimage(ctx, + &dstx, &dsty, + &srcx, &srcy, + &width, &height)) { + return; + } + + if (!do_copy_texsubimage(ctx, target, level, + radeon_tex_obj(texObj), (radeon_texture_image *)texImage, + 0, 0, x, y, width, height)) { + goto fail; + } + + return; + +fail: + _mesa_meta_CopyTexImage2D(ctx, target, level, internalFormat, x, y, + width, height, border); +} + +static void +r100CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); + struct gl_texture_object *texObj = _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + if (!do_copy_texsubimage(ctx, target, level, + radeon_tex_obj(texObj), (radeon_texture_image *)texImage, + xoffset, yoffset, x, y, width, height)) { + + //DEBUG_FALLBACKS + + _mesa_meta_CopyTexSubImage2D(ctx, target, level, + xoffset, yoffset, x, y, width, height); + } +} + + +void r100_init_texcopy_functions(struct dd_function_table *table) +{ + table->CopyTexImage2D = r100CopyTexImage2D; + table->CopyTexSubImage2D = r100CopyTexSubImage2D; +} diff --git a/src/mesa/drivers/dri/radeon/server/radeon_reg.h b/src/mesa/drivers/dri/radeon/server/radeon_reg.h index e81d7fdcd0e..1b33de1edf7 100644 --- a/src/mesa/drivers/dri/radeon/server/radeon_reg.h +++ b/src/mesa/drivers/dri/radeon/server/radeon_reg.h @@ -1959,7 +1959,30 @@ #define RADEON_SE_ZBIAS_FACTOR 0x1db0 #define RADEON_SE_ZBIAS_CONSTANT 0x1db4 - +#define RADEON_SE_VTX_FMT 0x2080 +# define RADEON_SE_VTX_FMT_XY 0x00000000 +# define RADEON_SE_VTX_FMT_W0 0x00000001 +# define RADEON_SE_VTX_FMT_FPCOLOR 0x00000002 +# define RADEON_SE_VTX_FMT_FPALPHA 0x00000004 +# define RADEON_SE_VTX_FMT_PKCOLOR 0x00000008 +# define RADEON_SE_VTX_FMT_FPSPEC 0x00000010 +# define RADEON_SE_VTX_FMT_FPFOG 0x00000020 +# define RADEON_SE_VTX_FMT_PKSPEC 0x00000040 +# define RADEON_SE_VTX_FMT_ST0 0x00000080 +# define RADEON_SE_VTX_FMT_ST1 0x00000100 +# define RADEON_SE_VTX_FMT_Q1 0x00000200 +# define RADEON_SE_VTX_FMT_ST2 0x00000400 +# define RADEON_SE_VTX_FMT_Q2 0x00000800 +# define RADEON_SE_VTX_FMT_ST3 0x00001000 +# define RADEON_SE_VTX_FMT_Q3 0x00002000 +# define RADEON_SE_VTX_FMT_Q0 0x00004000 +# define RADEON_SE_VTX_FMT_BLND_WEIGHT_CNT_MASK 0x00038000 +# define RADEON_SE_VTX_FMT_N0 0x00040000 +# define RADEON_SE_VTX_FMT_XY1 0x08000000 +# define RADEON_SE_VTX_FMT_Z1 0x10000000 +# define RADEON_SE_VTX_FMT_W1 0x20000000 +# define RADEON_SE_VTX_FMT_N1 0x40000000 +# define RADEON_SE_VTX_FMT_Z 0x80000000 /* Registers for CP and Microcode Engine */ #define RADEON_CP_ME_RAM_ADDR 0x07d4 |