1
/**************************************************************************
3
* Copyright (c) Intel Corp. 2007.
6
* Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
9
* Permission is hereby granted, free of charge, to any person obtaining a
10
* copy of this software and associated documentation files (the
11
* "Software"), to deal in the Software without restriction, including
12
* without limitation the rights to use, copy, modify, merge, publish,
13
* distribute, sub license, and/or sell copies of the Software, and to
14
* permit persons to whom the Software is furnished to do so, subject to
15
* the following conditions:
17
* The above copyright notice and this permission notice (including the
18
* next paragraph) shall be included in all copies or substantial portions
21
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
24
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
25
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
27
* USE OR OTHER DEALINGS IN THE SOFTWARE.
29
**************************************************************************/
32
* Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
40
#include <picturestr.h>
42
#include "psb_accel.h"
43
#include "psb_driver.h"
45
static Bool psbSupportDstA0[] =
46
{ TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE,
47
FALSE, FALSE, FALSE, TRUE, FALSE
51
psbIsPot(unsigned int val)
53
unsigned int test = 0x1;
58
while ((val & test) == 0)
65
psbExaSrfInfo(ScrnInfoPtr pScrn, XpsbSurfacePtr srf,
66
PixmapPtr pPix, PicturePtr pPict)
69
struct _MMBuffer *mmBuffer;
71
unsigned int needed_pitch;
73
pDraw = (pPict->repeat) ? pPict->pDrawable : &pPix->drawable;
74
srf->w = pDraw->width;
75
srf->h = pDraw->height;
76
srf->stride = exaGetPixmapPitch(pPix);
77
if (!psbExaGetSuperOffset(pPix, &offset, &mmBuffer))
83
ALIGN_TO(pDraw->width, 32) * (pDraw->bitsPerPixel >> 3);
85
if (srf->stride != needed_pitch) {
86
unsigned int tmp = srf->stride / (pDraw->bitsPerPixel >> 3);
96
* Poulsbo can only do repeat on power-of-two textures.
100
ALIGN_TO(pDraw->width, 32) * (pDraw->bitsPerPixel >> 3);
101
if (srf->stride != needed_pitch || !psbIsPot(pDraw->width)
102
|| !psbIsPot(pDraw->height))
106
* FIXME: Need to check whether we should add the drawable start offset from
107
* the pixmap base here...
110
srf->offset = offset;
113
srf->buffer = mmKernelBuf(mmBuffer);
116
srf->pictFormat = pPict->format;
117
srf->minFilter = Xpsb_nearest;
118
srf->magFilter = Xpsb_nearest;
119
srf->uMode = (pPict->repeat) ? Xpsb_repeat : Xpsb_clamp;
120
srf->vMode = srf->uMode;
126
psbIsScalar(PicturePtr pPict)
128
return (pPict->repeat && pPict->pDrawable->width == 1 &&
129
pPict->pDrawable->height == 1 &&
130
psbExpandablePixel(pPict->format));
134
psbExaPrepareComposite3D(int op, PicturePtr pSrcPicture,
135
PicturePtr pMaskPicture, PicturePtr pDstPicture,
136
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
138
ScreenPtr pScreen = pDst->drawable.pScreen;
139
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
140
PsbPtr pPsb = psbPTR(pScrn);
141
PsbExaPtr pPsbExa = pPsb->pPsbExa;
142
XpsbSurfacePtr opTex[2];
144
unsigned int numTex = 0;
146
if (PICT_FORMAT_A(pDstPicture->format) == 0 && !psbSupportDstA0[op])
149
pPsbExa->scalarSrc = psbIsScalar(pSrcPicture);
150
pPsbExa->scalarMask = (pMaskPicture == NULL) ||
151
PICT_FORMAT_A(pMaskPicture->format) == 0 || psbIsScalar(pMaskPicture);
153
if (pPsbExa->scalarSrc && pPsbExa->scalarMask) {
156
* Ouch. EXA should've optimized this away.
159
pPsbExa->scalarSrc = FALSE;
162
if ((pPsbExa->scalarSrc || pPsbExa->scalarMask) &&
163
!(pPsbExa->scalarSrc && pPsbExa->scalarMask)) {
166
* Get the scalar pixel value.
169
if (pPsbExa->scalarSrc)
170
psbPixelARGB8888(pSrcPicture->format, pSrc->devPrivate.ptr,
172
else if (pMaskPicture != NULL &&
173
PICT_FORMAT_A(pMaskPicture->format) > 0)
174
psbPixelARGB8888(pMaskPicture->format, pMask->devPrivate.ptr,
177
scalarPixel = 0xFF000000;
180
if (!pPsbExa->scalarSrc) {
181
if (!psbExaSrfInfo(pScrn, &pPsbExa->src, pSrc, pSrcPicture))
184
opTex[numTex] = &pPsbExa->src;
185
pPsbExa->src.texCoordIndex = numTex++;
187
if (!pPsbExa->scalarMask) {
188
if (!psbExaSrfInfo(pScrn, &pPsbExa->mask, pMask, pMaskPicture))
191
opTex[numTex] = &pPsbExa->mask;
192
pPsbExa->mask.texCoordIndex = numTex++;
194
if (!psbExaSrfInfo(pScrn, &pPsbExa->dst, pDst, pDstPicture)) {
198
pPsbExa->dst.texCoordIndex = 0;
200
if (!psb3DPrepareComposite(pScrn, &pPsbExa->dst,
202
(unsigned int)scalarPixel,
203
pPsbExa->scalarSrc, pPsbExa->scalarMask))
210
psbExaComposite3D(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
211
int dstX, int dstY, int width, int height)
213
ScreenPtr pScreen = pDst->drawable.pScreen;
214
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
215
PsbPtr pPsb = psbPTR(pScrn);
216
PsbExaPtr pPsbExa = pPsb->pPsbExa;
217
float vertices[4 * XPSB_VOFFSET_COUNT];
218
XpsbSurface *src = &pPsbExa->src;
219
XpsbSurface *mask = &pPsbExa->mask;
220
Bool scalar = pPsbExa->scalarSrc || pPsbExa->scalarMask;
221
unsigned int used_coords = ((scalar) ? 4 : 6);
225
float *vertex0 = &vertices[0 * used_coords];
226
float *vertex3 = &vertices[3 * used_coords];
233
coord = XPSB_VOFFSET_UT0;
234
vertex0[XPSB_VOFFSET_X] = dstX;
235
vertex0[XPSB_VOFFSET_Y] = dstY;
236
if (!pPsbExa->scalarSrc) {
237
vertex0[coord++] = (float)srcX / (float)src->w;
238
vertex0[coord++] = (float)srcY / (float)src->h;
240
if (!pPsbExa->scalarMask) {
241
vertex0[coord++] = (float)maskX / (float)mask->w;
242
vertex0[coord++] = (float)maskY / (float)mask->h;
249
coord = XPSB_VOFFSET_UT0;
250
vertex3[XPSB_VOFFSET_X] = dstX + width;
251
vertex3[XPSB_VOFFSET_Y] = dstY + height;
252
if (!pPsbExa->scalarSrc) {
253
vertex3[coord++] = (float)(srcX + width) / (float)src->w;
254
vertex3[coord++] = (float)(srcY + height) / (float)src->h;
256
if (!pPsbExa->scalarMask) {
257
vertex3[coord++] = (float)(maskX + width) / (float)mask->w;
258
vertex3[coord++] = (float)(maskY + height) / (float)mask->h;
265
vertex = &vertices[1 * used_coords];
266
vertex[XPSB_VOFFSET_X] = vertex3[XPSB_VOFFSET_X];
267
vertex[XPSB_VOFFSET_Y] = vertex0[XPSB_VOFFSET_Y];
268
vertex[XPSB_VOFFSET_UT0] = vertex3[XPSB_VOFFSET_UT0];
269
vertex[XPSB_VOFFSET_VT0] = vertex0[XPSB_VOFFSET_VT0];
271
vertex[XPSB_VOFFSET_UT1] = vertex3[XPSB_VOFFSET_UT1];
272
vertex[XPSB_VOFFSET_VT1] = vertex0[XPSB_VOFFSET_VT1];
279
vertex = &vertices[2 * used_coords];
280
vertex[XPSB_VOFFSET_X] = vertex0[XPSB_VOFFSET_X];
281
vertex[XPSB_VOFFSET_Y] = vertex3[XPSB_VOFFSET_Y];
282
vertex[XPSB_VOFFSET_UT0] = vertex0[XPSB_VOFFSET_UT0];
283
vertex[XPSB_VOFFSET_VT0] = vertex3[XPSB_VOFFSET_VT0];
285
vertex[XPSB_VOFFSET_UT1] = vertex0[XPSB_VOFFSET_UT1];
286
vertex[XPSB_VOFFSET_VT1] = vertex3[XPSB_VOFFSET_VT1];
289
psb3DCompositeQuad(pScrn, vertices);
293
psbExaDoneComposite3D(PixmapPtr pPixmap)
295
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
297
psb3DCompositeFinish(pScrn);