#include "radeon_common.h"
#include "radeon_context.h"
#include "radeon_blit.h"
+#include "radeon_tex.h"
static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
int reg, int count)
}
/* common formats supported as both textures and render targets */
-unsigned r100_check_blit(gl_format mesa_format)
+unsigned r100_check_blit(mesa_format mesa_format, uint32_t dst_pitch)
{
- /* XXX others? BE/LE? */
- switch (mesa_format) {
- case MESA_FORMAT_ARGB8888:
- case MESA_FORMAT_XRGB8888:
- case MESA_FORMAT_RGB565:
- case MESA_FORMAT_ARGB4444:
- case MESA_FORMAT_ARGB1555:
- case MESA_FORMAT_A8:
- case MESA_FORMAT_L8:
- case MESA_FORMAT_I8:
+ /* XXX others? */
+ if (_mesa_little_endian()) {
+ switch (mesa_format) {
+ case MESA_FORMAT_B8G8R8A8_UNORM:
+ case MESA_FORMAT_B8G8R8X8_UNORM:
+ case MESA_FORMAT_B5G6R5_UNORM:
+ case MESA_FORMAT_B4G4R4A4_UNORM:
+ case MESA_FORMAT_B5G5R5A1_UNORM:
+ case MESA_FORMAT_A_UNORM8:
+ case MESA_FORMAT_L_UNORM8:
+ case MESA_FORMAT_I_UNORM8:
break;
- default:
+ default:
+ return 0;
+ }
+ }
+ else {
+ switch (mesa_format) {
+ case MESA_FORMAT_A8R8G8B8_UNORM:
+ case MESA_FORMAT_X8R8G8B8_UNORM:
+ case MESA_FORMAT_R5G6B5_UNORM:
+ case MESA_FORMAT_A4R4G4B4_UNORM:
+ case MESA_FORMAT_A1R5G5B5_UNORM:
+ case MESA_FORMAT_A_UNORM8:
+ case MESA_FORMAT_L_UNORM8:
+ case MESA_FORMAT_I_UNORM8:
+ break;
+ default:
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;
}
static void inline emit_tx_setup(struct r100_context *r100,
- gl_format mesa_format,
+ mesa_format mesa_format,
struct radeon_bo *bo,
intptr_t offset,
unsigned width,
uint32_t txformat = RADEON_TXFORMAT_NON_POWER2;
BATCH_LOCALS(&r100->radeon);
- assert(width <= 2047);
- assert(height <= 2047);
+ assert(width <= 2048);
+ assert(height <= 2048);
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_RGBA8888:
- txformat |= RADEON_TXFORMAT_RGBA8888 | 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_ARGB4444:
- txformat |= RADEON_TXFORMAT_ARGB4444 | RADEON_TXFORMAT_ALPHA_IN_MAP;
- break;
- case MESA_FORMAT_ARGB1555:
- txformat |= RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP;
- break;
- case MESA_FORMAT_A8:
- case MESA_FORMAT_I8:
- txformat |= RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP;
- break;
- case MESA_FORMAT_L8:
- txformat |= RADEON_TXFORMAT_I8;
- break;
- case MESA_FORMAT_AL88:
- txformat |= RADEON_TXFORMAT_AI88 | RADEON_TXFORMAT_ALPHA_IN_MAP;
- break;
- default:
- break;
- }
+ txformat |= tx_table[mesa_format].format;
+
+ if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
+ offset |= RADEON_TXO_MACRO_TILE;
+ if (bo->flags & RADEON_BO_FLAGS_MICRO_TILE)
+ offset |= RADEON_TXO_MICRO_TILE_X2;
BEGIN_BATCH(18);
OUT_BATCH_REGVAL(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE);
OUT_BATCH_REGVAL(RADEON_PP_TEX_PITCH_0, pitch * _mesa_get_format_bytes(mesa_format) - 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);
+ OUT_BATCH_RELOC(offset, bo, offset, 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,
+ mesa_format mesa_format,
unsigned pitch,
unsigned width,
unsigned height)
uint32_t dst_format = 0;
BATCH_LOCALS(&r100->radeon);
- /* XXX others? BE/LE? */
+ /* XXX others? */
switch (mesa_format) {
- case MESA_FORMAT_ARGB8888:
- case MESA_FORMAT_XRGB8888:
+ /* The first of each pair is for little, the second for big endian. */
+ case MESA_FORMAT_B8G8R8A8_UNORM:
+ case MESA_FORMAT_A8R8G8B8_UNORM:
+ case MESA_FORMAT_B8G8R8X8_UNORM:
+ case MESA_FORMAT_X8R8G8B8_UNORM:
dst_format = RADEON_COLOR_FORMAT_ARGB8888;
break;
- case MESA_FORMAT_RGB565:
+ case MESA_FORMAT_B5G6R5_UNORM:
+ case MESA_FORMAT_R5G6B5_UNORM:
dst_format = RADEON_COLOR_FORMAT_RGB565;
break;
- case MESA_FORMAT_ARGB4444:
+ case MESA_FORMAT_B4G4R4A4_UNORM:
+ case MESA_FORMAT_A4R4G4B4_UNORM:
dst_format = RADEON_COLOR_FORMAT_ARGB4444;
break;
- case MESA_FORMAT_ARGB1555:
+ case MESA_FORMAT_B5G5R5A1_UNORM:
+ case MESA_FORMAT_A1R5G5B5_UNORM:
dst_format = RADEON_COLOR_FORMAT_ARGB1555;
break;
- case MESA_FORMAT_A8:
- case MESA_FORMAT_L8:
- case MESA_FORMAT_I8:
+ case MESA_FORMAT_A_UNORM8:
+ case MESA_FORMAT_L_UNORM8:
+ case MESA_FORMAT_I_UNORM8:
dst_format = RADEON_COLOR_FORMAT_RGB8;
break;
default:
break;
}
- BEGIN_BATCH_NO_AUTOSTATE(18);
+ if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
+ dst_pitch |= RADEON_COLOR_TILE_ENABLE;
+
+ if (bo->flags & RADEON_BO_FLAGS_MICRO_TILE)
+ dst_pitch |= RADEON_COLOR_MICROTILE_ENABLE;
+
+ BEGIN_BATCH(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_RE_WIDTH_HEIGHT, (((width - 1) << RADEON_RE_WIDTH_SHIFT) |
+ ((height - 1) << 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_RELOC(offset, bo, offset, 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);
* @param[in] height region height
* @param[in] flip_y set if y coords of the source image need to be flipped
*/
-unsigned r100_blit(GLcontext *ctx,
+unsigned r100_blit(struct gl_context *ctx,
struct radeon_bo *src_bo,
intptr_t src_offset,
- gl_format src_mesaformat,
+ mesa_format src_mesaformat,
unsigned src_pitch,
unsigned src_width,
unsigned src_height,
unsigned src_y_offset,
struct radeon_bo *dst_bo,
intptr_t dst_offset,
- gl_format dst_mesaformat,
+ mesa_format dst_mesaformat,
unsigned dst_pitch,
unsigned dst_width,
unsigned dst_height,
{
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.
}
if (0) {
- fprintf(stderr, "src: size [%d x %d], pitch %d, "
+ fprintf(stderr, "src: size [%d x %d], pitch %d, offset %zd "
"offset [%d x %d], format %s, bo %p\n",
- src_width, src_height, src_pitch,
+ src_width, src_height, src_pitch, src_offset,
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,
+ fprintf(stderr, "dst: pitch %d offset %zd, offset[%d x %d], format %s, bo %p\n",
+ dst_pitch, dst_offset, 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(ctx);
- rcommonEnsureCmdBufSpace(&r100->radeon, 59, __FUNCTION__);
+ rcommonEnsureCmdBufSpace(&r100->radeon, 59, __func__);
if (!validate_buffers(r100, src_bo, dst_bo))
return GL_FALSE;
radeonFlush(ctx);
+ /* We submitted those packets outside our state atom mechanism. Thus
+ * make sure they are all resubmitted the next time. */
+ r100->hw.ctx.dirty = GL_TRUE;
+ r100->hw.msk.dirty = GL_TRUE;
+ r100->hw.set.dirty = GL_TRUE;
+ r100->hw.tex[0].dirty = GL_TRUE;
+ r100->hw.txr[0].dirty = GL_TRUE;
+
return GL_TRUE;
}