#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include "glheader.h"
#include "mtypes.h"
#include "macros.h"
#include "dd.h"
#include "swrast/swrast.h"
#include "mm.h"
#include "i830_screen.h"
#include "i830_dri.h"
#include "i830_context.h"
#include "i830_ioctl.h"
#include "i830_state.h"
#include "i830_debug.h"
#include "drm.h"
static drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa )
{
drmI830DMA dma;
drmBufPtr buf;
int retcode,i = 0;
while (1) {
retcode = drmCommandWriteRead(imesa->driFd,
DRM_I830_GETBUF,
&dma,
sizeof(drmI830DMA));
if (dma.granted == 1 && retcode == 0)
break;
if (++i > 1000) {
imesa->sarea->perf_boxes |= I830_BOX_WAIT;
retcode = drmCommandNone(imesa->driFd, DRM_I830_FLUSH);
i = 0;
}
}
buf = &(imesa->i830Screen->bufs->list[dma.request_idx]);
buf->idx = dma.request_idx;
buf->used = 0;
buf->total = dma.request_size;
buf->address = (drmAddress)dma.virtual;
return buf;
}
static void i830ClearDrawQuad(i830ContextPtr imesa, float left,
float right,
float bottom, float top, GLubyte red,
GLubyte green, GLubyte blue, GLubyte alpha)
{
GLuint *vb = i830AllocDmaLowLocked( imesa, 128 );
i830Vertex tmp;
int i;
tmp.v.x = left;
tmp.v.y = bottom;
tmp.v.z = 1.0;
tmp.v.w = 1.0;
tmp.v.color.red = red;
tmp.v.color.green = green;
tmp.v.color.blue = blue;
tmp.v.color.alpha = alpha;
tmp.v.specular.red = 0;
tmp.v.specular.green = 0;
tmp.v.specular.blue = 0;
tmp.v.specular.alpha = 0;
tmp.v.u0 = 0.0f;
tmp.v.v0 = 0.0f;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
vb += 8;
tmp.v.x = right;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
vb += 8;
tmp.v.y = top;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
vb += 8;
tmp.v.x = left;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
}
static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask,
GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch)
{
i830ContextPtr imesa = I830_CONTEXT( ctx );
__DRIdrawablePrivate *dPriv = imesa->driDrawable;
i830ScreenPrivate *i830Screen = imesa->i830Screen;
I830SAREAPtr sarea = imesa->sarea;
GLuint old_vertex_prim;
GLuint old_dirty;
int x0, y0, x1, y1;
if (I830_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "Clearing with triangles\n");
old_dirty = imesa->dirty & ~I830_UPLOAD_CLIPRECTS;
imesa->dirty &= I830_UPLOAD_CLIPRECTS;
if(!all) {
x0 = cx;
y0 = cy;
x1 = x0 + cw;
y1 = y0 + ch;
} else {
x0 = 0;
y0 = 0;
x1 = x0 + dPriv->w;
y1 = y0 + dPriv->h;
}
if (x0 < 0) x0 = 0;
if (y0 < 0) y0 = 0;
if (x1 > i830Screen->width-1) x1 = i830Screen->width-1;
if (y1 > i830Screen->height-1) y1 = i830Screen->height-1;
LOCK_HARDWARE(imesa);
memcpy(sarea->ContextState,
imesa->Init_Setup,
sizeof(imesa->Setup) );
memcpy(sarea->BufferState,
imesa->BufferSetup,
sizeof(imesa->BufferSetup) );
sarea->StippleState[I830_STPREG_ST1] = 0;
old_vertex_prim = imesa->hw_primitive;
imesa->hw_primitive = PRIM3D_TRIFAN;
if(mask & DD_FRONT_LEFT_BIT) {
GLuint tmp = sarea->ContextState[I830_CTXREG_ENABLES_2];
sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS |
I830_UPLOAD_TEXBLEND0);
sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
TEXPIPE_COLOR |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
DISABLE_TEX_CNTRL_STAGE |
TEXOP_SCALE_1X |
TEXOP_MODIFY_PARMS |
TEXOP_LAST_STAGE |
TEXBLENDOP_ARG1);
sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
TEXPIPE_ALPHA |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
TEXOP_SCALE_1X |
TEXOP_MODIFY_PARMS |
TEXBLENDOP_ARG1);
sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
TEXPIPE_COLOR |
TEXBLEND_ARG1 |
TEXBLENDARG_MODIFY_PARMS |
TEXBLENDARG_CURRENT);
sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
TEXPIPE_ALPHA |
TEXBLEND_ARG1 |
TEXBLENDARG_MODIFY_PARMS |
TEXBLENDARG_CURRENT);
sarea->TexBlendStateWordsUsed[0] = 4;
tmp &= ~(ENABLE_STENCIL_WRITE | ENABLE_DEPTH_WRITE);
tmp |= (DISABLE_STENCIL_WRITE |
DISABLE_DEPTH_WRITE |
(imesa->mask_red << WRITEMASK_RED_SHIFT) |
(imesa->mask_green << WRITEMASK_GREEN_SHIFT) |
(imesa->mask_blue << WRITEMASK_BLUE_SHIFT) |
(imesa->mask_alpha << WRITEMASK_ALPHA_SHIFT));
sarea->ContextState[I830_CTXREG_ENABLES_2] = tmp;
if(0)
fprintf(stderr, "fcdq : r_mask(%d) g_mask(%d) b_mask(%d) a_mask(%d)\n",
imesa->mask_red, imesa->mask_green, imesa->mask_blue,
imesa->mask_alpha);
sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset;
if(0)
fprintf(stderr, "fcdq : x0(%d) x1(%d) y0(%d) y1(%d)\n"
"r(0x%x) g(0x%x) b(0x%x) a(0x%x)\n",
x0, x1, y0, y1, imesa->clear_red, imesa->clear_green,
imesa->clear_blue, imesa->clear_alpha);
i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1,
imesa->clear_red, imesa->clear_green,
imesa->clear_blue, imesa->clear_alpha);
i830FlushPrimsLocked( imesa );
}
if(mask & DD_BACK_LEFT_BIT) {
GLuint tmp = sarea->ContextState[I830_CTXREG_ENABLES_2];
sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS |
I830_UPLOAD_TEXBLEND0);
sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
TEXPIPE_COLOR |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
DISABLE_TEX_CNTRL_STAGE |
TEXOP_SCALE_1X |
TEXOP_MODIFY_PARMS |
TEXOP_LAST_STAGE |
TEXBLENDOP_ARG1);
sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
TEXPIPE_ALPHA |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
TEXOP_SCALE_1X |
TEXOP_MODIFY_PARMS |
TEXBLENDOP_ARG1);
sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
TEXPIPE_COLOR |
TEXBLEND_ARG1 |
TEXBLENDARG_MODIFY_PARMS |
TEXBLENDARG_CURRENT);
sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
TEXPIPE_ALPHA |
TEXBLEND_ARG2 |
TEXBLENDARG_MODIFY_PARMS |
TEXBLENDARG_CURRENT);
sarea->TexBlendStateWordsUsed[0] = 4;
tmp &= ~(ENABLE_STENCIL_WRITE | ENABLE_DEPTH_WRITE);
tmp |= (DISABLE_STENCIL_WRITE |
DISABLE_DEPTH_WRITE |
(imesa->mask_red << WRITEMASK_RED_SHIFT) |
(imesa->mask_green << WRITEMASK_GREEN_SHIFT) |
(imesa->mask_blue << WRITEMASK_BLUE_SHIFT) |
(imesa->mask_alpha << WRITEMASK_ALPHA_SHIFT));
if(0)
fprintf(stderr, "bcdq : r_mask(%d) g_mask(%d) b_mask(%d) a_mask(%d)\n",
imesa->mask_red, imesa->mask_green, imesa->mask_blue,
imesa->mask_alpha);
sarea->ContextState[I830_CTXREG_ENABLES_2] = tmp;
sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->backOffset;
if(0)
fprintf(stderr, "bcdq : x0(%d) x1(%d) y0(%d) y1(%d)\n"
"r(0x%x) g(0x%x) b(0x%x) a(0x%x)\n",
x0, x1, y0, y1, imesa->clear_red, imesa->clear_green,
imesa->clear_blue, imesa->clear_alpha);
i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1,
imesa->clear_red, imesa->clear_green,
imesa->clear_blue, imesa->clear_alpha);
i830FlushPrimsLocked( imesa );
}
if(mask & DD_STENCIL_BIT) {
GLuint s_mask = ctx->Stencil.WriteMask[0];
sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS |
I830_UPLOAD_TEXBLEND0);
sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
TEXPIPE_COLOR |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
DISABLE_TEX_CNTRL_STAGE |
TEXOP_SCALE_1X |
TEXOP_MODIFY_PARMS |
TEXOP_LAST_STAGE |
TEXBLENDOP_ARG1);
sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
TEXPIPE_ALPHA |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
TEXOP_SCALE_1X |
TEXOP_MODIFY_PARMS |
TEXBLENDOP_ARG1);
sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
TEXPIPE_COLOR |
TEXBLEND_ARG1 |
TEXBLENDARG_MODIFY_PARMS |
TEXBLENDARG_CURRENT);
sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
TEXPIPE_ALPHA |
TEXBLEND_ARG2 |
TEXBLENDARG_MODIFY_PARMS |
TEXBLENDARG_CURRENT);
sarea->TexBlendStateWordsUsed[0] = 4;
sarea->ContextState[I830_CTXREG_ENABLES_1] |= (ENABLE_STENCIL_TEST |
ENABLE_DEPTH_TEST);
sarea->ContextState[I830_CTXREG_ENABLES_2] &= ~(ENABLE_STENCIL_WRITE |
ENABLE_DEPTH_WRITE |
ENABLE_COLOR_WRITE);
sarea->ContextState[I830_CTXREG_ENABLES_2] |=
(ENABLE_STENCIL_WRITE |
DISABLE_DEPTH_WRITE |
(1 << WRITEMASK_RED_SHIFT) |
(1 << WRITEMASK_GREEN_SHIFT) |
(1 << WRITEMASK_BLUE_SHIFT) |
(1 << WRITEMASK_ALPHA_SHIFT) |
ENABLE_COLOR_WRITE);
sarea->ContextState[I830_CTXREG_STATE4] &=
~MODE4_ENABLE_STENCIL_WRITE_MASK;
sarea->ContextState[I830_CTXREG_STATE4] |=
(ENABLE_STENCIL_WRITE_MASK |
STENCIL_WRITE_MASK(s_mask));
sarea->ContextState[I830_CTXREG_STENCILTST] &=
~(STENCIL_OPS_MASK |
STENCIL_REF_VALUE_MASK |
ENABLE_STENCIL_TEST_FUNC_MASK);
sarea->ContextState[I830_CTXREG_STENCILTST] |=
(ENABLE_STENCIL_PARMS |
ENABLE_STENCIL_REF_VALUE |
ENABLE_STENCIL_TEST_FUNC |
STENCIL_FAIL_OP(STENCILOP_REPLACE) |
STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) |
STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE) |
STENCIL_REF_VALUE((ctx->Stencil.Clear & 0xff)) |
STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS));
if(0)
fprintf(stderr, "Enables_1 (0x%x) Enables_2 (0x%x) StenTst (0x%x)\n"
"Modes_4 (0x%x)\n",
sarea->ContextState[I830_CTXREG_ENABLES_1],
sarea->ContextState[I830_CTXREG_ENABLES_2],
sarea->ContextState[I830_CTXREG_STENCILTST],
sarea->ContextState[I830_CTXREG_STATE4]);
sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset;
i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1,
255, 255, 255, 255);
i830FlushPrimsLocked( imesa );
}
UNLOCK_HARDWARE(imesa);
imesa->dirty = old_dirty;
imesa->dirty |= (I830_UPLOAD_CTX |
I830_UPLOAD_BUFFERS |
I830_UPLOAD_TEXBLEND0);
imesa->hw_primitive = old_vertex_prim;
}
static void i830Clear(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch)
{
i830ContextPtr imesa = I830_CONTEXT( ctx );
__DRIdrawablePrivate *dPriv = imesa->driDrawable;
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
drmI830Clear clear;
GLbitfield tri_mask = 0;
int i;
GLint cx, cy;
cy = dPriv->h-cy1-ch;
cx = cx1 + imesa->drawX;
cy += imesa->drawY;
if(0) fprintf(stderr, "\nClearColor : 0x%08x\n", imesa->ClearColor);
clear.flags = 0;
clear.clear_color = imesa->ClearColor;
clear.clear_depth = 0;
clear.clear_colormask = 0;
clear.clear_depthmask = 0;
I830_FIREVERTICES( imesa );
if (mask & DD_FRONT_LEFT_BIT) {
if(colorMask == ~0) {
clear.flags |= I830_FRONT;
} else {
tri_mask |= DD_FRONT_LEFT_BIT;
}
mask &= ~DD_FRONT_LEFT_BIT;
}
if (mask & DD_BACK_LEFT_BIT) {
if(colorMask == ~0) {
clear.flags |= I830_BACK;
} else {
tri_mask |= DD_BACK_LEFT_BIT;
}
mask &= ~DD_BACK_LEFT_BIT;
}
if (mask & DD_DEPTH_BIT) {
clear.flags |= I830_DEPTH;
clear.clear_depthmask = imesa->depth_clear_mask;
clear.clear_depth = (GLuint)(ctx->Depth.Clear * imesa->ClearDepth);
mask &= ~DD_DEPTH_BIT;
}
if((mask & DD_STENCIL_BIT) && imesa->hw_stencil) {
if (ctx->Stencil.WriteMask[0] != 0xff) {
tri_mask |= DD_STENCIL_BIT;
} else {
clear.flags |= I830_DEPTH;
clear.clear_depthmask |= imesa->stencil_clear_mask;
clear.clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
}
mask &= ~DD_STENCIL_BIT;
}
if(tri_mask) {
i830ClearWithTris(ctx, tri_mask, all, cx, cy, cw, ch);
}
if (clear.flags) {
LOCK_HARDWARE( imesa );
for (i = 0 ; i < imesa->numClipRects ; )
{
int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, imesa->numClipRects);
XF86DRIClipRectRec *box = imesa->pClipRects;
drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes;
int n = 0;
if (!all) {
for ( ; i < nr ; i++) {
GLint x = box[i].x1;
GLint y = box[i].y1;
GLint w = box[i].x2 - x;
GLint h = box[i].y2 - y;
if (x < cx) w -= cx - x, x = cx;
if (y < cy) h -= cy - y, y = cy;
if (x + w > cx + cw) w = cx + cw - x;
if (y + h > cy + ch) h = cy + ch - y;
if (w <= 0) continue;
if (h <= 0) continue;
b->x1 = x;
b->y1 = y;
b->x2 = x + w;
b->y2 = y + h;
b++;
n++;
}
} else {
for ( ; i < nr ; i++) {
*b++ = *(drm_clip_rect_t *)&box[i];
n++;
}
}
imesa->sarea->nbox = n;
drmCommandWrite(imesa->driFd, DRM_I830_CLEAR,
&clear, sizeof(drmI830Clear));
}
UNLOCK_HARDWARE( imesa );
imesa->upload_cliprects = GL_TRUE;
}
if (mask)
_swrast_Clear( ctx, mask, all, cx1, cy1, cw, ch );
}
void i830CopyBuffer( const __DRIdrawablePrivate *dPriv )
{
i830ContextPtr imesa;
XF86DRIClipRectPtr pbox;
int nbox, i, tmp;
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate;
I830_FIREVERTICES( imesa );
LOCK_HARDWARE( imesa );
imesa->sarea->perf_boxes |= imesa->perf_boxes;
imesa->perf_boxes = 0;
pbox = dPriv->pClipRects;
nbox = dPriv->numClipRects;
for (i = 0 ; i < nbox ; )
{
int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)imesa->sarea->boxes;
imesa->sarea->nbox = nr - i;
for ( ; i < nr ; i++)
*b++ = pbox[i];
drmCommandNone(imesa->driFd, DRM_I830_SWAP);
}
tmp = GET_ENQUEUE_AGE(imesa);
UNLOCK_HARDWARE( imesa );
if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
i830WaitAge(imesa, imesa->lastSwap);
}
imesa->lastSwap = tmp;
imesa->upload_cliprects = GL_TRUE;
}
void i830PageFlip( const __DRIdrawablePrivate *dPriv )
{
#if 0
i830ContextPtr imesa;
int tmp, ret;
if (I830_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate;
I830_FIREVERTICES( imesa );
LOCK_HARDWARE( imesa );
imesa->sarea->perf_boxes |= imesa->perf_boxes;
imesa->perf_boxes = 0;
if (dPriv->pClipRects) {
*(XF86DRIClipRectRec *)imesa->sarea->boxes = dPriv->pClipRects[0];
imesa->sarea->nbox = 1;
}
ret = drmCommandNone(imesa->driFd, DRM_I830_FLIP);
if (ret) {
fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
UNLOCK_HARDWARE( imesa );
exit(1);
}
tmp = GET_ENQUEUE_AGE(imesa);
UNLOCK_HARDWARE( imesa );
if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
i830WaitAge(imesa, imesa->lastSwap);
}
i830SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer );
imesa->upload_cliprects = GL_TRUE;
imesa->lastSwap = tmp;
#endif
}
void i830DmaFinish( i830ContextPtr imesa )
{
I830_FIREVERTICES( imesa );
LOCK_HARDWARE_QUIESCENT( imesa );
UNLOCK_HARDWARE( imesa );
}
void i830RegetLockQuiescent( i830ContextPtr imesa )
{
drmUnlock(imesa->driFd, imesa->hHWContext);
i830GetLock( imesa, DRM_LOCK_QUIESCENT );
}
void i830WaitAgeLocked( i830ContextPtr imesa, int age )
{
int i = 0;
while (++i < 5000) {
drmCommandNone(imesa->driFd, DRM_I830_GETAGE);
if (GET_DISPATCH_AGE(imesa) >= age) return;
imesa->sarea->perf_boxes |= I830_BOX_WAIT;
UNLOCK_HARDWARE( imesa );
if (I830_DEBUG & DEBUG_SLEEP) fprintf(stderr, ".");
usleep(1);
LOCK_HARDWARE( imesa );
}
drmCommandNone(imesa->driFd, DRM_I830_FLUSH);
}
void i830WaitAge( i830ContextPtr imesa, int age )
{
int i = 0;
if (GET_DISPATCH_AGE(imesa) >= age) return;
while (1) {
drmCommandNone(imesa->driFd, DRM_I830_GETAGE);
if (GET_DISPATCH_AGE(imesa) >= age) return;
imesa->perf_boxes |= I830_BOX_WAIT;
if (imesa->do_irqs) {
drmI830IrqEmit ie;
drmI830IrqWait iw;
int ret;
ie.irq_seq = &iw.irq_seq;
LOCK_HARDWARE( imesa );
ret = drmCommandWriteRead( imesa->driFd, DRM_I830_IRQ_EMIT, &ie, sizeof(ie) );
if ( ret ) {
fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret );
exit(1);
}
UNLOCK_HARDWARE(imesa);
ret = drmCommandWrite( imesa->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
if ( ret ) {
fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret );
exit(1);
}
} else {
if (++i > 5000) usleep(1);
}
}
}
static void age_imesa( i830ContextPtr imesa, int age )
{
if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->base.timestamp = age;
if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->base.timestamp = age;
}
void i830FlushPrimsLocked( i830ContextPtr imesa )
{
XF86DRIClipRectPtr pbox = (XF86DRIClipRectPtr)imesa->pClipRects;
int nbox = imesa->numClipRects;
drmBufPtr buffer = imesa->vertex_buffer;
I830SAREAPtr sarea = imesa->sarea;
drmI830Vertex vertex;
int i, nr;
if (I830_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s dirty: %08x\n", __FUNCTION__, imesa->dirty);
vertex.idx = buffer->idx;
vertex.used = imesa->vertex_low;
vertex.discard = 0;
sarea->vertex_prim = imesa->hw_primitive;
imesa->vertex_buffer = 0;
imesa->vertex_addr = 0;
imesa->vertex_low = 0;
imesa->vertex_high = 0;
imesa->vertex_last_prim = 0;
if (imesa->dirty) {
if (I830_DEBUG & DEBUG_SANITY)
i830EmitHwStateLockedDebug(imesa);
else
i830EmitHwStateLocked(imesa);
}
if (I830_DEBUG & DEBUG_IOCTL)
fprintf(stderr,"%s: Vertex idx %d used %d discard %d\n",
__FUNCTION__, vertex.idx, vertex.used, vertex.discard);
if (!nbox) {
vertex.used = 0;
vertex.discard = 1;
if (drmCommandWrite (imesa->driFd, DRM_I830_VERTEX,
&vertex, sizeof(drmI830Vertex))) {
fprintf(stderr, "DRM_I830_VERTEX: %d\n", -errno);
UNLOCK_HARDWARE(imesa);
exit(1);
}
return;
}
for (i = 0 ; i < nbox ; i = nr ) {
XF86DRIClipRectPtr b = sarea->boxes;
int j;
nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, nbox);
sarea->nbox = nr - i;
for ( j = i ; j < nr ; j++) {
b[j-i] = pbox[j];
}
if (nr == nbox)
vertex.discard = 1;
if (I830_DEBUG & DEBUG_SANITY) {
i830VertexSanity(imesa, vertex);
for ( j = 0 ; j < sarea->nbox ; j++) {
fprintf(stderr, "box %d/%d %d,%d %d,%d\n",
j, sarea->nbox, b[j].x1, b[j].y1, b[j].x2, b[j].y2);
}
}
drmCommandWrite (imesa->driFd, DRM_I830_VERTEX,
&vertex, sizeof(drmI830Vertex));
age_imesa(imesa, imesa->sarea->last_enqueue);
}
imesa->dirty = 0;
imesa->upload_cliprects = GL_FALSE;
}
void i830FlushPrimsGetBufferLocked( i830ContextPtr imesa )
{
if (imesa->vertex_buffer)
i830FlushPrimsLocked( imesa );
imesa->vertex_buffer = i830_get_buffer_ioctl( imesa );
imesa->vertex_addr = (char *)imesa->vertex_buffer->address;
imesa->vertex_high = imesa->vertex_buffer->total - 4;
imesa->vertex_low = 4;
imesa->vertex_last_prim = imesa->vertex_low;
}
void i830FlushPrimsGetBuffer( i830ContextPtr imesa )
{
LOCK_HARDWARE(imesa);
i830FlushPrimsGetBufferLocked( imesa );
UNLOCK_HARDWARE(imesa);
}
void i830FlushPrims( i830ContextPtr imesa )
{
if (imesa->vertex_buffer) {
LOCK_HARDWARE( imesa );
i830FlushPrimsLocked( imesa );
UNLOCK_HARDWARE( imesa );
}
}
int i830_check_copy(int fd)
{
return drmCommandNone(fd, DRM_I830_DOCOPY);
}
static void i830DDFlush( GLcontext *ctx )
{
i830ContextPtr imesa = I830_CONTEXT( ctx );
I830_FIREVERTICES( imesa );
}
static void i830DDFinish( GLcontext *ctx )
{
i830ContextPtr imesa = I830_CONTEXT( ctx );
i830DmaFinish( imesa );
}
void i830DDInitIoctlFuncs( GLcontext *ctx )
{
ctx->Driver.Flush = i830DDFlush;
ctx->Driver.Clear = i830Clear;
ctx->Driver.Finish = i830DDFinish;
}