static Bool RADEONPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); uint32_t datatype, dst_pitch_offset; struct radeon_exa_pixmap_priv *driver_priv; int ret; TRACE; if (pPix->drawable.bitsPerPixel == 24) RADEON_FALLBACK(("24bpp unsupported\n")); if (!RADEONGetDatatypeBpp(pPix->drawable.bitsPerPixel, &datatype)) RADEON_FALLBACK(("RADEONGetDatatypeBpp failed\n")); if (!RADEONGetPixmapOffsetPitch(pPix, &dst_pitch_offset)) RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n")); RADEON_SWITCH_TO_2D(); radeon_cs_space_reset_bos(info->cs); driver_priv = exaGetPixmapDriverPrivate(pPix); radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); ret = radeon_cs_space_check(info->cs); if (ret) RADEON_FALLBACK(("Not enough RAM to hw accel solid operation\n")); driver_priv = exaGetPixmapDriverPrivate(pPix); if (driver_priv) { info->state_2d.dst_bo = driver_priv->bo; info->state_2d.dst_domain = driver_priv->shared ? RADEON_GEM_DOMAIN_GTT : RADEON_GEM_DOMAIN_VRAM; } info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX); info->state_2d.dp_brush_bkgd_clr = 0x00000000; info->state_2d.dp_src_frgd_clr = 0xffffffff; info->state_2d.dp_src_bkgd_clr = 0x00000000; info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_SOLID_COLOR | (datatype << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP[alu].pattern | RADEON_GMC_CLR_CMP_CNTL_DIS); info->state_2d.dp_brush_frgd_clr = fg; info->state_2d.dp_cntl = (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM); info->state_2d.dp_write_mask = pm; info->state_2d.dst_pitch_offset = dst_pitch_offset; info->state_2d.src_pitch_offset = 0; info->state_2d.src_bo = NULL; info->accel_state->dst_pix = pPix; Emit2DState(pScrn, RADEON_2D_EXA_SOLID); return TRUE; }
/** * Ensure all enabled and complete textures are uploaded along with any buffers being used. */ GLboolean r300ValidateBuffers(GLcontext * ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); struct radeon_renderbuffer *rrb; int i; int ret; radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); rrb = radeon_get_colorbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM); } /* depth buffer */ rrb = radeon_get_depthbuffer(&rmesa->radeon); if (rrb && rrb->bo) { radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM); } for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { radeonTexObj *t; if (!ctx->Texture.Unit[i]._ReallyEnabled) continue; if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) { _mesa_warning(ctx, "failed to validate texture for unit %d.\n", i); } t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); if (t->image_override && t->bo) radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); else if (t->mt->bo) radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); } ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0); if (ret) return GL_FALSE; return GL_TRUE; }
static Bool RADEONPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int xdir, int ydir, int rop, Pixel planemask) { RINFO_FROM_SCREEN(pDst->drawable.pScreen); uint32_t datatype, src_pitch_offset, dst_pitch_offset; struct radeon_exa_pixmap_priv *driver_priv; int ret; TRACE; if (pDst->drawable.bitsPerPixel == 24) RADEON_FALLBACK(("24bpp unsupported")); if (!RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype)) RADEON_FALLBACK(("RADEONGetDatatypeBpp failed\n")); if (!RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset)) RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch source failed\n")); if (!RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset)) RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch dest failed\n")); RADEON_SWITCH_TO_2D(); radeon_cs_space_reset_bos(info->cs); driver_priv = exaGetPixmapDriverPrivate(pSrc); radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); info->state_2d.src_bo = driver_priv->bo; driver_priv = exaGetPixmapDriverPrivate(pDst); info->state_2d.dst_bo = driver_priv->bo; info->state_2d.dst_domain = driver_priv->shared ? RADEON_GEM_DOMAIN_GTT : RADEON_GEM_DOMAIN_VRAM; radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, info->state_2d.dst_domain); ret = radeon_cs_space_check(info->cs); if (ret) RADEON_FALLBACK(("Not enough RAM to hw accel copy operation\n")); info->accel_state->xdir = xdir; info->accel_state->ydir = ydir; info->accel_state->dst_pix = pDst; RADEONDoPrepareCopy(pScrn, src_pitch_offset, dst_pitch_offset, datatype, rop, planemask); return TRUE; }
static GLboolean validate_buffers(struct r200_context *r200, struct radeon_bo *src_bo, struct radeon_bo *dst_bo) { int ret; radeon_cs_space_reset_bos(r200->radeon.cmdbuf.cs); ret = radeon_cs_space_check_with_bo(r200->radeon.cmdbuf.cs, src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); if (ret) return GL_FALSE; ret = radeon_cs_space_check_with_bo(r200->radeon.cmdbuf.cs, dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT); if (ret) return GL_FALSE; return GL_TRUE; }
static Bool RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch) { RINFO_FROM_SCREEN(pSrc->drawable.pScreen); struct radeon_exa_pixmap_priv *driver_priv; struct radeon_bo *scratch = NULL; struct radeon_bo *copy_src; unsigned size; uint32_t datatype = 0; uint32_t src_domain = 0; uint32_t src_pitch_offset; unsigned bpp = pSrc->drawable.bitsPerPixel; uint32_t scratch_pitch = RADEON_ALIGN(w * bpp / 8, 64); uint32_t copy_pitch; uint32_t swap = RADEON_HOST_DATA_SWAP_NONE; int ret; Bool flush = FALSE; Bool r; if (bpp < 8) return FALSE; driver_priv = exaGetPixmapDriverPrivate(pSrc); if (!driver_priv || !driver_priv->bo) return FALSE; #if X_BYTE_ORDER == X_BIG_ENDIAN switch (bpp) { case 32: swap = RADEON_HOST_DATA_SWAP_32BIT; break; case 16: swap = RADEON_HOST_DATA_SWAP_16BIT; break; } #endif /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */ copy_src = driver_priv->bo; copy_pitch = pSrc->devKind; if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { src_domain = radeon_bo_get_src_domain(driver_priv->bo); if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) src_domain = 0; else /* A write may be scheduled */ flush = TRUE; } if (!src_domain) radeon_bo_is_busy(driver_priv->bo, &src_domain); if (src_domain & ~(uint32_t)RADEON_GEM_DOMAIN_VRAM) goto copy; } size = scratch_pitch * h; scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0); if (scratch == NULL) { goto copy; } radeon_cs_space_reset_bos(info->cs); radeon_add_pixmap(info->cs, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); radeon_cs_space_add_persistent_bo(info->cs, scratch, 0, RADEON_GEM_DOMAIN_GTT); ret = radeon_cs_space_check(info->cs); if (ret) { goto copy; } RADEONGetDatatypeBpp(pSrc->drawable.bitsPerPixel, &datatype); RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset); RADEON_SWITCH_TO_2D(); RADEONBlitChunk(pScrn, driver_priv->bo, scratch, datatype, src_pitch_offset, scratch_pitch << 16, x, y, 0, 0, w, h, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_GTT); copy_src = scratch; copy_pitch = scratch_pitch; flush = TRUE; copy: if (flush) FLUSH_RING(); ret = radeon_bo_map(copy_src, 0); if (ret) { ErrorF("failed to map pixmap: %d\n", ret); r = FALSE; goto out; } r = TRUE; w *= bpp / 8; if (copy_src == driver_priv->bo) size = y * copy_pitch + x * bpp / 8; else size = 0; while (h--) { RADEONCopySwap((uint8_t*)dst, copy_src->ptr + size, w, swap); size += copy_pitch; dst += dst_pitch; } radeon_bo_unmap(copy_src); out: if (scratch) radeon_bo_unref(scratch); return r; }
static Bool RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch) { ScreenPtr pScreen = pDst->drawable.pScreen; RINFO_FROM_SCREEN(pScreen); struct radeon_exa_pixmap_priv *driver_priv; struct radeon_bo *scratch = NULL; struct radeon_bo *copy_dst; unsigned char *dst; unsigned size; uint32_t datatype = 0; uint32_t dst_domain; uint32_t dst_pitch_offset; unsigned bpp = pDst->drawable.bitsPerPixel; uint32_t scratch_pitch = RADEON_ALIGN(w * bpp / 8, 64); uint32_t copy_pitch; uint32_t swap = RADEON_HOST_DATA_SWAP_NONE; int ret; Bool flush = TRUE; Bool r; int i; if (bpp < 8) return FALSE; driver_priv = exaGetPixmapDriverPrivate(pDst); if (!driver_priv || !driver_priv->bo) return FALSE; #if X_BYTE_ORDER == X_BIG_ENDIAN switch (bpp) { case 32: swap = RADEON_HOST_DATA_SWAP_32BIT; break; case 16: swap = RADEON_HOST_DATA_SWAP_16BIT; break; } #endif /* If we know the BO won't be busy / in VRAM, don't bother with a scratch */ copy_dst = driver_priv->bo; copy_pitch = pDst->devKind; if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { flush = FALSE; if (!radeon_bo_is_busy(driver_priv->bo, &dst_domain) && !(dst_domain & RADEON_GEM_DOMAIN_VRAM)) goto copy; } /* use cpu copy for fast fb access */ if (info->is_fast_fb) goto copy; } size = scratch_pitch * h; scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0); if (scratch == NULL) { goto copy; } radeon_cs_space_reset_bos(info->cs); radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM); radeon_cs_space_add_persistent_bo(info->cs, scratch, RADEON_GEM_DOMAIN_GTT, 0); ret = radeon_cs_space_check(info->cs); if (ret) { goto copy; } copy_dst = scratch; copy_pitch = scratch_pitch; flush = FALSE; copy: if (flush) radeon_cs_flush_indirect(pScrn); ret = radeon_bo_map(copy_dst, 0); if (ret) { r = FALSE; goto out; } r = TRUE; size = w * bpp / 8; dst = copy_dst->ptr; if (copy_dst == driver_priv->bo) dst += y * copy_pitch + x * bpp / 8; for (i = 0; i < h; i++) { RADEONCopySwap(dst + i * copy_pitch, (uint8_t*)src, size, swap); src += src_pitch; } radeon_bo_unmap(copy_dst); if (copy_dst == scratch) { RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype); RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset); RADEON_SWITCH_TO_2D(); RADEONBlitChunk(pScrn, scratch, driver_priv->bo, datatype, scratch_pitch << 16, dst_pitch_offset, 0, 0, x, y, w, h, RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_VRAM); } out: if (scratch) radeon_bo_unref(scratch); return r; }