| @@ -11,27 +11,27 @@ | | | @@ -11,27 +11,27 @@ |
11 | * furnished to do so, subject to the following conditions: | | 11 | * furnished to do so, subject to the following conditions: |
12 | * | | 12 | * |
13 | * The above copyright notice and this permission notice shall be included in | | 13 | * The above copyright notice and this permission notice shall be included in |
14 | * all copies or substantial portions of the Software. | | 14 | * all copies or substantial portions of the Software. |
15 | * | | 15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | | 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | | 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
19 | * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | | 19 | * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | | 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | | 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
22 | */ | | 22 | */ |
23 | | | 23 | |
24 | /* $NetBSD: igs_accel.c,v 1.2 2009/11/21 22:22:27 macallan Exp $ */ | | 24 | /* $NetBSD: igs_accel.c,v 1.3 2010/05/20 07:55:20 macallan Exp $ */ |
25 | | | 25 | |
26 | #include <sys/types.h> | | 26 | #include <sys/types.h> |
27 | | | 27 | |
28 | #include "igs.h" | | 28 | #include "igs.h" |
29 | | | 29 | |
30 | /*#define DEBUG*/ | | 30 | /*#define DEBUG*/ |
31 | | | 31 | |
32 | #ifdef DEBUG | | 32 | #ifdef DEBUG |
33 | #define ENTER xf86Msg(X_ERROR, "%s\n", __func__) | | 33 | #define ENTER xf86Msg(X_ERROR, "%s\n", __func__) |
34 | #define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__) | | 34 | #define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__) |
35 | #else | | 35 | #else |
36 | #define ENTER | | 36 | #define ENTER |
37 | #define LEAVE | | 37 | #define LEAVE |
| @@ -61,61 +61,61 @@ static inline uint8_t IgsRead1(IgsPtr fP | | | @@ -61,61 +61,61 @@ static inline uint8_t IgsRead1(IgsPtr fP |
61 | static inline uint16_t IgsRead2(IgsPtr fPtr, int offset) | | 61 | static inline uint16_t IgsRead2(IgsPtr fPtr, int offset) |
62 | { | | 62 | { |
63 | return *(uint16_t *)(fPtr->reg + offset); | | 63 | return *(uint16_t *)(fPtr->reg + offset); |
64 | } | | 64 | } |
65 | | | 65 | |
66 | static void | | 66 | static void |
67 | IgsWaitMarker(ScreenPtr pScreen, int Marker) | | 67 | IgsWaitMarker(ScreenPtr pScreen, int Marker) |
68 | { | | 68 | { |
69 | ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; | | 69 | ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; |
70 | IgsPtr fPtr = IGSPTR(pScrn); | | 70 | IgsPtr fPtr = IGSPTR(pScrn); |
71 | int bail = 0x0fffffff; | | 71 | int bail = 0x0fffffff; |
72 | | | 72 | |
73 | ENTER; | | 73 | ENTER; |
74 | IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, (fPtr->info.depth >> 3) - 1); | | 74 | IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt); |
75 | while ((IgsRead1(fPtr, | | 75 | while ((IgsRead1(fPtr, |
76 | IGS_COP_CTL_REG) & (IGS_COP_CTL_BUSY | IGS_COP_CTL_HFEMPTZ) != 0) | | 76 | IGS_COP_CTL_REG) & (IGS_COP_CTL_BUSY | IGS_COP_CTL_HFEMPTZ) != 0) |
77 | && (bail > 0)) { | | 77 | && (bail > 0)) { |
78 | bail--; | | 78 | bail--; |
79 | usleep(1); | | 79 | IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt); |
80 | } | | 80 | } |
81 | | | 81 | |
82 | /* reset the coprocessor if we run into a timeout */ | | 82 | /* reset the coprocessor if we run into a timeout */ |
83 | if (bail == 0) { | | 83 | if (bail == 0) { |
84 | xf86Msg(X_ERROR, "%s: timeout\n", __func__); | | 84 | xf86Msg(X_ERROR, "%s: timeout\n", __func__); |
85 | IgsWrite1(fPtr, IGS_COP_CTL_REG, 0); | | 85 | IgsWrite1(fPtr, IGS_COP_CTL_REG, 0); |
86 | } | | 86 | } |
87 | LEAVE; | | 87 | LEAVE; |
88 | } | | 88 | } |
89 | | | 89 | |
90 | static int | | 90 | static int |
91 | IgsMarkSync(ScreenPtr pScreenInfo) | | 91 | IgsMarkSync(ScreenPtr pScreenInfo) |
92 | { | | 92 | { |
93 | ENTER; | | 93 | ENTER; |
94 | return 0; | | 94 | return 0; |
95 | } | | 95 | } |
96 | | | 96 | |
97 | static void | | 97 | static void |
98 | IgsWaitReady(IgsPtr fPtr) | | 98 | IgsWaitReady(IgsPtr fPtr) |
99 | { | | 99 | { |
100 | int bail = 0x0fffffff; | | 100 | int bail = 0x0fffffff; |
101 | | | 101 | |
102 | ENTER; | | 102 | ENTER; |
103 | IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, (fPtr->info.depth >> 3) - 1); | | 103 | IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt); |
104 | while (((IgsRead1(fPtr, | | 104 | while (((IgsRead1(fPtr, |
105 | IGS_COP_CTL_REG) & (IGS_COP_CTL_BUSY | IGS_COP_CTL_HFEMPTZ)) != 0) | | 105 | IGS_COP_CTL_REG) & (IGS_COP_CTL_BUSY | IGS_COP_CTL_HFEMPTZ)) != 0) |
106 | && (bail > 0)) { | | 106 | && (bail > 0)) { |
107 | bail--; | | 107 | bail--; |
108 | usleep(1); | | 108 | IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt); |
109 | } | | 109 | } |
110 | | | 110 | |
111 | /* reset the coprocessor if we run into a timeout */ | | 111 | /* reset the coprocessor if we run into a timeout */ |
112 | if (bail == 0) { | | 112 | if (bail == 0) { |
113 | xf86Msg(X_ERROR, "%s: timeout\n", __func__); | | 113 | xf86Msg(X_ERROR, "%s: timeout\n", __func__); |
114 | IgsWrite1(fPtr, IGS_COP_CTL_REG, 0); | | 114 | IgsWrite1(fPtr, IGS_COP_CTL_REG, 0); |
115 | } | | 115 | } |
116 | LEAVE; | | 116 | LEAVE; |
117 | } | | 117 | } |
118 | | | 118 | |
119 | static Bool | | 119 | static Bool |
120 | IgsPrepareCopy | | 120 | IgsPrepareCopy |
121 | ( | | 121 | ( |
| @@ -251,60 +251,64 @@ IgsSolid( | | | @@ -251,60 +251,64 @@ IgsSolid( |
251 | /* | | 251 | /* |
252 | * Memcpy-based UTS. | | 252 | * Memcpy-based UTS. |
253 | */ | | 253 | */ |
254 | static Bool | | 254 | static Bool |
255 | IgsUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, | | 255 | IgsUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, |
256 | char *src, int src_pitch) | | 256 | char *src, int src_pitch) |
257 | { | | 257 | { |
258 | ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; | | 258 | ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; |
259 | IgsPtr fPtr = IGSPTR(pScrn); | | 259 | IgsPtr fPtr = IGSPTR(pScrn); |
260 | char *dst = fPtr->fbmem + exaGetPixmapOffset(pDst); | | 260 | char *dst = fPtr->fbmem + exaGetPixmapOffset(pDst); |
261 | int dst_pitch = exaGetPixmapPitch(pDst); | | 261 | int dst_pitch = exaGetPixmapPitch(pDst); |
262 | | | 262 | |
263 | int bpp = pDst->drawable.bitsPerPixel; | | 263 | int bpp = pDst->drawable.bitsPerPixel; |
264 | int cpp = (bpp + 7) / 8; | | 264 | int cpp = (bpp + 7) >> 3; |
265 | int wBytes = w * cpp; | | 265 | int wBytes = w * cpp; |
266 | | | 266 | |
267 | ENTER; | | 267 | ENTER; |
268 | dst += (x * cpp) + (y * dst_pitch); | | 268 | dst += (x * cpp) + (y * dst_pitch); |
269 | | | 269 | |
| | | 270 | IgsWaitReady(fPtr); |
| | | 271 | |
270 | while (h--) { | | 272 | while (h--) { |
271 | memcpy(dst, src, wBytes); | | 273 | memcpy(dst, src, wBytes); |
272 | src += src_pitch; | | 274 | src += src_pitch; |
273 | dst += dst_pitch; | | 275 | dst += dst_pitch; |
274 | } | | 276 | } |
275 | LEAVE; | | 277 | LEAVE; |
276 | return TRUE; | | 278 | return TRUE; |
277 | } | | 279 | } |
278 | | | 280 | |
279 | /* | | 281 | /* |
280 | * Memcpy-based DFS. | | 282 | * Memcpy-based DFS. |
281 | */ | | 283 | */ |
282 | static Bool | | 284 | static Bool |
283 | IgsDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, | | 285 | IgsDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, |
284 | char *dst, int dst_pitch) | | 286 | char *dst, int dst_pitch) |
285 | { | | 287 | { |
286 | ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; | | 288 | ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; |
287 | IgsPtr fPtr = IGSPTR(pScrn); | | 289 | IgsPtr fPtr = IGSPTR(pScrn); |
288 | char *src = fPtr->fbmem + exaGetPixmapOffset(pSrc); | | 290 | char *src = fPtr->fbmem + exaGetPixmapOffset(pSrc); |
289 | int src_pitch = exaGetPixmapPitch(pSrc); | | 291 | int src_pitch = exaGetPixmapPitch(pSrc); |
290 | | | 292 | |
291 | int bpp = pSrc->drawable.bitsPerPixel; | | 293 | int bpp = pSrc->drawable.bitsPerPixel; |
292 | int cpp = (bpp + 7) / 8; | | 294 | int cpp = (bpp + 7) >> 3; |
293 | int wBytes = w * cpp; | | 295 | int wBytes = w * cpp; |
294 | | | 296 | |
295 | ENTER; | | 297 | ENTER; |
296 | src += (x * cpp) + (y * src_pitch); | | 298 | src += (x * cpp) + (y * src_pitch); |
297 | | | 299 | |
| | | 300 | IgsWaitReady(fPtr); |
| | | 301 | |
298 | while (h--) { | | 302 | while (h--) { |
299 | memcpy(dst, src, wBytes); | | 303 | memcpy(dst, src, wBytes); |
300 | src += src_pitch; | | 304 | src += src_pitch; |
301 | dst += dst_pitch; | | 305 | dst += dst_pitch; |
302 | } | | 306 | } |
303 | LEAVE; | | 307 | LEAVE; |
304 | return TRUE; | | 308 | return TRUE; |
305 | } | | 309 | } |
306 | | | 310 | |
307 | Bool | | 311 | Bool |
308 | IgsInitAccel(ScreenPtr pScreen) | | 312 | IgsInitAccel(ScreenPtr pScreen) |
309 | { | | 313 | { |
310 | ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; | | 314 | ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; |
| @@ -333,29 +337,37 @@ IgsInitAccel(ScreenPtr pScreen) | | | @@ -333,29 +337,37 @@ IgsInitAccel(ScreenPtr pScreen) |
333 | | | 337 | |
334 | pExa->MarkSync = IgsMarkSync; | | 338 | pExa->MarkSync = IgsMarkSync; |
335 | pExa->WaitMarker = IgsWaitMarker; | | 339 | pExa->WaitMarker = IgsWaitMarker; |
336 | pExa->PrepareSolid = IgsPrepareSolid; | | 340 | pExa->PrepareSolid = IgsPrepareSolid; |
337 | pExa->Solid = IgsSolid; | | 341 | pExa->Solid = IgsSolid; |
338 | pExa->DoneSolid = IgsDoneCopy; | | 342 | pExa->DoneSolid = IgsDoneCopy; |
339 | pExa->PrepareCopy = IgsPrepareCopy; | | 343 | pExa->PrepareCopy = IgsPrepareCopy; |
340 | pExa->Copy = IgsCopy; | | 344 | pExa->Copy = IgsCopy; |
341 | pExa->DoneCopy = IgsDoneCopy; | | 345 | pExa->DoneCopy = IgsDoneCopy; |
342 | | | 346 | |
343 | switch(fPtr->info.depth) { | | 347 | switch(fPtr->info.depth) { |
344 | case 8: | | 348 | case 8: |
345 | fPtr->shift = 0; | | 349 | fPtr->shift = 0; |
| | | 350 | fPtr->mapfmt = IGS_COP_MAP_8BPP; |
346 | break; | | 351 | break; |
347 | case 16: | | 352 | case 16: |
348 | fPtr->shift = 1; | | 353 | fPtr->shift = 1; |
| | | 354 | fPtr->mapfmt = IGS_COP_MAP_16BPP; |
349 | break; | | 355 | break; |
| | | 356 | case 24: |
350 | case 32: | | 357 | case 32: |
351 | fPtr->shift = 2; | | 358 | fPtr->shift = 2; |
| | | 359 | fPtr->mapfmt = IGS_COP_MAP_32BPP; |
352 | break; | | 360 | break; |
| | | 361 | default: |
| | | 362 | ErrorF("Unsupported depth: %d\n", fPtr->info.depth); |
353 | } | | 363 | } |
| | | 364 | IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt); |
| | | 365 | |
354 | /* EXA hits more optimized paths when it does not have to fallback | | 366 | /* EXA hits more optimized paths when it does not have to fallback |
355 | * because of missing UTS/DFS, hook memcpy-based UTS/DFS. | | 367 | * because of missing UTS/DFS, hook memcpy-based UTS/DFS. |
356 | */ | | 368 | */ |
357 | pExa->UploadToScreen = IgsUploadToScreen; | | 369 | pExa->UploadToScreen = IgsUploadToScreen; |
358 | pExa->DownloadFromScreen = IgsDownloadFromScreen; | | 370 | pExa->DownloadFromScreen = IgsDownloadFromScreen; |
359 | | | 371 | |
360 | return exaDriverInit(pScreen, pExa); | | 372 | return exaDriverInit(pScreen, pExa); |
361 | } | | 373 | } |