📄 savageioctl.c
字号:
GLuint colorMask, depthMask, clearColor, clearDepth, flags; GLint cx = ctx->DrawBuffer->_Xmin; GLint cy = ctx->DrawBuffer->_Ymin; GLint cw = ctx->DrawBuffer->_Xmax - cx; GLint ch = ctx->DrawBuffer->_Ymax - cy; /* XXX FIX ME: the cx,cy,cw,ch vars are currently ignored! */ if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) fprintf (stderr, "%s\n", __FUNCTION__); clearColor = imesa->ClearColor; if (imesa->float_depth) { if (imesa->savageScreen->zpp == 2) clearDepth = savageEncodeFloat16(1.0 - ctx->Depth.Clear); else clearDepth = savageEncodeFloat24(1.0 - ctx->Depth.Clear); } else { if (imesa->savageScreen->zpp == 2) clearDepth = (GLuint) ((1.0 - ctx->Depth.Clear) * DEPTH_SCALE_16); else clearDepth = (GLuint) ((1.0 - ctx->Depth.Clear) * DEPTH_SCALE_24); } colorMask = 0; depthMask = 0; switch (imesa->savageScreen->cpp) { case 2: colorMask = PACK_COLOR_565(ctx->Color.ColorMask[0], ctx->Color.ColorMask[1], ctx->Color.ColorMask[2]); break; case 4: colorMask = PACK_COLOR_8888(ctx->Color.ColorMask[3], ctx->Color.ColorMask[2], ctx->Color.ColorMask[1], ctx->Color.ColorMask[0]); break; } flags = 0; if (mask & BUFFER_BIT_FRONT_LEFT) { flags |= SAVAGE_FRONT; mask &= ~BUFFER_BIT_FRONT_LEFT; } if (mask & BUFFER_BIT_BACK_LEFT) { flags |= SAVAGE_BACK; mask &= ~BUFFER_BIT_BACK_LEFT; } if ((mask & BUFFER_BIT_DEPTH) && ctx->Depth.Mask) { flags |= SAVAGE_DEPTH; depthMask |= (imesa->savageScreen->zpp == 2) ? 0xffffffff : 0x00ffffff; mask &= ~BUFFER_BIT_DEPTH; } if((mask & BUFFER_BIT_STENCIL) && imesa->hw_stencil) { flags |= SAVAGE_DEPTH; depthMask |= 0xff000000; mask &= ~BUFFER_BIT_STENCIL; } savageFlushVertices(imesa); if (flags) { GLboolean depthCleared = GL_FALSE; if (flags & (SAVAGE_FRONT|SAVAGE_BACK)) { drm_savage_cmd_header_t *cmd; cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t)); cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR; if ((flags & SAVAGE_DEPTH) && clearDepth == clearColor && depthMask == colorMask) { cmd[0].clear0.flags = flags; depthCleared = GL_TRUE; } else cmd[0].clear0.flags = flags & (SAVAGE_FRONT|SAVAGE_BACK); cmd[1].clear1.mask = colorMask; cmd[1].clear1.value = clearColor; } if ((flags & SAVAGE_DEPTH) && !depthCleared) { drm_savage_cmd_header_t *cmd; cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t)); cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR; cmd[0].clear0.flags = SAVAGE_DEPTH; cmd[1].clear1.mask = depthMask; cmd[1].clear1.value = clearDepth; } } if (mask) _swrast_Clear( ctx, mask );}/* * Copy the back buffer to the front buffer. */void savageSwapBuffers( __DRIdrawablePrivate *dPriv ){ savageContextPtr imesa; if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) fprintf (stderr, "%s\n================================\n", __FUNCTION__); assert(dPriv); assert(dPriv->driContextPriv); assert(dPriv->driContextPriv->driverPrivate); imesa = (savageContextPtr) dPriv->driContextPriv->driverPrivate; if (imesa->IsDouble) _mesa_notifySwapBuffers( imesa->glCtx ); FLUSH_BATCH(imesa); if (imesa->sync_frames) imesa->lastSwap = savageEmitEvent( imesa, 0 ); if (imesa->lastSwap != 0) savageWaitEvent( imesa, imesa->lastSwap ); { drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, 0); cmd->cmd.cmd = SAVAGE_CMD_SWAP; imesa->inSwap = GL_TRUE; /* ignore scissors in savageFlushCmdBuf */ savageFlushCmdBuf(imesa, GL_FALSE); imesa->inSwap = GL_FALSE; } if (!imesa->sync_frames) /* don't sync, but limit the lag to one frame. */ imesa->lastSwap = savageEmitEvent( imesa, 0 );}unsigned int savageEmitEventLocked( savageContextPtr imesa, unsigned int flags ){ drm_savage_event_emit_t event; int ret; event.count = 0; event.flags = flags; ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_EMIT, &event, sizeof(event) ); if (ret) { fprintf (stderr, "emit event returned %d\n", ret); exit (1); } return event.count;}unsigned int savageEmitEvent( savageContextPtr imesa, unsigned int flags ){ unsigned int ret; LOCK_HARDWARE( imesa ); ret = savageEmitEventLocked( imesa, flags ); UNLOCK_HARDWARE( imesa ); return ret;}void savageWaitEvent( savageContextPtr imesa, unsigned int count ){ drm_savage_event_wait_t event; int ret; event.count = count; event.flags = 0; ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_WAIT, &event, sizeof(event) ); if (ret) { fprintf (stderr, "wait event returned %d\n", ret); exit (1); }}void savageFlushVertices( savageContextPtr imesa ){ struct savage_vtxbuf_t *buffer = imesa->vtxBuf; if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) fprintf (stderr, "%s\n", __FUNCTION__); if (!buffer->total) return; if (buffer->used > buffer->flushed) { drm_savage_cmd_header_t *cmd; /* State must be updated "per primitive" because hardware * culling must be disabled for unfilled primitives, points * and lines. */ savageEmitChangedState (imesa); cmd = savageAllocCmdBuf(imesa, 0); cmd->prim.cmd = buffer == &imesa->dmaVtxBuf ? SAVAGE_CMD_DMA_PRIM : SAVAGE_CMD_VB_PRIM; cmd->prim.prim = imesa->HwPrim; cmd->prim.skip = imesa->skip; cmd->prim.start = buffer->flushed / imesa->HwVertexSize; cmd->prim.count = buffer->used / imesa->HwVertexSize - cmd->prim.start; buffer->flushed = buffer->used; }}void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard ){ __DRIdrawablePrivate *dPriv = imesa->driDrawable; if (!imesa->dmaVtxBuf.total) discard = GL_FALSE; /* complete indexed drawing commands */ savageFlushElts(imesa); if (imesa->cmdBuf.write != imesa->cmdBuf.start || discard) { drm_savage_cmdbuf_t cmdbuf; drm_savage_cmd_header_t *start; int ret; /* If we lost the context we must restore the initial state (at * the start of the command buffer). */ if (imesa->lostContext) { start = imesa->cmdBuf.base; imesa->lostContext = GL_FALSE; } else start = imesa->cmdBuf.start; if ((SAVAGE_DEBUG & DEBUG_DMA) && discard) fprintf (stderr, "Discarding DMA buffer, used=%u\n", imesa->dmaVtxBuf.used); cmdbuf.dma_idx = imesa->dmaVtxBuf.idx; cmdbuf.discard = discard; cmdbuf.vb_addr = imesa->clientVtxBuf.buf; cmdbuf.vb_size = imesa->clientVtxBuf.total*4; cmdbuf.vb_stride = imesa->HwVertexSize; cmdbuf.cmd_addr = start; cmdbuf.size = (imesa->cmdBuf.write - start); if (!imesa->inSwap && imesa->scissor.enabled) { drm_clip_rect_t *box = dPriv->pClipRects, *ibox; drm_clip_rect_t scissor; GLuint nbox = dPriv->numClipRects, nibox; /* transform and clip scissor to viewport */ scissor.x1 = MAX2(imesa->scissor.x, 0) + dPriv->x; scissor.y1 = MAX2(dPriv->h - imesa->scissor.y - imesa->scissor.h, 0) + dPriv->y; scissor.x2 = MIN2(imesa->scissor.x + imesa->scissor.w, dPriv->w) + dPriv->x; scissor.y2 = MIN2(dPriv->h - imesa->scissor.y, dPriv->h) + dPriv->y; /* intersect cliprects with scissor */ ibox = malloc(dPriv->numClipRects*sizeof(drm_clip_rect_t)); if (!ibox) { fprintf(stderr, "Out of memory.\n"); exit(1); } nibox = savageIntersectClipRects(ibox, box, nbox, &scissor); cmdbuf.nbox = nibox; cmdbuf.box_addr = ibox; } else { cmdbuf.nbox = dPriv->numClipRects; cmdbuf.box_addr = dPriv->pClipRects; } ret = drmCommandWrite( imesa->driFd, DRM_SAVAGE_BCI_CMDBUF, &cmdbuf, sizeof(cmdbuf) ); if (ret) { fprintf (stderr, "cmdbuf ioctl returned %d\n", ret); exit(1); } if (cmdbuf.box_addr != dPriv->pClipRects) { free(cmdbuf.box_addr); } /* Save the current state at the start of the command buffer. That * state will only be emitted, if the context was lost since the * last command buffer. */ imesa->cmdBuf.write = imesa->cmdBuf.base; savageEmitOldState(imesa); imesa->cmdBuf.start = imesa->cmdBuf.write; } if (discard) { assert (!savageHaveIndexedVerts(imesa)); imesa->dmaVtxBuf.total = 0; imesa->dmaVtxBuf.used = 0; imesa->dmaVtxBuf.flushed = 0; } if (!savageHaveIndexedVerts(imesa)) { imesa->clientVtxBuf.used = 0; imesa->clientVtxBuf.flushed = 0; }}void savageFlushCmdBuf( savageContextPtr imesa, GLboolean discard ) { if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) fprintf (stderr, "%s\n", __FUNCTION__); LOCK_HARDWARE(imesa); savageFlushCmdBufLocked (imesa, discard); UNLOCK_HARDWARE(imesa);}static void savageDDFlush( GLcontext *ctx ){ savageContextPtr imesa = SAVAGE_CONTEXT(ctx); if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) fprintf (stderr, "%s\n", __FUNCTION__); savageFlushVertices (imesa); savageFlushCmdBuf(imesa, GL_FALSE);}static void savageDDFinish( GLcontext *ctx ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) fprintf (stderr, "%s\n", __FUNCTION__); savageFlushVertices (imesa); savageFlushCmdBuf(imesa, GL_FALSE); WAIT_IDLE_EMPTY(imesa);}void savageDDInitIoctlFuncs( GLcontext *ctx ){ ctx->Driver.Clear = savageDDClear; ctx->Driver.Flush = savageDDFlush; ctx->Driver.Finish = savageDDFinish;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -