blob: d0b64e801a973795ce3f989418f482b856b81234 [file] [log] [blame]
Felix Kuehling263581b2004-02-22 16:11:12 +00001/*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
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,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25
26#include <stdio.h>
27#include <unistd.h>
28#include <sys/mman.h>
29
Brian Paulecadb512008-09-18 15:17:05 -060030#include "main/mtypes.h"
31#include "main/macros.h"
32#include "main/dd.h"
33#include "main/context.h"
34#include "main/colormac.h"
35#include "main/mm.h"
Felix Kuehling263581b2004-02-22 16:11:12 +000036#include "swrast/swrast.h"
37
Felix Kuehling263581b2004-02-22 16:11:12 +000038#include "savagecontext.h"
39#include "savageioctl.h"
40#include "savage_bci.h"
Felix Kuehling1067ce02005-01-01 20:40:14 +000041#include "savagestate.h"
Felix Kuehlinge3748eb2005-01-03 22:24:44 +000042#include "savagespan.h"
Felix Kuehling263581b2004-02-22 16:11:12 +000043
44#include "drm.h"
45#include <sys/ioctl.h>
46#include <sys/timeb.h>
47
Felix Kuehling263581b2004-02-22 16:11:12 +000048#define DEPTH_SCALE_16 ((1<<16)-1)
49#define DEPTH_SCALE_24 ((1<<24)-1)
50
Felix Kuehling1067ce02005-01-01 20:40:14 +000051
52void savageGetDMABuffer( savageContextPtr imesa )
53{
54 int idx = 0;
55 int size = 0;
56 drmDMAReq dma;
57 int retcode;
58 drmBufPtr buf;
59
Felix Kuehlinge6aa2112005-03-06 01:28:30 +000060 assert (imesa->savageScreen->bufs);
61
Felix Kuehling1067ce02005-01-01 20:40:14 +000062 if (SAVAGE_DEBUG & DEBUG_DMA)
63 fprintf(stderr, "Getting dma buffer\n");
64
65 dma.context = imesa->hHWContext;
66 dma.send_count = 0;
67 dma.send_list = NULL;
68 dma.send_sizes = NULL;
69 dma.flags = 0;
70 dma.request_count = 1;
71 dma.request_size = imesa->bufferSize;
72 dma.request_list = &idx;
73 dma.request_sizes = &size;
74 dma.granted_count = 0;
75
76
77 if (SAVAGE_DEBUG & DEBUG_DMA)
78 fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",
79 dma.context, dma.request_count,
80 dma.request_size);
81
82 while (1) {
83 retcode = drmDMA(imesa->driFd, &dma);
84
85 if (SAVAGE_DEBUG & DEBUG_DMA)
86 fprintf(stderr, "retcode %d sz %d idx %d count %d\n",
87 retcode,
88 dma.request_sizes[0],
89 dma.request_list[0],
90 dma.granted_count);
91
92 if (retcode == 0 &&
93 dma.request_sizes[0] &&
94 dma.granted_count)
95 break;
96
97 if (SAVAGE_DEBUG & DEBUG_DMA)
98 fprintf(stderr, "\n\nflush");
99 }
100
101 buf = &(imesa->savageScreen->bufs->list[idx]);
102
103 if (SAVAGE_DEBUG & DEBUG_DMA)
104 fprintf(stderr,
105 "drmDMA (get) returns size[0] 0x%x idx[0] %d\n"
106 "dma_buffer now: buf idx: %d size: %d used: %d addr %p\n",
107 dma.request_sizes[0], dma.request_list[0],
108 buf->idx, buf->total,
109 buf->used, buf->address);
110
111 imesa->dmaVtxBuf.total = buf->total / 4;
112 imesa->dmaVtxBuf.used = 0;
113 imesa->dmaVtxBuf.flushed = 0;
114 imesa->dmaVtxBuf.idx = buf->idx;
Keith Whitwell5a46e172008-09-20 07:32:30 -0700115 imesa->dmaVtxBuf.buf = (uint32_t *)buf->address;
Felix Kuehling1067ce02005-01-01 20:40:14 +0000116
117 if (SAVAGE_DEBUG & DEBUG_DMA)
118 fprintf(stderr, "finished getbuffer\n");
119}
120
121#if 0
122/* Still keeping this around because it demonstrates page flipping and
123 * automatic z-clear. */
Felix Kuehling263581b2004-02-22 16:11:12 +0000124static void savage_BCI_clear(GLcontext *ctx, drm_savage_clear_t *pclear)
125{
126 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
127 int nbox = imesa->sarea->nbox;
128 drm_clip_rect_t *pbox = imesa->sarea->boxes;
129 int i;
130
131
132 if (nbox > SAVAGE_NR_SAREA_CLIPRECTS)
133 nbox = SAVAGE_NR_SAREA_CLIPRECTS;
134
135 for (i = 0 ; i < nbox ; i++, pbox++) {
136 unsigned int x = pbox->x1;
137 unsigned int y = pbox->y1;
Felix Kuehling2462f6b2004-03-04 00:27:36 +0000138 unsigned int width = pbox->x2 - x;
139 unsigned int height = pbox->y2 - y;
Keith Whitwell5a46e172008-09-20 07:32:30 -0700140 uint32_t *bciptr;
Felix Kuehling263581b2004-02-22 16:11:12 +0000141
142 if (pbox->x1 > pbox->x2 ||
143 pbox->y1 > pbox->y2 ||
144 pbox->x2 > imesa->savageScreen->width ||
145 pbox->y2 > imesa->savageScreen->height)
146 continue;
147
Felix Kuehling58fa2a82004-03-26 23:27:24 +0000148 if ( pclear->flags & SAVAGE_FRONT ) {
Felix Kuehling263581b2004-02-22 16:11:12 +0000149 bciptr = savageDMAAlloc (imesa, 8);
Keith Whitwell5a46e172008-09-20 07:32:30 -0700150 WRITE_CMD((bciptr) , 0x4BCC8C00,uint32_t);
151 WRITE_CMD((bciptr) , imesa->savageScreen->frontOffset,uint32_t);
152 WRITE_CMD((bciptr) , imesa->savageScreen->frontBitmapDesc,uint32_t);
153 WRITE_CMD((bciptr) , pclear->clear_color,uint32_t);
154 WRITE_CMD((bciptr) , (y <<16) | x,uint32_t);
155 WRITE_CMD((bciptr) , (height << 16) | width,uint32_t);
Felix Kuehling263581b2004-02-22 16:11:12 +0000156 savageDMACommit (imesa, bciptr);
157 }
Felix Kuehling58fa2a82004-03-26 23:27:24 +0000158 if ( pclear->flags & SAVAGE_BACK ) {
Felix Kuehling263581b2004-02-22 16:11:12 +0000159 bciptr = savageDMAAlloc (imesa, 8);
Keith Whitwell5a46e172008-09-20 07:32:30 -0700160 WRITE_CMD((bciptr) , 0x4BCC8C00,uint32_t);
161 WRITE_CMD((bciptr) , imesa->savageScreen->backOffset,uint32_t);
162 WRITE_CMD((bciptr) , imesa->savageScreen->backBitmapDesc,uint32_t);
163 WRITE_CMD((bciptr) , pclear->clear_color,uint32_t);
164 WRITE_CMD((bciptr) , (y <<16) | x,uint32_t);
165 WRITE_CMD((bciptr) , (height << 16) | width,uint32_t);
Felix Kuehling263581b2004-02-22 16:11:12 +0000166 savageDMACommit (imesa, bciptr);
167 }
168
169 if ( pclear->flags & (SAVAGE_DEPTH |SAVAGE_STENCIL) ) {
Keith Whitwell5a46e172008-09-20 07:32:30 -0700170 uint32_t writeMask = 0x0;
Felix Kuehling263581b2004-02-22 16:11:12 +0000171 if(imesa->hw_stencil)
172 {
173 if(pclear->flags & SAVAGE_STENCIL)
174 {
175
176 writeMask |= 0xFF000000;
177 }
178 if(pclear->flags & SAVAGE_DEPTH)
179 {
180 writeMask |= 0x00FFFFFF;
181 }
182 }
Felix Kuehling263581b2004-02-22 16:11:12 +0000183 if(imesa->IsFullScreen && imesa->NotFirstFrame &&
184 imesa->savageScreen->chipset >= S3_SAVAGE4)
185 {
Felix Kuehlingc6338e62004-02-29 20:42:22 +0000186 imesa->regs.s4.zBufCtrl.ni.autoZEnable = GL_TRUE;
187 imesa->regs.s4.zBufCtrl.ni.frameID =
188 ~imesa->regs.s4.zBufCtrl.ni.frameID;
Felix Kuehling263581b2004-02-22 16:11:12 +0000189
Felix Kuehling1067ce02005-01-01 20:40:14 +0000190 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
Felix Kuehling263581b2004-02-22 16:11:12 +0000191 }
192 else
193 {
194 if(imesa->IsFullScreen)
195 imesa->NotFirstFrame = GL_TRUE;
196
Felix Kuehling263581b2004-02-22 16:11:12 +0000197 if(imesa->hw_stencil)
198 {
199 bciptr = savageDMAAlloc (imesa, 10);
200 if(writeMask != 0xFFFFFFFF)
201 {
Keith Whitwell5a46e172008-09-20 07:32:30 -0700202 WRITE_CMD((bciptr) , 0x960100D7,uint32_t);
203 WRITE_CMD((bciptr) , writeMask,uint32_t);
Felix Kuehling263581b2004-02-22 16:11:12 +0000204 }
205 }
206 else
Felix Kuehling263581b2004-02-22 16:11:12 +0000207 {
208 bciptr = savageDMAAlloc (imesa, 6);
209 }
210
Keith Whitwell5a46e172008-09-20 07:32:30 -0700211 WRITE_CMD((bciptr) , 0x4BCC8C00,uint32_t);
212 WRITE_CMD((bciptr) , imesa->savageScreen->depthOffset,uint32_t);
213 WRITE_CMD((bciptr) , imesa->savageScreen->depthBitmapDesc,uint32_t);
214 WRITE_CMD((bciptr) , pclear->clear_depth,uint32_t);
215 WRITE_CMD((bciptr) , (y <<16) | x,uint32_t);
216 WRITE_CMD((bciptr) , (height << 16) | width,uint32_t);
Felix Kuehling263581b2004-02-22 16:11:12 +0000217 if(imesa->hw_stencil)
218 {
219 if(writeMask != 0xFFFFFFFF)
220 {
Keith Whitwell5a46e172008-09-20 07:32:30 -0700221 WRITE_CMD((bciptr) , 0x960100D7,uint32_t);
222 WRITE_CMD((bciptr) , 0xFFFFFFFF,uint32_t);
Felix Kuehling263581b2004-02-22 16:11:12 +0000223 }
224 }
Felix Kuehling263581b2004-02-22 16:11:12 +0000225 savageDMACommit (imesa, bciptr);
226 }
227 }
228 }
229 /* FK: Make sure that the clear stuff is emitted. Otherwise a
230 software fallback may get overwritten by a delayed clear. */
231 savageDMAFlush (imesa);
232}
233
Felix Kuehling263581b2004-02-22 16:11:12 +0000234static void savage_BCI_swap(savageContextPtr imesa)
235{
236 int nbox = imesa->sarea->nbox;
237 drm_clip_rect_t *pbox = imesa->sarea->boxes;
238 int i;
Keith Whitwell5a46e172008-09-20 07:32:30 -0700239 volatile uint32_t *bciptr;
Felix Kuehling263581b2004-02-22 16:11:12 +0000240
241 if (nbox > SAVAGE_NR_SAREA_CLIPRECTS)
242 nbox = SAVAGE_NR_SAREA_CLIPRECTS;
243 savageDMAFlush (imesa);
Felix Kuehling263581b2004-02-22 16:11:12 +0000244
245 if(imesa->IsFullScreen)
246 { /* full screen*/
247 unsigned int tmp0;
248 tmp0 = imesa->savageScreen->frontOffset;
249 imesa->savageScreen->frontOffset = imesa->savageScreen->backOffset;
250 imesa->savageScreen->backOffset = tmp0;
251
252 if(imesa->toggle == TARGET_BACK)
253 imesa->toggle = TARGET_FRONT;
254 else
255 imesa->toggle = TARGET_BACK;
256
Brian Paul687918b2005-09-03 16:43:02 +0000257 driFlipRenderbuffers(imesa->glCtx->DrawBuffer,
258 imesa->toggle != TARGET_FRONT);
259
Felix Kuehlingc6338e62004-02-29 20:42:22 +0000260 imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
Felix Kuehling1067ce02005-01-01 20:40:14 +0000261 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
Felix Kuehling263581b2004-02-22 16:11:12 +0000262 bciptr = SAVAGE_GET_BCI_POINTER(imesa,3);
263 *(bciptr) = 0x960100B0;
264 *(bciptr) = (imesa->savageScreen->frontOffset);
265 *(bciptr) = 0xA0000000;
266 }
267
268 else
269 { /* Use bitblt copy from back to front buffer*/
270
271 for (i = 0 ; i < nbox; i++, pbox++)
272 {
273 unsigned int w = pbox->x2 - pbox->x1;
274 unsigned int h = pbox->y2 - pbox->y1;
275
276 if (pbox->x1 > pbox->x2 ||
277 pbox->y1 > pbox->y2 ||
278 pbox->x2 > imesa->savageScreen->width ||
279 pbox->y2 > imesa->savageScreen->height)
280 continue;
281
282 bciptr = SAVAGE_GET_BCI_POINTER(imesa,6);
283
284 *(bciptr) = 0x4BCC00C0;
285
286 *(bciptr) = imesa->savageScreen->backOffset;
287 *(bciptr) = imesa->savageScreen->backBitmapDesc;
288 *(bciptr) = (pbox->y1 <<16) | pbox->x1; /*x0, y0*/
289 *(bciptr) = (pbox->y1 <<16) | pbox->x1;
290 *(bciptr) = (h << 16) | w;
291 }
292
293 }
294}
Felix Kuehling1067ce02005-01-01 20:40:14 +0000295#endif
296
297
298static GLboolean intersect_rect( drm_clip_rect_t *out,
299 const drm_clip_rect_t *a,
300 const drm_clip_rect_t *b )
301{
302 *out = *a;
303 if (b->x1 > out->x1) out->x1 = b->x1;
304 if (b->y1 > out->y1) out->y1 = b->y1;
305 if (b->x2 < out->x2) out->x2 = b->x2;
306 if (b->y2 < out->y2) out->y2 = b->y2;
307
308 return ((out->x1 < out->x2) && (out->y1 < out->y2));
309}
310
311
312static GLuint savageIntersectClipRects(drm_clip_rect_t *dest,
313 const drm_clip_rect_t *src,
314 GLuint nsrc,
315 const drm_clip_rect_t *clip)
316{
317 GLuint i, ndest;
318
319 for (i = 0, ndest = 0; i < nsrc; ++i, ++src) {
320 if (intersect_rect(dest, src, clip)) {
321 dest++;
322 ndest++;
323 }
324 }
325
326 return ndest;
327}
Felix Kuehling263581b2004-02-22 16:11:12 +0000328
329
Brian Paula5676792006-11-01 19:35:22 +0000330static void savageDDClear( GLcontext *ctx, GLbitfield mask )
Felix Kuehling263581b2004-02-22 16:11:12 +0000331{
Brian Paul446972b2006-10-18 20:02:42 +0000332 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
Felix Kuehling1067ce02005-01-01 20:40:14 +0000333 GLuint colorMask, depthMask, clearColor, clearDepth, flags;
Brian Paul446972b2006-10-18 20:02:42 +0000334 GLint cx = ctx->DrawBuffer->_Xmin;
335 GLint cy = ctx->DrawBuffer->_Ymin;
336 GLint cw = ctx->DrawBuffer->_Xmax - cx;
337 GLint ch = ctx->DrawBuffer->_Ymax - cy;
338
339 /* XXX FIX ME: the cx,cy,cw,ch vars are currently ignored! */
Vinson Lee7e3825a2009-12-15 16:32:51 -0800340 (void) ch;
341 (void) cw;
Felix Kuehling263581b2004-02-22 16:11:12 +0000342
Felix Kuehling1067ce02005-01-01 20:40:14 +0000343 if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
344 fprintf (stderr, "%s\n", __FUNCTION__);
Felix Kuehling263581b2004-02-22 16:11:12 +0000345
Felix Kuehling1067ce02005-01-01 20:40:14 +0000346 clearColor = imesa->ClearColor;
Felix Kuehlinge3748eb2005-01-03 22:24:44 +0000347 if (imesa->float_depth) {
348 if (imesa->savageScreen->zpp == 2)
349 clearDepth = savageEncodeFloat16(1.0 - ctx->Depth.Clear);
350 else
351 clearDepth = savageEncodeFloat24(1.0 - ctx->Depth.Clear);
352 } else {
353 if (imesa->savageScreen->zpp == 2)
354 clearDepth = (GLuint) ((1.0 - ctx->Depth.Clear) * DEPTH_SCALE_16);
355 else
356 clearDepth = (GLuint) ((1.0 - ctx->Depth.Clear) * DEPTH_SCALE_24);
357 }
Felix Kuehling67d03432004-03-24 16:15:28 +0000358
Felix Kuehlinged9119b2005-02-12 14:35:17 +0000359 colorMask = 0;
Felix Kuehling1067ce02005-01-01 20:40:14 +0000360 depthMask = 0;
Felix Kuehlinged9119b2005-02-12 14:35:17 +0000361 switch (imesa->savageScreen->cpp) {
362 case 2:
Brian Paulfd5511d2009-12-29 16:17:14 -0700363 colorMask = PACK_COLOR_565(ctx->Color.ColorMask[0][0],
364 ctx->Color.ColorMask[0][1],
365 ctx->Color.ColorMask[0][2]);
Felix Kuehlinged9119b2005-02-12 14:35:17 +0000366 break;
367 case 4:
Brian Paulfd5511d2009-12-29 16:17:14 -0700368 colorMask = PACK_COLOR_8888(ctx->Color.ColorMask[0][3],
369 ctx->Color.ColorMask[0][2],
370 ctx->Color.ColorMask[0][1],
371 ctx->Color.ColorMask[0][0]);
Felix Kuehlinged9119b2005-02-12 14:35:17 +0000372 break;
373 }
Felix Kuehling67d03432004-03-24 16:15:28 +0000374
Felix Kuehling1067ce02005-01-01 20:40:14 +0000375 flags = 0;
376
Brian Paule4b23562005-05-04 20:11:35 +0000377 if (mask & BUFFER_BIT_FRONT_LEFT) {
Felix Kuehling1067ce02005-01-01 20:40:14 +0000378 flags |= SAVAGE_FRONT;
Brian Paule4b23562005-05-04 20:11:35 +0000379 mask &= ~BUFFER_BIT_FRONT_LEFT;
Felix Kuehling263581b2004-02-22 16:11:12 +0000380 }
381
Brian Paule4b23562005-05-04 20:11:35 +0000382 if (mask & BUFFER_BIT_BACK_LEFT) {
Felix Kuehling1067ce02005-01-01 20:40:14 +0000383 flags |= SAVAGE_BACK;
Brian Paule4b23562005-05-04 20:11:35 +0000384 mask &= ~BUFFER_BIT_BACK_LEFT;
Felix Kuehling263581b2004-02-22 16:11:12 +0000385 }
386
Brian Paule4b23562005-05-04 20:11:35 +0000387 if ((mask & BUFFER_BIT_DEPTH) && ctx->Depth.Mask) {
Felix Kuehling1067ce02005-01-01 20:40:14 +0000388 flags |= SAVAGE_DEPTH;
389 depthMask |=
390 (imesa->savageScreen->zpp == 2) ? 0xffffffff : 0x00ffffff;
Brian Paule4b23562005-05-04 20:11:35 +0000391 mask &= ~BUFFER_BIT_DEPTH;
Felix Kuehling263581b2004-02-22 16:11:12 +0000392 }
393
Brian Paule4b23562005-05-04 20:11:35 +0000394 if((mask & BUFFER_BIT_STENCIL) && imesa->hw_stencil)
Felix Kuehling263581b2004-02-22 16:11:12 +0000395 {
Felix Kuehling1067ce02005-01-01 20:40:14 +0000396 flags |= SAVAGE_DEPTH;
397 depthMask |= 0xff000000;
Brian Paule4b23562005-05-04 20:11:35 +0000398 mask &= ~BUFFER_BIT_STENCIL;
Felix Kuehling263581b2004-02-22 16:11:12 +0000399 }
400
Felix Kuehling1067ce02005-01-01 20:40:14 +0000401 savageFlushVertices(imesa);
Felix Kuehling263581b2004-02-22 16:11:12 +0000402
Felix Kuehling1067ce02005-01-01 20:40:14 +0000403 if (flags) {
404 GLboolean depthCleared = GL_FALSE;
405 if (flags & (SAVAGE_FRONT|SAVAGE_BACK)) {
406 drm_savage_cmd_header_t *cmd;
407 cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t));
408 cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR;
409 if ((flags & SAVAGE_DEPTH) &&
410 clearDepth == clearColor && depthMask == colorMask) {
411 cmd[0].clear0.flags = flags;
412 depthCleared = GL_TRUE;
413 } else
414 cmd[0].clear0.flags = flags & (SAVAGE_FRONT|SAVAGE_BACK);
415 cmd[1].clear1.mask = colorMask;
416 cmd[1].clear1.value = clearColor;
Felix Kuehling263581b2004-02-22 16:11:12 +0000417 }
418
Felix Kuehling1067ce02005-01-01 20:40:14 +0000419 if ((flags & SAVAGE_DEPTH) && !depthCleared) {
420 drm_savage_cmd_header_t *cmd;
421 cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t));
422 cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR;
423 cmd[0].clear0.flags = SAVAGE_DEPTH;
424 cmd[1].clear1.mask = depthMask;
425 cmd[1].clear1.value = clearDepth;
426 }
Felix Kuehling263581b2004-02-22 16:11:12 +0000427 }
428
429 if (mask)
Brian Paula5676792006-11-01 19:35:22 +0000430 _swrast_Clear( ctx, mask );
Felix Kuehling263581b2004-02-22 16:11:12 +0000431}
432
Felix Kuehling263581b2004-02-22 16:11:12 +0000433/*
434 * Copy the back buffer to the front buffer.
435 */
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500436void savageSwapBuffers( __DRIdrawable *dPriv )
Felix Kuehling263581b2004-02-22 16:11:12 +0000437{
438 savageContextPtr imesa;
Felix Kuehling263581b2004-02-22 16:11:12 +0000439
Felix Kuehling1067ce02005-01-01 20:40:14 +0000440 if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
441 fprintf (stderr, "%s\n================================\n", __FUNCTION__);
Felix Kuehling263581b2004-02-22 16:11:12 +0000442
443 assert(dPriv);
444 assert(dPriv->driContextPriv);
445 assert(dPriv->driContextPriv->driverPrivate);
446
447 imesa = (savageContextPtr) dPriv->driContextPriv->driverPrivate;
448 if (imesa->IsDouble)
449 _mesa_notifySwapBuffers( imesa->glCtx );
450
Felix Kuehling67d03432004-03-24 16:15:28 +0000451 FLUSH_BATCH(imesa);
452
Felix Kuehling9d05d3d2005-03-06 03:52:01 +0000453 if (imesa->sync_frames)
454 imesa->lastSwap = savageEmitEvent( imesa, 0 );
455
Felix Kuehling1067ce02005-01-01 20:40:14 +0000456 if (imesa->lastSwap != 0)
457 savageWaitEvent( imesa, imesa->lastSwap );
Felix Kuehling263581b2004-02-22 16:11:12 +0000458
Felix Kuehling263581b2004-02-22 16:11:12 +0000459 {
Felix Kuehling1067ce02005-01-01 20:40:14 +0000460 drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, 0);
461 cmd->cmd.cmd = SAVAGE_CMD_SWAP;
462 imesa->inSwap = GL_TRUE; /* ignore scissors in savageFlushCmdBuf */
463 savageFlushCmdBuf(imesa, GL_FALSE);
464 imesa->inSwap = GL_FALSE;
Felix Kuehling263581b2004-02-22 16:11:12 +0000465 }
Felix Kuehling263581b2004-02-22 16:11:12 +0000466
Felix Kuehling9d05d3d2005-03-06 03:52:01 +0000467 if (!imesa->sync_frames)
468 /* don't sync, but limit the lag to one frame. */
469 imesa->lastSwap = savageEmitEvent( imesa, 0 );
Felix Kuehling263581b2004-02-22 16:11:12 +0000470}
471
Felix Kuehling1067ce02005-01-01 20:40:14 +0000472unsigned int savageEmitEventLocked( savageContextPtr imesa, unsigned int flags )
Felix Kuehling263581b2004-02-22 16:11:12 +0000473{
Felix Kuehling1067ce02005-01-01 20:40:14 +0000474 drm_savage_event_emit_t event;
475 int ret;
476 event.count = 0;
477 event.flags = flags;
478 ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_EMIT,
479 &event, sizeof(event) );
480 if (ret) {
481 fprintf (stderr, "emit event returned %d\n", ret);
482 exit (1);
483 }
484 return event.count;
485}
486unsigned int savageEmitEvent( savageContextPtr imesa, unsigned int flags )
487{
488 unsigned int ret;
489 LOCK_HARDWARE( imesa );
490 ret = savageEmitEventLocked( imesa, flags );
491 UNLOCK_HARDWARE( imesa );
492 return ret;
493}
Felix Kuehling263581b2004-02-22 16:11:12 +0000494
Felix Kuehling67d03432004-03-24 16:15:28 +0000495
Felix Kuehling1067ce02005-01-01 20:40:14 +0000496void savageWaitEvent( savageContextPtr imesa, unsigned int count )
497{
498 drm_savage_event_wait_t event;
499 int ret;
500 event.count = count;
501 event.flags = 0;
502 ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_WAIT,
503 &event, sizeof(event) );
504 if (ret) {
505 fprintf (stderr, "wait event returned %d\n", ret);
506 exit (1);
Felix Kuehling67d03432004-03-24 16:15:28 +0000507 }
Felix Kuehling263581b2004-02-22 16:11:12 +0000508}
509
510
Felix Kuehling1067ce02005-01-01 20:40:14 +0000511void savageFlushVertices( savageContextPtr imesa )
Felix Kuehling263581b2004-02-22 16:11:12 +0000512{
Felix Kuehling1067ce02005-01-01 20:40:14 +0000513 struct savage_vtxbuf_t *buffer = imesa->vtxBuf;
514
515 if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
516 fprintf (stderr, "%s\n", __FUNCTION__);
517
518 if (!buffer->total)
519 return;
520
521 if (buffer->used > buffer->flushed) {
522 drm_savage_cmd_header_t *cmd;
523 /* State must be updated "per primitive" because hardware
524 * culling must be disabled for unfilled primitives, points
525 * and lines. */
526 savageEmitChangedState (imesa);
527 cmd = savageAllocCmdBuf(imesa, 0);
528 cmd->prim.cmd = buffer == &imesa->dmaVtxBuf ?
529 SAVAGE_CMD_DMA_PRIM : SAVAGE_CMD_VB_PRIM;
530 cmd->prim.prim = imesa->HwPrim;
531 cmd->prim.skip = imesa->skip;
532 cmd->prim.start = buffer->flushed / imesa->HwVertexSize;
533 cmd->prim.count = buffer->used / imesa->HwVertexSize - cmd->prim.start;
534 buffer->flushed = buffer->used;
Felix Kuehling1067ce02005-01-01 20:40:14 +0000535 }
536}
537
538void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard )
539{
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500540 __DRIdrawable *dPriv = imesa->driDrawable;
Felix Kuehling1067ce02005-01-01 20:40:14 +0000541
Felix Kuehlingfa15f6c2005-01-21 01:39:09 +0000542 if (!imesa->dmaVtxBuf.total)
543 discard = GL_FALSE;
544
Felix Kuehlingedb9a162005-01-20 13:59:49 +0000545 /* complete indexed drawing commands */
546 savageFlushElts(imesa);
547
Felix Kuehling8b211662005-02-02 14:43:03 +0000548 if (imesa->cmdBuf.write != imesa->cmdBuf.start || discard) {
549 drm_savage_cmdbuf_t cmdbuf;
550 drm_savage_cmd_header_t *start;
551 int ret;
Felix Kuehlingfa15f6c2005-01-21 01:39:09 +0000552
Felix Kuehling8b211662005-02-02 14:43:03 +0000553 /* If we lost the context we must restore the initial state (at
554 * the start of the command buffer). */
555 if (imesa->lostContext) {
556 start = imesa->cmdBuf.base;
557 imesa->lostContext = GL_FALSE;
558 } else
559 start = imesa->cmdBuf.start;
Felix Kuehling1067ce02005-01-01 20:40:14 +0000560
Felix Kuehling8b211662005-02-02 14:43:03 +0000561 if ((SAVAGE_DEBUG & DEBUG_DMA) && discard)
562 fprintf (stderr, "Discarding DMA buffer, used=%u\n",
563 imesa->dmaVtxBuf.used);
Felix Kuehling1067ce02005-01-01 20:40:14 +0000564
Felix Kuehling8b211662005-02-02 14:43:03 +0000565 cmdbuf.dma_idx = imesa->dmaVtxBuf.idx;
566 cmdbuf.discard = discard;
567 cmdbuf.vb_addr = imesa->clientVtxBuf.buf;
568 cmdbuf.vb_size = imesa->clientVtxBuf.total*4;
569 cmdbuf.vb_stride = imesa->HwVertexSize;
570 cmdbuf.cmd_addr = start;
571 cmdbuf.size = (imesa->cmdBuf.write - start);
Felix Kuehling5bdf2bc2005-02-05 21:21:02 +0000572 if (!imesa->inSwap && imesa->scissor.enabled) {
Felix Kuehling8b211662005-02-02 14:43:03 +0000573 drm_clip_rect_t *box = dPriv->pClipRects, *ibox;
Felix Kuehling5bdf2bc2005-02-05 21:21:02 +0000574 drm_clip_rect_t scissor;
Felix Kuehling8b211662005-02-02 14:43:03 +0000575 GLuint nbox = dPriv->numClipRects, nibox;
Felix Kuehling5bdf2bc2005-02-05 21:21:02 +0000576 /* transform and clip scissor to viewport */
577 scissor.x1 = MAX2(imesa->scissor.x, 0) + dPriv->x;
578 scissor.y1 = MAX2(dPriv->h - imesa->scissor.y - imesa->scissor.h,
579 0) + dPriv->y;
580 scissor.x2 = MIN2(imesa->scissor.x + imesa->scissor.w,
581 dPriv->w) + dPriv->x;
582 scissor.y2 = MIN2(dPriv->h - imesa->scissor.y,
583 dPriv->h) + dPriv->y;
584 /* intersect cliprects with scissor */
Felix Kuehling8b211662005-02-02 14:43:03 +0000585 ibox = malloc(dPriv->numClipRects*sizeof(drm_clip_rect_t));
586 if (!ibox) {
587 fprintf(stderr, "Out of memory.\n");
588 exit(1);
589 }
Felix Kuehling5bdf2bc2005-02-05 21:21:02 +0000590 nibox = savageIntersectClipRects(ibox, box, nbox, &scissor);
Felix Kuehling8b211662005-02-02 14:43:03 +0000591 cmdbuf.nbox = nibox;
592 cmdbuf.box_addr = ibox;
593 } else {
594 cmdbuf.nbox = dPriv->numClipRects;
595 cmdbuf.box_addr = dPriv->pClipRects;
596 }
597
598 ret = drmCommandWrite( imesa->driFd, DRM_SAVAGE_BCI_CMDBUF,
599 &cmdbuf, sizeof(cmdbuf) );
600 if (ret) {
601 fprintf (stderr, "cmdbuf ioctl returned %d\n", ret);
Felix Kuehling1067ce02005-01-01 20:40:14 +0000602 exit(1);
603 }
Felix Kuehling1067ce02005-01-01 20:40:14 +0000604
Felix Kuehling8b211662005-02-02 14:43:03 +0000605 if (cmdbuf.box_addr != dPriv->pClipRects) {
606 free(cmdbuf.box_addr);
607 }
Felix Kuehling1067ce02005-01-01 20:40:14 +0000608
Felix Kuehling8b211662005-02-02 14:43:03 +0000609 /* Save the current state at the start of the command buffer. That
610 * state will only be emitted, if the context was lost since the
611 * last command buffer. */
612 imesa->cmdBuf.write = imesa->cmdBuf.base;
613 savageEmitOldState(imesa);
614 imesa->cmdBuf.start = imesa->cmdBuf.write;
Felix Kuehling1067ce02005-01-01 20:40:14 +0000615 }
616
617 if (discard) {
Felix Kuehlingedb9a162005-01-20 13:59:49 +0000618 assert (!savageHaveIndexedVerts(imesa));
Felix Kuehling1067ce02005-01-01 20:40:14 +0000619 imesa->dmaVtxBuf.total = 0;
620 imesa->dmaVtxBuf.used = 0;
621 imesa->dmaVtxBuf.flushed = 0;
622 }
Felix Kuehlingedb9a162005-01-20 13:59:49 +0000623 if (!savageHaveIndexedVerts(imesa)) {
624 imesa->clientVtxBuf.used = 0;
625 imesa->clientVtxBuf.flushed = 0;
626 }
Felix Kuehling1067ce02005-01-01 20:40:14 +0000627}
628
629
630void savageFlushCmdBuf( savageContextPtr imesa, GLboolean discard )
631{
632 if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
633 fprintf (stderr, "%s\n", __FUNCTION__);
Felix Kuehling67d03432004-03-24 16:15:28 +0000634 LOCK_HARDWARE(imesa);
Felix Kuehling1067ce02005-01-01 20:40:14 +0000635 savageFlushCmdBufLocked (imesa, discard);
Felix Kuehling67d03432004-03-24 16:15:28 +0000636 UNLOCK_HARDWARE(imesa);
Felix Kuehling263581b2004-02-22 16:11:12 +0000637}
638
639
Felix Kuehling263581b2004-02-22 16:11:12 +0000640static void savageDDFlush( GLcontext *ctx )
641{
Brian Paulffec1052005-10-31 21:52:56 +0000642 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
Felix Kuehling1067ce02005-01-01 20:40:14 +0000643 if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
644 fprintf (stderr, "%s\n", __FUNCTION__);
Felix Kuehling1067ce02005-01-01 20:40:14 +0000645 savageFlushVertices (imesa);
Felix Kuehlingfa15f6c2005-01-21 01:39:09 +0000646 savageFlushCmdBuf(imesa, GL_FALSE);
Felix Kuehling263581b2004-02-22 16:11:12 +0000647}
648
649static void savageDDFinish( GLcontext *ctx )
650{
Brian Paulffec1052005-10-31 21:52:56 +0000651 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
Felix Kuehling1067ce02005-01-01 20:40:14 +0000652 if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
653 fprintf (stderr, "%s\n", __FUNCTION__);
Felix Kuehling1067ce02005-01-01 20:40:14 +0000654 savageFlushVertices (imesa);
Felix Kuehlingfa15f6c2005-01-21 01:39:09 +0000655 savageFlushCmdBuf(imesa, GL_FALSE);
656 WAIT_IDLE_EMPTY(imesa);
Felix Kuehling263581b2004-02-22 16:11:12 +0000657}
658
Felix Kuehling263581b2004-02-22 16:11:12 +0000659void savageDDInitIoctlFuncs( GLcontext *ctx )
660{
661 ctx->Driver.Clear = savageDDClear;
662 ctx->Driver.Flush = savageDDFlush;
663 ctx->Driver.Finish = savageDDFinish;
Felix Kuehling263581b2004-02-22 16:11:12 +0000664}