Checkpoint FBO work:

The progs/tests/fbotest1.c demo works (yeah!), with some caveats:
 - Only glClear is done in hardware, actually rendering is sw fallback now.
 - Initial expose/draw is broken, works on subsequent draws.
Lots of changes in fallback/span code for FB objects.
Almost full rewrite of intelClearWithBlit() for renderbuffers.
Total rewrite of intelDrawBuffer() function.
Add FBO support to intelClearWithTris() but is currently broken.
Temporary hack in MakeCurrent():
 - since we can't create the screen/static renderbuffer regions in
   intelCreateBuffer() like we should (no current context with which to lock),
   init the renderbuffer's regions in MakeCurrent by copying from
   intel->front/back/depth_region.
Still using old DRI front/back/depth mappings for sw rendering to windows.
When those mappings go away, we'll use the new renderbuffer region mappings.
This commit is contained in:
Brian Paul 2006-03-18 21:55:34 +00:00
parent 0a5fea5f96
commit 6734bab3b2
14 changed files with 589 additions and 291 deletions

View file

@ -1010,7 +1010,7 @@ static void i830_init_packets( struct i830_context *i830 )
i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH |
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) | /* XXX FBO fix */
BUF_3D_USE_FENCE);
/* i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset; */

View file

@ -699,7 +699,7 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state)
/* Logicop doesn't seem to work at 16bpp:
*/
if (i915->intel.intelScreen->cpp == 2)
if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */
FALLBACK( &i915->intel, I915_FALLBACK_LOGICOP, state );
break;
@ -808,7 +808,7 @@ static void i915_init_packets( struct i915_context *i915 )
i915->state.Ctx[I915_CTXREG_LIS4] = 0;
i915->state.Ctx[I915_CTXREG_LIS5] = 0;
if (screen->cpp == 2)
if (screen->cpp == 2) /* XXX FBO fix */
i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE;
@ -858,13 +858,13 @@ static void i915_init_packets( struct i915_context *i915 )
i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i915->state.Buffer[I915_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK |
BUF_3D_PITCH(screen->front.pitch * screen->cpp) |
BUF_3D_PITCH(screen->front.pitch * screen->cpp) | /* XXX FBO fix */
BUF_3D_USE_FENCE);
i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH |
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) | /* XXX FBO fix */
BUF_3D_USE_FENCE);
i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;

View file

@ -250,9 +250,11 @@ static void i915_emit_state( struct intel_context *intel )
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]);
OUT_RELOC(state->draw_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0);
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]);
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]);
OUT_RELOC(state->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0);
if (state->depth_region) {
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]);
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]);
OUT_RELOC(state->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0);
}
OUT_BATCH(state->Buffer[I915_DESTREG_DV0]);
OUT_BATCH(state->Buffer[I915_DESTREG_DV1]);

View file

@ -33,10 +33,11 @@
#include "context.h"
#include "enums.h"
#include "intel_reg.h"
#include "intel_batchbuffer.h"
#include "intel_context.h"
#include "intel_blit.h"
#include "intel_context.h"
#include "intel_fbo.h"
#include "intel_reg.h"
#include "intel_regions.h"
#include "intel_bufmgr.h"
@ -66,6 +67,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
*/
LOCK_HARDWARE( intel );
/* XXX FBO: change this to if intel->numClipRects */
if (intel->driDrawable &&
intel->driDrawable->numClipRects)
{
@ -73,8 +75,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int nbox = dPriv->numClipRects;
drm_clip_rect_t *pbox = dPriv->pClipRects;
int pitch = intelScreen->front.pitch;
int cpp = intelScreen->cpp;
int pitch = intelScreen->front.pitch; /* XXX FBO change */
int cpp = intelScreen->cpp; /* XXX FBO change */
int BR13, CMD;
int i;
@ -255,15 +257,12 @@ void intelEmitCopyBlit( struct intel_context *intel,
void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch)
GLint cx, GLint cy, GLint cw, GLint ch)
{
struct intel_context *intel = intel_context( ctx );
intelScreenPrivate *intelScreen = intel->intelScreen;
GLuint clear_depth, clear_color;
GLint pitch = intelScreen->front.pitch;
GLint cpp = intelScreen->cpp;
GLint i;
GLuint BR13, CMD, D_CMD;
GLbitfield skipBuffer = 0;
BATCH_LOCALS;
if (INTEL_DEBUG & DEBUG_DRI)
@ -280,52 +279,55 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
}
switch(cpp) {
case 2:
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
D_CMD = CMD = XY_COLOR_BLT_CMD;
break;
case 4:
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
CMD = (XY_COLOR_BLT_CMD |
XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
D_CMD = XY_COLOR_BLT_CMD;
if (flags & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB;
if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
break;
default:
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
D_CMD = CMD = XY_COLOR_BLT_CMD;
break;
/* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in
* the loop below.
*/
if ((flags & BUFFER_BIT_DEPTH) && (flags & BUFFER_BIT_STENCIL)) {
skipBuffer = BUFFER_BIT_STENCIL;
}
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
if (intel->driDrawable->numClipRects)
if (intel->numClipRects)
{
drm_clip_rect_t clear;
int i;
/* flip top to bottom */
clear.x1 = cx + intel->drawX;
clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch;
clear.x2 = clear.x1 + cw;
clear.y2 = clear.y1 + ch;
if (intel->ctx.DrawBuffer->Name == 0) {
/* clearing a window */
/* adjust for page flipping */
if ( intel->sarea->pf_current_page == 1 ) {
GLuint tmp = flags;
/* flip top to bottom */
clear.x1 = cx + intel->drawX;
clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch;
clear.x2 = clear.x1 + cw;
clear.y2 = clear.y1 + ch;
flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT;
if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT;
/* adjust for page flipping */
if ( intel->sarea->pf_current_page == 1 ) {
GLuint tmp = flags;
flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT;
if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT;
}
}
else {
/* clearing FBO */
ASSERT(intel->numClipRects == 1);
ASSERT(intel->pClipRects == &intel->fboRect);
clear.x1 = cx;
clear.y1 = intel->ctx.DrawBuffer->Height - cy - ch;
clear.x2 = clear.y1 + cw;
clear.y2 = clear.y1 + ch;
/* no change to flags */
}
for (i = 0 ; i < intel->numClipRects ; i++)
{
drm_clip_rect_t *box = &intel->pClipRects[i];
const drm_clip_rect_t *box = &intel->pClipRects[i];
drm_clip_rect_t b;
GLuint buf;
if (!all) {
intel_intersect_cliprects(&b, &clear, box);
@ -339,38 +341,67 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
b.x2, b.y2,
flags);
if ( flags & BUFFER_BIT_FRONT_LEFT ) {
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_RELOC( intel->front_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
/* Loop over all renderbuffers */
for (buf = 0; buf < BUFFER_COUNT && flags; buf++) {
const GLbitfield bufBit = 1 << buf;
if ((flags & bufBit) && !(bufBit & skipBuffer)) {
/* OK, clear this renderbuffer */
const struct intel_renderbuffer *irb
= intel_renderbuffer(ctx->DrawBuffer->
Attachment[buf].Renderbuffer);
GLuint clearVal;
GLint pitch, cpp;
GLuint BR13, CMD;
if ( flags & BUFFER_BIT_BACK_LEFT ) {
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_RELOC( intel->back_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
ASSERT(irb);
ASSERT(irb->region);
if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH( D_CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_RELOC( intel->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 );
OUT_BATCH( clear_depth );
ADVANCE_BATCH();
}
pitch = irb->region->pitch;
cpp = irb->region->cpp;
if (cpp == 4) {
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) {
CMD = XY_COLOR_BLT_CMD;
if (flags & BUFFER_BIT_DEPTH)
CMD |= XY_COLOR_BLT_WRITE_RGB;
if (flags & BUFFER_BIT_STENCIL)
CMD |= XY_COLOR_BLT_WRITE_ALPHA;
}
else {
/* clearing RGBA */
CMD = (XY_COLOR_BLT_CMD |
XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
}
}
else {
ASSERT(cpp == 2 || cpp == 0);
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
CMD = XY_COLOR_BLT_CMD;
}
if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) {
clearVal = clear_depth;
}
else {
clearVal = clear_color;
}
/*
_mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n",
buf, irb->Base.Name);
*/
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_RELOC( irb->region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 );
OUT_BATCH( clearVal );
ADVANCE_BATCH();
flags &= ~(1 << buf); /* turn off bit, for faster loop exit */
}
}
}
intel_batchbuffer_flush( intel->batch );
}

View file

@ -82,6 +82,7 @@ struct intel_region *intel_readbuf_region( struct intel_context *intel )
/* This will have to change to support EXT_fbo's, but is correct
* for now:
*/
#if 0 /* XXX FBO */
switch (ctx->ReadBuffer->_ColorReadBufferIndex) {
case BUFFER_FRONT_LEFT:
return intel->front_region;
@ -91,6 +92,10 @@ struct intel_region *intel_readbuf_region( struct intel_context *intel )
assert(0);
return NULL;
}
#else
struct intel_renderbuffer *irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
return irb->region;
#endif
}
@ -213,8 +218,7 @@ static void intelSetBackClipRects( struct intel_context *intel )
/**
* This will be called whenever the currently bound window is moved/resized.
* Actually, it seems that only window moves which expose new regions
* cause this function to be called. (BP)
* XXX: actually, it seems to NOT be called when the window is only moved (BP).
*/
void intelWindowMoved( struct intel_context *intel )
{
@ -246,14 +250,9 @@ void intelWindowMoved( struct intel_context *intel )
intel->driDrawable->w, intel->driDrawable->h);
}
/* Set state we know depends on drawable parameters:
*/
{
GLcontext *ctx = &intel->ctx;
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height );
}
/* Update hardware scissor */
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height );
}
@ -267,32 +266,28 @@ static void intelClearWithTris(struct intel_context *intel,
GLint cx, GLint cy,
GLint cw, GLint ch)
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
GLcontext *ctx = &intel->ctx;
drm_clip_rect_t clear;
if (INTEL_DEBUG & DEBUG_DRI)
_mesa_printf("%s %x\n", __FUNCTION__, mask);
if (1/*INTEL_DEBUG & DEBUG_DRI*/)
_mesa_printf("%s 0x%x\n", __FUNCTION__, mask);
LOCK_HARDWARE(intel);
if (intel->driDrawable->numClipRects) {
/* XXX FBO: was: intel->driDrawable->numClipRects */
if (intel->numClipRects) {
intel->vtbl.install_meta_state(intel);
if(!all) {
clear.x1 = cx;
clear.y1 = cy;
clear.x2 = cx + cw;
clear.y2 = cy + ch;
} else {
clear.x1 = 0;
clear.y1 = 0;
clear.x2 = dPriv->w;
clear.y2 = dPriv->h;
}
/* note: regardless of 'all', cx, cy, cw, ch are correct */
clear.x1 = cx;
clear.y1 = cy;
clear.x2 = cx + cw;
clear.y2 = cy + ch;
/* Back and stencil cliprects are the same. Try and do both
* buffers at once:
* XXX FBO: This is broken for FBO depth/stencil buffers!
*/
if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL|BUFFER_BIT_DEPTH)) {
intel->vtbl.meta_draw_region(intel,
@ -348,6 +343,46 @@ static void intelClearWithTris(struct intel_context *intel,
0, 0, 0, 0);
}
/*
* User-created RGBA renderbuffers
*/
if (mask & (BUFFER_BIT_COLOR0 |
BUFFER_BIT_COLOR1 |
BUFFER_BIT_COLOR2 |
BUFFER_BIT_COLOR3)) {
struct intel_region *depth_region = NULL;
GLuint buf;
ASSERT(ctx->Const.MaxColorAttachments == 4); /* XXX FBO fix */
for (buf = BUFFER_COLOR0; buf <= BUFFER_COLOR3; buf++) {
const GLbitfield bufBit = 1 << buf;
if (mask & bufBit) {
struct intel_renderbuffer *irb =
intel_renderbuffer(ctx->DrawBuffer->
Attachment[buf].Renderbuffer);
ASSERT(irb);
ASSERT(irb->region);
/* XXX move these three calls outside loop? */
intel->vtbl.meta_no_depth_write(intel);
intel->vtbl.meta_no_stencil_write(intel);
intel->vtbl.meta_color_mask(intel, GL_TRUE );
intel->vtbl.meta_draw_region(intel, irb->region, depth_region);
/* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the
* drawing origin may not be correctly emitted.
*/
intel_meta_draw_quad(intel,
clear.x1, clear.x2,
clear.y1, clear.y2,
0,
intel->ClearColor,
0, 0, 0, 0);
}
}
}
intel->vtbl.leave_meta_state( intel );
intel_batchbuffer_flush( intel->batch );
}
@ -357,13 +392,21 @@ static void intelClearWithTris(struct intel_context *intel,
/**
* Called by ctx->Driver.Clear.
*/
static void intelClear(GLcontext *ctx,
GLbitfield mask,
GLboolean all,
GLint cx, GLint cy,
GLint cw, GLint ch)
{
const GLbitfield colorBufferBits = (BUFFER_BIT_FRONT_LEFT |
BUFFER_BIT_BACK_LEFT |
BUFFER_BIT_COLOR0 |
BUFFER_BIT_COLOR1 |
BUFFER_BIT_COLOR2 |
BUFFER_BIT_COLOR3);
struct intel_context *intel = intel_context( ctx );
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
GLbitfield tri_mask = 0;
@ -374,30 +417,19 @@ static void intelClear(GLcontext *ctx,
fprintf(stderr, "%s\n", __FUNCTION__);
if (mask & BUFFER_BIT_FRONT_LEFT) {
if (colorMask == ~0) {
blit_mask |= BUFFER_BIT_FRONT_LEFT;
}
else {
tri_mask |= BUFFER_BIT_FRONT_LEFT;
}
/* HW color buffers (front, back, aux, generic FBO, etc) */
if (colorMask == ~0) {
/* clear all R,G,B,A */
blit_mask |= (mask & colorBufferBits);
}
else {
/* glColorMask in effect */
tri_mask |= (mask & colorBufferBits);
}
if (mask & BUFFER_BIT_BACK_LEFT) {
if (colorMask == ~0) {
blit_mask |= BUFFER_BIT_BACK_LEFT;
}
else {
tri_mask |= BUFFER_BIT_BACK_LEFT;
}
}
if (mask & BUFFER_BIT_STENCIL) {
if (!intel->hw_stencil) {
swrast_mask |= BUFFER_BIT_STENCIL;
}
else if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
/* HW stencil */
if (intel->hw_stencil && (mask & BUFFER_BIT_STENCIL)) {
if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
tri_mask |= BUFFER_BIT_STENCIL;
}
else {
@ -409,13 +441,20 @@ static void intelClear(GLcontext *ctx,
* same buffer.
*/
if (mask & BUFFER_BIT_DEPTH) {
/* XXX is this logic correct? It looks like the blit routine
* can only clear both buffers while the triangle routine can do
* one or the other. (BP)
*/
if (tri_mask & BUFFER_BIT_STENCIL)
tri_mask |= BUFFER_BIT_DEPTH;
else
blit_mask |= BUFFER_BIT_DEPTH;
}
swrast_mask |= (mask & BUFFER_BIT_ACCUM);
/*
* Clear in software whatever can't be done w/ hardware.
*/
swrast_mask = mask & ~tri_mask & ~blit_mask;
intelFlush( ctx );
@ -498,62 +537,109 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
}
}
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
/**
* Called via glDrawBuffer, glBindFramebufferEXT, and from various places
* within the driver.
* Note: mode parameter is not used.
*/
static void
intelDrawBuffer(GLcontext *ctx, GLenum mode )
{
struct intel_context *intel = intel_context(ctx);
int front = 0;
struct intel_renderbuffer *irb;
struct intel_region *colorRegion, *depthRegion;
int front = 0; /* drawing to front color buffer? */
if (!ctx->DrawBuffer) {
/* XXX I don't think this should ever happen. -BP */
return;
}
switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
case BUFFER_BIT_FRONT_LEFT:
front = 1;
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
case BUFFER_BIT_BACK_LEFT:
front = 0;
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
default:
/* GL_FRONT_AND_BACK, GL_NONE, etc */
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
return;
if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
_mesa_update_framebuffer(ctx);
}
if ( intel->sarea->pf_current_page == 1 )
front ^= 1;
/*
* How many color buffers are we drawing into?
*/
if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1
#if 1
/* XXX FBO temporary - always use software rendering */
|| ctx->DrawBuffer->Name != 0
#endif
) {
/* writing to 0 or 2 or 4 color buffers */
/*_mesa_debug(ctx, "Software rendering\n");*/
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
front = 1; /* might not have back color buffer */
}
else {
/* draw to exactly one color buffer */
/*_mesa_debug(ctx, "Hardware rendering\n");*/
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
if (ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) {
front = 1;
}
}
/*
* Get the intel_renderbuffer we're drawing into.
* And set up cliprects.
*/
if (ctx->DrawBuffer->Name == 0) {
/* drawing to window system buffer */
intelSetFrontClipRects( intel );
if (intel->sarea->pf_current_page == 1 ) {
/* page flipped back/front */
front ^= 1;
}
if (front) {
intelSetFrontClipRects( intel );
irb = intel_renderbuffer(ctx->DrawBuffer->
Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
}
else {
intelSetBackClipRects( intel );
irb = intel_renderbuffer(ctx->DrawBuffer->
Attachment[BUFFER_BACK_LEFT].Renderbuffer);
}
}
else {
/* drawing to user-created FBO */
intelSetRenderbufferClipRects(intel);
irb = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
ASSERT(irb);
}
if (front) {
if (intel->draw_region != intel->front_region) {
intel_region_release(intel, &intel->draw_region);
intel_region_reference(&intel->draw_region, intel->front_region);
}
} else {
if (intel->draw_region != intel->back_region) {
intel_region_release(intel, &intel->draw_region);
intel_region_reference(&intel->draw_region, intel->back_region);
}
/*
* Get color buffer region.
*/
if (irb && irb->region)
colorRegion = irb->region;
else
colorRegion = NULL;
/*
* Unbind old region, bind new region
*/
if (intel->draw_region != colorRegion) {
intel_region_release(intel, &intel->draw_region);
intel_region_reference(&intel->draw_region, colorRegion);
}
intel->vtbl.set_draw_region( intel,
intel->draw_region,
intel->depth_region);
/*
* Get depth buffer region
*/
irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer);
if (irb && irb->region)
depthRegion = irb->region;
else
depthRegion = NULL;
intel->vtbl.set_draw_region( intel, colorRegion, depthRegion );
}
static void intelReadBuffer( GLcontext *ctx, GLenum mode )
{
/* Nothing.

View file

@ -79,6 +79,7 @@ int INTEL_DEBUG = (0);
#define need_GL_EXT_blend_minmax
#define need_GL_EXT_cull_vertex
#define need_GL_EXT_fog_coord
#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_NV_vertex_program
@ -166,6 +167,7 @@ const struct dri_extension card_extensions[] =
{ "GL_EXT_blend_subtract", NULL },
{ "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions },
{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{ "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
{ "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
{ "GL_EXT_stencil_wrap", NULL },
@ -322,6 +324,8 @@ GLboolean intelInitContext( struct intel_context *intel,
ctx->Const.MaxPointSizeAA = 3.0;
ctx->Const.PointSizeGranularity = 1.0;
ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext( ctx );
_ac_CreateContext( ctx );
@ -394,6 +398,10 @@ GLboolean intelInitContext( struct intel_context *intel,
intel->intelScreen->tex.size,
DRM_MM_TT);
#endif
/* XXX FBO: these have to go away!
* FBO regions should be setup when creating the drawable. */
/* These are still static, but create regions for them.
*/
intel->front_region =
@ -481,7 +489,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
/* This share group is about to go away, free our private
* texture object data.
*/
fprintf(stderr, "do somethign to free texture heaps\n");
fprintf(stderr, "do something to free texture heaps\n");
}
/* free the Mesa context */
@ -501,6 +509,8 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
if (driContextPriv) {
struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
GLframebuffer *drawFb = (GLframebuffer *) driDrawPriv->driverPrivate;
GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate;
if ( intel->driDrawable != driDrawPriv ) {
/* Shouldn't the readbuffer be stored also? */
@ -508,9 +518,25 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
intelWindowMoved( intel );
}
_mesa_make_current(&intel->ctx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate);
/* XXX temporary fix-ups! */
/* if the renderbuffers don't have regions, init them from the context */
{
struct intel_renderbuffer *irbFront = intel_renderbuffer(drawFb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
struct intel_renderbuffer *irbBack = intel_renderbuffer(drawFb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
struct intel_renderbuffer *irbDepth = intel_renderbuffer(drawFb->Attachment[BUFFER_DEPTH].Renderbuffer);
struct intel_renderbuffer *irbStencil = intel_renderbuffer(drawFb->Attachment[BUFFER_STENCIL].Renderbuffer);
if (irbFront && !irbFront->region)
irbFront->region = intel->front_region;
if (irbBack && !irbBack->region)
irbBack->region = intel->back_region;
if (irbDepth && !irbDepth->region)
irbDepth->region = intel->depth_region;
if (irbStencil && !irbStencil->region)
irbStencil->region = intel->depth_region; /* YES */
}
_mesa_make_current(&intel->ctx, drawFb, readFb);
intel->ctx.Driver.DrawBuffer( &intel->ctx, intel->ctx.Color.DrawBuffer[0] );
} else {

View file

@ -559,6 +559,8 @@ static inline struct intel_texture_image *intel_texture_image( struct gl_texture
return (struct intel_texture_image *)img;
}
extern struct intel_renderbuffer *intel_renderbuffer( struct gl_renderbuffer *rb );
#endif

View file

@ -40,6 +40,18 @@
#include "intel_span.h"
#define MAGIC 0x12345678
struct intel_renderbuffer *intel_renderbuffer( struct gl_renderbuffer *rb )
{
struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
if (irb) {
assert(irb->Magic == 0x12345678);
}
return irb;
}
/**
* Create a new framebuffer object.
*/
@ -56,9 +68,9 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb)
{
GET_CURRENT_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
if (irb->region) {
if (intel && irb->region) {
intel_region_release(intel, &irb->region);
}
@ -76,7 +88,7 @@ static void *
intel_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb,
GLint x, GLint y)
{
struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
/* Actually, we could _always_ return NULL from this function and
* be OK. The swrast code would just use the Get/Put routines as needed.
@ -106,7 +118,7 @@ intel_alloc_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint width, GLuint height)
{
struct intel_context *intel = intel_context(ctx);
struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
const GLenum format = _mesa_base_fbo_format(ctx, internalFormat);
GLboolean softwareBuffer = GL_FALSE;
int cpp;
@ -126,25 +138,33 @@ intel_alloc_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
switch (format) {
case GL_RGB:
case GL_RGBA:
internalFormat = GL_RGBA8;
rb->RedBits = 8;
rb->GreenBits = 8;
rb->BlueBits = 8;
rb->AlphaBits = 8;
rb->DataType = GL_UNSIGNED_BYTE;
cpp = 4;
break;
case GL_DEPTH_COMPONENT:
internalFormat = GL_DEPTH24_STENCIL8_EXT;
rb->DepthBits = 24;
rb->DataType = GL_UNSIGNED_BYTE;
cpp = 4;
break;
case GL_STENCIL_INDEX:
internalFormat = GL_STENCIL_INDEX8_EXT;
rb->StencilBits = 8;
rb->DataType = GL_UNSIGNED_BYTE;
cpp = 1;
softwareBuffer = GL_TRUE;
/* XXX software buffer? */
break;
case GL_DEPTH_STENCIL_EXT:
internalFormat = GL_DEPTH24_STENCIL8_EXT;
rb->DepthBits = 24;
rb->StencilBits = 8;
rb->DataType = GL_UNSIGNED_INT;
cpp = 4;
break;
default:
@ -164,26 +184,40 @@ intel_alloc_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
else {
/* hardware renderbuffer */
/* alloc new region */
assert(width > 1);
assert(height > 1);
_mesa_debug(ctx, "Allocating %d x %d Intel RBO\n", width, height);
irb->region = intel_region_alloc(intel, cpp, width, height);
if (!irb->region)
return GL_FALSE; /* out of memory? */
}
rb->InternalFormat = internalFormat;
rb->Width = width;
rb->Height = height;
/* This sets the Get/PutRow/Value functions */
intel_set_span_functions(&irb->Base);
return GL_TRUE;
}
/**
* Just an error catcher.
* Called for each hardware renderbuffer when a _window_ is resized.
* Just update fields.
* Not use for user-created renderbuffers!
*/
static GLboolean
intel_alloc_storage_nop(GLcontext *ctx, struct gl_renderbuffer *rb,
GLenum internalFormat,
GLuint width, GLuint height)
intel_alloc_storage_window(GLcontext *ctx, struct gl_renderbuffer *rb,
GLenum internalFormat,
GLuint width, GLuint height)
{
_mesa_problem(ctx, "RenderBuffer storage called for intel window system renderbuffer!");
return GL_FALSE;
rb->Width = width;
rb->Height = height;
rb->InternalFormat = internalFormat;
return GL_TRUE;
}
@ -196,16 +230,20 @@ intel_alloc_storage_nop(GLcontext *ctx, struct gl_renderbuffer *rb,
*/
struct intel_renderbuffer *
intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height,
int offset, void *map)
int offset, int pitch, int cpp, void *map)
{
GET_CURRENT_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
struct intel_renderbuffer *irb;
const GLuint name = 0;
int cpp;
irb = CALLOC_STRUCT(intel_renderbuffer);
if (!irb)
return NULL;
irb->Magic = MAGIC;
_mesa_init_renderbuffer(&irb->Base, name);
switch (intFormat) {
@ -214,6 +252,7 @@ intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height,
irb->Base.RedBits = 5;
irb->Base.GreenBits = 6;
irb->Base.BlueBits = 5;
irb->Base.DataType = GL_UNSIGNED_BYTE;
cpp = 2;
break;
case GL_RGBA8:
@ -222,27 +261,32 @@ intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height,
irb->Base.GreenBits = 8;
irb->Base.BlueBits = 8;
irb->Base.AlphaBits = 8;
irb->Base.DataType = GL_UNSIGNED_BYTE;
cpp = 4;
break;
case GL_STENCIL_INDEX8_EXT:
irb->Base._BaseFormat = GL_STENCIL_INDEX;
irb->Base.StencilBits = 8;
irb->Base.DataType = GL_UNSIGNED_BYTE;
cpp = 1;
break;
case GL_DEPTH_COMPONENT16:
irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
irb->Base.DepthBits = 16;
irb->Base.DataType = GL_UNSIGNED_SHORT;
cpp = 2;
break;
case GL_DEPTH_COMPONENT24:
irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
irb->Base.DepthBits = 24;
irb->Base.DataType = GL_UNSIGNED_INT;
cpp = 4;
break;
case GL_DEPTH24_STENCIL8_EXT:
irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT;
irb->Base.DepthBits = 24;
irb->Base.StencilBits = 8;
irb->Base.DataType = GL_UNSIGNED_INT;
cpp = 4;
break;
default:
@ -250,14 +294,19 @@ intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height,
return NULL;
}
irb->Base.InternalFormat = intFormat;
/* intel-specific methods */
irb->Base.Delete = intel_delete_renderbuffer;
irb->Base.AllocStorage = intel_alloc_storage_nop;
irb->Base.AllocStorage = intel_alloc_storage_window;
irb->Base.GetPointer = intel_get_pointer;
/* This sets the Get/PutRow/Value functions */
intel_set_span_functions(&irb->Base);
#if 0
irb->pfMap = map;
irb->pfPitch = pitch;
#if 00
irb->region = intel_region_create_static(intel,
DRM_MM_TT,
offset,
@ -286,6 +335,8 @@ intel_new_renderbuffer(GLcontext *ctx, GLuint name)
if (!irb)
return NULL;
irb->Magic = MAGIC;
_mesa_init_renderbuffer(&irb->Base, name);
/* intel-specific methods */
@ -304,7 +355,10 @@ static void
intel_bind_framebuffer(GLcontext *ctx, GLenum target,
struct gl_framebuffer *fb)
{
_mesa_debug(ctx, "%s %d\n", __FUNCTION__, fb->Name);
if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
#if 00
struct intel_context *intel = intel_context(ctx);
struct gl_renderbuffer *rbColor, *rbDepth;
struct intel_renderbuffer *irbColor, *irbDepth;
@ -314,8 +368,8 @@ intel_bind_framebuffer(GLcontext *ctx, GLenum target,
rbColor = intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0];
rbDepth = intel->ctx.DrawBuffer->_DepthBuffer;
irbColor = (struct intel_renderbuffer *) rbColor;
irbDepth = (struct intel_renderbuffer *) rbDepth;
irbColor = intel_renderbuffer(rbColor);
irbDepth = intel_renderbuffer(rbDepth);
if (irbColor && irbColor->region)
colorRegion = irbColor->region;
@ -327,7 +381,11 @@ intel_bind_framebuffer(GLcontext *ctx, GLenum target,
else
depthRegion = NULL;
/* XXX FBO */
intel->vtbl.set_draw_region(intel, colorRegion, depthRegion);
#else
ctx->Driver.DrawBuffer(ctx, 0); /* second param is ignored */
#endif
}
else {
/* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
@ -344,7 +402,10 @@ intel_framebuffer_renderbuffer(GLcontext *ctx,
GLenum attachment,
struct gl_renderbuffer *rb)
{
/* no-op */
_mesa_debug(ctx, "Intel FramebufferRenderbuffer %u %u\n",
fb->Name, rb->Name);
_mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
}

View file

@ -28,10 +28,9 @@
#ifndef INTEL_FBO_H
#define INTEL_FBO_H
#include "drirenderbuffer.h"
struct intel_context;
struct intel_region;
/**
@ -40,12 +39,15 @@ struct intel_context;
struct intel_renderbuffer {
struct gl_renderbuffer Base;
struct intel_region *region;
void *pfMap; /* possibly paged flipped map pointer */
GLuint pfPitch; /* possibly paged flipped pitch */
GLuint Magic; /* for debug/sanity */
};
extern struct intel_renderbuffer *
intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height,
int offset, void *map);
int offset, int pitch, int cpp, void *map);
extern void

View file

@ -89,9 +89,11 @@ struct intel_region *intel_region_alloc( struct intel_context *intel,
void intel_region_reference( struct intel_region **dst,
struct intel_region *src)
{
src->refcount++;
assert(*dst == NULL);
*dst = src;
if (src) {
src->refcount++;
*dst = src;
}
}
void intel_region_release( struct intel_context *intel,
@ -111,7 +113,7 @@ void intel_region_release( struct intel_context *intel,
}
struct intel_region *intel_region_create_static( struct intel_context *intel,
struct intel_region *intel_region_create_static( struct intel_context *intel,
GLuint mem_type,
GLuint offset,
void *virtual,

View file

@ -41,7 +41,7 @@ struct intel_context;
* - Blitter commands for copying 2D regions between buffers. (really???)
*/
struct intel_region {
GLuint buffer;
GLuint buffer; /* buffer manager's buffer ID */
GLuint refcount;
GLuint cpp; /* bytes per pixel */
GLuint pitch; /* in pixels */

View file

@ -222,6 +222,9 @@ static void intelDestroyScreen(__DRIscreenPrivate *sPriv)
}
/**
* This is called when we need to set up GL rendering to a new X window.
*/
static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
@ -238,62 +241,82 @@ static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv,
struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
printf("** front addr = %p\n", (void*) driScrnPriv->pFB);
printf("** back addr = %p\n", (void*) screen->back.map);
printf("** depth addr = %p\n", (void*) screen->depth.map);
/* setup the hardware-based renderbuffers */
{
driRenderbuffer *frontRb
= driNewRenderbuffer(rgbFormat,
driScrnPriv->pFB,
screen->cpp,
screen->front.offset, screen->front.pitch,
driDrawPriv);
struct intel_renderbuffer *frontRb
= intel_create_renderbuffer(rgbFormat,
screen->width, screen->height,
screen->front.offset,
screen->front.pitch,
screen->cpp,
driScrnPriv->pFB);
intel_set_span_functions(&frontRb->Base);
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
}
if (mesaVis->doubleBufferMode) {
driRenderbuffer *backRb
= driNewRenderbuffer(rgbFormat,
screen->back.map,
screen->cpp,
screen->back.offset, screen->back.pitch,
driDrawPriv);
struct intel_renderbuffer *backRb
= intel_create_renderbuffer(rgbFormat,
screen->width, screen->height,
screen->back.offset,
screen->back.pitch,
screen->cpp,
screen->back.map);
intel_set_span_functions(&backRb->Base);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
}
if (mesaVis->depthBits > 0) {
/* XXX if 32bpp, this should probably be a GL_DEPTH_STENCIL buffer */
GLenum depthFormat = (mesaVis->depthBits == 16)
? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24;
driRenderbuffer *depthRb
= driNewRenderbuffer(depthFormat,
screen->depth.map,
screen->cpp,
screen->depth.offset, screen->depth.pitch,
driDrawPriv);
intel_set_span_functions(&depthRb->Base);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) {
/* combined depth/stencil buffer */
struct intel_renderbuffer *depthStencilRb
= intel_create_renderbuffer(/**GL_DEPTH24_STENCIL8_EXT,**/
GL_DEPTH_COMPONENT24,
screen->width, screen->height,
screen->depth.offset,
screen->depth.pitch,
screen->cpp, /* 4! */
screen->depth.map);
intel_set_span_functions(&depthStencilRb->Base);
/* note: bind RB to two attachment points */
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthStencilRb->Base);
#if 1
/* XXX TEMP: separate stencil */
depthStencilRb
= intel_create_renderbuffer(GL_STENCIL_INDEX8_EXT,
screen->width, screen->height,
screen->depth.offset,
screen->depth.pitch,
screen->cpp, /* 4! */
screen->depth.map);
intel_set_span_functions(&depthStencilRb->Base);
#endif
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &depthStencilRb->Base);
}
if (mesaVis->stencilBits > 0 && !swStencil) {
driRenderbuffer *stencilRb
= driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
screen->depth.map,
screen->cpp,
screen->depth.offset, screen->depth.pitch,
driDrawPriv);
intel_set_span_functions(&stencilRb->Base);
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
else if (mesaVis->depthBits == 16) {
/* just 16-bit depth buffer, no hw stencil */
struct intel_renderbuffer *depthRb
= intel_create_renderbuffer(GL_DEPTH_COMPONENT16,
screen->width, screen->height,
screen->depth.offset,
screen->depth.pitch,
screen->cpp, /* 2! */
screen->depth.map);
intel_set_span_functions(&depthRb->Base);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &depthRb->Base);
}
/* now add any/all software-based renderbuffers we may need */
_mesa_add_soft_renderbuffers(fb,
GL_FALSE, /* color */
GL_FALSE, /* depth */
GL_FALSE, /* never sw color */
GL_FALSE, /* never sw depth */
swStencil,
mesaVis->accumRedBits > 0,
GL_FALSE, /* alpha */
GL_FALSE /* aux */);
GL_FALSE, /* never sw alpha */
GL_FALSE /* never sw aux */);
driDrawPriv->driverPrivate = (void *) fb;
return (driDrawPriv->driverPrivate != NULL);

View file

@ -39,21 +39,39 @@
#include "swrast/swrast.h"
/*
break intelWriteRGBASpan_ARGB8888
*/
#undef DBG
#define DBG 0
#define LOCAL_VARS \
struct intel_context *intel = intel_context(ctx); \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
const __DRIdrawablePrivate *dPriv = drb->dPriv; \
const GLuint bottom = dPriv->h - 1; \
GLubyte *buf = (GLubyte *) drb->flippedData \
+ (dPriv->y * drb->flippedPitch + dPriv->x) * drb->cpp; \
GLuint p; \
assert(dPriv->x == intel->drawX); \
assert(dPriv->y == intel->drawY); \
#define LOCAL_VARS \
struct intel_context *intel = intel_context(ctx); \
struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
const GLuint bottom = irb->Base.Height - 1; \
GLubyte *buf = (GLubyte *) irb->pfMap \
+ (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\
GLuint p; \
assert(irb->pfMap);\
(void) p;
/* XXX FBO: this is identical to the macro in spantmp2.h except we get
* the cliprect info from the context, not the driDrawable.
* Move this into spantmp2.h someday.
*/
#define HW_CLIPLOOP() \
do { \
int _nc = intel->numClipRects; \
while ( _nc-- ) { \
int minx = intel->pClipRects[_nc].x1 - intel->drawX; \
int miny = intel->pClipRects[_nc].y1 - intel->drawY; \
int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \
int maxy = intel->pClipRects[_nc].y2 - intel->drawY;
#define Y_FLIP(_y) (bottom - _y)
#define HW_LOCK()
@ -67,7 +85,7 @@
#define TAG(x) intel##x##_RGB565
#define TAG2(x,y) intel##x##_RGB565##y
#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 2)
#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2)
#include "spantmp2.h"
/* 32 bit, ARGB8888 color spanline and pixel functions
@ -77,29 +95,28 @@
#define TAG(x) intel##x##_ARGB8888
#define TAG2(x,y) intel##x##_ARGB8888##y
#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 4)
#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4)
#include "spantmp2.h"
#define LOCAL_DEPTH_VARS \
struct intel_context *intel = intel_context(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
const GLuint pitch = drb->pitch * drb->cpp; \
const GLuint bottom = dPriv->h - 1; \
char *buf = (char *) drb->Base.Data + \
dPriv->x * drb->cpp + \
dPriv->y * pitch
#define LOCAL_DEPTH_VARS \
struct intel_context *intel = intel_context(ctx); \
struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \
const GLuint bottom = rb->Height - 1; \
char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \
(intel->drawY * pitch + intel->drawX) * irb->region->cpp;
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
/* 16 bit depthbuffer functions.
*/
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
((GLushort *)buf)[(_x) + (_y) * pitch] = d;
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
d = ((GLushort *)buf)[(_x) + (_y) * pitch];
#define TAG(x) intel##x##_z16
@ -108,29 +125,29 @@
/* 24/8 bit interleaved depth/stencil functions
*/
#define WRITE_DEPTH( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
tmp &= 0xff000000; \
tmp |= (d) & 0xffffff; \
*(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
#define WRITE_DEPTH( _x, _y, d ) { \
GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \
tmp &= 0xff000000; \
tmp |= (d) & 0xffffff; \
((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \
}
#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xffffff;
#define READ_DEPTH( d, _x, _y ) \
d = ((GLuint *)buf)[(_x) + (_y) * pitch] & 0xffffff;
#define TAG(x) intel##x##_z24_s8
#include "depthtmp.h"
#define WRITE_STENCIL( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
tmp &= 0xffffff; \
tmp |= ((d)<<24); \
*(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
#define WRITE_STENCIL( _x, _y, d ) { \
GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \
tmp &= 0xffffff; \
tmp |= ((d) << 24); \
((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \
}
#define READ_STENCIL( d, _x, _y ) \
d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) >> 24;
#define READ_STENCIL( d, _x, _y ) \
d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24;
#define TAG(x) intel##x##_z24_s8
#include "stenciltmp.h"
@ -150,49 +167,82 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
GLcontext *ctx = &intel->ctx;
GLuint i, j;
struct intel_renderbuffer *irb;
/* color draw buffers */
for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) {
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i][j];
irb = (struct intel_renderbuffer *) rb;
irb = intel_renderbuffer(rb);
ASSERT(irb);
if (irb->region) {
if (map)
intel_region_map(intel, irb->region);
else
intel_region_unmap(intel, irb->region);
if (irb->Base.Name != 0) { /* XXX FBO temporary test */
if (irb->region) {
if (map)
intel_region_map(intel, irb->region);
else
intel_region_unmap(intel, irb->region);
}
irb->pfMap = irb->region->map;
irb->pfPitch = irb->region->pitch;
}
}
}
/* color read buffers */
irb = (struct intel_renderbuffer *) ctx->ReadBuffer->_ColorReadBuffer;
if (irb && irb->region) {
irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
if (irb && irb->region && irb->Base.Name != 0) {
if (map)
intel_region_map(intel, irb->region);
else
intel_region_unmap(intel, irb->region);
}
/* depth buffer */
/* XXX wrappers? */
irb = (struct intel_renderbuffer *) ctx->ReadBuffer->_DepthBuffer;
if (irb && irb->region) {
if (map)
intel_region_map(intel, irb->region);
else
intel_region_unmap(intel, irb->region);
/* Account for front/back color page flipping.
* The span routines use the pfMap and pfPitch fields which will
* swap the front/back region map/pitch if we're page flipped.
* Do this after mapping, above, so the map field is valid.
*/
#if 0
if (map && ctx->DrawBuffer->Name == 0) {
struct intel_renderbuffer *irbFront = intel_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
struct intel_renderbuffer *irbBack = intel_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
if (irbBack) {
/* double buffered */
if (intel->sarea->pf_current_page == 0) {
irbFront->pfMap = irbFront->region->map;
irbFront->pfPitch = irbFront->region->pitch;
irbBack->pfMap = irbBack->region->map;
irbBack->pfPitch = irbBack->region->pitch;
}
else {
irbFront->pfMap = irbBack->region->map;
irbFront->pfPitch = irbBack->region->pitch;
irbBack->pfMap = irbFront->region->map;
irbBack->pfPitch = irbFront->region->pitch;
}
}
}
#endif
/* depth buffer (Note wrapper!) */
if (ctx->DrawBuffer->_DepthBuffer) {
irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
if (irb && irb->region && irb->Base.Name != 0) {
if (map)
intel_region_map(intel, irb->region);
else
intel_region_unmap(intel, irb->region);
}
}
/* stencil buffer */
irb = (struct intel_renderbuffer *) ctx->ReadBuffer->_StencilBuffer;
if (irb && irb->region) {
if (map)
intel_region_map(intel, irb->region);
else
intel_region_unmap(intel, irb->region);
/* stencil buffer (Note wrapper!) */
if (ctx->DrawBuffer->_StencilBuffer) {
irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
if (irb && irb->region && irb->Base.Name != 0) {
if (map)
intel_region_map(intel, irb->region);
else
intel_region_unmap(intel, irb->region);
}
}
}
@ -212,12 +262,14 @@ void intelSpanRenderStart( GLcontext *ctx )
intelFlush(&intel->ctx);
LOCK_HARDWARE(intel);
#if 0
/* Just map the framebuffer and all textures. Bufmgr code will
* take care of waiting on the necessary fences:
*/
intel_region_map(intel, intel->front_region);
intel_region_map(intel, intel->back_region);
intel_region_map(intel, intel->depth_region);
#endif
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled) {
@ -225,6 +277,11 @@ void intelSpanRenderStart( GLcontext *ctx )
intel_tex_map_images(intel, intel_texture_object(texObj));
}
}
#if 1
/* XXX FBO: enable this code when old DRI screen mappings go away */
intel_map_unmap_buffers(intel, GL_TRUE);
#endif
}
/**
@ -240,9 +297,11 @@ void intelSpanRenderFinish( GLcontext *ctx )
/* Now unmap the framebuffer:
*/
#if 0
intel_region_unmap(intel, intel->front_region);
intel_region_unmap(intel, intel->back_region);
intel_region_unmap(intel, intel->depth_region);
#endif
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled) {
@ -251,6 +310,11 @@ void intelSpanRenderFinish( GLcontext *ctx )
}
}
#if 1
/* XXX FBO: enable this code when old DRI screen mappings go away */
intel_map_unmap_buffers(intel, GL_FALSE);
#endif
UNLOCK_HARDWARE( intel );
}
@ -276,10 +340,11 @@ intel_set_span_functions(struct gl_renderbuffer *rb)
else if (rb->InternalFormat == GL_DEPTH_COMPONENT16) {
intelInitDepthPointers_z16(rb);
}
else if (rb->InternalFormat == GL_DEPTH_COMPONENT24) {
else if (rb->InternalFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */
rb->InternalFormat == GL_DEPTH24_STENCIL8_EXT) {
intelInitDepthPointers_z24_s8(rb);
}
else if (rb->InternalFormat == GL_STENCIL_INDEX8_EXT) {
else if (rb->InternalFormat == GL_STENCIL_INDEX8_EXT) { /* XXX FBO remove */
intelInitStencilPointers_z24_s8(rb);
}
else {

View file

@ -28,8 +28,6 @@
#ifndef _INTEL_SPAN_H
#define _INTEL_SPAN_H
#include "drirenderbuffer.h"
extern void intelInitSpanFuncs( GLcontext *ctx );
extern void intelSpanRenderFinish( GLcontext *ctx );