static Bool NV40EXACheckCompositeTexture(PicturePtr pPict, PicturePtr pdPict, int op) { nv_pict_texture_format_t *fmt; int w = 1, h = 1; if (pPict->pDrawable) { w = pPict->pDrawable->width; h = pPict->pDrawable->height; } else { switch (pPict->pSourcePict->type) { case SourcePictTypeSolidFill: break; default: NOUVEAU_FALLBACK("gradient\n"); } } if ((w > 4096) || (h > 4096)) NOUVEAU_FALLBACK("picture too large, %dx%d\n", w, h); fmt = NV40_GetPictTextureFormat(pPict->format); if (!fmt) NOUVEAU_FALLBACK("picture format 0x%08x not supported\n", pPict->format); if (pPict->filter != PictFilterNearest && pPict->filter != PictFilterBilinear) NOUVEAU_FALLBACK("filter 0x%x not supported\n", pPict->filter); /* Opengl and Render disagree on what should be sampled outside an XRGB * texture (with no repeating). Opengl has a hardcoded alpha value of * 1.0, while render expects 0.0. We assume that clipping is done for * untranformed sources. */ if (NV40PictOp[op].src_alpha && !pPict->repeat && pPict->transform && (PICT_FORMAT_A(pPict->format) == 0) && (PICT_FORMAT_A(pdPict->format) != 0)) NOUVEAU_FALLBACK("REPEAT_NONE unsupported for XRGB source\n"); return TRUE; }
static Bool NV40EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) { NVPtr pNv = NVPTR(pScrn); struct nouveau_channel *chan = pNv->chan; struct nouveau_grobj *curie = pNv->Nv3D; struct nouveau_bo *bo = nouveau_pixmap_bo(pPix); unsigned tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; nv_pict_texture_format_t *fmt; NV40EXA_STATE; fmt = NV40_GetPictTextureFormat(pPict->format); if (!fmt) return FALSE; BEGIN_RING(chan, curie, NV40TCL_TEX_OFFSET(unit), 8); if (OUT_RELOCl(chan, bo, 0, tex_reloc) || OUT_RELOCd(chan, bo, fmt->card_fmt | NV40TCL_TEX_FORMAT_LINEAR | NV40TCL_TEX_FORMAT_DIMS_2D | 0x8000 | NV40TCL_TEX_FORMAT_NO_BORDER | (1 << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT), tex_reloc | NOUVEAU_BO_OR, NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1)) return FALSE; if (pPict->repeat) { switch(pPict->repeatType) { case RepeatPad: OUT_RING (chan, NV40TCL_TEX_WRAP_S_CLAMP | NV40TCL_TEX_WRAP_T_CLAMP | NV40TCL_TEX_WRAP_R_CLAMP); break; case RepeatReflect: OUT_RING (chan, NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT | NV40TCL_TEX_WRAP_T_MIRRORED_REPEAT | NV40TCL_TEX_WRAP_R_MIRRORED_REPEAT); break; case RepeatNormal: default: OUT_RING (chan, NV40TCL_TEX_WRAP_S_REPEAT | NV40TCL_TEX_WRAP_T_REPEAT | NV40TCL_TEX_WRAP_R_REPEAT); break; } } else { OUT_RING (chan, NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER | NV40TCL_TEX_WRAP_T_CLAMP_TO_BORDER | NV40TCL_TEX_WRAP_R_CLAMP_TO_BORDER); } OUT_RING (chan, NV40TCL_TEX_ENABLE_ENABLE); OUT_RING (chan, fmt->card_swz); if (pPict->filter == PictFilterBilinear) { OUT_RING (chan, NV40TCL_TEX_FILTER_MIN_LINEAR | NV40TCL_TEX_FILTER_MAG_LINEAR | 0x3fd6); } else { OUT_RING (chan, NV40TCL_TEX_FILTER_MIN_NEAREST | NV40TCL_TEX_FILTER_MAG_NEAREST | 0x3fd6); } OUT_RING (chan, (pPix->drawable.width << 16) | pPix->drawable.height); OUT_RING (chan, 0); /* border ARGB */ BEGIN_RING(chan, curie, NV40TCL_TEX_SIZE1(unit), 1); OUT_RING (chan, (1 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | (uint32_t)exaGetPixmapPitch(pPix)); state->unit[unit].width = (float)pPix->drawable.width; state->unit[unit].height = (float)pPix->drawable.height; state->unit[unit].transform = pPict->transform; return TRUE; }
static Bool NV40EXAPictTexture(NVPtr pNv, PixmapPtr pPix, PicturePtr pPict, int unit) { unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR; struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(pPix); nv_pict_texture_format_t *fmt; fmt = NV40_GetPictTextureFormat(pPict->format); if (!fmt) return FALSE; BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8); PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), bo, 0, reloc); PUSH_MTHDs(push, NV30_3D(TEX_FORMAT(unit)), bo, fmt->card_fmt | NV40_3D_TEX_FORMAT_LINEAR | NV30_3D_TEX_FORMAT_DIMS_2D | 0x8000 | NV30_3D_TEX_FORMAT_NO_BORDER | (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT), reloc | NOUVEAU_BO_OR, NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1); if (pPict->repeat) { switch(pPict->repeatType) { case RepeatPad: PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP | NV30_3D_TEX_WRAP_T_CLAMP | NV30_3D_TEX_WRAP_R_CLAMP); break; case RepeatReflect: PUSH_DATA (push, NV30_3D_TEX_WRAP_S_MIRRORED_REPEAT | NV30_3D_TEX_WRAP_T_MIRRORED_REPEAT | NV30_3D_TEX_WRAP_R_MIRRORED_REPEAT); break; case RepeatNormal: default: PUSH_DATA (push, NV30_3D_TEX_WRAP_S_REPEAT | NV30_3D_TEX_WRAP_T_REPEAT | NV30_3D_TEX_WRAP_R_REPEAT); break; } } else { PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_BORDER | NV30_3D_TEX_WRAP_T_CLAMP_TO_BORDER | NV30_3D_TEX_WRAP_R_CLAMP_TO_BORDER); } PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE); PUSH_DATA (push, fmt->card_swz); if (pPict->filter == PictFilterBilinear) { PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR | NV30_3D_TEX_FILTER_MAG_LINEAR | 0x3fd6); } else { PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST | NV30_3D_TEX_FILTER_MAG_NEAREST | 0x3fd6); } PUSH_DATA (push, (pPix->drawable.width << 16) | pPix->drawable.height); PUSH_DATA (push, 0); /* border ARGB */ BEGIN_NV04(push, NV40_3D(TEX_SIZE1(unit)), 1); PUSH_DATA (push, (1 << NV40_3D_TEX_SIZE1_DEPTH__SHIFT) | (uint32_t)exaGetPixmapPitch(pPix)); BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 17); PUSH_DATA (push, unit * 4); if (pPict->transform) { PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[0][0])); PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[0][1])); PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[0][2])); PUSH_DATAf(push, 0); PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[1][0])); PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[1][1])); PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[1][2])); PUSH_DATAf(push, 0); PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[2][0])); PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[2][1])); PUSH_DATAf(push, xFixedToFloat(pPict->transform->matrix[2][2])); PUSH_DATAf(push, 0); } else { PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 0.0); } PUSH_DATAf(push, 1.0 / pPix->drawable.width); PUSH_DATAf(push, 1.0 / pPix->drawable.height); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); return TRUE; }