Compare commits

..

11 Commits

Author SHA1 Message Date
Keith Whitwell
b3b325e560 get 3d textures working again 2006-02-23 11:47:36 +00:00
Keith Whitwell
382ce985ac Fix cubemap layout 2006-02-22 19:54:32 +00:00
Keith Whitwell
54b7eca7a0 Append an MI_FLUSH to each batchbuffer for synchronization. Not really
ideal from a performance viewpoint and there are mechanisms to avoid this
in future.
2006-02-22 19:26:37 +00:00
Keith Whitwell
f74e06bf11 restore swapbuffers throttling 2006-02-22 17:18:19 +00:00
Keith Whitwell
9c02649d18 Introduce fixup/relocation lists for dma buffers. 2006-02-22 15:16:01 +00:00
Keith Whitwell
2c34704e41 tweaks 2006-02-13 00:41:33 +00:00
Keith Whitwell
85d0041ff0 rename texdown to reflect behaviour changes 2006-02-13 00:40:33 +00:00
Keith Whitwell
67ff8b354e bump driver date, etc 2006-02-13 00:39:20 +00:00
Keith Whitwell
08e7957571 Fix inverted image in copytexsubimage by tickling the hardware to
do the inversion in the blitter.
2006-02-13 00:38:46 +00:00
Keith Whitwell
9c1f7089d8 Some functions had been indented by one space?! 2006-02-11 04:28:13 +00:00
Keith Whitwell
5381ac5f11 move blit functions to new file 2006-02-11 02:54:09 +00:00
58 changed files with 3387 additions and 3277 deletions

View File

@@ -52,7 +52,7 @@ PROGS = \
terrain \
tessdemo \
texcyl \
texdown \
texdown-pool \
texenv \
texobj \
trispd \

View File

@@ -77,15 +77,15 @@ DoCopyTex(GLboolean doSubRect)
int w = TexWidth / 2, h = TexHeight / 2;
int x0 = 0, y0 = 0;
int x1 = w, y1 = h;
#if 1
#if 0
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, x0, y0, w, h);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, x1, y0, w, h);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, x0, y1, w, h);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, x1, y1, w, h);
#else
/* scramble */
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, x1, y1, w, h);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, x0, y1, w, h);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, x1, y1, w, h);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, x0, y1, w, h);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, x1, y0, w, h);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, x0, y0, w, h);
#endif
@@ -110,26 +110,31 @@ SubTex(GLboolean doSubRect, const GLubyte *image)
int x1 = w, y1 = h;
glPixelStorei(GL_UNPACK_ROW_LENGTH, TexWidth);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei( GL_PACK_INVERT_MESA, GL_TRUE );
glPixelStorei(GL_UNPACK_SKIP_ROWS, y0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, y0); */
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0); */
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, w, h,
ReadFormat, GL_UNSIGNED_BYTE, image);
glPixelStorei(GL_UNPACK_SKIP_ROWS, y0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1);
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, y0); */
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1); */
glTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, w, h,
ReadFormat, GL_UNSIGNED_BYTE, image);
glPixelStorei(GL_UNPACK_SKIP_ROWS, y1);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0);
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, y1); */
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0); */
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, w, h,
ReadFormat, GL_UNSIGNED_BYTE, image);
glPixelStorei(GL_UNPACK_SKIP_ROWS, y1);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1);
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, y1); */
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1); */
glTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, w, h,
ReadFormat, GL_UNSIGNED_BYTE, image);
glPixelStorei( GL_PACK_INVERT_MESA, GL_FALSE );
}
else {
/* all at once */
@@ -173,6 +178,9 @@ RunTest(GLboolean copyTex, GLboolean doSubRect)
t0 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
if (!DrawQuad)
glDrawBuffer(GL_FRONT);
do {
if (copyTex)
/* Framebuffer -> Texture */
@@ -194,16 +202,36 @@ RunTest(GLboolean copyTex, GLboolean doSubRect)
glTexCoord2f(0, 1); glVertex2f(-1, 1);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
else {
/* Draw something tiny to ensure that the texture is really
* uploaded:
*/
glPushMatrix();
glRotatef(rot, 0, 0, 1);
glTranslatef(1, 0, 0);
glBegin(GL_POLYGON);
glTexCoord2f(0, 0); glVertex2f(-.01, -.01);
glTexCoord2f(.01, 0); glVertex2f( .01, -.01);
glTexCoord2f(.01, .01); glVertex2f( .01, .01);
glTexCoord2f(0, .01); glVertex2f(-.01, .01);
glEnd();
glPopMatrix();
glFlush();
}
iters++;
rot += 2.0;
t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
if (DrawQuad) {
glutSwapBuffers();
}
} while (t1 - t0 < 5.0);
} while (t1 - t0 < 2.0);
/* Make sure everything is done before taking the final timing:
*/
glFinish();
t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
glDisable(GL_TEXTURE_2D);
if (image)
@@ -242,17 +270,15 @@ Draw(void)
glutSwapBuffers();
}
/* RunTest(GL_FALSE, GL_FALSE); */
/* RunTest(GL_FALSE, GL_TRUE); */
while (1) {
RunTest(GL_TRUE, GL_FALSE);
RunTest(GL_TRUE, GL_TRUE);
RunTest(GL_FALSE, GL_FALSE);
RunTest(GL_FALSE, GL_TRUE);
RunTest(GL_TRUE, GL_FALSE);
RunTest(GL_TRUE, GL_TRUE);
glutSwapBuffers();
}
glutSwapBuffers();
printf("exiting\n");
exit(0);
/* printf("exiting\n"); */
/* exit(0); */
}

View File

@@ -7,6 +7,7 @@ LIBNAME = i915_dri.so
DRIVER_SOURCES = \
bufmgr_fake.c \
intel_regions.c \
intel_batchbuffer.c \
intel_mipmap_tree.c \
i915_tex_layout.c \
intel_tex_image.c \
@@ -15,6 +16,12 @@ DRIVER_SOURCES = \
intel_tex_validate.c \
intel_tex_format.c \
intel_tex.c \
intel_pixel.c \
intel_pixel_copy.c \
intel_pixel_read.c \
intel_pixel_draw.c \
intel_buffers.c \
intel_blit.c \
i915_tex.c \
i915_texstate.c \
i915_context.c \
@@ -25,10 +32,8 @@ DRIVER_SOURCES = \
i915_state.c \
i915_texprog.c \
i915_vtbl.c \
intel_batchbuffer.c \
intel_context.c \
intel_ioctl.c \
intel_pixel.c \
intel_screen.c \
intel_span.c \
intel_state.c \

View File

@@ -10,9 +10,23 @@
/* The buffer manager context. Opaque.
*/
struct bufmgr;
struct bm_buffer_list;
struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel );
#define BM_LIST_MAX 32
/* List of buffers to validate. Probably better managed by the client:
*/
struct bm_buffer_list {
struct {
unsigned buffer;
unsigned *offset_return;
unsigned *memtype_return;
} elem[BM_LIST_MAX];
unsigned nr;
};
struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel );
/* struct bufmgr *bmCreate( ... ); */
/* struct bufmgr *bmAttach( ... ); */
@@ -58,7 +72,8 @@ int bmInitPool( struct bufmgr *,
#define BM_NO_EVICT 0x40
#define BM_NO_MOVE 0x80 /* not yet used */
#define BM_NO_ALLOC 0x100 /* legacy "fixed" buffers only */
#define BM_CLIENT 0x200 /* for map - pointer will be accessed
* without dri lock */
#define BM_MEM_MASK (BM_MEM_LOCAL|BM_MEM_AGP|BM_MEM_VRAM)

View File

@@ -21,9 +21,6 @@ struct _mesa_HashTable;
static int delayed_free( struct bufmgr *bm );
/* Maximum number of buffers to pass to bmValidateBufferList:
*/
#define BM_LIST_MAX 32
#define BM_POOL_MAX 8
@@ -72,17 +69,6 @@ struct bufmgr {
};
/* List of buffers to validate:
*/
struct bm_buffer_list {
struct {
unsigned buffer;
unsigned *offset_return;
unsigned *memtype_return;
} elem[BM_LIST_MAX];
unsigned nr;
};
@@ -145,20 +131,22 @@ static struct block *alloc_block( struct bufmgr *bm,
{
GLuint i;
for (i = 0; i < bm->nr_pools; i++) {
struct block *block;
if (bm->pool[i].flags & BM_NO_ALLOC)
continue;
if ((bm->pool[i].flags & flags & BM_MEM_MASK) == 0)
continue;
block = alloc_from_pool(bm, i, size, align);
if (block)
return block;
if (!(flags & BM_CLIENT)) {
for (i = 0; i < bm->nr_pools; i++) {
struct block *block;
if (bm->pool[i].flags & BM_NO_ALLOC)
continue;
if ((bm->pool[i].flags & flags & BM_MEM_MASK) == 0)
continue;
block = alloc_from_pool(bm, i, size, align);
if (block)
return block;
}
}
if (flags & BM_MEM_LOCAL)
return alloc_local(size);
@@ -166,14 +154,15 @@ static struct block *alloc_block( struct bufmgr *bm,
}
static int bmAllocMem( struct bufmgr *bm,
struct buffer *buf )
struct buffer *buf,
GLuint flags )
{
delayed_free(bm);
buf->block = alloc_block(bm,
buf->size,
buf->alignment,
buf->flags);
buf->flags | flags);
if (buf->block)
buf->block->buf = buf;
@@ -191,30 +180,43 @@ static int bmAllocMem( struct bufmgr *bm,
*/
static void free_block( struct bufmgr *bm, struct block *block )
{
DBG("free block %p\n", block);
if (!block)
return;
remove_from_list(block);
DBG("free block (mem: %d, sz %d) from buf %d\n",
block->mem_type,
block->buf->size,
block->buf->id);
switch (block->mem_type) {
case BM_MEM_AGP:
case BM_MEM_VRAM:
remove_from_list(block);
DBG(" - offset %x\n", block->mem->ofs);
if (bmTestFence(bm, block->fence)) {
DBG(" - free immediately\n");
mmFreeMem(block->mem);
free(block);
}
else {
DBG(" - place on delayed_free list\n");
block->buf = NULL;
insert_at_tail(&block->pool->freed, block);
}
break;
case BM_MEM_LOCAL:
DBG(" - free local memory\n");
ALIGN_FREE(block->virtual);
free(block);
break;
default:
DBG(" - unknown memory type\n");
free(block);
break;
}
@@ -259,8 +261,8 @@ static int move_buffers( struct bufmgr *bm,
*/
for (i = 0; i < nr; i++) {
if (!buffers[i]->block) {
/* if (flags & BM_NO_ALLOC) */
/* goto cleanup; */
if (flags & BM_NO_ALLOC)
goto cleanup;
newMem[i] = alloc_block(bm,
buffers[i]->size,
@@ -276,8 +278,8 @@ static int move_buffers( struct bufmgr *bm,
goto cleanup;
/* Known issue: this assert will get hit on texture swapping.
* There's not much to do about that at this stage - it's
* tbd.
* There's not much to do about that at this stage - it's a
* todo item.
*/
assert(!buffers[i]->mapped);
@@ -304,7 +306,7 @@ static int move_buffers( struct bufmgr *bm,
* mechanisms in final version. Memcpy (or sse_memcpy) is
* probably pretty good for local->agp uploads.
*/
_mesa_printf("* %d\n", buffers[i]->size);
DBG("memcpy %d bytes\n", buffers[i]->size);
memcpy(newMem[i]->virtual,
buffers[i]->block->virtual,
buffers[i]->size);
@@ -535,25 +537,9 @@ unsigned bmBufferStatic(struct bufmgr *bm,
}
#if 0
/* How wise/useful is this?
*/
void bmBufferSetParams( struct bufmgr *bm,
unsigned buffer,
unsigned flags,
unsigned alignment )
{
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
assert(!buf->block);
buf->flags = flags;
buf->alignment = alignment;
}
#endif
/* If buffer size changes, create new buffer in local memory.
* Otherwise update in place.
/* If buffer size changes, free and reallocate. Otherwise update in
* place.
*/
void bmBufferData(struct bufmgr *bm,
unsigned buffer,
@@ -579,7 +565,7 @@ void bmBufferData(struct bufmgr *bm,
buf->size = size;
if (data != NULL) {
bmAllocMem(bm, buf);
bmAllocMem(bm, buf, buf->flags | flags);
memcpy(buf->block->virtual, data, size);
}
}
@@ -597,7 +583,7 @@ void bmBufferSubData(struct bufmgr *bm,
DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buffer, offset, size);
if (buf->block == 0)
bmAllocMem(bm, buf);
bmAllocMem(bm, buf, buf->flags);
if (buf->block->mem_type != BM_MEM_LOCAL)
bmFinishFence(bm, buf->block->fence);
@@ -611,7 +597,7 @@ void bmBufferSubData(struct bufmgr *bm,
*/
void *bmMapBuffer( struct bufmgr *bm,
unsigned buffer,
unsigned access )
unsigned flags )
{
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
@@ -620,10 +606,13 @@ void *bmMapBuffer( struct bufmgr *bm,
if (buf->mapped)
return NULL;
buf->mapped = 1;
if (buf->block == 0)
bmAllocMem(bm, buf, flags);
if (buf->block == 0)
bmAllocMem(bm, buf);
return NULL;
buf->mapped = 1;
/* Finish any outstanding operations to/from this memory:
*/
@@ -728,6 +717,7 @@ int bmValidateBufferList( struct bufmgr *bm,
if (!delayed_free(bm) &&
!evict_lru(bm, flags))
return 0;
_mesa_printf("couldn't allocate sufficient texture memory\n");
exit(1);
}
@@ -736,6 +726,8 @@ int bmValidateBufferList( struct bufmgr *bm,
DBG("%d: buf %d ofs 0x%x\n",
i, bufs[i]->id, bufs[i]->block->mem->ofs);
assert(!bufs[i]->mapped);
if (list->elem[i].offset_return)
list->elem[i].offset_return[0] = bufs[i]->block->mem->ofs;
@@ -788,7 +780,6 @@ unsigned bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list )
*/
unsigned bmSetFence( struct bufmgr *bm )
{
assert(bm->intel->batch.space == bm->intel->batch.size);
assert(bm->intel->locked);
return intelEmitIrqLocked( bm->intel );

View File

@@ -59,7 +59,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis,
{
struct dd_function_table functions;
i830ContextPtr i830 = (i830ContextPtr) CALLOC_STRUCT(i830_context);
intelContextPtr intel = &i830->intel;
struct intel_context *intel = &i830->intel;
GLcontext *ctx = &intel->ctx;
if (!i830) return GL_FALSE;

View File

@@ -48,10 +48,8 @@
*/
#define I830_DESTREG_CBUFADDR0 0
#define I830_DESTREG_CBUFADDR1 1
#define I830_DESTREG_CBUFADDR2 2
#define I830_DESTREG_DBUFADDR0 3
#define I830_DESTREG_DBUFADDR1 4
#define I830_DESTREG_DBUFADDR2 5
#define I830_DESTREG_DV0 6
#define I830_DESTREG_DV1 7
#define I830_DESTREG_SENABLE 8
@@ -160,7 +158,7 @@ i830CreateContext( const __GLcontextModes *mesaVis,
/* i830_tex.c, i830_texstate.c
*/
extern void
i830UpdateTextureState( intelContextPtr intel );
i830UpdateTextureState( struct intel_context *intel );
extern void
i830InitTextureFuncs( struct dd_function_table *functions );
@@ -206,7 +204,7 @@ i830TryTextureDrawPixels( GLcontext *ctx,
const GLvoid *pixels );
extern void
i830ClearWithTris( intelContextPtr intel, GLbitfield mask,
i830ClearWithTris( struct intel_context *intel, GLbitfield mask,
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);

View File

@@ -58,7 +58,7 @@ do { \
* current GL state and used for other purposes than simply rendering
* incoming triangles.
*/
static void set_initial_state( i830ContextPtr i830 )
static void set_initial_state( struct intel_context *intel )
{
memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) );
i830->meta.active = ACTIVE;
@@ -66,7 +66,7 @@ static void set_initial_state( i830ContextPtr i830 )
}
static void set_no_depth_stencil_write( i830ContextPtr i830 )
static void set_no_depth_stencil_write( struct intel_context *intel )
{
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
*/
@@ -88,7 +88,7 @@ static void set_no_depth_stencil_write( i830ContextPtr i830 )
/* Set stencil unit to replace always with the reference value.
*/
static void set_stencil_replace( i830ContextPtr i830,
static void set_stencil_replace( struct intel_context *intel,
GLuint s_mask,
GLuint s_clear)
{
@@ -140,7 +140,7 @@ static void set_stencil_replace( i830ContextPtr i830,
}
static void set_color_mask( i830ContextPtr i830, GLboolean state )
static void set_color_mask( struct intel_context *intel, GLboolean state )
{
const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) |
(1 << WRITEMASK_GREEN_SHIFT) |
@@ -161,7 +161,7 @@ static void set_color_mask( i830ContextPtr i830, GLboolean state )
/* Installs a one-stage passthrough texture blend pipeline. Is there
* more that can be done to turn off texturing?
*/
static void set_no_texture( i830ContextPtr i830 )
static void set_no_texture( struct intel_context *intel )
{
static const struct gl_tex_env_combine_state comb = {
GL_NONE, GL_NONE,
@@ -181,7 +181,7 @@ static void set_no_texture( i830ContextPtr i830 )
/* Set up a single element blend stage for 'replace' texturing with no
* funny ops.
*/
static void enable_texture_blend_replace( i830ContextPtr i830,
static void enable_texture_blend_replace( struct intel_context *intel,
GLenum format )
{
static const struct gl_tex_env_combine_state comb = {
@@ -207,7 +207,7 @@ static void enable_texture_blend_replace( i830ContextPtr i830,
/* Set up an arbitary piece of memory as a rectangular texture
* (including the front or back buffer).
*/
static void set_tex_rect_source( i830ContextPtr i830,
static void set_tex_rect_source( struct intel_context *intel,
GLuint offset,
GLuint width,
GLuint height,
@@ -249,17 +249,17 @@ static void set_tex_rect_source( i830ContextPtr i830,
/* Select between front and back draw buffers.
*/
static void set_draw_offset( i830ContextPtr i830,
static void set_draw_offset( struct intel_context *intel,
GLuint offset )
{
i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset;
/* i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset; */
i830->meta.emitted &= ~I830_UPLOAD_BUFFERS;
}
/* Setup an arbitary draw format, useful for targeting
* texture or agp memory.
*/
static void set_draw_format( i830ContextPtr i830,
static void set_draw_format( struct intel_context *intel,
GLuint format,
GLuint depth_format)
{
@@ -271,7 +271,7 @@ static void set_draw_format( i830ContextPtr i830,
}
static void set_vertex_format( i830ContextPtr i830 )
static void set_vertex_format( struct intel_context *intel )
{
i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD |
VFT0_TEX_COUNT(1) |
@@ -287,448 +287,6 @@ static void set_vertex_format( i830ContextPtr i830 )
}
static void draw_quad(i830ContextPtr i830,
GLfloat x0, GLfloat x1,
GLfloat y0, GLfloat y1,
GLubyte red, GLubyte green,
GLubyte blue, GLubyte alpha,
GLfloat s0, GLfloat s1,
GLfloat t0, GLfloat t1 )
{
#if 0
GLuint vertex_size = 8;
GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel,
PRIM3D_TRIFAN,
4*vertex_size,
vertex_size );
intelVertex tmp;
int i;
/* fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", */
/* __FUNCTION__, */
/* x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); */
/* initial vertex, left bottom */
tmp.v.x = x0;
tmp.v.y = y0;
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 = s0;
tmp.v.v0 = t0;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
/* right bottom */
vb += 8;
tmp.v.x = x1;
tmp.v.u0 = s1;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
/* right top */
vb += 8;
tmp.v.y = y1;
tmp.v.v0 = t1;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
/* left top */
vb += 8;
tmp.v.x = x0;
tmp.v.u0 = s0;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
/* fprintf(stderr, "%s: DV1: %x\n", */
/* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */
#endif
}
void
i830ClearWithTris(intelContextPtr intel, GLbitfield mask,
GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch)
{
i830ContextPtr i830 = I830_CONTEXT( intel );
__DRIdrawablePrivate *dPriv = intel->driDrawable;
intelScreenPrivate *screen = intel->intelScreen;
int x0, y0, x1, y1;
SET_STATE( i830, meta );
set_initial_state( i830 );
set_no_texture( i830 );
set_vertex_format( i830 );
LOCK_HARDWARE(intel);
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;
}
/* Don't do any clipping to screen - these are window coordinates.
* The active cliprects will be applied as for any other geometry.
*/
if(mask & BUFFER_BIT_FRONT_LEFT) {
set_no_depth_stencil_write( i830 );
set_color_mask( i830, GL_TRUE );
set_draw_offset( i830, screen->front.offset );
draw_quad(i830, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
if(mask & BUFFER_BIT_BACK_LEFT) {
set_no_depth_stencil_write( i830 );
set_color_mask( i830, GL_TRUE );
set_draw_offset( i830, screen->back.offset );
draw_quad(i830, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
if(mask & BUFFER_BIT_STENCIL) {
set_stencil_replace( i830,
intel->ctx.Stencil.WriteMask[0],
intel->ctx.Stencil.Clear);
set_color_mask( i830, GL_FALSE );
set_draw_offset( i830, screen->front.offset );
draw_quad( i830, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
}
UNLOCK_HARDWARE(intel);
SET_STATE( i830, state );
}
GLboolean
i830TryTextureReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
intelContextPtr intel = INTEL_CONTEXT(ctx);
intelScreenPrivate *screen = i830->intel.intelScreen;
GLint pitch = pack->RowLength ? pack->RowLength : width;
__DRIdrawablePrivate *dPriv = i830->intel.driDrawable;
int textureFormat;
GLenum glTextureFormat;
int src_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
int destOffset = 0;
int destFormat, depthFormat, destPitch;
drm_clip_rect_t tmp;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if ( ctx->_ImageTransferState ||
pack->SwapBytes ||
pack->LsbFirst ||
!pack->Invert) {
fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
return GL_FALSE;
}
switch (screen->fbFormat) {
case DV_PF_565:
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
glTextureFormat = GL_RGB;
break;
case DV_PF_555:
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
glTextureFormat = GL_RGBA;
break;
case DV_PF_8888:
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
glTextureFormat = GL_RGBA;
break;
default:
fprintf(stderr, "%s: textureFormat failed %x\n", __FUNCTION__,
screen->fbFormat);
return GL_FALSE;
}
switch (type) {
case GL_UNSIGNED_SHORT_5_6_5:
if (format != GL_RGB) return GL_FALSE;
destFormat = COLR_BUF_RGB565;
depthFormat = DEPTH_FRMT_16_FIXED;
destPitch = pitch * 2;
break;
case GL_UNSIGNED_INT_8_8_8_8_REV:
if (format != GL_BGRA) return GL_FALSE;
destFormat = COLR_BUF_ARGB8888;
depthFormat = DEPTH_FRMT_24_FIXED_8_OTHER;
destPitch = pitch * 4;
break;
default:
fprintf(stderr, "%s: destFormat failed %s\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(type));
return GL_FALSE;
}
destFormat |= (0x02<<24);
/* fprintf(stderr, "type: %s destFormat: %x\n", */
/* _mesa_lookup_enum_by_nr(type), */
/* destFormat); */
intelFlush( ctx );
SET_STATE( i830, meta );
set_initial_state( i830 );
set_no_depth_stencil_write( i830 );
LOCK_HARDWARE( intel );
{
intelWaitForIdle( intel ); /* required by GL */
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
SET_STATE(i830, state);
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
return GL_TRUE;
}
#if 0
/* FIXME -- Just emit the correct state
*/
if (i830SetParam(i830->driFd, I830_SETPARAM_CBUFFER_PITCH,
destPitch) != 0) {
UNLOCK_HARDWARE( intel );
SET_STATE(i830, state);
fprintf(stderr, "%s: setparam failed\n", __FUNCTION__);
return GL_FALSE;
}
#endif
y = dPriv->h - y - height;
x += dPriv->x;
y += dPriv->y;
/* Set the frontbuffer up as a large rectangular texture.
*/
set_tex_rect_source( i830,
src_offset,
screen->width,
screen->height,
screen->front.pitch,
textureFormat );
enable_texture_blend_replace( i830, glTextureFormat );
/* Set the 3d engine to draw into the agp memory
*/
set_draw_offset( i830, destOffset );
set_draw_format( i830, destFormat, depthFormat );
/* Draw a single quad, no cliprects:
*/
i830->intel.numClipRects = 1;
i830->intel.pClipRects = &tmp;
i830->intel.pClipRects[0].x1 = 0;
i830->intel.pClipRects[0].y1 = 0;
i830->intel.pClipRects[0].x2 = width;
i830->intel.pClipRects[0].y2 = height;
draw_quad( i830,
0, width, 0, height,
0, 255, 0, 0,
x, x+width, y, y+height );
intelWindowMoved( intel );
}
UNLOCK_HARDWARE( intel );
intelFinish( ctx ); /* required by GL */
SET_STATE( i830, state );
return GL_TRUE;
}
GLboolean
i830TryTextureDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
i830ContextPtr i830 = I830_CONTEXT(ctx);
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int textureFormat;
GLenum glTextureFormat;
int dst_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
int src_offset = 0;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
/* Todo -- upload images that aren't in agp space, then texture
* from them.
*/
if ( !intelIsAgpMemory( intel, pixels, pitch*height ) ) {
fprintf(stderr, "%s: intelIsAgpMemory failed\n", __FUNCTION__);
return GL_FALSE;
}
/* Todo -- don't want to clobber all the drawing state like we do
* for readpixels -- most of this state can be handled just fine.
*/
if ( ctx->_ImageTransferState ||
unpack->SwapBytes ||
unpack->LsbFirst ||
ctx->Color.AlphaEnabled ||
ctx->Depth.Test ||
ctx->Fog.Enabled ||
ctx->Scissor.Enabled ||
ctx->Stencil.Enabled ||
!ctx->Color.ColorMask[0] ||
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||
!ctx->Color.ColorMask[3] ||
ctx->Color.ColorLogicOpEnabled ||
ctx->Texture._EnabledUnits) {
fprintf(stderr, "%s: other tests failed\n", __FUNCTION__);
return GL_FALSE;
}
/* Todo -- remove these restrictions:
*/
if (ctx->Pixel.ZoomX != 1.0F ||
ctx->Pixel.ZoomY != -1.0F)
return GL_FALSE;
switch (type) {
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
if (format != GL_BGRA) return GL_FALSE;
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
glTextureFormat = GL_RGBA;
break;
case GL_UNSIGNED_SHORT_5_6_5:
if (format != GL_RGB) return GL_FALSE;
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
glTextureFormat = GL_RGB;
break;
case GL_UNSIGNED_SHORT_8_8_MESA:
if (format != GL_YCBCR_MESA) return GL_FALSE;
textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY
/* | TM0S1_COLORSPACE_CONVERSION */
);
glTextureFormat = GL_YCBCR_MESA;
break;
case GL_UNSIGNED_SHORT_8_8_REV_MESA:
if (format != GL_YCBCR_MESA) return GL_FALSE;
textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL
/* | TM0S1_COLORSPACE_CONVERSION */
);
glTextureFormat = GL_YCBCR_MESA;
break;
case GL_UNSIGNED_INT_8_8_8_8_REV:
if (format != GL_BGRA) return GL_FALSE;
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
glTextureFormat = GL_RGBA;
break;
default:
fprintf(stderr, "%s: destFormat failed\n", __FUNCTION__);
return GL_FALSE;
}
intelFlush( ctx );
SET_STATE( i830, meta );
LOCK_HARDWARE( intel );
{
intelWaitForIdle( intel ); /* required by GL */
y -= height; /* cope with pixel zoom */
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
SET_STATE(i830, state);
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
return GL_TRUE;
}
y = dPriv->h - y - height;
set_initial_state( i830 );
/* Set the pixel image up as a rectangular texture.
*/
set_tex_rect_source( i830,
src_offset,
width,
height,
pitch, /* XXXX!!!! -- /2 sometimes */
textureFormat );
enable_texture_blend_replace( i830, glTextureFormat );
/* Draw to the current draw buffer:
*/
set_draw_offset( i830, dst_offset );
/* Draw a quad, use regular cliprects
*/
/* fprintf(stderr, "x: %d y: %d width %d height %d\n", x, y, width, height); */
draw_quad( i830,
x, x+width, y, y+height,
0, 255, 0, 0,
0, width, 0, height );
intelWindowMoved( intel );
}
UNLOCK_HARDWARE( intel );
intelFinish( ctx ); /* required by GL */
SET_STATE(i830, state);
return GL_TRUE;
}

View File

@@ -407,10 +407,10 @@
#define LOGICOP_SET 0xf
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
#define ENABLE_STENCIL_TEST_MASK (1<<17)
#define STENCIL_TEST_MASK(x) ((x)<<8)
#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8)
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
#define ENABLE_STENCIL_WRITE_MASK (1<<16)
#define STENCIL_WRITE_MASK(x) (x)
#define STENCIL_WRITE_MASK(x) ((x)&0xff)
/* _3DSTATE_MODES_5, p196 */
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))

View File

@@ -1012,13 +1012,12 @@ static void i830_init_packets( i830ContextPtr i830 )
(BUF_3D_ID_DEPTH |
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
BUF_3D_USE_FENCE);
i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset;
/* i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset; */
i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
switch (screen->fbFormat) {
case DV_PF_555:
case DV_PF_565:
i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | /* .5 */

View File

@@ -101,7 +101,7 @@ static GLuint emit_factor( GLuint blendUnit, GLuint *state, GLuint count,
}
static __inline__ GLuint GetTexelOp(GLint unit)
static inline GLuint GetTexelOp(GLint unit)
{
switch(unit) {
case 0: return TEXBLENDARG_TEXEL0;

View File

@@ -428,7 +428,7 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit )
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
if (texUnit->_ReallyEnabled &&
INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024)
intel_context(ctx)->intelScreen->tex.size < 2048 * 1024)
return GL_FALSE;
switch(texUnit->_ReallyEnabled) {
@@ -450,7 +450,7 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit )
}
void i830UpdateTextureState( intelContextPtr intel )
void i830UpdateTextureState( struct intel_context *intel )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
GLcontext *ctx = &intel->ctx;

View File

@@ -34,7 +34,7 @@
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
static GLboolean i830_check_vertex_size( intelContextPtr intel,
static GLboolean i830_check_vertex_size( struct intel_context *intel,
GLuint expected );
#define SZ_TO_HW(sz) ((sz-2)&0x3)
@@ -59,7 +59,7 @@ do { \
#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2))
#define TEXBIND_SET(n, x) ((x)<<((n)*4))
static void i830_render_start( intelContextPtr intel )
static void i830_render_start( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
i830ContextPtr i830 = I830_CONTEXT(intel);
@@ -186,7 +186,7 @@ static void i830_render_start( intelContextPtr intel )
}
}
static void i830_reduced_primitive_state( intelContextPtr intel,
static void i830_reduced_primitive_state( struct intel_context *intel,
GLenum rprim )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
@@ -217,7 +217,7 @@ static void i830_reduced_primitive_state( intelContextPtr intel,
/* Pull apart the vertex format registers and figure out how large a
* vertex is supposed to be.
*/
static GLboolean i830_check_vertex_size( intelContextPtr intel,
static GLboolean i830_check_vertex_size( struct intel_context *intel,
GLuint expected )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
@@ -257,11 +257,11 @@ static GLboolean i830_check_vertex_size( intelContextPtr intel,
return sz == expected;
}
static void i830_emit_invarient_state( intelContextPtr intel )
static void i830_emit_invarient_state( struct intel_context *intel )
{
BATCH_LOCALS;
BEGIN_BATCH( 200 );
BEGIN_BATCH(200, 0);
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
@@ -355,7 +355,7 @@ static void i830_emit_invarient_state( intelContextPtr intel )
#define emit( intel, state, size ) \
do { \
int k; \
BEGIN_BATCH( size / sizeof(GLuint)); \
BEGIN_BATCH(size / sizeof(GLuint), 0); \
for (k = 0 ; k < size / sizeof(GLuint) ; k++) \
OUT_BATCH(state[k]); \
ADVANCE_BATCH(); \
@@ -364,7 +364,7 @@ do { \
/* Push the state into the sarea and/or texture memory.
*/
static void i830_emit_state( intelContextPtr intel )
static void i830_emit_state( struct intel_context *intel )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
struct i830_hw_state *state = i830->current;
@@ -405,32 +405,32 @@ static void i830_emit_state( intelContextPtr intel )
state->emitted |= dirty;
}
static void i830_destroy_context( intelContextPtr intel )
static void i830_destroy_context( struct intel_context *intel )
{
_tnl_free_vertices(&intel->ctx);
}
static void i830_set_draw_offset( intelContextPtr intel, int offset )
static void i830_set_draw_offset( struct intel_context *intel, int offset )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS );
i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset;
/* i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset; */
}
/* This isn't really handled at the moment.
*/
static void i830_lost_hardware( intelContextPtr intel )
static void i830_lost_hardware( struct intel_context *intel )
{
I830_CONTEXT(intel)->state.emitted = 0;
}
static void i830_emit_flush( intelContextPtr intel )
static void i830_emit_flush( struct intel_context *intel )
{
BATCH_LOCALS;
BEGIN_BATCH(2);
BEGIN_BATCH(2, 0);
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE );
OUT_BATCH( 0 );
ADVANCE_BATCH();

View File

@@ -69,7 +69,7 @@ static void i915InvalidateState( GLcontext *ctx, GLuint new_state )
_ac_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_tnl_invalidate_vertex_state( ctx, new_state );
INTEL_CONTEXT(ctx)->NewGLState |= new_state;
intel_context(ctx)->NewGLState |= new_state;
/* Todo: gather state values under which tracked parameters become
* invalidated, add callbacks for things like
@@ -103,16 +103,16 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
void *sharedContextPrivate)
{
struct dd_function_table functions;
i915ContextPtr i915 = (i915ContextPtr) CALLOC_STRUCT(i915_context);
intelContextPtr intel = &i915->intel;
intelScreenPrivate *intelScreen;
struct i915_context *i915 = (struct i915_context *) CALLOC_STRUCT(i915_context);
struct intel_context *intel = &i915->intel;
GLcontext *ctx = &intel->ctx;
if (!i915) return GL_FALSE;
_mesa_printf( "\ntexmem branch (i915)\n\n");
_mesa_printf( "\ntexmem branch (i915, drop2)\n\n");
i915InitVtbl( i915 );
i915InitMetaFuncs( i915 );
i915InitDriverFunctions( &functions );
@@ -126,49 +126,6 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS;
intel->bm = bm_fake_intel_Attach( intel );
bmInitPool(intel->bm,
intel->intelScreen->tex.offset, /* low offset */
intel->intelScreen->tex.map, /* low virtual */
intel->intelScreen->tex.size,
BM_MEM_AGP);
intelScreen = intel->intelScreen;
/* These are still static, but create regions for them.
*/
intel->front_region =
intel_region_create_static(intel,
BM_MEM_AGP,
intelScreen->front.offset,
intelScreen->front.map,
intelScreen->cpp,
intelScreen->front.pitch,
intelScreen->height);
intel->back_region =
intel_region_create_static(intel,
BM_MEM_AGP,
intelScreen->back.offset,
intelScreen->back.map,
intelScreen->cpp,
intelScreen->back.pitch,
intelScreen->height);
/* Still assuming front.cpp == depth.cpp
*/
intel->depth_region =
intel_region_create_static(intel,
BM_MEM_AGP,
intelScreen->depth.offset,
intelScreen->depth.map,
intelScreen->cpp,
intelScreen->depth.pitch,
intelScreen->height);
intelInitBatchBuffer(intel);
/* Advertise the full hardware capabilities. The new memory
* manager should cope much better with overload situations:

View File

@@ -53,10 +53,8 @@
*/
#define I915_DESTREG_CBUFADDR0 0
#define I915_DESTREG_CBUFADDR1 1
#define I915_DESTREG_CBUFADDR2 2
#define I915_DESTREG_DBUFADDR0 3
#define I915_DESTREG_DBUFADDR1 4
#define I915_DESTREG_DBUFADDR2 5
#define I915_DESTREG_DV0 6
#define I915_DESTREG_DV1 7
#define I915_DESTREG_SENABLE 8
@@ -87,7 +85,6 @@
#define I915_STPREG_ST1 1
#define I915_STP_SETUP_SIZE 2
#define I915_TEXREG_MS2 0
#define I915_TEXREG_MS3 1
#define I915_TEXREG_MS4 2
#define I915_TEXREG_SS2 3
@@ -198,6 +195,15 @@ struct i915_hw_state {
GLuint ConstantSize;
GLuint Program[I915_PROGRAM_SIZE];
GLuint ProgramSize;
/* Region pointers for relocation:
*/
struct intel_region *draw_region;
struct intel_region *depth_region;
struct intel_region *tex_region[I915_TEX_UNITS];
GLuint tex_offset[I915_TEX_UNITS];
GLuint active; /* I915_UPLOAD_* */
GLuint emitted; /* I915_UPLOAD_* */
};
@@ -222,20 +228,14 @@ struct i915_context
};
typedef struct i915_context *i915ContextPtr;
#define I915_STATECHANGE(i915, flag) \
do { \
if (0) fprintf(stderr, "I915_STATECHANGE %x in %s\n", flag, __FUNCTION__); \
INTEL_FIREVERTICES( &(i915)->intel ); \
(i915)->state.emitted &= ~(flag); \
} while (0)
#define I915_ACTIVESTATE(i915, flag, mode) \
do { \
if (0) fprintf(stderr, "I915_ACTIVESTATE %x %d in %s\n", \
flag, mode, __FUNCTION__); \
INTEL_FIREVERTICES( &(i915)->intel ); \
if (mode) \
(i915)->state.active |= (flag); \
@@ -247,7 +247,7 @@ do { \
/*======================================================================
* i915_vtbl.c
*/
extern void i915InitVtbl( i915ContextPtr i915 );
extern void i915InitVtbl( struct i915_context *i915 );
@@ -284,7 +284,7 @@ extern GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
/*======================================================================
* i915_texprog.c
*/
extern void i915ValidateTextureProgram( i915ContextPtr i915 );
extern void i915ValidateTextureProgram( struct i915_context *i915 );
/*======================================================================
@@ -298,42 +298,26 @@ extern void i915_print_ureg( const char *msg, GLuint ureg );
* i915_state.c
*/
extern void i915InitStateFunctions( struct dd_function_table *functions );
extern void i915InitState( i915ContextPtr i915 );
extern void i915InitState( struct i915_context *i915 );
extern void i915_update_fog( GLcontext *ctx );
/*======================================================================
* i915_tex.c
*/
extern void i915UpdateTextureState( intelContextPtr intel );
extern void i915UpdateTextureState( struct intel_context *intel );
extern void i915InitTextureFuncs( struct dd_function_table *functions );
/*======================================================================
* i915_metaops.c
*/
extern GLboolean
i915TryTextureReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels );
extern GLboolean
i915TryTextureDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels );
extern void
i915ClearWithTris( intelContextPtr intel, GLbitfield mask,
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
void i915InitMetaFuncs( struct i915_context *i915 );
/*======================================================================
* i915_fragprog.c
*/
extern void i915ValidateFragmentProgram( i915ContextPtr i915 );
extern void i915ValidateFragmentProgram( struct i915_context *i915 );
extern void i915InitFragProgFuncs( struct dd_function_table *functions );
/*======================================================================

View File

@@ -806,7 +806,7 @@ static void check_wpos( struct i915_fragment_program *p )
static void translate_program( struct i915_fragment_program *p )
{
i915ContextPtr i915 = I915_CONTEXT(p->ctx);
struct i915_context *i915 = I915_CONTEXT(p->ctx);
i915_init_program( i915, p );
check_wpos( p );
@@ -840,7 +840,7 @@ static void i915BindProgram( GLcontext *ctx,
struct program *prog )
{
if (target == GL_FRAGMENT_PROGRAM_ARB) {
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
struct i915_fragment_program *p = (struct i915_fragment_program *)prog;
if (i915->current_program == p)
@@ -896,7 +896,7 @@ static void i915DeleteProgram( GLcontext *ctx,
struct program *prog )
{
if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
struct i915_fragment_program *p = (struct i915_fragment_program *)prog;
if (i915->current_program == p)
@@ -940,10 +940,10 @@ static void i915ProgramStringNotify( GLcontext *ctx,
}
void i915ValidateFragmentProgram( i915ContextPtr i915 )
void i915ValidateFragmentProgram( struct i915_context *i915 )
{
GLcontext *ctx = &i915->intel.ctx;
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;

View File

@@ -34,39 +34,32 @@
#include "intel_screen.h"
#include "intel_batchbuffer.h"
#include "intel_ioctl.h"
#include "intel_regions.h"
#include "i915_context.h"
#include "i915_reg.h"
/* A large amount of state doesn't need to be uploaded.
*/
#define ACTIVE (I915_UPLOAD_PROGRAM | \
#define ACTIVE (I915_UPLOAD_INVARIENT | \
I915_UPLOAD_PROGRAM | \
I915_UPLOAD_STIPPLE | \
I915_UPLOAD_CTX | \
I915_UPLOAD_BUFFERS | \
I915_UPLOAD_TEX(0))
#define SET_STATE( i915, STATE ) \
#define SET_STATE( i915, STATE ) \
do { \
i915->current->emitted &= ~ACTIVE; \
i915->current = &i915->STATE; \
i915->current = &i915->STATE; \
i915->current->emitted &= ~ACTIVE; \
} while (0)
/* Operations where the 3D engine is decoupled temporarily from the
* current GL state and used for other purposes than simply rendering
* incoming triangles.
*/
static void set_initial_state( i915ContextPtr i915 )
{
memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) );
i915->meta.active = ACTIVE;
i915->meta.emitted = 0;
}
static void set_no_depth_stencil_write( i915ContextPtr i915 )
static void meta_no_depth_stencil_write( struct intel_context *intel )
{
struct i915_context *i915 = i915_context(&intel->ctx);
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
*/
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE |
@@ -82,10 +75,11 @@ static void set_no_depth_stencil_write( i915ContextPtr i915 )
/* Set stencil unit to replace always with the reference value.
*/
static void set_stencil_replace( i915ContextPtr i915,
static void meta_stencil_replace( struct intel_context *intel,
GLuint s_mask,
GLuint s_clear)
{
struct i915_context *i915 = i915_context(&intel->ctx);
GLuint op = STENCILOP_REPLACE;
GLuint func = COMPAREFUNC_ALWAYS;
@@ -100,7 +94,6 @@ static void set_stencil_replace( i915ContextPtr i915,
i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE |
S6_DEPTH_WRITE_ENABLE);
/* ctx->Driver.StencilMask( ctx, s_mask )
*/
i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
@@ -108,7 +101,6 @@ static void set_stencil_replace( i915ContextPtr i915,
i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
STENCIL_WRITE_MASK(s_mask));
/* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE )
*/
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |
@@ -137,8 +129,9 @@ static void set_stencil_replace( i915ContextPtr i915,
}
static void set_color_mask( i915ContextPtr i915, GLboolean state )
static void meta_color_mask( struct intel_context *intel, GLboolean state )
{
struct i915_context *i915 = i915_context(&intel->ctx);
const GLuint mask = (S5_WRITEDISABLE_RED |
S5_WRITEDISABLE_GREEN |
S5_WRITEDISABLE_BLUE |
@@ -210,8 +203,10 @@ static void set_color_mask( i915ContextPtr i915, GLboolean state )
static void set_no_texture( i915ContextPtr i915 )
static void meta_no_texture( struct intel_context *intel )
{
struct i915_context *i915 = i915_context(&intel->ctx);
static const GLuint prog[] = {
_3DSTATE_PIXEL_SHADER_PROGRAM,
@@ -240,9 +235,10 @@ static void set_no_texture( i915ContextPtr i915 )
i915->meta.emitted &= ~I915_UPLOAD_PROGRAM;
}
#if 0
static void enable_texture_blend_replace( i915ContextPtr i915 )
static void meta_texture_blend_replace( struct intel_context *intel )
{
struct i915_context *i915 = i915_context(&intel->ctx);
static const GLuint prog[] = {
_3DSTATE_PIXEL_SHADER_PROGRAM,
@@ -285,78 +281,86 @@ static void enable_texture_blend_replace( i915ContextPtr i915 )
/* Set up an arbitary piece of memory as a rectangular texture
* (including the front or back buffer).
*/
static void set_tex_rect_source( i915ContextPtr i915,
GLuint offset,
GLuint width,
GLuint height,
GLuint pitch,
static void meta_tex_rect_source( struct intel_context *intel,
struct intel_region *region,
GLuint textureFormat )
{
struct i915_context *i915 = i915_context(&intel->ctx);
GLuint unit = 0;
GLint numLevels = 1;
GLuint *state = i915->meta.Tex[0];
pitch *= i915->intel.intelScreen->cpp;
GLuint pitch = region->pitch * region->cpp;
/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
state[I915_TEXREG_MS2] = offset;
state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) |
((width - 1) << MS3_WIDTH_SHIFT) |
textureFormat |
MS3_USE_FENCE_REGS);
intel_region_release(intel, &i915->meta.tex_region[0]);
intel_region_reference(&i915->meta.tex_region[0], region);
i915->meta.tex_offset[0] = 0;
state[I915_TEXREG_MS3] = (((region->height - 1) << MS3_HEIGHT_SHIFT) |
((region->pitch - 1) << MS3_WIDTH_SHIFT) |
textureFormat |
MS3_USE_FENCE_REGS);
state[I915_TEXREG_MS4] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
MS4_CUBE_FACE_ENA_MASK |
((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT));
MS4_CUBE_FACE_ENA_MASK |
((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT));
state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) |
(MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) |
(FILTER_NEAREST << SS2_MAG_FILTER_SHIFT));
(MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) |
(FILTER_NEAREST << SS2_MAG_FILTER_SHIFT));
state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) |
(TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) |
(TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) |
(unit<<SS3_TEXTUREMAP_INDEX_SHIFT));
(TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) |
(TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) |
(unit<<SS3_TEXTUREMAP_INDEX_SHIFT));
state[I915_TEXREG_SS4] = 0;
i915->meta.emitted &= ~I915_UPLOAD_TEX(0);
}
#endif
/* Select between front and back draw buffers.
*/
static void set_draw_offset( i915ContextPtr i915,
GLuint offset )
static void meta_draw_region( struct intel_context *intel,
struct intel_region *draw_region,
struct intel_region *depth_region )
{
i915->meta.Buffer[I915_DESTREG_CBUFADDR2] = offset;
struct i915_context *i915 = i915_context(&intel->ctx);
intel_region_release(intel, &i915->meta.draw_region);
intel_region_release(intel, &i915->meta.depth_region);
intel_region_reference(&i915->meta.draw_region, draw_region);
intel_region_reference(&i915->meta.depth_region, depth_region);
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
}
#if 0
/* Setup an arbitary draw format, useful for targeting texture or agp
* memory.
*/
static void set_draw_format( i915ContextPtr i915,
static void set_draw_format( struct intel_context *intel,
GLuint format,
GLuint depth_format)
{
struct i915_context *i915 = i915_context(&intel->ctx);
i915->meta.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | /* .5 */
format |
LOD_PRECLAMP_OGL |
TEX_DEFAULT_COLOR_OGL |
depth_format);
DSTORG_VERT_BIAS(0x8) | /* .5 */
format |
LOD_PRECLAMP_OGL |
TEX_DEFAULT_COLOR_OGL |
depth_format);
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
/* fprintf(stderr, "%s: DV1: %x\n", */
/* __FUNCTION__, i915->meta.Buffer[I915_DESTREG_DV1]); */
}
#endif
static void set_vertex_format( i915ContextPtr i915 )
static void set_vertex_format( struct intel_context *intel )
{
struct i915_context *i915 = i915_context(&intel->ctx);
i915->meta.Ctx[I915_CTXREG_LIS2] =
(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
@@ -371,148 +375,50 @@ static void set_vertex_format( i915ContextPtr i915 )
i915->meta.Ctx[I915_CTXREG_LIS4] |=
(S4_VFMT_COLOR |
S4_VFMT_SPEC_FOG |
S4_VFMT_XYZW);
S4_VFMT_XYZ);
i915->meta.emitted &= ~I915_UPLOAD_CTX;
}
static void draw_quad(i915ContextPtr i915,
GLfloat x0, GLfloat x1,
GLfloat y0, GLfloat y1,
GLubyte red, GLubyte green,
GLubyte blue, GLubyte alpha,
GLfloat s0, GLfloat s1,
GLfloat t0, GLfloat t1 )
/* Operations where the 3D engine is decoupled temporarily from the
* current GL state and used for other purposes than simply rendering
* incoming triangles.
*/
static void install_meta_state( struct intel_context *intel )
{
#if 0
GLuint vertex_size = 8;
GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel,
PRIM3D_TRIFAN,
4 * vertex_size,
vertex_size );
intelVertex tmp;
int i;
struct i915_context *i915 = i915_context(&intel->ctx);
memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) );
i915->meta.active = ACTIVE;
i915->meta.emitted = 0;
if (0)
fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n",
__FUNCTION__,
x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1);
/* initial vertex, left bottom */
tmp.v.x = x0;
tmp.v.y = y0;
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 = s0;
tmp.v.v0 = t0;
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
/* right bottom */
vb += vertex_size;
tmp.v.x = x1;
tmp.v.u0 = s1;
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
/* right top */
vb += vertex_size;
tmp.v.y = y1;
tmp.v.v0 = t1;
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
/* left top */
vb += vertex_size;
tmp.v.x = x0;
tmp.v.u0 = s0;
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
#endif
SET_STATE(i915, meta);
set_vertex_format(intel);
meta_no_texture(intel);
}
void
i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch)
static void leave_meta_state( struct intel_context *intel )
{
i915ContextPtr i915 = i915_context( &intel->ctx );
__DRIdrawablePrivate *dPriv = intel->driDrawable;
intelScreenPrivate *screen = intel->intelScreen;
int x0, y0, x1, y1;
SET_STATE( i915, meta );
set_initial_state( i915 );
set_no_texture( i915 );
set_vertex_format( i915 );
LOCK_HARDWARE(intel);
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;
}
/* Don't do any clipping to screen - these are window coordinates.
* The active cliprects will be applied as for any other geometry.
*/
if (mask & BUFFER_BIT_FRONT_LEFT) {
set_no_depth_stencil_write( i915 );
set_color_mask( i915, GL_TRUE );
set_draw_offset( i915, screen->front.offset );
draw_quad(i915, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
if (mask & BUFFER_BIT_BACK_LEFT) {
set_no_depth_stencil_write( i915 );
set_color_mask( i915, GL_TRUE );
set_draw_offset( i915, screen->back.offset );
draw_quad(i915, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
if (mask & BUFFER_BIT_STENCIL) {
set_stencil_replace( i915,
intel->ctx.Stencil.WriteMask[0],
intel->ctx.Stencil.Clear);
set_color_mask( i915, GL_FALSE );
set_draw_offset( i915, screen->front.offset ); /* could be either? */
draw_quad( i915, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
}
UNLOCK_HARDWARE(intel);
SET_STATE( i915, state );
struct i915_context *i915 = i915_context(&intel->ctx);
intel_region_release(intel, &i915->meta.draw_region);
intel_region_release(intel, &i915->meta.depth_region);
intel_region_release(intel, &i915->meta.tex_region[0]);
SET_STATE(i915, state);
}
void i915InitMetaFuncs( struct i915_context *i915 )
{
i915->intel.vtbl.install_meta_state = install_meta_state;
i915->intel.vtbl.leave_meta_state = leave_meta_state;
i915->intel.vtbl.meta_no_depth_stencil_write = meta_no_depth_stencil_write;
i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace;
i915->intel.vtbl.meta_color_mask = meta_color_mask;
i915->intel.vtbl.meta_no_texture = meta_no_texture;
i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace;
i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source;
i915->intel.vtbl.meta_draw_region = meta_draw_region;
i915->intel.vtbl.meta_draw_format = set_draw_format;
}

View File

@@ -358,7 +358,7 @@ void i915_program_error( struct i915_fragment_program *p, const char *msg )
p->error = 1;
}
void i915_init_program( i915ContextPtr i915, struct i915_fragment_program *p )
void i915_init_program( struct i915_context *i915, struct i915_fragment_program *p )
{
GLcontext *ctx = &i915->intel.ctx;
TNLcontext *tnl = TNL_CONTEXT( ctx );
@@ -431,7 +431,7 @@ void i915_fini_program( struct i915_fragment_program *p )
p->declarations[0] |= program_size + decl_size - 2;
}
void i915_upload_program( i915ContextPtr i915, struct i915_fragment_program *p )
void i915_upload_program( struct i915_context *i915, struct i915_fragment_program *p )
{
GLuint program_size = p->csr - p->program;
GLuint decl_size = p->decl - p->declarations;

View File

@@ -84,7 +84,7 @@
/* One neat thing about the UREG representation:
*/
static __inline int swizzle( int reg, int x, int y, int z, int w )
static inline int swizzle( int reg, int x, int y, int z, int w )
{
return ((reg & ~UREG_XYZW_CHANNEL_MASK) |
CHANNEL_SRC( GET_CHANNEL_SRC( reg, x ), 0 ) |
@@ -95,7 +95,7 @@ static __inline int swizzle( int reg, int x, int y, int z, int w )
/* Another neat thing about the UREG representation:
*/
static __inline int negate( int reg, int x, int y, int z, int w )
static inline int negate( int reg, int x, int y, int z, int w )
{
return reg ^ (((x&1)<<UREG_CHANNEL_X_NEGATE_SHIFT)|
((y&1)<<UREG_CHANNEL_Y_NEGATE_SHIFT)|
@@ -149,10 +149,10 @@ extern GLuint i915_emit_param4fv( struct i915_fragment_program *p,
extern void i915_program_error( struct i915_fragment_program *p,
const char *msg );
extern void i915_init_program( i915ContextPtr i915,
extern void i915_init_program( struct i915_context *i915,
struct i915_fragment_program *p );
extern void i915_upload_program( i915ContextPtr i915,
extern void i915_upload_program( struct i915_context *i915,
struct i915_fragment_program *p );
extern void i915_fini_program( struct i915_fragment_program *p );

View File

@@ -435,10 +435,10 @@
#define LOGICOP_MASK (0xf<<18)
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
#define ENABLE_STENCIL_TEST_MASK (1<<17)
#define STENCIL_TEST_MASK(x) ((x)<<8)
#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8)
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
#define ENABLE_STENCIL_WRITE_MASK (1<<16)
#define STENCIL_WRITE_MASK(x) (x)
#define STENCIL_WRITE_MASK(x) ((x)&0xff)
/* _3DSTATE_MODES_5, p220 */
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))

View File

@@ -48,7 +48,7 @@ static void
i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
GLuint mask)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
int test = intel_translate_compare_func( func );
mask = mask & 0xff;
@@ -73,7 +73,7 @@ i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
static void
i915StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask);
@@ -91,7 +91,7 @@ static void
i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
GLenum zpass)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
int fop = intel_translate_stencil_op(fail);
int dfop = intel_translate_stencil_op(zfail);
int dpop = intel_translate_stencil_op(zpass);
@@ -116,7 +116,7 @@ i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
int test = intel_translate_compare_func( func );
GLubyte refByte;
@@ -137,7 +137,7 @@ static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
*/
static void i915EvalLogicOpBlendState(GLcontext *ctx)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
@@ -157,7 +157,7 @@ static void i915EvalLogicOpBlendState(GLcontext *ctx)
static void i915BlendColor(GLcontext *ctx, const GLfloat color[4])
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
GLubyte r, g, b, a;
if (INTEL_DEBUG&DEBUG_DRI)
@@ -194,7 +194,7 @@ static GLuint translate_blend_equation( GLenum mode )
static void i915UpdateBlendState( GLcontext *ctx )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] &
~(IAB_SRC_FACTOR_MASK |
IAB_DST_FACTOR_MASK |
@@ -261,7 +261,7 @@ static void i915BlendEquationSeparate(GLcontext *ctx, GLenum eqRGB,
static void i915DepthFunc(GLcontext *ctx, GLenum func)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
int test = intel_translate_compare_func( func );
if (INTEL_DEBUG&DEBUG_DRI)
@@ -274,7 +274,7 @@ static void i915DepthFunc(GLcontext *ctx, GLenum func)
static void i915DepthMask(GLcontext *ctx, GLboolean flag)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag);
@@ -295,7 +295,7 @@ static void i915DepthMask(GLcontext *ctx, GLboolean flag)
*/
static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
const GLubyte *m = mask;
GLubyte p[4];
int i,j,k;
@@ -348,7 +348,7 @@ static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask )
static void i915Scissor(GLcontext *ctx, GLint x, GLint y,
GLsizei w, GLsizei h)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
intelScreenPrivate *screen = i915->intel.intelScreen;
int x1, y1, x2, y2;
@@ -382,7 +382,7 @@ static void i915Scissor(GLcontext *ctx, GLint x, GLint y,
static void i915LogicOp(GLcontext *ctx, GLenum opcode)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
int tmp = intel_translate_logic_op(opcode);
if (INTEL_DEBUG&DEBUG_DRI)
@@ -397,7 +397,7 @@ static void i915LogicOp(GLcontext *ctx, GLenum opcode)
static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
GLuint mode;
if (INTEL_DEBUG&DEBUG_DRI)
@@ -425,7 +425,7 @@ static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused)
static void i915LineWidth( GLcontext *ctx, GLfloat widthf )
{
i915ContextPtr i915 = I915_CONTEXT( ctx );
struct i915_context *i915 = I915_CONTEXT( ctx );
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK;
int width;
@@ -444,7 +444,7 @@ static void i915LineWidth( GLcontext *ctx, GLfloat widthf )
static void i915PointSize(GLcontext *ctx, GLfloat size)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
GLint point_size = (int)size;
@@ -469,7 +469,7 @@ static void i915ColorMask(GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a)
{
i915ContextPtr i915 = I915_CONTEXT( ctx );
struct i915_context *i915 = I915_CONTEXT( ctx );
GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK;
if (INTEL_DEBUG&DEBUG_DRI)
@@ -490,7 +490,7 @@ static void update_specular( GLcontext *ctx )
{
/* A hack to trigger the rebuild of the fragment program.
*/
INTEL_CONTEXT(ctx)->NewGLState |= _NEW_TEXTURE;
intel_context(ctx)->NewGLState |= _NEW_TEXTURE;
I915_CONTEXT(ctx)->tex_program.translated = 0;
}
@@ -507,7 +507,7 @@ static void i915LightModelfv(GLcontext *ctx, GLenum pname,
static void i915ShadeModel(GLcontext *ctx, GLenum mode)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (mode == GL_SMOOTH) {
@@ -526,7 +526,7 @@ static void i915ShadeModel(GLcontext *ctx, GLenum mode)
*/
void i915_update_fog( GLcontext *ctx )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
GLenum mode;
GLboolean enabled;
GLboolean try_pixel_fog;
@@ -619,7 +619,7 @@ void i915_update_fog( GLcontext *ctx )
static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
switch (pname) {
case GL_FOG_COORDINATE_SOURCE_EXT:
@@ -671,7 +671,7 @@ static void i915Hint(GLcontext *ctx, GLenum target, GLenum state)
static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct i915_context *i915 = I915_CONTEXT(ctx);
switch(cap) {
case GL_TEXTURE_2D:
@@ -785,7 +785,7 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state)
}
static void i915_init_packets( i915ContextPtr i915 )
static void i915_init_packets( struct i915_context *i915 )
{
intelScreenPrivate *screen = i915->intel.intelScreen;
@@ -823,7 +823,6 @@ static void i915_init_packets( i915ContextPtr i915 )
ENABLE_STENCIL_WRITE_MASK |
STENCIL_WRITE_MASK(0xff));
i915->state.Ctx[I915_CTXREG_IAB] = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
IAB_MODIFY_ENABLE |
IAB_MODIFY_FUNC |
@@ -862,19 +861,15 @@ static void i915_init_packets( i915ContextPtr i915 )
BUF_3D_PITCH(screen->front.pitch * screen->cpp) |
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_USE_FENCE);
i915->state.Buffer[I915_DESTREG_DBUFADDR2] = screen->depth.offset;
i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
switch (screen->fbFormat) {
case DV_PF_555:
case DV_PF_565:
i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | /* .5 */
@@ -938,7 +933,7 @@ void i915InitStateFunctions( struct dd_function_table *functions )
}
void i915InitState( i915ContextPtr i915 )
void i915InitState( struct i915_context *i915 )
{
GLcontext *ctx = &i915->intel.ctx;

View File

@@ -48,7 +48,7 @@
static void i915TexEnv( GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
i915ContextPtr i915 = I915_CONTEXT( ctx );
struct i915_context *i915 = I915_CONTEXT( ctx );
switch (pname) {
case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */

View File

@@ -71,15 +71,15 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
GLuint d = dim;
for (i = mt->first_level; i <= mt->last_level; i++) {
mt->offset[face][i].x = x;
mt->offset[face][i].y = y;
mt->offset[face][i].width = d;
mt->offset[face][i].height = d;
mt->offset[face][i].depth = 1;
d >>= 1;
assert(d > 0);
intel_miptree_set_image_offset(mt, face, i,
x, y,
d, d, 1);
if (d == 0)
_mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n",
face, i, mt->first_level, mt->last_level);
d >>= 1;
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
}
@@ -91,21 +91,17 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
GLuint height = mt->height0;
GLuint depth = mt->depth0;
/* Calculate the size of a single slice. Hardware demands a
* minimum of 8 mipmaps, some of which might ultimately not be
* used:
/* Calculate the size of a single slice.
*/
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
mt->total_height = 0;
/* XXX: fixme! hardware expects/requires 9 levels at minimum.
/* XXX: hardware expects/requires 9 levels at minimum.
*/
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].x = 0;
mt->offset[0][i].y = mt->total_height;
mt->offset[0][i].width = width;
mt->offset[0][i].height = height;
mt->offset[0][i].depth = depth;
for ( i = mt->first_level ; i <= MAX2(8, mt->last_level) ; i++ ) {
intel_miptree_set_image_offset(mt, 0, i,
0, mt->total_height,
width, height, depth);
mt->total_height += MAX2(2, height);
@@ -114,12 +110,17 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
depth = minify(depth);
}
/* Fixup depth_image_stride:
*/
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].depth_image_stride = mt->total_height * mt->pitch * mt->cpp;
}
/* Multiply slice size by texture depth for total size. It's
* remarkable how wasteful of memory the i915 texture layouts
* are. They are largely fixed in the i945.
*/
mt->depth_pitch = mt->total_height * mt->pitch;
mt->total_height *= mt->depth0;
break;
}
@@ -132,13 +133,10 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
mt->total_height = 0;
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].x = 0;
mt->offset[0][i].y = mt->total_height;
mt->offset[0][i].height = height;
mt->offset[0][i].width = width;
mt->offset[0][i].depth = 1;
intel_miptree_set_image_offset(mt, 0, i,
0, mt->total_height,
width, height, 1);
if (mt->compressed)
mt->total_height += MAX2(1, height/4);
else
@@ -196,14 +194,11 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
}
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[face][i].x = x;
mt->offset[face][i].y = y;
mt->offset[face][i].width = d;
mt->offset[face][i].height = d;
mt->offset[face][i].depth = 1;
intel_miptree_set_image_offset(mt, face, i,
x, y,
d, d, 1);
d >>= 1;
assert(d > 0);
switch (d) {
case 4:
@@ -257,11 +252,11 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].x = 0;
mt->offset[0][i].y = mt->total_height;
mt->offset[0][i].width = width;
mt->offset[0][i].height = height;
mt->offset[0][i].depth = depth;
intel_miptree_set_image_offset(mt, 0, i,
0, mt->total_height,
width, height, depth);
mt->total_height += MAX2(2, height) * MAX2((depth >> depth_packing), 1);
@@ -271,7 +266,7 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
*/
if (depth_pack_pitch > 4) {
depth_packing++;
depth_pack_pitch <<= 2; /* KW: is this right?? */
depth_pack_pitch >>= 2; /* KW: is this right?? */
}
width = minify(width);
@@ -296,11 +291,9 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
mt->total_height = 0;
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
mt->offset[0][i].x = x;
mt->offset[0][i].y = y;
mt->offset[0][i].height = height;
mt->offset[0][i].width = width;
mt->offset[0][i].depth = 1;
intel_miptree_set_image_offset(mt, 0, i,
x, y,
width, height, 1);
/* LPT change: step right after second mipmap.

View File

@@ -536,7 +536,7 @@ static void emit_program_fini( struct i915_fragment_program *p )
}
static void i915EmitTextureProgram( i915ContextPtr i915 )
static void i915EmitTextureProgram( struct i915_context *i915 )
{
GLcontext *ctx = &i915->intel.ctx;
struct i915_fragment_program *p = &i915->tex_program;
@@ -570,9 +570,9 @@ static void i915EmitTextureProgram( i915ContextPtr i915 )
}
void i915ValidateTextureProgram( i915ContextPtr i915 )
void i915ValidateTextureProgram( struct i915_context *i915 )
{
intelContextPtr intel = &i915->intel;
struct intel_context *intel = &i915->intel;
GLcontext *ctx = &intel->ctx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;

View File

@@ -110,19 +110,31 @@ static GLuint translate_wrap_mode( GLenum wrap )
* efficient, but this has gotten complex enough that we need
* something which is understandable and reliable.
*/
static GLboolean i915_update_tex_unit( GLcontext *ctx,
static GLboolean i915_update_tex_unit( struct intel_context *intel,
GLuint unit,
GLuint ss3 )
{
GLcontext *ctx = &intel->ctx;
struct i915_context *i915 = i915_context(ctx);
struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
struct intel_texture_object *intelObj = intel_texture_object(tObj);
struct i915_context *i915 = i915_context(ctx);
GLuint state[I915_TEX_SETUP_SIZE];
struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel];
GLuint *state = i915->state.Tex[unit];
memset(state, 0, sizeof(state));
state[I915_TEXREG_MS2] = 0; /* will fixup later */
intel_region_release(intel, &i915->state.tex_region[unit]);
if (!intel_finalize_mipmap_tree(intel, unit))
return GL_FALSE;
intel_region_reference(&i915->state.tex_region[unit],
intelObj->mt->region);
i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0,
intelObj->firstLevel);
state[I915_TEXREG_MS3] =
(((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
((firstImage->Width - 1) << MS3_WIDTH_SHIFT) |
@@ -253,11 +265,11 @@ static GLboolean i915_update_tex_unit( GLcontext *ctx,
I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE);
/* memcmp was already disabled, but definitely won't work as the
* region might now change and that wouldn't be detected:
*/
I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) );
if (1 || memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) {
I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) );
memcpy(i915->state.Tex[unit], state, sizeof(state));
}
#if 0
DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]);
@@ -274,25 +286,24 @@ static GLboolean i915_update_tex_unit( GLcontext *ctx,
void i915UpdateTextureState( intelContextPtr intel )
void i915UpdateTextureState( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
GLboolean ok = GL_TRUE;
GLuint i;
for (i = 0 ; i < I915_TEX_UNITS && ok ; i++) {
switch (ctx->Texture.Unit[i]._ReallyEnabled) {
switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) {
case TEXTURE_1D_BIT:
case TEXTURE_2D_BIT:
case TEXTURE_CUBE_BIT:
ok = i915_update_tex_unit( ctx, i, SS3_NORMALIZED_COORDS );
case TEXTURE_3D_BIT:
ok = i915_update_tex_unit( intel, i, SS3_NORMALIZED_COORDS );
break;
case TEXTURE_RECT_BIT:
case TEXTURE_3D_BIT:
ok = i915_update_tex_unit( ctx, i, 0 );
ok = i915_update_tex_unit( intel, i, 0 );
break;
case 0: {
struct i915_context *i915 = i915_context(ctx);
struct i915_context *i915 = i915_context(&intel->ctx);
if (i915->state.active & I915_UPLOAD_TEX(i))
I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE);
break;

View File

@@ -38,14 +38,15 @@
#include "intel_batchbuffer.h"
#include "intel_tex.h"
#include "intel_regions.h"
#include "i915_reg.h"
#include "i915_context.h"
static void i915_render_start( intelContextPtr intel )
static void i915_render_start( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
i915ContextPtr i915 = i915_context(&intel->ctx);
struct i915_context *i915 = i915_context(&intel->ctx);
if (ctx->FragmentProgram._Active)
i915ValidateFragmentProgram( i915 );
@@ -54,42 +55,42 @@ static void i915_render_start( intelContextPtr intel )
}
static void i915_reduced_primitive_state( intelContextPtr intel,
static void i915_reduced_primitive_state( struct intel_context *intel,
GLenum rprim )
{
i915ContextPtr i915 = i915_context(&intel->ctx);
GLuint st1 = i915->state.Stipple[I915_STPREG_ST1];
struct i915_context *i915 = i915_context(&intel->ctx);
GLuint st1 = i915->state.Stipple[I915_STPREG_ST1];
st1 &= ~ST1_ENABLE;
st1 &= ~ST1_ENABLE;
switch (rprim) {
case GL_TRIANGLES:
if (intel->ctx.Polygon.StippleFlag &&
intel->hw_stipple)
st1 |= ST1_ENABLE;
break;
case GL_LINES:
case GL_POINTS:
default:
break;
}
switch (rprim) {
case GL_TRIANGLES:
if (intel->ctx.Polygon.StippleFlag &&
intel->hw_stipple)
st1 |= ST1_ENABLE;
break;
case GL_LINES:
case GL_POINTS:
default:
break;
}
i915->intel.reduced_primitive = rprim;
i915->intel.reduced_primitive = rprim;
if (st1 != i915->state.Stipple[I915_STPREG_ST1]) {
I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
i915->state.Stipple[I915_STPREG_ST1] = st1;
}
if (st1 != i915->state.Stipple[I915_STPREG_ST1]) {
I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
i915->state.Stipple[I915_STPREG_ST1] = st1;
}
}
/* Pull apart the vertex format registers and figure out how large a
* vertex is supposed to be.
*/
static GLboolean i915_check_vertex_size( intelContextPtr intel,
static GLboolean i915_check_vertex_size( struct intel_context *intel,
GLuint expected )
{
i915ContextPtr i915 = i915_context(&intel->ctx);
struct i915_context *i915 = i915_context(&intel->ctx);
int lis2 = i915->current->Ctx[I915_CTXREG_LIS2];
int lis4 = i915->current->Ctx[I915_CTXREG_LIS4];
int i, sz = 0;
@@ -133,11 +134,11 @@ static GLboolean i915_check_vertex_size( intelContextPtr intel,
}
static void i915_emit_invarient_state( intelContextPtr intel )
static void i915_emit_invarient_state( struct intel_context *intel )
{
BATCH_LOCALS;
BEGIN_BATCH( 200 );
BEGIN_BATCH( 200, 0 );
OUT_BATCH(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE |
@@ -205,21 +206,15 @@ static void i915_emit_invarient_state( intelContextPtr intel )
}
#define emit( intel, state, size ) \
do { \
int k; \
BEGIN_BATCH( (size) / sizeof(GLuint)); \
for (k = 0 ; k < (size) / sizeof(GLuint) ; k++) \
OUT_BATCH((state)[k]); \
ADVANCE_BATCH(); \
} while (0);
#define emit(intel, state, size ) \
intel_batchbuffer_data(intel->batch, state, size, 0 )
/* Push the state into the sarea and/or texture memory.
*/
static void i915_emit_state( intelContextPtr intel )
static void i915_emit_state( struct intel_context *intel )
{
i915ContextPtr i915 = i915_context(&intel->ctx);
struct i915_context *i915 = i915_context(&intel->ctx);
struct i915_hw_state *state = i915->current;
int i;
GLuint dirty;
@@ -234,32 +229,48 @@ static void i915_emit_state( intelContextPtr intel )
dirty = state->active & ~state->emitted;
if (VERBOSE)
if (INTEL_DEBUG & DEBUG_STATE)
fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty);
if (dirty & I915_UPLOAD_INVARIENT) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n");
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n");
i915_emit_invarient_state( intel );
}
if (dirty & I915_UPLOAD_CTX) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CTX:\n");
emit( i915, state->Ctx, sizeof(state->Ctx) );
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CTX:\n");
emit(intel, state->Ctx, sizeof(state->Ctx) );
}
if (dirty & I915_UPLOAD_BUFFERS) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
emit( i915, state->Buffer, sizeof(state->Buffer) );
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
BEGIN_BATCH(I915_DEST_SETUP_SIZE, 0);
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]);
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]);
OUT_RELOC(state->draw_region->buffer, BM_MEM_AGP|BM_WRITE, 0);
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]);
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]);
OUT_RELOC(state->depth_region->buffer, BM_MEM_AGP|BM_WRITE, 0);
OUT_BATCH(state->Buffer[I915_DESTREG_DV0]);
OUT_BATCH(state->Buffer[I915_DESTREG_DV1]);
OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]);
OUT_BATCH(state->Buffer[I915_DESTREG_SR0]);
OUT_BATCH(state->Buffer[I915_DESTREG_SR1]);
OUT_BATCH(state->Buffer[I915_DESTREG_SR2]);
ADVANCE_BATCH();
}
if (dirty & I915_UPLOAD_STIPPLE) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n");
emit( i915, state->Stipple, sizeof(state->Stipple) );
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n");
emit(intel, state->Stipple, sizeof(state->Stipple) );
}
if (dirty & I915_UPLOAD_FOG) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_FOG:\n");
emit( i915, state->Fog, sizeof(state->Fog) );
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_FOG:\n");
emit(intel, state->Fog, sizeof(state->Fog) );
}
/* Combine all the dirty texture state into a single command to
@@ -272,20 +283,29 @@ static void i915_emit_state( intelContextPtr intel )
if (dirty & I915_UPLOAD_TEX(i))
nr++;
BEGIN_BATCH(2+nr*3);
BEGIN_BATCH(2+nr*3, 0);
OUT_BATCH(_3DSTATE_MAP_STATE | (3*nr));
OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
for (i = 0 ; i < I915_TEX_UNITS ; i++)
if (dirty & I915_UPLOAD_TEX(i)) {
/* Emit zero texture offset, will fixup before firing */
intel_add_texoffset_fixup(intel, i, (GLuint *)batch_ptr);
batch_ptr += 4;
if (state->tex_region[i]) {
OUT_RELOC(state->tex_region[i]->buffer,
BM_MEM_AGP|BM_READ,
state->tex_offset[i]);
}
else {
assert(i == 0);
assert(state == &i915->meta);
OUT_BATCH(0);
}
OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]);
OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]);
}
ADVANCE_BATCH();
BEGIN_BATCH(2+nr*3);
BEGIN_BATCH(2+nr*3, 0);
OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3*nr));
OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
for (i = 0 ; i < I915_TEX_UNITS ; i++)
@@ -298,64 +318,65 @@ static void i915_emit_state( intelContextPtr intel )
}
if (dirty & I915_UPLOAD_CONSTANTS) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n");
emit( i915, state->Constant, state->ConstantSize * sizeof(GLuint) );
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n");
emit(intel, state->Constant, state->ConstantSize * sizeof(GLuint) );
}
if (dirty & I915_UPLOAD_PROGRAM) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
assert((state->Program[0] & 0x1ff)+2 == state->ProgramSize);
emit( i915, state->Program, state->ProgramSize * sizeof(GLuint) );
if (VERBOSE)
emit(intel, state->Program, state->ProgramSize * sizeof(GLuint) );
if (INTEL_DEBUG & DEBUG_STATE)
i915_disassemble_program( state->Program, state->ProgramSize );
}
state->emitted |= dirty;
}
static void i915_destroy_context( intelContextPtr intel )
static void i915_destroy_context( struct intel_context *intel )
{
_tnl_free_vertices(&intel->ctx);
}
static void i915_set_draw_offset( intelContextPtr intel, int offset )
static void i915_set_draw_region( struct intel_context *intel,
struct intel_region *draw_region,
struct intel_region *depth_region)
{
i915ContextPtr i915 = i915_context(&intel->ctx);
struct i915_context *i915 = i915_context(&intel->ctx);
intel_region_release(intel, &i915->state.draw_region);
intel_region_release(intel, &i915->state.depth_region);
intel_region_reference(&i915->state.draw_region, draw_region);
intel_region_reference(&i915->state.depth_region, depth_region);
I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS );
i915->state.Buffer[I915_DESTREG_CBUFADDR2] = offset;
}
static void i915_lost_hardware( intelContextPtr intel )
static void i915_lost_hardware( struct intel_context *intel )
{
i915ContextPtr i915 = i915_context(&intel->ctx);
struct i915_context *i915 = i915_context(&intel->ctx);
i915->state.emitted = 0;
}
static void i915_emit_flush( intelContextPtr intel )
static GLuint i915_flush_cmd( void )
{
BATCH_LOCALS;
BEGIN_BATCH(2);
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE );
OUT_BATCH( 0 );
ADVANCE_BATCH();
return MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE;
}
void i915InitVtbl( i915ContextPtr i915 )
void i915InitVtbl( struct i915_context *i915 )
{
i915->intel.vtbl.check_vertex_size = i915_check_vertex_size;
i915->intel.vtbl.clear_with_tris = i915ClearWithTris;
i915->intel.vtbl.destroy = i915_destroy_context;
i915->intel.vtbl.emit_invarient_state = i915_emit_invarient_state;
i915->intel.vtbl.emit_state = i915_emit_state;
i915->intel.vtbl.lost_hardware = i915_lost_hardware;
i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state;
i915->intel.vtbl.render_start = i915_render_start;
i915->intel.vtbl.set_draw_offset = i915_set_draw_offset;
i915->intel.vtbl.set_draw_region = i915_set_draw_region;
i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
i915->intel.vtbl.emit_flush = i915_emit_flush;
i915->intel.vtbl.flush_cmd = i915_flush_cmd;
}

View File

@@ -1,6 +1,6 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,408 +25,266 @@
*
**************************************************************************/
#include <stdio.h>
#include <errno.h>
#include "mtypes.h"
#include "context.h"
#include "enums.h"
#include "intel_reg.h"
#include "intel_batchbuffer.h"
#include "intel_context.h"
#include "intel_ioctl.h"
#include "bufmgr.h"
/*
* Copy the back buffer to the front buffer.
/* Relocations in kernel space:
* - pass dma buffer seperately
* - memory manager knows how to patch
* - pass list of dependent buffers
* - pass relocation list
*
* Either:
* - get back an offset for buffer to fire
* - memory manager knows how to fire buffer
*
* Really want the buffer to be AGP and pinned.
*
*/
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
/* Cliprect fence: The highest fence protecting a dma buffer
* containing explicit cliprect information. Like the old drawable
* lock but irq-driven. X server must wait for this fence to expire
* before changing cliprects [and then doing sw rendering?]. For
* other dma buffers, the scheduler will grab current cliprect info
* and mix into buffer. X server must hold the lock while changing
* cliprects??? Make per-drawable. Need cliprects in shared memory
* -- beats storing them with every cmd buffer in the queue.
*
* ==> X server must wait for this fence to expire before touching the
* framebuffer with new cliprects.
*
* ==> Cliprect-dependent buffers associated with a
* cliprect-timestamp. All of the buffers associated with a timestamp
* must go to hardware before any buffer with a newer timestamp.
*
* ==> Dma should be queued per-drawable for correct X/GL
* synchronization. Or can fences be used for this?
*
* Applies to: Blit operations, metaops, X server operations -- X
* server automatically waits on its own dma to complete before
* modifying cliprects ???
*/
static void intel_dump_batchbuffer( unsigned offset,
int *ptr,
int count )
{
intelContextPtr intel;
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
intelInstallBatchBuffer(intel);
intelValidateBuffers( intel );
{
intelScreenPrivate *intelScreen = intel->intelScreen;
__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 i;
GLuint CMD, BR13;
BATCH_LOCALS;
switch(cpp) {
case 2:
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
break;
default:
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
}
for (i = 0 ; i < nbox; i++, pbox++)
{
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
pbox->x2 > intelScreen->width ||
pbox->y2 > intelScreen->height)
continue;
BEGIN_BATCH( 8);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
OUT_BATCH( (pbox->y2 << 16) | pbox->x2 );
if (intel->sarea->pf_current_page == 0)
OUT_BATCH( intelScreen->front.offset );
else
OUT_BATCH( intelScreen->back.offset );
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
OUT_BATCH( BR13 & 0xffff );
if (intel->sarea->pf_current_page == 0)
OUT_BATCH( intelScreen->back.offset );
else
OUT_BATCH( intelScreen->front.offset );
ADVANCE_BATCH();
}
}
intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE );
assert(intel->buffer_list == NULL);
UNLOCK_HARDWARE( intel );
int i;
fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count/4);
for (i = 0; i < count/4; i += 4)
fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n",
offset + i*4, ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]);
fprintf(stderr, "END BATCH\n\n\n");
}
void intelEmitFillBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort dst_pitch,
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color )
static void intel_batchbuffer_reset( struct intel_batchbuffer *batch )
{
GLuint BR13, CMD;
BATCH_LOCALS;
dst_pitch *= cpp;
switch(cpp) {
case 1:
case 2:
case 3:
BR13 = dst_pitch | (0xF0 << 16) | (1<<24);
CMD = XY_COLOR_BLT_CMD;
break;
case 4:
BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25);
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
break;
default:
return;
}
BEGIN_BATCH( 6);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (y << 16) | x );
OUT_BATCH( ((y+h) << 16) | (x+w) );
OUT_BATCH( dst_offset );
OUT_BATCH( color );
ADVANCE_BATCH();
}
/* Copy BitBlt
*/
void intelEmitCopyBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort src_pitch,
GLuint src_offset,
GLshort dst_pitch,
GLuint dst_offset,
GLshort src_x, GLshort src_y,
GLshort dst_x, GLshort dst_y,
GLshort w, GLshort h )
{
GLuint CMD, BR13;
int dst_y2 = dst_y + h;
int dst_x2 = dst_x + w;
BATCH_LOCALS;
if (0)
_mesa_printf("%s src:0x%x/%d %d,%d dst:0x%x/%d %d,%d sz:%dx%d\n",
__FUNCTION__,
src_offset, src_pitch, src_x, src_y,
dst_offset, dst_pitch, dst_x, dst_y,
w,h);
src_pitch *= cpp;
dst_pitch *= cpp;
switch(cpp) {
case 1:
case 2:
case 3:
BR13 = dst_pitch | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
BR13 = dst_pitch | (0xCC << 16) | (1<<24) | (1<<25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
break;
default:
return;
}
if (dst_y2 < dst_y ||
dst_x2 < dst_x) {
return;
}
BEGIN_BATCH( 12);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (dst_y << 16) | dst_x );
OUT_BATCH( (dst_y2 << 16) | dst_x2 );
OUT_BATCH( dst_offset );
OUT_BATCH( (src_y << 16) | src_x );
OUT_BATCH( src_pitch );
OUT_BATCH( src_offset );
ADVANCE_BATCH();
}
void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch)
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
intelScreenPrivate *intelScreen = intel->intelScreen;
GLuint clear_depth, clear_color;
GLint cx, cy;
GLint pitch = intelScreen->front.pitch;
GLint cpp = intelScreen->cpp;
GLint i;
GLuint BR13, CMD, D_CMD;
BATCH_LOCALS;
clear_color = intel->ClearColor;
clear_depth = 0;
if (flags & BUFFER_BIT_DEPTH) {
clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
}
if (flags & BUFFER_BIT_STENCIL) {
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;
}
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
intelInstallBatchBuffer(intel);
intelValidateBuffers( intel );
{
/* flip top to bottom */
cy = intel->driDrawable->h-cy1-ch;
cx = cx1 + intel->drawX;
cy += intel->drawY;
/* 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;
}
for (i = 0 ; i < intel->numClipRects ; i++)
{
drm_clip_rect_t *box = &intel->pClipRects[i];
drm_clip_rect_t b;
if (!all) {
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;
} else {
b = *box;
}
if (b.x1 > b.x2 ||
b.y1 > b.y2 ||
b.x2 > intelScreen->width ||
b.y2 > intelScreen->height)
continue;
if ( flags & BUFFER_BIT_FRONT_LEFT ) {
BEGIN_BATCH( 6);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_BATCH( intelScreen->front.offset );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
if ( flags & BUFFER_BIT_BACK_LEFT ) {
BEGIN_BATCH( 6);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_BATCH( intelScreen->back.offset );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
BEGIN_BATCH( 6);
OUT_BATCH( D_CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_BATCH( intelScreen->depth.offset );
OUT_BATCH( clear_depth );
ADVANCE_BATCH();
}
}
}
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
UNLOCK_HARDWARE( intel );
}
void intelDestroyBatchBuffer( struct intel_context *intel )
{
}
void intelInstallBatchBuffer( struct intel_context *intel )
{
assert(!intel->batch.ptr);
intel->alloc.current++;
intel->alloc.current %= INTEL_ALLOC_NR;
DBG("%s: %d\n", __FUNCTION__, intel->alloc.current);
intel->batch.size = INTEL_ALLOC_SIZE;
intel->batch.space = intel->batch.size;
intel->batch.start_offset = 0;
intel->batch.ptr = bmMapBuffer( intel->bm,
intel->alloc.buffer[intel->alloc.current],
BM_WRITE | BM_MEM_AGP );
assert(!intel->buffer_list);
intel->buffer_list = bmNewBufferList();
/* Add the batchbuffer
*/
bmAddBuffer(intel->buffer_list,
intel->alloc.buffer[intel->alloc.current],
BM_READ,
NULL,
&intel->batch.start_offset);
}
void intelInitBatchBuffer( struct intel_context *intel )
{
GLint i;
_mesa_printf("%s: %d\n", __FUNCTION__, intel->alloc.current);
bmGenBuffers(intel->bm,
INTEL_ALLOC_NR,
intel->alloc.buffer);
for (i = 0; i < INTEL_ALLOC_NR; i++)
bmBufferData(intel->bm,
intel->alloc.buffer[i],
INTEL_ALLOC_SIZE,
NULL,
BM_MEM_AGP);
bmBufferData(batch->bm,
batch->buffer,
BATCH_SZ,
NULL,
0);
if (!batch->list)
batch->list = bmNewBufferList();
batch->list->nr = 0;
batch->nr_relocs = 0;
batch->flags = 0;
bmAddBuffer( batch->list,
batch->buffer,
0,
NULL,
&batch->offset[batch->list->nr]);
batch->map = bmMapBuffer(batch->bm, batch->buffer,
BM_MEM_AGP|BM_MEM_LOCAL|BM_CLIENT|BM_WRITE);
batch->ptr = batch->map;
}
void intelValidateBuffers( struct intel_context *intel )
/*======================================================================
* Public functions
*/
struct intel_batchbuffer *intel_batchbuffer_alloc( struct intel_context *intel )
{
if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP))
assert(0);
struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);
batch->intel = intel;
batch->bm = intel->bm;
bmGenBuffers(intel->bm, 1, &batch->buffer);
intel_batchbuffer_reset( batch );
return batch;
}
void intel_batchbuffer_free( struct intel_batchbuffer *batch )
{
if (batch->map)
bmUnmapBuffer(batch->bm, batch->buffer);
free(batch);
}
/* TODO: Push this whole function into bufmgr.
*/
static void do_flush_locked( struct intel_batchbuffer *batch,
GLuint used,
GLboolean ignore_cliprects)
{
GLuint *ptr;
GLuint i;
bmValidateBufferList( batch->bm,
batch->list,
BM_MEM_AGP );
/* Apply the relocations. This nasty map indicates to me that the
* whole task should be done internally by the memory manager, and
* that dma buffers probably need to be pinned within agp space.
*/
ptr = (GLuint *)bmMapBuffer(batch->bm, batch->buffer,
BM_NO_MOVE|BM_NO_UPLOAD|
BM_NO_EVICT|BM_MEM_AGP|
BM_WRITE);
for (i = 0; i < batch->nr_relocs; i++) {
struct buffer_reloc *r = &batch->reloc[i];
DBG("apply fixup at offset 0x%x, elem %d (buf %d, offset 0x%x), delta 0x%x\n",
r->offset, r->elem, batch->list->elem[r->elem].buffer,
batch->offset[r->elem], r->delta);
ptr[r->offset/4] = batch->offset[r->elem] + r->delta;
}
if (INTEL_DEBUG & DEBUG_DMA)
intel_dump_batchbuffer( 0, ptr, used );
bmUnmapBuffer(batch->bm, batch->buffer);
/* Fire the batch buffer, which was uploaded above:
*/
intel_batch_ioctl(batch->intel,
batch->offset[0],
used,
ignore_cliprects);
batch->last_fence = bmFenceBufferList(batch->bm, batch->list);
}
GLuint intel_batchbuffer_flush( struct intel_batchbuffer *batch )
{
struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;
if (used == 0)
return batch->last_fence;
/* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a
* performance drain that we would like to avoid.
*/
if (used & 4) {
((int *)batch->ptr)[0] = intel->vtbl.flush_cmd();
((int *)batch->ptr)[1] = 0;
((int *)batch->ptr)[2] = MI_BATCH_BUFFER_END;
used += 12;
}
else {
((int *)batch->ptr)[0] = intel->vtbl.flush_cmd();
((int *)batch->ptr)[1] = MI_BATCH_BUFFER_END;
used += 8;
}
bmUnmapBuffer(batch->bm, batch->buffer);
batch->ptr = NULL;
batch->map = NULL;
/* TODO: Just pass the relocation list and dma buffer up to the
* kernel.
*/
if (!intel->locked)
{
assert(!(batch->flags & INTEL_BATCH_NO_CLIPRECTS));
LOCK_HARDWARE(intel);
do_flush_locked(batch, used, GL_FALSE);
UNLOCK_HARDWARE(intel);
}
else {
assert(!(batch->flags & INTEL_BATCH_CLIPRECTS));
do_flush_locked(batch, used, GL_TRUE);
}
/* Reset the buffer:
*/
intel_batchbuffer_reset( batch );
return batch->last_fence;
}
void intel_batchbuffer_finish( struct intel_batchbuffer *batch )
{
bmFinishFence(batch->bm,
intel_batchbuffer_flush(batch));
}
/* This is the only way buffers get added to the validate list.
*/
GLboolean intel_batchbuffer_emit_reloc( struct intel_batchbuffer *batch,
GLuint buffer,
GLuint flags,
GLuint delta )
{
GLuint i;
assert(batch->nr_relocs <= MAX_RELOCS);
for (i = 0; i < batch->list->nr; i++)
if (buffer == batch->list->elem[i].buffer)
break;
if (i == batch->list->nr) {
if (i == BM_LIST_MAX)
return GL_FALSE;
bmAddBuffer(batch->list,
buffer,
flags,
NULL,
&batch->offset[i]);
}
{
struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++];
r->offset = batch->ptr - batch->map;
r->delta = delta;
r->elem = i;
}
batch->ptr += 4;
return GL_TRUE;
}
void intel_batchbuffer_data(struct intel_batchbuffer *batch,
const void *data,
GLuint bytes,
GLuint flags)
{
assert((bytes & 3) == 0);
intel_batchbuffer_require_space(batch, bytes, flags);
__memcpy(batch->ptr, data, bytes);
batch->ptr += bytes;
}

View File

@@ -1,106 +1,113 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTEL_BATCHBUFFER_H
#define INTEL_BATCHBUFFER_H
#include "intel_context.h"
#include "intel_ioctl.h"
#include "mtypes.h"
#include "bufmgr.h"
struct intel_context;
#define BATCH_SZ 4096
#define BATCH_RESERVED 16
#define MAX_RELOCS 100
#define INTEL_BATCH_NO_CLIPRECTS 0x1
#define INTEL_BATCH_CLIPRECTS 0x2
struct buffer_reloc {
GLuint offset;
GLuint elem; /* elem in buffer list, not buffer id */
GLuint delta; /* not needed? */
};
struct intel_batchbuffer {
struct bufmgr *bm;
struct intel_context *intel;
GLuint buffer;
GLuint last_fence;
GLuint flags;
/* In progress:
*/
GLuint offset[BM_LIST_MAX];
struct bm_buffer_list *list;
GLubyte *map;
GLubyte *ptr;
struct buffer_reloc reloc[MAX_RELOCS];
GLuint nr_relocs;
};
struct intel_batchbuffer *intel_batchbuffer_alloc( struct intel_context *intel );
void intel_batchbuffer_free( struct intel_batchbuffer *batch );
#define BATCH_LOCALS GLubyte *batch_ptr;
void intel_batchbuffer_finish( struct intel_batchbuffer *batch );
#define VERBOSE 0
GLuint intel_batchbuffer_flush( struct intel_batchbuffer *batch );
#define BEGIN_BATCH(n) \
do { \
if (VERBOSE) fprintf(stderr, \
"BEGIN_BATCH(%d) in %s, %d dwords free\n", \
(n), __FUNCTION__, intel->batch.space/4); \
assert(intel->locked); \
if (intel->batch.space < (n)*4) \
intelFlushBatch(intel, GL_TRUE); \
batch_ptr = intel->batch.ptr; \
} while (0)
/* Unlike bmBufferData, this currently requires the buffer be mapped.
* Consider it a convenience function wrapping multple
* intel_buffer_dword() calls.
*/
void intel_batchbuffer_data(struct intel_batchbuffer *batch,
const void *data,
GLuint bytes,
GLuint flags);
#define OUT_BATCH(n) \
do { \
*(GLuint *)batch_ptr = (n); \
if (VERBOSE) fprintf(stderr, " -- %08x at %s/%d\n", (n), __FILE__, __LINE__); \
batch_ptr += 4; \
} while (0)
void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
GLuint bytes);
#define ADVANCE_BATCH() \
do { \
if (VERBOSE) fprintf(stderr, "ADVANCE_BATCH()\n"); \
intel->batch.space -= (batch_ptr - intel->batch.ptr); \
intel->batch.ptr = batch_ptr; \
assert(intel->batch.space >= 0); \
} while(0)
GLboolean intel_batchbuffer_emit_reloc( struct intel_batchbuffer *batch,
GLuint buffer,
GLuint flags,
GLuint offset );
extern void intelInitBatchBuffer( struct intel_context *intel );
extern void intelDestroyBatchBuffer( struct intel_context *intel );
void intelInstallBatchBuffer( struct intel_context *intel );
/* Inline functions - might actually be better off with these
* non-inlined. Certainly better off switching all command packets to
* be passed as structs rather than dwords, but that's a little bit of
* work...
*/
static inline GLuint
intel_batchbuffer_space( struct intel_batchbuffer *batch )
{
return (BATCH_SZ - BATCH_RESERVED) - (batch->ptr - batch->map);
}
extern void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim );
extern void intelWrapInlinePrimitive( intelContextPtr intel );
extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
int primitive, int dwords,
int vertex_size);
extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv );
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch);
static inline void
intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch,
GLuint dword)
{
assert(batch->map);
assert(intel_batchbuffer_space(batch) >= 4);
*(GLuint *)(batch->ptr) = dword;
batch->ptr += 4;
}
extern void intelEmitCopyBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort src_pitch,
GLuint src_offset,
GLshort dst_pitch,
GLuint dst_offset,
GLshort srcx, GLshort srcy,
GLshort dstx, GLshort dsty,
GLshort w, GLshort h );
static inline void
intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
GLuint sz,
GLuint flags)
{
assert(sz < BATCH_SZ - 8);
if (intel_batchbuffer_space(batch) < sz ||
(batch->flags != 0 && flags != 0 && batch->flags != flags))
intel_batchbuffer_flush(batch);
batch->flags |= flags;
}
extern void intelEmitFillBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort dst_pitch,
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color );
/* Here are the crusty old macros, to be removed:
*/
#define BATCH_LOCALS
#define BEGIN_BATCH(n, flags) intel_batchbuffer_require_space(intel->batch, n*4, flags)
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
#define OUT_RELOC(buf,flags,delta) intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta)
#define ADVANCE_BATCH() do { } while(0)
GLuint *intelExtendInlinePrimitive( intelContextPtr intel,
GLuint dwords );
void intelValidateBuffers( struct intel_context *intel );
#endif

View File

@@ -0,0 +1,384 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include <stdio.h>
#include <errno.h>
#include "mtypes.h"
#include "context.h"
#include "enums.h"
#include "intel_reg.h"
#include "intel_batchbuffer.h"
#include "intel_context.h"
#include "intel_blit.h"
#include "intel_regions.h"
#include "bufmgr.h"
/*
* Copy the back buffer to the front buffer.
*/
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
{
struct intel_context *intel;
DBG("%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
bmFinishFence(intel->bm, intel->last_swap_fence);
/* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
* should work regardless.
*/
LOCK_HARDWARE( intel );
{
intelScreenPrivate *intelScreen = intel->intelScreen;
__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 BR13, CMD;
int i;
if (cpp == 2) {
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
}
else {
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
}
for (i = 0 ; i < nbox; i++, pbox++)
{
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
pbox->x2 > intelScreen->width ||
pbox->y2 > intelScreen->height)
continue;
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
OUT_BATCH( (pbox->y2 << 16) | pbox->x2 );
if (intel->sarea->pf_current_page == 0)
OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
else
OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
OUT_BATCH( BR13 & 0xffff );
if (intel->sarea->pf_current_page == 0)
OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_READ, 0 );
else
OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_READ, 0 );
ADVANCE_BATCH();
}
}
intel->last_swap_fence = intel_batchbuffer_flush( intel->batch );
UNLOCK_HARDWARE( intel );
}
void intelEmitFillBlit( struct intel_context *intel,
GLuint cpp,
GLshort dst_pitch,
GLuint dst_buffer,
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color )
{
GLuint BR13, CMD;
BATCH_LOCALS;
dst_pitch *= cpp;
switch(cpp) {
case 1:
case 2:
case 3:
BR13 = dst_pitch | (0xF0 << 16) | (1<<24);
CMD = XY_COLOR_BLT_CMD;
break;
case 4:
BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25);
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
break;
default:
return;
}
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (y << 16) | x );
OUT_BATCH( ((y+h) << 16) | (x+w) );
OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset );
OUT_BATCH( color );
ADVANCE_BATCH();
}
/* Copy BitBlt
*/
void intelEmitCopyBlit( struct intel_context *intel,
GLuint cpp,
GLshort src_pitch,
GLuint src_buffer,
GLuint src_offset,
GLshort dst_pitch,
GLuint dst_buffer,
GLuint dst_offset,
GLshort src_x, GLshort src_y,
GLshort dst_x, GLshort dst_y,
GLshort w, GLshort h )
{
GLuint CMD, BR13;
int dst_y2 = dst_y + h;
int dst_x2 = dst_x + w;
BATCH_LOCALS;
DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d\n",
__FUNCTION__,
src_buffer, src_pitch, src_x, src_y,
dst_buffer, dst_pitch, dst_x, dst_y,
w,h);
src_pitch *= cpp;
dst_pitch *= cpp;
switch(cpp) {
case 1:
case 2:
case 3:
BR13 = dst_pitch | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
BR13 = dst_pitch | (0xCC << 16) | (1<<24) | (1<<25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
break;
default:
return;
}
if (dst_y2 < dst_y ||
dst_x2 < dst_x) {
return;
}
/* Initial y values don't seem to work with negative pitches. If
* we adjust the offsets manually (below), it seems to work fine.
*/
if (0) {
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (dst_y << 16) | dst_x );
OUT_BATCH( (dst_y2 << 16) | dst_x2 );
OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset );
OUT_BATCH( (src_y << 16) | src_x );
OUT_BATCH( ((GLint)src_pitch&0xffff) );
OUT_RELOC( src_buffer, BM_MEM_AGP|BM_READ, src_offset );
ADVANCE_BATCH();
}
else {
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (0 << 16) | dst_x );
OUT_BATCH( (h << 16) | dst_x2 );
OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset + dst_y * dst_pitch );
OUT_BATCH( (0 << 16) | src_x );
OUT_BATCH( ((GLint)src_pitch&0xffff) );
OUT_RELOC( src_buffer, BM_MEM_AGP|BM_READ, src_offset + src_y * src_pitch );
ADVANCE_BATCH();
}
}
void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch)
{
struct intel_context *intel = intel_context( ctx );
intelScreenPrivate *intelScreen = intel->intelScreen;
GLuint clear_depth, clear_color;
GLint cx, cy;
GLint pitch = intelScreen->front.pitch;
GLint cpp = intelScreen->cpp;
GLint i;
GLuint BR13, CMD, D_CMD;
BATCH_LOCALS;
clear_color = intel->ClearColor;
clear_depth = 0;
if (flags & BUFFER_BIT_DEPTH) {
clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
}
if (flags & BUFFER_BIT_STENCIL) {
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;
}
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
{
/* flip top to bottom */
cy = intel->driDrawable->h-cy1-ch;
cx = cx1 + intel->drawX;
cy += intel->drawY;
/* 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;
}
for (i = 0 ; i < intel->numClipRects ; i++)
{
drm_clip_rect_t *box = &intel->pClipRects[i];
drm_clip_rect_t b;
if (!all) {
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;
} else {
b = *box;
}
if (b.x1 > b.x2 ||
b.y1 > b.y2 ||
b.x2 > intelScreen->width ||
b.y2 > intelScreen->height)
continue;
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, BM_MEM_AGP|BM_WRITE, 0 );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
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, BM_MEM_AGP|BM_WRITE, 0 );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
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, BM_MEM_AGP|BM_WRITE, 0 );
OUT_BATCH( clear_depth );
ADVANCE_BATCH();
}
}
}
intel_batchbuffer_flush( intel->batch );
UNLOCK_HARDWARE( intel );
}

View File

@@ -0,0 +1,60 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTEL_BLIT_H
#define INTEL_BLIT_H
#include "intel_context.h"
#include "intel_ioctl.h"
extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv );
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch);
extern void intelEmitCopyBlit( struct intel_context *intel,
GLuint cpp,
GLshort src_pitch,
GLuint src_buffer,
GLuint src_offset,
GLshort dst_pitch,
GLuint dst_buffer,
GLuint dst_offset,
GLshort srcx, GLshort srcy,
GLshort dstx, GLshort dsty,
GLshort w, GLshort h );
extern void intelEmitFillBlit( struct intel_context *intel,
GLuint cpp,
GLshort dst_pitch,
GLuint dst_buffer,
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color );
#endif

View File

@@ -0,0 +1,505 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_blit.h"
#include "intel_tris.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
#include "context.h"
#include "framebuffer.h"
#include "swrast/swrast.h"
GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst,
const drm_clip_rect_t *a,
const drm_clip_rect_t *b )
{
GLint bx = b->x1;
GLint by = b->y1;
GLint bw = b->x2 - bx;
GLint bh = b->y2 - by;
if (bx < a->x1) bw -= a->x1 - bx, bx = a->x1;
if (by < a->y1) bh -= a->y1 - by, by = a->y1;
if (bx + bw > a->x2) bw = a->x2 - bx;
if (by + bh > a->y2) bh = a->y2 - by;
if (bw <= 0) return GL_FALSE;
if (bh <= 0) return GL_FALSE;
dst->x1 = bx;
dst->y1 = by;
dst->x2 = bx + bw;
dst->y2 = by + bh;
return GL_TRUE;
}
struct intel_region *intel_drawbuf_region( struct intel_context *intel )
{
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
return intel->front_region;
case BUFFER_BIT_BACK_LEFT:
return intel->back_region;
default:
/* Not necessary to fallback - could handle either NONE or
* FRONT_AND_BACK cases below.
*/
return NULL;
}
}
struct intel_region *intel_readbuf_region( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
/* This will have to change to support EXT_fbo's, but is correct
* for now:
*/
switch (ctx->ReadBuffer->_ColorReadBufferIndex) {
case BUFFER_FRONT_LEFT:
return intel->front_region;
case BUFFER_BACK_LEFT:
return intel->back_region;
default:
assert(0);
return NULL;
}
}
static void intelBufferSize(GLframebuffer *buffer,
GLuint *width,
GLuint *height)
{
GET_CURRENT_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
/* Need to lock to make sure the driDrawable is uptodate. This
* information is used to resize Mesa's software buffers, so it has
* to be correct.
*/
LOCK_HARDWARE(intel);
if (intel->driDrawable) {
*width = intel->driDrawable->w;
*height = intel->driDrawable->h;
}
else {
*width = 0;
*height = 0;
}
UNLOCK_HARDWARE(intel);
}
static void intelSetFrontClipRects( struct intel_context *intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!dPriv) return;
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
}
static void intelSetBackClipRects( struct intel_context *intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!dPriv) return;
if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
} else {
intel->numClipRects = dPriv->numBackClipRects;
intel->pClipRects = dPriv->pBackClipRects;
intel->drawX = dPriv->backX;
intel->drawY = dPriv->backY;
if (dPriv->numBackClipRects == 1 &&
dPriv->x == dPriv->backX &&
dPriv->y == dPriv->backY) {
/* Repeat the calculation of the back cliprect dimensions here
* as early versions of dri.a in the Xserver are incorrect. Try
* very hard not to restrict future versions of dri.a which
* might eg. allocate truly private back buffers.
*/
int x1, y1;
int x2, y2;
x1 = dPriv->x;
y1 = dPriv->y;
x2 = dPriv->x + dPriv->w;
y2 = dPriv->y + dPriv->h;
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;
if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
if (x1 == dPriv->pBackClipRects[0].x1 &&
y1 == dPriv->pBackClipRects[0].y1) {
dPriv->pBackClipRects[0].x2 = x2;
dPriv->pBackClipRects[0].y2 = y2;
}
}
}
}
void intelWindowMoved( struct intel_context *intel )
{
if (!intel->ctx.DrawBuffer) {
intelSetFrontClipRects( intel );
}
else {
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
intelSetFrontClipRects( intel );
break;
case BUFFER_BIT_BACK_LEFT:
intelSetBackClipRects( intel );
break;
default:
/* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
intelSetFrontClipRects( intel );
}
}
/* 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 );
ctx->Driver.DepthRange( ctx,
ctx->Viewport.Near,
ctx->Viewport.Far );
}
}
static void emit_clip_rect_quads(struct intel_context *intel,
const drm_clip_rect_t *clear)
{
GLuint i;
for (i = 0; i < intel->numClipRects; i++) {
drm_clip_rect_t rect;
if (intel_intersect_cliprects(&rect,
clear,
&intel->pClipRects[i]))
{
intel_meta_draw_quad(intel,
rect.x1, rect.x2,
rect.y1, rect.y2,
0,
intel->ClearColor,
0, 0, 0, 0,
INTEL_BATCH_NO_CLIPRECTS);
}
}
}
/* A true meta version of this would be very simple and additionally
* machine independent. Maybe we'll get there one day.
*/
static void intelClearWithTris(struct intel_context *intel,
GLbitfield mask,
GLboolean all,
GLint cx, GLint cy,
GLint cw, GLint ch)
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
drm_clip_rect_t clear;
LOCK_HARDWARE(intel);
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;
}
/* Back and stencil cliprects are the same. Try and do both
* buffers at once:
*/
if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL)) {
intel->vtbl.meta_draw_region(intel,
intel->back_region,
intel->depth_region );
if (mask & BUFFER_BIT_BACK_LEFT)
intel->vtbl.meta_color_mask(intel, GL_TRUE );
else
intel->vtbl.meta_color_mask(intel, GL_FALSE );
if (mask & BUFFER_BIT_STENCIL)
intel->vtbl.meta_stencil_replace( intel,
intel->ctx.Stencil.WriteMask[0],
intel->ctx.Stencil.Clear);
else
intel->vtbl.meta_no_depth_stencil_write(intel);
/* Do cliprects explicitly:
*/
emit_clip_rect_quads(intel, &clear);
}
/* Front may have different cliprects:
*/
if (mask & BUFFER_BIT_FRONT_LEFT) {
intel->vtbl.meta_no_depth_stencil_write(intel);
intel->vtbl.meta_color_mask(intel, GL_TRUE );
intel->vtbl.meta_draw_region(intel,
intel->front_region,
intel->depth_region);
emit_clip_rect_quads(intel, &clear);
}
intel->vtbl.leave_meta_state( intel );
intel_batchbuffer_flush( intel->batch );
UNLOCK_HARDWARE(intel);
}
static void intelClear(GLcontext *ctx,
GLbitfield mask,
GLboolean all,
GLint cx, GLint cy,
GLint cw, GLint ch)
{
struct intel_context *intel = intel_context( ctx );
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
GLbitfield tri_mask = 0;
GLbitfield blit_mask = 0;
GLbitfield swrast_mask = 0;
if (0)
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;
}
}
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_DEPTH) {
blit_mask |= BUFFER_BIT_DEPTH;
}
if (mask & BUFFER_BIT_STENCIL) {
if (!intel->hw_stencil) {
swrast_mask |= BUFFER_BIT_STENCIL;
}
else if (ctx->Stencil.WriteMask[0] != 0xff) {
tri_mask |= BUFFER_BIT_STENCIL;
}
else {
blit_mask |= BUFFER_BIT_STENCIL;
}
}
swrast_mask |= (mask & BUFFER_BIT_ACCUM);
intelFlush( ctx );
if (blit_mask)
intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch );
if (tri_mask)
intelClearWithTris( intel, tri_mask, all, cx, cy, cw, ch);
if (swrast_mask)
_swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch );
}
/* Flip the front & back buffers
*/
static void intelPageFlip( const __DRIdrawablePrivate *dPriv )
{
#if 0
struct intel_context *intel;
int tmp, ret;
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
if (dPriv->pClipRects) {
*(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0];
intel->sarea->nbox = 1;
}
ret = drmCommandNone(intel->driFd, DRM_I830_FLIP);
if (ret) {
fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
UNLOCK_HARDWARE( intel );
exit(1);
}
tmp = intel->sarea->last_enqueue;
intelRefillBatchLocked( intel );
UNLOCK_HARDWARE( intel );
intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer );
#endif
}
void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
struct intel_context *intel;
GLcontext *ctx;
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
ctx = &intel->ctx;
if (ctx->Visual.doubleBufferMode) {
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
intelPageFlip( dPriv );
} else {
intelCopyBuffer( dPriv );
}
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
}
}
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
{
struct intel_context *intel = intel_context(ctx);
int front = 0;
if (!ctx->DrawBuffer)
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:
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
return;
}
if ( intel->sarea->pf_current_page == 1 )
front ^= 1;
intelSetFrontClipRects( intel );
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);
}
}
intel->vtbl.set_draw_region( intel,
intel->draw_region,
intel->depth_region);
}
static void intelReadBuffer( GLcontext *ctx, GLenum mode )
{
/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
}
void intelInitBufferFuncs( struct dd_function_table *functions )
{
functions->Clear = intelClear;
functions->GetBufferSize = intelBufferSize;
functions->ResizeBuffers = _mesa_resize_framebuffer;
functions->DrawBuffer = intelDrawBuffer;
functions->ReadBuffer = intelReadBuffer;
}

View File

@@ -54,6 +54,9 @@
#include "intel_tris.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "intel_pixel.h"
#include "intel_regions.h"
#include "bufmgr.h"
@@ -79,9 +82,6 @@ int INTEL_DEBUG = (0);
#define need_GL_NV_vertex_program
#include "extension_helper.h"
#ifndef VERBOSE
int VERBOSE = 0;
#endif
#if DEBUG_LOCKING
char *prevLockFile;
@@ -92,9 +92,9 @@ int prevLockLine;
* Mesa's Driver Functions
***************************************/
#define DRIVER_DATE "20060201"
#define DRIVER_DATE "20060212"
const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
static const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
{
const char * chipset;
static char buffer[128];
@@ -105,7 +105,7 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
break;
case GL_RENDERER:
switch (INTEL_CONTEXT(ctx)->intelScreen->deviceID) {
switch (intel_context(ctx)->intelScreen->deviceID) {
case PCI_CHIP_845_G:
chipset = "Intel(R) 845G"; break;
case PCI_CHIP_I830_M:
@@ -132,27 +132,6 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
}
}
static void intelBufferSize(GLframebuffer *buffer,
GLuint *width, GLuint *height)
{
GET_CURRENT_CONTEXT(ctx);
intelContextPtr intel = INTEL_CONTEXT(ctx);
/* Need to lock to make sure the driDrawable is uptodate. This
* information is used to resize Mesa's software buffers, so it has
* to be correct.
*/
LOCK_HARDWARE(intel);
if (intel->driDrawable) {
*width = intel->driDrawable->w;
*height = intel->driDrawable->h;
}
else {
*width = 0;
*height = 0;
}
UNLOCK_HARDWARE(intel);
}
/**
* Extension strings exported by the intel driver.
@@ -251,7 +230,32 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state )
_ac_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_tnl_invalidate_vertex_state( ctx, new_state );
INTEL_CONTEXT(ctx)->NewGLState |= new_state;
intel_context(ctx)->NewGLState |= new_state;
}
void intelFlush( GLcontext *ctx )
{
struct intel_context *intel = intel_context( ctx );
if (intel->Fallback)
_swrast_flush( ctx );
INTEL_FIREVERTICES( intel );
if (intel->batch->map != intel->batch->ptr)
intel_batchbuffer_flush( intel->batch );
/* XXX: Need to do an MI_FLUSH here. Actually, the bufmgr_fake.c
* code will have done one already.
*/
}
void intelFinish( GLcontext *ctx )
{
struct intel_context *intel = intel_context( ctx );
intelFlush( ctx );
bmFinishFence( intel->bm, intel->last_fence );
}
@@ -260,10 +264,7 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
_mesa_init_driver_functions( functions );
functions->Flush = intelFlush;
functions->Clear = intelClear;
functions->Finish = intelFinish;
functions->GetBufferSize = intelBufferSize;
functions->ResizeBuffers = _mesa_resize_framebuffer;
functions->GetString = intelGetString;
functions->UpdateState = intelInvalidateState;
functions->CopyColorTable = _swrast_CopyColorTable;
@@ -274,11 +275,12 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
intelInitTextureFuncs( functions );
intelInitPixelFuncs( functions );
intelInitStateFuncs( functions );
intelInitBufferFuncs( functions );
}
GLboolean intelInitContext( intelContextPtr intel,
GLboolean intelInitContext( struct intel_context *intel,
const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate,
@@ -378,6 +380,51 @@ GLboolean intelInitContext( intelContextPtr intel,
/* GL_TRUE, */
GL_FALSE);
/* Buffer manager:
*/
intel->bm = bm_fake_intel_Attach( intel );
bmInitPool(intel->bm,
intel->intelScreen->tex.offset, /* low offset */
intel->intelScreen->tex.map, /* low virtual */
intel->intelScreen->tex.size,
BM_MEM_AGP);
/* These are still static, but create regions for them.
*/
intel->front_region =
intel_region_create_static(intel,
BM_MEM_AGP,
intelScreen->front.offset,
intelScreen->front.map,
intelScreen->cpp,
intelScreen->front.pitch,
intelScreen->height);
intel->back_region =
intel_region_create_static(intel,
BM_MEM_AGP,
intelScreen->back.offset,
intelScreen->back.map,
intelScreen->cpp,
intelScreen->back.pitch,
intelScreen->height);
/* Still assuming front.cpp == depth.cpp
*/
intel->depth_region =
intel_region_create_static(intel,
BM_MEM_AGP,
intelScreen->depth.offset,
intelScreen->depth.map,
intelScreen->cpp,
intelScreen->depth.pitch,
intelScreen->height);
intel->batch = intel_batchbuffer_alloc( intel );
if (intel->ctx.Mesa_DXTn) {
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
_mesa_enable_extension( ctx, "GL_S3_s3tc" );
@@ -392,24 +439,16 @@ GLboolean intelInitContext( intelContextPtr intel,
/* DRI_TEXMGR_DO_TEXTURE_RECT ); */
intel->prim.flush = NULL;
intel->prim.primitive = ~0;
#if DO_DEBUG
INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ),
debug_control );
INTEL_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
debug_control );
#endif
#ifndef VERBOSE
if (getenv("INTEL_VERBOSE"))
VERBOSE=1;
#endif
if (getenv("INTEL_NO_RAST") ||
getenv("INTEL_NO_RAST")) {
if (getenv("INTEL_NO_RAST")) {
fprintf(stderr, "disabling 3D rasterization\n");
FALLBACK(intel, INTEL_FALLBACK_USER, 1);
}
@@ -419,7 +458,7 @@ GLboolean intelInitContext( intelContextPtr intel,
void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
{
intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
assert(intel); /* should never be null */
if (intel) {
@@ -436,7 +475,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
_swrast_DestroyContext (&intel->ctx);
intel->Fallback = 0; /* don't call _swrast_Flush later */
intelDestroyBatchBuffer(intel);
intel_batchbuffer_free(intel->batch);
if ( release_texture_heaps ) {
@@ -451,102 +490,6 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
}
}
void intelSetFrontClipRects( intelContextPtr intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!dPriv) return;
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
}
void intelSetBackClipRects( intelContextPtr intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!dPriv) return;
if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
} else {
intel->numClipRects = dPriv->numBackClipRects;
intel->pClipRects = dPriv->pBackClipRects;
intel->drawX = dPriv->backX;
intel->drawY = dPriv->backY;
if (dPriv->numBackClipRects == 1 &&
dPriv->x == dPriv->backX &&
dPriv->y == dPriv->backY) {
/* Repeat the calculation of the back cliprect dimensions here
* as early versions of dri.a in the Xserver are incorrect. Try
* very hard not to restrict future versions of dri.a which
* might eg. allocate truly private back buffers.
*/
int x1, y1;
int x2, y2;
x1 = dPriv->x;
y1 = dPriv->y;
x2 = dPriv->x + dPriv->w;
y2 = dPriv->y + dPriv->h;
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;
if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
if (x1 == dPriv->pBackClipRects[0].x1 &&
y1 == dPriv->pBackClipRects[0].y1) {
dPriv->pBackClipRects[0].x2 = x2;
dPriv->pBackClipRects[0].y2 = y2;
}
}
}
}
void intelWindowMoved( intelContextPtr intel )
{
if (!intel->ctx.DrawBuffer) {
intelSetFrontClipRects( intel );
}
else {
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
intelSetFrontClipRects( intel );
break;
case BUFFER_BIT_BACK_LEFT:
intelSetBackClipRects( intel );
break;
default:
/* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
intelSetFrontClipRects( intel );
}
}
/* 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 );
ctx->Driver.DepthRange( ctx,
ctx->Viewport.Near,
ctx->Viewport.Far );
}
}
GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
@@ -558,7 +501,7 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
{
if (driContextPriv) {
intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
if ( intel->driDrawable != driDrawPriv ) {
/* Shouldn't the readbuffer be stored also? */
@@ -578,7 +521,7 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
return GL_TRUE;
}
void intelGetLock( intelContextPtr intel, GLuint flags )
void intelGetLock( struct intel_context *intel, GLuint flags )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
__DRIscreenPrivate *sPriv = intel->driScreen;
@@ -610,117 +553,4 @@ void intelGetLock( intelContextPtr intel, GLuint flags )
}
}
void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
intelContextPtr intel;
GLcontext *ctx;
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = &intel->ctx;
if (ctx->Visual.doubleBufferMode) {
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
intelPageFlip( dPriv );
} else {
intelCopyBuffer( dPriv );
}
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
}
}
void intelInitState( GLcontext *ctx )
{
/* Mesa should do this for us:
*/
ctx->Driver.AlphaFunc( ctx,
ctx->Color.AlphaFunc,
ctx->Color.AlphaRef);
ctx->Driver.BlendColor( ctx,
ctx->Color.BlendColor );
ctx->Driver.BlendEquationSeparate( ctx,
ctx->Color.BlendEquationRGB,
ctx->Color.BlendEquationA);
ctx->Driver.BlendFuncSeparate( ctx,
ctx->Color.BlendSrcRGB,
ctx->Color.BlendDstRGB,
ctx->Color.BlendSrcA,
ctx->Color.BlendDstA);
ctx->Driver.ColorMask( ctx,
ctx->Color.ColorMask[RCOMP],
ctx->Color.ColorMask[GCOMP],
ctx->Color.ColorMask[BCOMP],
ctx->Color.ColorMask[ACOMP]);
ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
ctx->Driver.DepthFunc( ctx, ctx->Depth.Func );
ctx->Driver.DepthMask( ctx, ctx->Depth.Mask );
ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled );
ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag );
ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled );
ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled );
ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE );
ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE );
ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE );
ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
{
GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
}
ctx->Driver.LineWidth( ctx, ctx->Line.Width );
ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp );
ctx->Driver.PointSize( ctx, ctx->Point.Size );
ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple );
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height );
ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel );
ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT,
ctx->Stencil.Function[0],
ctx->Stencil.Ref[0],
ctx->Stencil.ValueMask[0] );
ctx->Driver.StencilFuncSeparate( ctx, GL_BACK,
ctx->Stencil.Function[1],
ctx->Stencil.Ref[1],
ctx->Stencil.ValueMask[1] );
ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
ctx->Driver.StencilOpSeparate( ctx, GL_FRONT,
ctx->Stencil.FailFunc[0],
ctx->Stencil.ZFailFunc[0],
ctx->Stencil.ZPassFunc[0]);
ctx->Driver.StencilOpSeparate( ctx, GL_BACK,
ctx->Stencil.FailFunc[1],
ctx->Stencil.ZFailFunc[1],
ctx->Stencil.ZPassFunc[1]);
ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
}

View File

@@ -48,28 +48,22 @@
#define DV_PF_8888 (3<<8)
struct intel_region;
struct intel_context;
typedef struct intel_context *intelContextPtr;
typedef void (*intel_tri_func)(intelContextPtr, intelVertex *, intelVertex *,
typedef void (*intel_tri_func)(struct intel_context *, intelVertex *, intelVertex *,
intelVertex *);
typedef void (*intel_line_func)(intelContextPtr, intelVertex *, intelVertex *);
typedef void (*intel_point_func)(intelContextPtr, intelVertex *);
typedef void (*intel_line_func)(struct intel_context *, intelVertex *, intelVertex *);
typedef void (*intel_point_func)(struct intel_context *, intelVertex *);
#define INTEL_FALLBACK_DRAW_BUFFER 0x1
#define INTEL_FALLBACK_READ_BUFFER 0x2
#define INTEL_FALLBACK_USER 0x4
#define INTEL_FALLBACK_NO_BATCHBUFFER 0x8
#define INTEL_FALLBACK_NO_TEXMEM 0x10
#define INTEL_FALLBACK_RENDERMODE 0x20
#define INTEL_FALLBACK_RENDERMODE 0x8
extern void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode );
extern void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode );
#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode )
#define INTEL_TEX_MAXLEVELS 10
struct intel_texture_object
{
@@ -93,7 +87,8 @@ struct intel_texture_object
struct intel_texture_image {
struct intel_texture_image
{
struct gl_texture_image base;
/* These aren't stored in gl_texture_image
@@ -109,12 +104,6 @@ struct intel_texture_image {
};
struct intel_reloc {
GLuint *value;
GLuint delta;
GLuint *dest;
};
#define INTEL_MAX_FIXUP 64
struct intel_context
@@ -122,24 +111,60 @@ struct intel_context
GLcontext ctx; /* the parent class */
struct {
void (*destroy)( intelContextPtr intel );
void (*emit_state)( intelContextPtr intel );
void (*emit_invarient_state)( intelContextPtr intel );
void (*lost_hardware)( intelContextPtr intel );
void (*update_texture_state)( intelContextPtr intel );
void (*destroy)( struct intel_context *intel );
void (*emit_state)( struct intel_context *intel );
void (*emit_invarient_state)( struct intel_context *intel );
void (*lost_hardware)( struct intel_context *intel );
void (*update_texture_state)( struct intel_context *intel );
void (*render_start)( intelContextPtr intel );
void (*set_draw_offset)( intelContextPtr intel, int offset );
void (*emit_flush)( intelContextPtr intel );
void (*render_start)( struct intel_context *intel );
void (*set_draw_region)( struct intel_context *intel,
struct intel_region *draw_region,
struct intel_region *depth_region );
void (*reduced_primitive_state)( intelContextPtr intel, GLenum rprim );
GLuint (*flush_cmd)( void );
GLboolean (*check_vertex_size)( intelContextPtr intel, GLuint expected );
void (*reduced_primitive_state)( struct intel_context *intel, GLenum rprim );
void (*clear_with_tris)( intelContextPtr intel, GLbitfield mask,
GLboolean (*check_vertex_size)( struct intel_context *intel, GLuint expected );
void (*clear_with_tris)( struct intel_context *intel, GLbitfield mask,
GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch);
/* Metaops:
*/
void (*install_meta_state)( struct intel_context *intel );
void (*leave_meta_state)( struct intel_context *intel );
void (*meta_draw_region)( struct intel_context *intel,
struct intel_region *draw_region,
struct intel_region *depth_region );
void (*meta_color_mask)( struct intel_context *intel,
GLboolean );
void (*meta_stencil_replace)( struct intel_context *intel,
GLuint mask,
GLuint clear );
void (*meta_no_depth_stencil_write)( struct intel_context *intel );
void (*meta_no_texture)( struct intel_context *intel );
void (*meta_texture_blend_replace)( struct intel_context *intel );
void (*meta_tex_rect_source)( struct intel_context *intel,
struct intel_region *region,
GLuint textureFormat );
void (*meta_draw_format)( struct intel_context *intel,
GLuint format,
GLuint depth_format );
} vtbl;
GLint refcount;
@@ -147,43 +172,26 @@ struct intel_context
GLuint NewGLState;
GLuint last_fence;
GLuint last_swap_fence;
struct {
GLuint start_offset;
GLint size;
GLint space;
GLubyte *ptr;
} batch;
#define INTEL_ALLOC_NR 64
#define INTEL_ALLOC_SIZE 4096
struct {
GLuint buffer[INTEL_ALLOC_NR];
GLuint current;
} alloc;
struct intel_batchbuffer *batch;
struct {
GLuint id;
GLuint primitive;
GLubyte *start_ptr;
void (*flush)( GLcontext * );
void (*flush)( struct intel_context * );
} prim;
GLboolean locked;
GLubyte clear_red;
GLubyte clear_green;
GLubyte clear_blue;
GLubyte clear_alpha;
GLuint ClearColor;
GLuint ClearDepth;
/* Offsets of fields within the current vertex:
*/
GLuint coloroffset;
GLuint specoffset;
/* Support for duplicating XYZW as WPOS parameter (crutch for I915).
*/
GLuint wpos_offset;
GLuint wpos_size;
@@ -201,10 +209,6 @@ struct intel_context
/* AGP memory buffer manager:
*/
struct bufmgr *bm;
struct bm_buffer_list *buffer_list;
struct intel_reloc fixup[INTEL_MAX_FIXUP];
GLuint nr_fixups;
/* State for intelvb.c and inteltris.c.
@@ -231,7 +235,6 @@ struct intel_context
/* These refer to the current draw (front vs. back) buffer:
*/
GLuint drawOffset; /* agp offset of drawbuffer */
int drawX; /* origin of drawable in draw buffer */
int drawY;
GLuint numClipRects; /* cliprects for that buffer */
@@ -347,8 +350,7 @@ do { \
#define INTEL_FIREVERTICES(intel) \
do { \
if ((intel)->prim.flush) \
(intel)->prim.flush(&(intel)->ctx); \
assert(!(intel)->prim.flush); \
} while (0)
/* ================================================================
@@ -382,7 +384,7 @@ do { \
* than COPY_DWORDS would:
*/
#if defined(i386) || defined(__i386__)
static __inline__ void * __memcpy(void * to, const void * from, size_t n)
static inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
@@ -443,21 +445,19 @@ extern int INTEL_DEBUG;
* intel_context.c:
*/
extern void intelInitDriverFunctions( struct dd_function_table *functions );
extern GLboolean intelInitContext( intelContextPtr intel,
extern GLboolean intelInitContext( struct intel_context *intel,
const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate,
struct dd_function_table *functions );
extern void intelGetLock(intelContextPtr intel, GLuint flags);
extern void intelSetBackClipRects(intelContextPtr intel);
extern void intelSetFrontClipRects(intelContextPtr intel);
extern void intelWindowMoved( intelContextPtr intel );
extern void intelGetLock(struct intel_context *intel, GLuint flags);
extern void intelInitState( GLcontext *ctx );
extern const GLubyte *intelGetString( GLcontext *ctx, GLenum name );
extern void intelFinish( GLcontext *ctx );
extern void intelFlush( GLcontext *ctx );
extern void intelInitDriverFunctions( struct dd_function_table *functions );
/* ================================================================
@@ -517,6 +517,8 @@ extern void intelInitStateFuncs( struct dd_function_table *functions );
#define BLENDFACT_INV_CONST_ALPHA 0x0f
#define BLENDFACT_MASK 0x0f
#define MI_BATCH_BUFFER_END (0xA<<23)
extern int intel_translate_compare_func( GLenum func );
extern int intel_translate_stencil_op( GLenum op );
@@ -525,28 +527,19 @@ extern int intel_translate_logic_op( GLenum opcode );
/* ================================================================
* intel_ioctl.c:
* intel_buffers.c:
*/
extern void intel_dump_batchbuffer( long offset,
int *ptr,
int count );
/* ================================================================
* intel_pixel.c:
*/
extern void intelInitPixelFuncs( struct dd_function_table *functions );
GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx );
GLboolean intel_clip_to_framebuffer( GLcontext *ctx,
const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height );
void intelInitBufferFuncs( struct dd_function_table *functions );
struct intel_region *intel_readbuf_region( struct intel_context *intel );
struct intel_region *intel_drawbuf_region( struct intel_context *intel );
extern void intelWindowMoved( struct intel_context *intel );
extern GLboolean intel_intersect_cliprects( drm_clip_rect_t *dest,
const drm_clip_rect_t *a,
const drm_clip_rect_t *b );
/*======================================================================
@@ -568,8 +561,6 @@ static inline struct intel_texture_image *intel_texture_image( struct gl_texture
return (struct intel_texture_image *)img;
}
#define INTEL_CONTEXT(ctx) intel_context(ctx)
#endif

View File

@@ -38,12 +38,13 @@
#include "intel_context.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "intel_regions.h"
#include "drm.h"
#include "bufmgr.h"
int intelEmitIrqLocked( intelContextPtr intel )
int intelEmitIrqLocked( struct intel_context *intel )
{
drmI830IrqEmit ie;
int ret, seq = 0;
@@ -53,14 +54,12 @@ int intelEmitIrqLocked( intelContextPtr intel )
ie.irq_seq = &seq;
#if 1
ret = drmCommandWriteRead( intel->driFd, DRM_I830_IRQ_EMIT,
&ie, sizeof(ie) );
if ( ret ) {
fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret );
exit(1);
}
#endif
if (0)
fprintf(stderr, "%s --> %d\n", __FUNCTION__, seq );
@@ -68,7 +67,7 @@ int intelEmitIrqLocked( intelContextPtr intel )
return seq;
}
void intelWaitIrq( intelContextPtr intel, int seq )
void intelWaitIrq( struct intel_context *intel, int seq )
{
drmI830IrqWait iw;
int ret;
@@ -78,7 +77,6 @@ void intelWaitIrq( intelContextPtr intel, int seq )
iw.irq_seq = seq;
#if 1
do {
ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
} while (ret == -EAGAIN || ret == -EINTR);
@@ -87,294 +85,61 @@ void intelWaitIrq( intelContextPtr intel, int seq )
fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret );
exit(1);
}
#endif
}
void intel_dump_batchbuffer( long offset,
int *ptr,
int count )
{
int i;
fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count);
for (i = 0; i < count/4; i += 4)
fprintf(stderr, "\t0x%08x 0x%08x 0x%08x 0x%08x\n",
/* (unsigned int)offset + i*4, */
ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]);
fprintf(stderr, "END BATCH\n\n\n");
}
#define MI_BATCH_BUFFER_END (0xA<<23)
void intelFlushBatchLocked( intelContextPtr intel,
GLboolean ignore_cliprects,
GLboolean refill,
GLboolean allow_unlock)
void intel_batch_ioctl( struct intel_context *intel,
GLuint start_offset,
GLuint used,
GLboolean ignore_cliprects)
{
drmI830BatchBuffer batch;
assert(intel->locked);
assert(intel->buffer_list);
assert(intel->batch.ptr);
assert(used);
if (0)
fprintf(stderr, "%s used %d of %d offset %x..%x refill %d\n",
fprintf(stderr, "%s used %d offset %x..%x ignore_cliprects %d\n",
__FUNCTION__,
(intel->batch.size - intel->batch.space),
intel->batch.size,
intel->batch.start_offset,
intel->batch.start_offset +
(intel->batch.size - intel->batch.space),
refill);
used,
start_offset,
start_offset + used,
ignore_cliprects);
/* Throw away non-effective packets. Won't work once we have
* hardware contexts which would preserve statechanges beyond a
* single buffer.
*/
if (intel->numClipRects == 0 && !ignore_cliprects) {
/* Note that any state thought to have been emitted actually
* hasn't:
*/
intel->batch.ptr -= (intel->batch.size - intel->batch.space);
intel->batch.space = intel->batch.size;
intel->vtbl.lost_hardware( intel );
return;
}
if (intel->batch.space != intel->batch.size) {
batch.start = intel->batch.start_offset;
batch.used = intel->batch.size - intel->batch.space;
batch.cliprects = intel->pClipRects;
batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
batch.DR1 = 0;
batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) |
(((GLuint)intel->drawY) << 16));
batch.start = start_offset;
batch.used = used;
batch.cliprects = intel->pClipRects;
batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
batch.DR1 = 0;
batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) |
(((GLuint)intel->drawY) << 16));
if ((batch.used & 0x4) == 0) {
((int *)intel->batch.ptr)[0] = 0;
((int *)intel->batch.ptr)[1] = MI_BATCH_BUFFER_END;
batch.used += 0x8;
intel->batch.ptr += 0x8;
}
else {
((int *)intel->batch.ptr)[0] = MI_BATCH_BUFFER_END;
batch.used += 0x4;
intel->batch.ptr += 0x4;
}
if (0)
intel_dump_batchbuffer( batch.start,
(int *)(intel->batch.ptr - batch.used),
batch.used );
if (0)
fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
__FUNCTION__,
batch.start,
batch.start + batch.used * 4,
batch.DR4, batch.num_cliprects);
if (INTEL_DEBUG & DEBUG_DMA)
fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
__FUNCTION__,
batch.start,
batch.start + batch.used * 4,
batch.DR4, batch.num_cliprects);
#if 1
if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch,
sizeof(batch))) {
fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno);
UNLOCK_HARDWARE(intel);
exit(1);
}
#endif
/* FIXME: use hardware contexts to avoid 'losing' hardware after
* each buffer flush.
*/
intel->vtbl.lost_hardware( intel );
}
bmUnmapBuffer( intel->bm,
intel->alloc.buffer[intel->alloc.current] );
intel->batch.ptr = NULL;
intel->batch.size = 0;
intel->batch.space = 0;
intel->last_fence = bmFenceBufferList(intel->bm, intel->buffer_list);
bmFreeBufferList(intel->buffer_list);
intel->buffer_list = NULL;
}
void intelFlushBatch( intelContextPtr intel, GLboolean refill )
{
if (intel->locked) {
intelFlushBatchLocked( intel, GL_FALSE, refill, GL_FALSE );
}
else {
assert(intel->batch.size == intel->batch.space);
}
}
static void wait_for_idle_locked( struct intel_context *intel )
{
intelInstallBatchBuffer(intel);
bmAddBuffer(intel->buffer_list, intel->draw_region->buffer,
BM_WRITE, NULL, NULL);
intelValidateBuffers(intel);
intel->vtbl.emit_flush( intel );
intelFlushBatch( intel, GL_TRUE );
bmFinishFence( intel->bm, intel->last_fence );
}
void intelWaitForIdle( intelContextPtr intel )
{
if (intel->locked) {
wait_for_idle_locked( intel );
}
else {
LOCK_HARDWARE(intel);
wait_for_idle_locked( intel );
if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch,
sizeof(batch))) {
fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno);
UNLOCK_HARDWARE(intel);
}
}
void intelFlush( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
if (intel->Fallback)
_swrast_flush( ctx );
INTEL_FIREVERTICES( intel );
if (intel->batch.size != intel->batch.space)
intelFlushBatch( intel, GL_FALSE );
}
void intelFinish( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
intelFlush( ctx );
intelWaitForIdle( intel );
}
void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch)
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
GLbitfield tri_mask = 0;
GLbitfield blit_mask = 0;
GLbitfield swrast_mask = 0;
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
/* Take care of cliprects, which are handled differently for
* clears, etc.
*/
intelFlush( &intel->ctx );
if (mask & BUFFER_BIT_FRONT_LEFT) {
if (colorMask == ~0) {
blit_mask |= BUFFER_BIT_FRONT_LEFT;
}
else {
tri_mask |= BUFFER_BIT_FRONT_LEFT;
}
}
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_DEPTH) {
blit_mask |= BUFFER_BIT_DEPTH;
}
if (mask & BUFFER_BIT_STENCIL) {
if (!intel->hw_stencil) {
swrast_mask |= BUFFER_BIT_STENCIL;
}
else if (ctx->Stencil.WriteMask[0] != 0xff) {
tri_mask |= BUFFER_BIT_STENCIL;
}
else {
blit_mask |= BUFFER_BIT_STENCIL;
}
}
swrast_mask |= (mask & BUFFER_BIT_ACCUM);
if (blit_mask)
intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch );
if (tri_mask)
intel->vtbl.clear_with_tris( intel, tri_mask, all, cx, cy, cw, ch);
if (swrast_mask)
_swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch );
}
/* Flip the front & back buffes
*/
void intelPageFlip( const __DRIdrawablePrivate *dPriv )
{
#if 0
intelContextPtr intel;
int tmp, ret;
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
if (dPriv->pClipRects) {
*(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0];
intel->sarea->nbox = 1;
}
ret = drmCommandNone(intel->driFd, DRM_I830_FLIP);
if (ret) {
fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
UNLOCK_HARDWARE( intel );
exit(1);
}
tmp = intel->sarea->last_enqueue;
intelRefillBatchLocked( intel );
UNLOCK_HARDWARE( intel );
intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer );
#endif
/* FIXME: use hardware contexts to avoid 'losing' hardware after
* each buffer flush.
*/
intel->vtbl.lost_hardware( intel );
}

View File

@@ -30,25 +30,13 @@
#include "intel_context.h"
extern void intelWaitAgeLocked( intelContextPtr intel, int age, GLboolean unlock );
void intelWaitIrq( struct intel_context *intel, int seq );
int intelEmitIrqLocked( struct intel_context *intel );
extern void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch);
extern void intelPageFlip( const __DRIdrawablePrivate *dpriv );
extern void intelWaitForIdle( intelContextPtr intel );
extern void intelFlushBatch( intelContextPtr intel, GLboolean refill );
extern void intelFlushBatchLocked( intelContextPtr intel,
GLboolean ignore_cliprects,
GLboolean refill,
GLboolean allow_unlock);
extern void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock );
extern void intelFinish( GLcontext *ctx );
extern void intelFlush( GLcontext *ctx );
void intelWaitIrq( intelContextPtr intel, int seq );
int intelEmitIrqLocked( intelContextPtr intel );
void intel_batch_ioctl( struct intel_context *intel,
GLuint start_offset,
GLuint used,
GLboolean ignore_cliprects);
#endif

View File

@@ -177,8 +177,27 @@ GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level)
{
return (mt->offset[face][level].x +
mt->offset[face][level].y * mt->pitch) * mt->cpp;
return mt->offset[face][level].offset;
}
GLuint intel_miptree_depth_image_stride(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level)
{
return mt->offset[face][level].depth_image_stride;
}
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level,
GLuint x, GLuint y,
GLuint w, GLuint h, GLuint d)
{
mt->offset[face][level].offset = (x + y * mt->pitch) * mt->cpp;
mt->offset[face][level].width = w;
mt->offset[face][level].height = h;
mt->offset[face][level].depth = d;
}
@@ -188,12 +207,16 @@ GLubyte *intel_miptree_image_map(struct intel_context *intel,
struct intel_mipmap_tree *mt,
GLuint face,
GLuint level,
GLuint *stride)
GLuint *row_stride,
GLuint *image_stride)
{
DBG("%s \n", __FUNCTION__);
if (stride)
*stride = mt->pitch * mt->cpp;
if (row_stride)
*row_stride = mt->pitch * mt->cpp;
if (image_stride)
*image_stride = mt->offset[face][level].depth_image_stride;
return (intel_region_map(intel, mt->region) +
intel_miptree_image_offset(mt, face, level));
@@ -209,25 +232,34 @@ void intel_miptree_image_unmap(struct intel_context *intel,
/* Upload data for a particular image.
*
* TODO: 3D textures
*/
void intel_miptree_image_data(struct intel_context *intel,
struct intel_mipmap_tree *dst,
GLuint face,
GLuint level,
void *src, GLuint src_pitch )
void *src,
GLuint src_row_pitch,
GLuint src_image_pitch)
{
GLuint depth = dst->offset[face][level].depth;
GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
GLuint dst_image_stride = intel_miptree_depth_image_stride(dst, face, level);
GLuint i;
DBG("%s\n", __FUNCTION__);
intel_region_data(intel,
dst->region,
dst->offset[face][level].x,
dst->offset[face][level].y,
src,
src_pitch,
0, 0, /* source x,y */
dst->offset[face][level].width,
dst->offset[face][level].height);
for (i = 0; i < depth; i++) {
intel_region_data(intel,
dst->region, dst_offset,
0,
0,
src,
src_row_pitch,
0, 0, /* source x,y */
dst->offset[face][level].width,
dst->offset[face][level].height);
dst_offset += dst_image_stride;
src += src_image_pitch;
}
}
/* Copy mipmap image between trees
@@ -237,21 +269,28 @@ void intel_miptree_image_copy( struct intel_context *intel,
GLuint face, GLuint level,
struct intel_mipmap_tree *src )
{
DBG("%s\n", __FUNCTION__);
assert(src->offset[face][level].width ==
dst->offset[face][level].width);
GLuint width = src->offset[face][level].width;
GLuint height = src->offset[face][level].height;
GLuint depth = src->offset[face][level].depth;
GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
GLuint src_offset = intel_miptree_image_offset(src, face, level);
GLuint dst_image_stride = intel_miptree_depth_image_stride(dst, face, level);
GLuint src_image_stride = intel_miptree_depth_image_stride(src, face, level);
GLuint i;
assert(src->offset[face][level].height ==
dst->offset[face][level].height);
for (i = 0; i < depth; i++) {
intel_region_copy(intel,
dst->region, dst_offset,
0,
0,
src->region, src_offset,
0,
0,
width,
height);
intel_region_copy(intel,
dst->region,
dst->offset[face][level].x,
dst->offset[face][level].y,
src->region,
src->offset[face][level].x,
src->offset[face][level].y,
src->offset[face][level].width,
src->offset[face][level].height);
dst_offset += dst_image_stride;
src_offset += src_image_stride;
}
}

View File

@@ -58,11 +58,11 @@
struct intel_mipmap_offset {
GLuint x;
GLuint y;
GLuint offset;
GLuint width;
GLuint height;
GLuint depth; /* how will this work? */
GLuint depth;
GLuint depth_image_stride;
};
struct intel_mipmap_tree {
@@ -127,7 +127,8 @@ GLubyte *intel_miptree_image_map( struct intel_context *intel,
struct intel_mipmap_tree *mt,
GLuint face,
GLuint level,
GLuint *stride );
GLuint *row_stride,
GLuint *image_stride);
void intel_miptree_image_unmap( struct intel_context *intel,
struct intel_mipmap_tree *mt );
@@ -140,6 +141,16 @@ GLuint intel_miptree_image_offset( struct intel_mipmap_tree *mt,
GLuint face,
GLuint level );
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level,
GLuint x, GLuint y,
GLuint w, GLuint h, GLuint d);
GLuint intel_miptree_depth_image_stride(struct intel_mipmap_tree *mt,
GLuint face,
GLuint level);
/* Upload an image into a tree
@@ -148,7 +159,9 @@ void intel_miptree_image_data(struct intel_context *intel,
struct intel_mipmap_tree *dst,
GLuint face,
GLuint level,
void *src, GLuint src_pitch );
void *src,
GLuint src_row_pitch,
GLuint src_image_pitch);
/* Copy an image between two trees
*/

View File

@@ -1,77 +1,40 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "enums.h"
#include "mtypes.h"
#include "macros.h"
#include "swrast/swrast.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "intel_regions.h"
#include "bufmgr.h"
#include "intel_pixel.h"
static GLboolean
check_color( GLcontext *ctx, GLenum type, GLenum format,
const struct gl_pixelstore_attrib *packing,
const void *pixels, GLint sz, GLint pitch )
#if 0
struct intel_client_region *intel_pack_region( struct intel_context *intel,
const struct gl_pixelstore_attrib *pack,
GLenum format,
GLenum type,
GLvoid *pixels )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
GLuint cpp = intel->intelScreen->cpp;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if ( (pitch & 63) ||
ctx->_ImageTransferState ||
packing->SwapBytes ||
packing->LsbFirst) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: failed 1\n", __FUNCTION__);
return GL_FALSE;
}
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV &&
cpp == 4 &&
format == GL_BGRA ) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: passed 2\n", __FUNCTION__);
return GL_TRUE;
}
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: failed\n", __FUNCTION__);
return GL_FALSE;
}
struct intel_client_region *intel_unpack_region( struct intel_context *intel,
const struct gl_pixelstore_attrib *pack,
GLenum format,
GLenum type,
GLvoid *pixels )
{
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
/* XXX: Need to adjust pixels pointer for unpack->skip pixels/rows
* offsets.
*/
}
void release_client_region( struct intel_context *intel,
struct intel_region *region )
{
}
#endif
GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx )
{
return !(ctx->Color.AlphaEnabled ||
@@ -87,6 +50,33 @@ GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx )
ctx->Texture._EnabledUnits);
}
#if 0
/* The intel_region struct doesn't really do enough to capture the
* format of the pixels in the region. For now this code assumes that
* the region is a display surface and hence is either ARGB8888 or
* RGB565.
*/
GLboolean intel_check_blit_format( struct intel_region *region,
struct intel_client_region *client_region )
{
if (region->cpp == 4
client_region->cpp == 4 &&
client_region->type == GL_UNSIGNED_INT_8_8_8_8_REV &&
client_region->format == GL_BGRA ) {
return GL_TRUE;
}
if (region->cpp == 2 &&
client_region->cpp == 2 &&
client_region->type == GL_UNSIGNED_INT_5_6_5_REV &&
client_region->format == GL_BGR ) {
return GL_TRUE;
}
fprintf(stderr, "%s: request doesn't match pixel format\n", __FUNCTION__);
return GL_FALSE;
}
#endif
GLboolean intel_clip_to_framebuffer( GLcontext *ctx,
@@ -123,496 +113,6 @@ GLboolean intel_clip_to_framebuffer( GLcontext *ctx,
return GL_TRUE;
}
static GLboolean
intelTryReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
GLint size = 0;
GLint pitch = pack->RowLength ? pack->RowLength : width;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
/* Only accelerate reading to agp buffers.
*/
if ( 1 ) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: dest not agp\n", __FUNCTION__);
return GL_FALSE;
}
/* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
* blitter:
*/
if (!pack->Invert) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
return GL_FALSE;
}
if (!check_color(ctx, type, format, pack, pixels, size, pitch))
return GL_FALSE;
switch ( intel->intelScreen->cpp ) {
case 4:
break;
default:
return GL_FALSE;
}
/* Although the blits go on the command buffer, need to do this and
* fire with lock held to guarentee cliprects and drawOffset are
* correct.
*
* This is an unusual situation however, as the code which flushes
* a full command buffer expects to be called unlocked. As a
* workaround, immediately flush the buffer on aquiring the lock.
*/
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int nbox = dPriv->numClipRects;
int src_offset = intel->drawOffset;
int src_pitch = intel->intelScreen->front.pitch;
int dst_offset = 0;
drm_clip_rect_t *box = dPriv->pClipRects;
int i;
if (!intel_clip_to_framebuffer(ctx, ctx->ReadBuffer, &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s totally clipped -- nothing to do\n",
__FUNCTION__);
return GL_TRUE;
}
y = dPriv->h - y - height;
x += dPriv->x;
y += dPriv->y;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
src_pitch, pitch);
for (i = 0 ; i < nbox ; i++)
{
GLint bx = box[i].x1;
GLint by = box[i].y1;
GLint bw = box[i].x2 - bx;
GLint bh = box[i].y2 - by;
if (bx < x) bw -= x - bx, bx = x;
if (by < y) bh -= y - by, by = y;
if (bx + bw > x + width) bw = x + width - bx;
if (by + bh > y + height) bh = y + height - by;
if (bw <= 0) continue;
if (bh <= 0) continue;
intelEmitCopyBlitLocked( intel,
intel->intelScreen->cpp,
src_pitch, src_offset,
pitch, dst_offset,
bx, by,
bx - x, by - y,
bw, bh );
}
}
UNLOCK_HARDWARE( intel );
intelFinish( &intel->ctx );
return GL_TRUE;
}
static void
intelReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!intelTryReadPixels( ctx, x, y, width, height, format, type, pack,
pixels))
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack,
pixels);
}
static void do_draw_pix( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint pitch,
const void *pixels,
GLuint dest )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = intel->driDrawable;
drm_clip_rect_t *box = dPriv->pClipRects;
int nbox = dPriv->numClipRects;
int i;
int src_offset = 0;
int src_pitch = pitch;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
if (ctx->DrawBuffer)
{
y -= height; /* cope with pixel zoom */
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer,
&x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
return;
}
y = dPriv->h - y - height; /* convert from gl to hardware coords */
x += dPriv->x;
y += dPriv->y;
for (i = 0 ; i < nbox ; i++ )
{
GLint bx = box[i].x1;
GLint by = box[i].y1;
GLint bw = box[i].x2 - bx;
GLint bh = box[i].y2 - by;
if (bx < x) bw -= x - bx, bx = x;
if (by < y) bh -= y - by, by = y;
if (bx + bw > x + width) bw = x + width - bx;
if (by + bh > y + height) bh = y + height - by;
if (bw <= 0) continue;
if (bh <= 0) continue;
intelEmitCopyBlitLocked( intel,
intel->intelScreen->cpp,
src_pitch, src_offset,
intel->intelScreen->front.pitch,
intel->drawOffset,
bx - x, by - y,
bx, by,
bw, bh );
}
}
UNLOCK_HARDWARE( intel );
intelFinish( &intel->ctx );
}
static GLboolean
intelTryDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
GLuint dest;
GLuint cpp = intel->intelScreen->cpp;
GLint size = width * pitch * cpp;
/* XXX: Need to adjust pixels pointer for unpack->skip pixels/rows
* offsets.
*/
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
switch (format) {
case GL_RGB:
case GL_RGBA:
case GL_BGRA:
dest = intel->drawOffset;
/* Planemask doesn't have full support in blits.
*/
if (!ctx->Color.ColorMask[RCOMP] ||
!ctx->Color.ColorMask[GCOMP] ||
!ctx->Color.ColorMask[BCOMP] ||
!ctx->Color.ColorMask[ACOMP]) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: planemask\n", __FUNCTION__);
return GL_FALSE;
}
/* Can't do conversions on agp reads/draws.
*/
if ( 1 ) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: not agp memory\n", __FUNCTION__);
return GL_FALSE;
}
if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
return GL_FALSE;
}
if (!intel_check_color_per_fragment_ops(ctx)) {
return GL_FALSE;
}
if (!ctx->Current.RasterPosValid)
return GL_FALSE;
if (ctx->Pixel.ZoomX != 1.0F ||
ctx->Pixel.ZoomY != -1.0F)
return GL_FALSE;
break;
default:
return GL_FALSE;
}
if ( 0 )
{
do_draw_pix( ctx, x, y, width, height, pitch, pixels,
dest );
return GL_TRUE;
}
else if (0)
{
/* Pixels is in regular memory -- get dma buffers and perform
* upload through them. No point doing this for regular uploads
* but once we remove some of the restrictions above (colormask,
* pixelformat conversion, zoom?, etc), this could be a win.
*/
}
else
return GL_FALSE;
}
static void
intelDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!intelTryDrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels ))
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels );
}
struct intel_region *intel_drawbuf_region( struct intel_context *intel )
{
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
return intel->front_region;
case BUFFER_BIT_BACK_LEFT:
return intel->back_region;
default:
/* Not necessary to fallback - could handle either NONE or
* FRONT_AND_BACK cases below.
*/
return NULL;
}
}
struct intel_region *intel_readbuf_region( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
/* This will have to change to support EXT_fbo's, but is correct
* for now:
*/
switch (ctx->ReadBuffer->_ColorReadBufferIndex) {
case BUFFER_FRONT_LEFT:
return intel->front_region;
case BUFFER_BACK_LEFT:
return intel->back_region;
default:
assert(0);
return NULL;
}
}
/**
* Implement glCopyPixels for the front color buffer (or back buffer Pixmap)
* for the color buffer. Don't support zooming, pixel transfer, etc.
* We do support copying from one window to another, ala glXMakeCurrentRead.
*/
static GLboolean intelTryCopyPixels( GLcontext *ctx,
GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint dstx, GLint dsty,
GLenum type )
{
struct intel_context *intel = intel_context( ctx );
struct intel_region *dst = intel_drawbuf_region( intel );
struct intel_region *src = NULL;
/* Copypixels can be more than a straight copy. Ensure all the
* extra operations are disabled:
*/
if (!intel_check_color_per_fragment_ops(ctx) ||
ctx->_ImageTransferState ||
ctx->Pixel.ZoomX != 1.0F ||
ctx->Pixel.ZoomY != 1.0F)
return GL_FALSE;
switch (type) {
case GL_COLOR:
src = intel_readbuf_region( intel );
/* No readbuffer, copypixels is a noop:
*/
if (!src)
return GL_TRUE;
break;
case GL_DEPTH:
/* Don't think this is really possible execpt at 16bpp, when we have no stencil.
*/
if (intel->intelScreen->cpp == 2)
src = intel->depth_region;
break;
case GL_STENCIL:
/* Don't think this is really possible.
*/
break;
case GL_DEPTH_STENCIL_EXT:
/* Does it matter whether it is stencil/depth or depth/stencil?
*/
src = intel->depth_region;
break;
default:
break;
}
if (!src || !dst)
return GL_FALSE;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
intelInstallBatchBuffer( intel );
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
drm_clip_rect_t *box = dPriv->pClipRects;
GLint nbox = dPriv->numClipRects;
GLint delta_x = srcx - dstx;
GLint delta_y = srcy - dsty;
GLuint dst_offset = 0;
GLuint src_offset = 0;
GLuint i;
#if 0
dsty -= height; /* cope with pixel zoom */
srcy -= height; /* cope with pixel zoom */
#endif
if (!ctx->DrawBuffer)
goto out;
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &dstx, &dsty, &width, &height))
goto out;
/* Update source for clipped dest. Need to also clip the source rect.
*/
srcx = dstx + delta_x;
srcy = dsty + delta_y;
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &srcx, &srcy, &width, &height))
goto out;
/* Update dest for clipped source:
*/
dstx = srcx - delta_x;
dsty = srcy - delta_y;
srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */
dsty = dPriv->h - dsty - height; /* convert from gl to hardware coords */
srcx += dPriv->x;
dstx += dPriv->x;
srcy += dPriv->y;
dsty += dPriv->y;
bmAddBuffer(intel->buffer_list, dst->buffer, BM_NO_EVICT|BM_NO_UPLOAD|BM_WRITE,
NULL, &dst_offset);
bmAddBuffer(intel->buffer_list, src->buffer, BM_NO_EVICT|BM_NO_UPLOAD|BM_READ,
NULL, &src_offset);
if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP))
goto out;
/* Could do slightly more clipping: Eg, take the intersection of
* the existing set of cliprects and those cliprects translated
* by delta_x, delta_y:
*
* This code will not overwrite other windows, but will
* introduce garbage when copying from obscured window regions.
*/
for (i = 0 ; i < nbox ; i++ )
{
GLint bx = box[i].x1;
GLint by = box[i].y1;
GLint bw = box[i].x2 - bx;
GLint bh = box[i].y2 - by;
if (bx < dstx) bw -= dstx - bx, bx = dstx;
if (by < dsty) bh -= dsty - by, by = dsty;
if (bx + bw > dstx + width) bw = dstx + width - bx;
if (by + bh > dsty + height) bh = dsty + height - by;
if (bw <= 0) continue;
if (bh <= 0) continue;
assert(dst_offset == intel->drawOffset);
intelEmitCopyBlitLocked( intel,
dst->cpp,
src->pitch, src_offset,
dst->pitch, dst_offset,
bx + delta_x, by - delta_y, /* srcx, srcy */
bx, by, /* dstx, dsty */
bw, bh );
}
}
out:
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE);
UNLOCK_HARDWARE( intel );
return GL_TRUE;
}
static void
intelCopyPixels( GLcontext *ctx,
GLint srcx, GLint srcy, GLsizei width, GLsizei height,
GLint destx, GLint desty, GLenum type )
{
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!intelTryCopyPixels( ctx, srcx, srcy, width, height, destx, desty, type)) {
/* if (INTEL_DEBUG & DEBUG_FALLBACKS) */
_mesa_printf("fallback to _swrast_CopyPixels\n");
_swrast_CopyPixels( ctx, srcx, srcy, width, height, destx, desty, type);
}
}
@@ -634,3 +134,4 @@ void intelInitPixelFuncs( struct dd_function_table *functions )
functions->DrawPixels = _swrast_DrawPixels;
}
}

View File

@@ -0,0 +1,63 @@
/**************************************************************************
*
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTEL_PIXEL_H
#define INTEL_PIXEL_H
#include "mtypes.h"
void intelInitPixelFuncs( struct dd_function_table *functions );
GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx );
GLboolean intel_clip_to_framebuffer( GLcontext *ctx,
const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height );
void intelReadPixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels );
void intelDrawPixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format,
GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels );
void intelCopyPixels( GLcontext *ctx,
GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint destx, GLint desty,
GLenum type );
#endif

View File

@@ -0,0 +1,196 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "enums.h"
#include "mtypes.h"
#include "macros.h"
#include "swrast/swrast.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "intel_regions.h"
#include "intel_pixel.h"
#include "bufmgr.h"
static GLboolean do_texture_copypixels( GLcontext *ctx,
GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint dstx, GLint dsty,
GLenum type )
{
return GL_FALSE;
}
/**
* CopyPixels with the blitter. Don't support zooming, pixel transfer, etc.
*/
static GLboolean do_blit_copypixels( GLcontext *ctx,
GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint dstx, GLint dsty,
GLenum type )
{
struct intel_context *intel = intel_context( ctx );
struct intel_region *dst = intel_drawbuf_region( intel );
struct intel_region *src = NULL;
/* Copypixels can be more than a straight copy. Ensure all the
* extra operations are disabled:
*/
if (!intel_check_color_per_fragment_ops(ctx) ||
ctx->Pixel.ZoomX != 1.0F ||
ctx->Pixel.ZoomY != 1.0F)
return GL_FALSE;
switch (type) {
case GL_COLOR:
src = intel_readbuf_region( intel );
break;
case GL_DEPTH:
/* Don't think this is really possible execpt at 16bpp, when we have no stencil.
*/
if (intel->intelScreen->cpp == 2)
src = intel->depth_region;
break;
case GL_STENCIL:
/* Don't think this is really possible.
*/
break;
case GL_DEPTH_STENCIL_EXT:
/* Does it matter whether it is stencil/depth or depth/stencil?
*/
src = intel->depth_region;
break;
default:
break;
}
if (!src || !dst)
return GL_FALSE;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
drm_clip_rect_t *box = dPriv->pClipRects;
GLint nbox = dPriv->numClipRects;
GLint delta_x = srcx - dstx;
GLint delta_y = srcy - dsty;
GLuint i;
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &dstx, &dsty, &width, &height))
goto out;
/* Update source for clipped dest. Need to also clip the source rect.
*/
srcx = dstx + delta_x;
srcy = dsty + delta_y;
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &srcx, &srcy, &width, &height))
goto out;
/* Update dest for clipped source:
*/
dstx = srcx - delta_x;
dsty = srcy - delta_y;
srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */
dsty = dPriv->h - dsty - height; /* convert from gl to hardware coords */
srcx += dPriv->x;
dstx += dPriv->x;
srcy += dPriv->y;
dsty += dPriv->y;
/* Could do slightly more clipping: Eg, take the intersection of
* the existing set of cliprects and those cliprects translated
* by delta_x, delta_y:
*
* This code will not overwrite other windows, but will
* introduce garbage when copying from obscured window regions.
*/
for (i = 0 ; i < nbox ; i++ )
{
GLint bx = box[i].x1;
GLint by = box[i].y1;
GLint bw = box[i].x2 - bx;
GLint bh = box[i].y2 - by;
if (bx < dstx) bw -= dstx - bx, bx = dstx;
if (by < dsty) bh -= dsty - by, by = dsty;
if (bx + bw > dstx + width) bw = dstx + width - bx;
if (by + bh > dsty + height) bh = dsty + height - by;
if (bw <= 0) continue;
if (bh <= 0) continue;
intelEmitCopyBlit( intel,
dst->cpp,
src->pitch, src->buffer, 0,
dst->pitch, dst->buffer, 0,
bx + delta_x, by - delta_y, /* srcx, srcy */
bx, by, /* dstx, dsty */
bw, bh );
}
}
out:
intel_batchbuffer_flush( intel->batch );
UNLOCK_HARDWARE( intel );
return GL_TRUE;
}
void intelCopyPixels( GLcontext *ctx,
GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint destx, GLint desty,
GLenum type )
{
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (do_blit_copypixels( ctx, srcx, srcy, width, height, destx, desty, type))
return;
if (do_texture_copypixels( ctx, srcx, srcy, width, height, destx, desty, type))
return;
_mesa_printf("fallback to _swrast_CopyPixels\n");
_swrast_CopyPixels( ctx, srcx, srcy, width, height, destx, desty, type);
}

View File

@@ -0,0 +1,242 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "enums.h"
#include "mtypes.h"
#include "macros.h"
#include "swrast/swrast.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "intel_regions.h"
#include "intel_pixel.h"
#include "bufmgr.h"
static GLboolean do_texture_draw_pixels( struct intel_context *intel,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
#if 0
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int textureFormat;
GLenum glTextureFormat;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if ( ctx->_ImageTransferState ||
unpack->SwapBytes ||
unpack->LsbFirst ||
ctx->Texture._EnabledUnits ||
ctx->FragmentProgram._Enabled) {
fprintf(stderr, "%s: cannot use texture path\n", __FUNCTION__);
return GL_FALSE;
}
glGenTextures();
glTextureImage2D();
glBindTexture();
glEnable(GL_TEXTURE_RECTANGLE_NV);
glDisable(GL_POLYGON_STIPPLE);
glDisable(GL_CULL);
_mesa_install_vp_passthrough(ctx);
_mesa_push_current(ctx);
if (intel->Fallback)
goto Fail;
glBegin(GL_QUADS);
glVertex3f();
glTexCoord2f();
glVertex3f();
glTexCoord2f();
glVertex3f();
glTexCoord2f();
glVertex3f();
glTexCoord2f();
glEnd();
glFinish();
ASSIGN_4V(ctx->Current.Atrrib[VERT_ATTRIB_TEX0], tex0);
fail:
glDisable(GL_TEXTURE_RECTANGLE_NV);
glDeleteTextures();
glBindTexture(old);
#endif
return GL_FALSE;
}
/* Pros:
* - no waiting for idle before updating framebuffer.
*
* Cons:
* - if upload is by memcpy, this may actually be slower than fallback path.
* - uploads the whole image even if destination is clipped
*
* Need to benchmark.
*/
static GLboolean do_blit_draw_pixels( struct intel_context *intel,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
#if 0
struct intel_region *dest = intel_drawbuf_region(intel);
struct intel_region *src = NULL;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!src || !dest)
return GL_FALSE;
if (!intel_check_blit_format(dest, src))
return GL_FALSE;
if (!intel_check_blit_fragment_ops(ctx))
return GL_FALSE;
if (ctx->Pixel.ZoomX != 1.0F)
return GL_FALSE;
if (ctx->Pixel.ZoomY == -1.0F)
y -= height;
else if (ctx->Pixel.ZoomY == 1.0F) {
src_pitch = -src_pitch;
src_y += height;
}
else
return GL_FALSE;
if (unpack->BufferObj->Name) {
src = intel_bufferobj_unpack_region(intel, unpack,
width, height,
format, type,
unpack->BufferObj);
src_offset = (unsigned long)pixels;
}
else {
src = intel_client_unpack_region(intel, unpack,
width, height,
format, type, pixels);
src_offset = 0;
}
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int nbox = dPriv->numClipRects;
drm_clip_rect_t *box = dPriv->pClipRects;
drm_clip_rect_t rect;
int i;
y = dPriv->h - y - height; /* convert from gl to hardware coords */
x += dPriv->x;
y += dPriv->y;
for (i = 0 ; i < nbox ; i++ )
{
if (!intel_intersect_cliprects(rect, db_rect, &box[i]))
continue;
intelEmitCopyBlit( intel,
intel->intelScreen->cpp,
src->pitch, src->buffer, src_offset,
dst->pitch, dst->buffer, 0,
rect->x1 - x,
rect->y1 - y,
rect->x1,
rect->y1,
rect->x2 - rect->x1,
rect->y2 - rect->y1 );
}
}
intel_release_unpack_region( intel, src );
fence = intel_batchbuffer_flush( intel->batch );
UNLOCK_HARDWARE( intel );
bmWaitFence(intel->bm, fence);
intel_region_release(intel, &src);
#endif
return GL_FALSE;
}
void intelDrawPixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format,
GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
struct intel_context *intel = intel_context(ctx);
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (do_texture_draw_pixels( intel, x, y, width, height, format, type,
unpack, pixels ))
return;
if (do_blit_draw_pixels( intel, x, y, width, height, format, type,
unpack, pixels ))
return;
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels );
}

View File

@@ -0,0 +1,249 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "enums.h"
#include "mtypes.h"
#include "macros.h"
#include "swrast/swrast.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "intel_regions.h"
#include "intel_pixel.h"
#include "bufmgr.h"
static GLboolean
do_texture_readpixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
struct intel_region *dest_region )
{
#if 0
struct intel_context *intel = intel_context(ctx);
intelScreenPrivate *screen = intel->intelScreen;
GLint pitch = pack->RowLength ? pack->RowLength : width;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int textureFormat;
GLenum glTextureFormat;
int destFormat, depthFormat, destPitch;
drm_clip_rect_t tmp;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if ( ctx->_ImageTransferState ||
pack->SwapBytes ||
pack->LsbFirst ||
!pack->Invert) {
fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
return GL_FALSE;
}
intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel));
if (!intel->vtbl.meta_render_dest(intel,
dest_region,
type, format))
{
fprintf(stderr, "%s: couldn't set dest %s/%s\n",
__FUNCTION__,
_mesa_lookup_enum_by_nr(type),
_mesa_lookup_enum_by_nr(format));
return GL_FALSE;
}
LOCK_HARDWARE( intel );
intel->vtbl.install_meta_state(intel);
intel->vtbl.meta_no_depth_stencil_write(intel);
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
SET_STATE(i830, state);
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
return GL_TRUE;
}
y = dPriv->h - y - height;
x += dPriv->x;
y += dPriv->y;
/* Set the frontbuffer up as a large rectangular texture.
*/
intel->vtbl.meta_tex_rect_source( intel,
src_region,
textureFormat );
intel->vtbl.meta_texture_blend_replace( i830, glTextureFormat );
/* Set the 3d engine to draw into the destination region:
*/
intel->vtbl.meta_draw_region(intel, dest_region);
intel->vtbl.meta_draw_format(intel, destFormat, depthFormat ); /* ?? */
/* Draw a single quad, no cliprects:
*/
intel->vtbl.meta_disable_cliprects(intel);
intel->vtbl.draw_quad(intel,
0, width, 0, height,
0x00ff00ff,
x, x+width,
y, y+height );
intel->vtbl.leave_meta_state(intel);
UNLOCK_HARDWARE( intel );
intel_region_wait_fence( ctx, dest_region ); /* required by GL */
return GL_TRUE;
#endif
return GL_FALSE;
}
static GLboolean do_blit_readpixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
#if 0
struct intel_context *intel = intel_context(ctx);
GLint pitch = pack->RowLength ? pack->RowLength : width;
struct intel_region *src = intel_readbuf_region(intel);
struct intel_client_region *dst = intel_client_pack_region(intel,
pack,
pixels);
if (ctx->_ImageTransferState ||
pack->SwapBytes ||
pack->LsbFirst) {
fprintf(stderr, "%s: failed 1\n", __FUNCTION__);
return GL_FALSE;
}
/* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
* blitter:
*/
if (!pack->Invert) {
fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
return GL_FALSE;
}
if (!intel_check_blit_format(src, format, type))
return GL_FALSE;
/* Although the blits go on the command buffer, need to do this and
* fire with lock held to guarentee cliprects are correct.
*/
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int nbox = dPriv->numClipRects;
drm_clip_rect_t *box = dPriv->pClipRects;
int i;
y = dPriv->h - y - height;
x += dPriv->x;
y += dPriv->y;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
src_pitch, pitch);
for (i = 0 ; i < nbox ; i++)
{
GLint bx = box[i].x1;
GLint by = box[i].y1;
GLint bw = box[i].x2 - bx;
GLint bh = box[i].y2 - by;
if (bx < x) bw -= x - bx, bx = x;
if (by < y) bh -= y - by, by = y;
if (bx + bw > x + width) bw = x + width - bx;
if (by + bh > y + height) bh = y + height - by;
if (bw <= 0) continue;
if (bh <= 0) continue;
intelEmitCopyBlit( intel,
src->cpp,
src->pitch, src->buffer, 0,
dst->pitch, dst->buffer, 0,
bx, by,
bx - x, by - y,
bw, bh );
}
intel_batchbuffer_flush(intel->batch);
intel_client_region_release(intel, dst);
}
UNLOCK_HARDWARE( intel );
return GL_TRUE;
#endif
return GL_FALSE;
}
void
intelReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
intelFlush( ctx );
if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack, pixels))
return;
if (do_texture_readpixels(ctx, x, y, width, height, format, type, pack, pixels))
return;
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, pixels);
}

View File

@@ -41,7 +41,7 @@
#include "intel_context.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "bufmgr.h"
/* XXX: Thread safety?
@@ -62,6 +62,7 @@ void intel_region_unmap(struct intel_context *intel,
DBG("%s\n", __FUNCTION__);
if (!--region->map_refcount) {
bmUnmapBuffer(intel->bm, region->buffer);
region->map = NULL;
}
}
@@ -89,6 +90,7 @@ void intel_region_reference( struct intel_region **dst,
struct intel_region *src)
{
src->refcount++;
assert(*dst == NULL);
*dst = src;
}
@@ -150,6 +152,7 @@ struct intel_region *intel_region_create_static( struct intel_context *intel,
static void _mesa_copy_rect( GLubyte *dst,
GLuint cpp,
GLuint dst_pitch,
@@ -185,60 +188,6 @@ static void _mesa_copy_rect( GLubyte *dst,
}
/* Could make color a char * to handle deeper buffers.
*/
static void _mesa_fill_rect( GLubyte *dst,
GLuint cpp,
GLuint dst_pitch,
GLuint dst_x,
GLuint dst_y,
GLuint width,
GLuint height,
GLuint color )
{
GLuint i,j;
switch (cpp) {
case 1:
dst += dst_x;
dst += dst_y * dst_pitch;
for (i = 0; i < height; i++) {
memset(dst, color, width);
dst += dst_pitch;
}
break;
case 2: {
GLushort color_short = color & 0xffff;
GLushort *dst_short = (GLushort *)dst;
dst_short += dst_x;
dst_short += dst_y * dst_pitch;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++)
dst_short[j] = color_short;
}
break;
}
case 4: {
GLuint *dst_int = (GLuint *)dst;
dst_int += dst_x;
dst_int += dst_y * dst_pitch;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++)
dst_int[j] = color;
}
break;
}
default:
assert(0);
return;
}
}
/* Upload data to a rectangular sub-region. Lots of choices how to do this:
*
* - memcpy by span to current destination
@@ -248,6 +197,7 @@ static void _mesa_fill_rect( GLubyte *dst,
*/
void intel_region_data(struct intel_context *intel,
struct intel_region *dst,
GLuint dst_offset,
GLuint dstx, GLuint dsty,
void *src, GLuint src_pitch,
GLuint srcx, GLuint srcy,
@@ -257,7 +207,7 @@ void intel_region_data(struct intel_context *intel,
LOCK_HARDWARE(intel);
_mesa_copy_rect(intel_region_map(intel, dst),
_mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
dst->cpp,
dst->pitch,
dstx, dsty,
@@ -277,52 +227,24 @@ void intel_region_data(struct intel_context *intel,
*/
void intel_region_copy( struct intel_context *intel,
struct intel_region *dst,
GLuint dst_offset,
GLuint dstx, GLuint dsty,
struct intel_region *src,
GLuint src_offset,
GLuint srcx, GLuint srcy,
GLuint width, GLuint height )
{
unsigned dst_offset;
unsigned src_offset;
struct bm_buffer_list *list = bmNewBufferList();
DBG("%s\n", __FUNCTION__);
assert(src->cpp == dst->cpp);
LOCK_HARDWARE(intel);
bmAddBuffer(list, dst->buffer, BM_WRITE, NULL, &dst_offset);
bmAddBuffer(list, src->buffer, BM_READ, NULL, &src_offset);
/* Query if both buffers are already uploaded:
*/
if (bmValidateBufferList(intel->bm, list, BM_NO_EVICT|BM_NO_UPLOAD|BM_MEM_AGP)) {
intelEmitCopyBlitLocked(intel,
dst->cpp,
src->pitch, src_offset,
dst->pitch, dst_offset,
srcx, srcy,
dstx, dsty,
width, height);
bmFenceBufferList(intel->bm, list);
}
else {
_mesa_copy_rect(intel_region_map(intel, dst),
dst->cpp,
dst->pitch,
dstx, dsty,
width, height,
intel_region_map(intel, src),
srcx, srcy,
src->pitch);
intel_region_unmap(intel, dst);
intel_region_unmap(intel, src);
}
bmFreeBufferList(list);
UNLOCK_HARDWARE(intel);
intelEmitCopyBlit(intel,
dst->cpp,
src->pitch, src->buffer, src_offset,
dst->pitch, dst->buffer, dst_offset,
srcx, srcy,
dstx, dsty,
width, height);
}
/* Fill a rectangular sub-region. Need better logic about when to
@@ -330,41 +252,18 @@ void intel_region_copy( struct intel_context *intel,
*/
void intel_region_fill( struct intel_context *intel,
struct intel_region *dst,
GLuint dst_offset,
GLuint dstx, GLuint dsty,
GLuint width, GLuint height,
GLuint color )
{
unsigned dst_offset;
struct bm_buffer_list *list = bmNewBufferList();
DBG("%s\n", __FUNCTION__);
LOCK_HARDWARE(intel);
bmAddBuffer(list, dst->buffer, BM_WRITE, NULL, &dst_offset);
if (bmValidateBufferList(intel->bm, list, BM_NO_EVICT|BM_NO_UPLOAD|BM_MEM_AGP)) {
intelEmitFillBlitLocked(intel,
dst->cpp,
dst->pitch,
dst_offset,
dstx, dsty,
width, height,
color );
bmFenceBufferList(intel->bm, list);
}
else {
_mesa_fill_rect(intel_region_map(intel, dst),
dst->cpp,
dst->pitch,
dstx, dsty,
width, height,
color);
intel_region_unmap(intel, dst);
}
bmFreeBufferList(list);
UNLOCK_HARDWARE(intel);
intelEmitFillBlit(intel,
dst->cpp,
dst->pitch, dst->buffer, dst_offset,
dstx, dsty,
width, height,
color );
}

View File

@@ -85,6 +85,7 @@ void intel_region_unmap(struct intel_context *intel,
*/
void intel_region_data(struct intel_context *intel,
struct intel_region *dest,
GLuint dest_offset,
GLuint destx, GLuint desty,
void *src, GLuint src_stride,
GLuint srcx, GLuint srcy,
@@ -94,8 +95,10 @@ void intel_region_data(struct intel_context *intel,
*/
void intel_region_copy( struct intel_context *intel,
struct intel_region *dest,
GLuint dest_offset,
GLuint destx, GLuint desty,
struct intel_region *src,
GLuint src_offset,
GLuint srcx, GLuint srcy,
GLuint width, GLuint height );
@@ -103,6 +106,7 @@ void intel_region_copy( struct intel_context *intel,
*/
void intel_region_fill( struct intel_context *intel,
struct intel_region *dest,
GLuint dest_offset,
GLuint destx, GLuint desty,
GLuint width, GLuint height,
GLuint color );

View File

@@ -106,7 +106,7 @@ static const int scale_prim[GL_POLYGON+1] = {
};
static void intelDmaPrimitive( intelContextPtr intel, GLenum prim )
static void intelDmaPrimitive( struct intel_context *intel, GLenum prim )
{
if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
INTEL_FIREVERTICES(intel);
@@ -115,7 +115,7 @@ static void intelDmaPrimitive( intelContextPtr intel, GLenum prim )
}
#define LOCAL_VARS intelContextPtr intel = INTEL_CONTEXT(ctx)
#define LOCAL_VARS struct intel_context *intel = intel_context(ctx)
#define INIT( prim ) \
do { \
intelDmaPrimitive( intel, prim ); \
@@ -142,7 +142,7 @@ do { \
/* Heuristic to choose between the two render paths:
*/
static GLboolean choose_render( intelContextPtr intel,
static GLboolean choose_render( struct intel_context *intel,
struct vertex_buffer *VB )
{
int vertsz = intel->vertex_size;
@@ -194,7 +194,7 @@ static GLboolean choose_render( intelContextPtr intel,
static GLboolean intel_run_render( GLcontext *ctx,
struct tnl_pipeline_stage *stage )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;

View File

@@ -104,9 +104,9 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
intelScreen->cpp = gDRIPriv->cpp;
switch (gDRIPriv->bitsPerPixel) {
case 15: intelScreen->fbFormat = DV_PF_555; break;
case 16: intelScreen->fbFormat = DV_PF_565; break;
case 32: intelScreen->fbFormat = DV_PF_8888; break;
default: exit(1); break;
}
intelScreen->front.pitch = gDRIPriv->fbStride;

View File

@@ -42,7 +42,7 @@
#define DBG 0
#define LOCAL_VARS \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
struct intel_context *intel = intel_context(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch * drb->cpp; \
@@ -54,7 +54,7 @@
(void) buf; (void) p
#define LOCAL_DEPTH_VARS \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
struct intel_context *intel = intel_context(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch * drb->cpp; \
@@ -95,27 +95,6 @@ do { \
#define TAG(x) intel##x##_565
#include "spantmp.h"
/* 15 bit, 555 rgb color spanline and pixel functions
*/
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
((g & 0xf8) << 3) | \
((b & 0xf8) >> 3))
#define WRITE_PIXEL( _x, _y, p ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = p
#define READ_RGBA( rgba, _x, _y ) \
do { \
GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
rgba[0] = (p >> 7) & 0xf8; \
rgba[1] = (p >> 3) & 0xf8; \
rgba[2] = (p << 3) & 0xf8; \
rgba[3] = 255; \
} while(0)
#define TAG(x) intel##x##_555
#include "spantmp.h"
/* 16 bit depthbuffer functions.
*/
@@ -132,7 +111,7 @@ do { \
#undef LOCAL_VARS
#define LOCAL_VARS \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
struct intel_context *intel = intel_context(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch * drb->cpp; \
@@ -206,12 +185,11 @@ do { \
*/
void intelSpanRenderStart( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
GLuint i;
intelFlush(&intel->ctx);
LOCK_HARDWARE(intel);
intelWaitForIdle(intel);
/* Just map the framebuffer and all textures. Bufmgr code will
* take care of waiting on the necessary fences:
@@ -230,7 +208,7 @@ void intelSpanRenderStart( GLcontext *ctx )
void intelSpanRenderFinish( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
struct intel_context *intel = intel_context( ctx );
GLuint i;
_swrast_flush( ctx );
@@ -266,10 +244,7 @@ void
intelSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
{
if (drb->Base.InternalFormat == GL_RGBA) {
if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) {
intelInitPointers_555(&drb->Base);
}
else if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
intelInitPointers_565(&drb->Base);
}
else {

View File

@@ -30,6 +30,7 @@
#include "context.h"
#include "macros.h"
#include "enums.h"
#include "colormac.h"
#include "dd.h"
#include "intel_screen.h"
@@ -165,79 +166,26 @@ int intel_translate_logic_op( GLenum opcode )
}
}
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
intelScreenPrivate *screen = intel->intelScreen;
int front = 0;
if (!ctx->DrawBuffer)
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:
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
return;
}
if ( intel->sarea->pf_current_page == 1 )
front ^= 1;
intelSetFrontClipRects( intel );
if (front) {
intel->drawOffset = screen->front.offset;
if (intel->draw_region != intel->front_region) {
intel_region_release(intel, &intel->draw_region);
intel_region_reference(&intel->draw_region, intel->front_region);
}
} else {
intel->drawOffset = screen->back.offset;
if (intel->draw_region != intel->back_region) {
intel_region_release(intel, &intel->draw_region);
intel_region_reference(&intel->draw_region, intel->back_region);
}
}
intel->vtbl.set_draw_offset( intel, intel->drawOffset );
}
static void intelReadBuffer( GLcontext *ctx, GLenum mode )
{
/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
}
static void intelClearColor(GLcontext *ctx, const GLfloat color[4])
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
intelScreenPrivate *screen = intel->intelScreen;
GLubyte clear_chan[4];
CLAMPED_FLOAT_TO_UBYTE(intel->clear_red, color[0]);
CLAMPED_FLOAT_TO_UBYTE(intel->clear_green, color[1]);
CLAMPED_FLOAT_TO_UBYTE(intel->clear_blue, color[2]);
CLAMPED_FLOAT_TO_UBYTE(intel->clear_alpha, color[3]);
UNCLAMPED_FLOAT_TO_RGBA_CHAN(clear_chan, color);
intel->ClearColor = INTEL_PACKCOLOR(screen->fbFormat,
intel->clear_red,
intel->clear_green,
intel->clear_blue,
intel->clear_alpha);
clear_chan[0],
clear_chan[1],
clear_chan[2],
clear_chan[3]);
}
static void intelCalcViewport( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
const GLfloat *v = ctx->Viewport._WindowMap.m;
GLfloat *m = intel->ViewportMatrix.m;
GLint h = 0;
@@ -273,18 +221,111 @@ static void intelDepthRange( GLcontext *ctx,
*/
static void intelRenderMode( GLcontext *ctx, GLenum mode )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
FALLBACK( intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
}
void intelInitStateFuncs( struct dd_function_table *functions )
{
functions->DrawBuffer = intelDrawBuffer;
functions->ReadBuffer = intelReadBuffer;
functions->RenderMode = intelRenderMode;
functions->Viewport = intelViewport;
functions->DepthRange = intelDepthRange;
functions->ClearColor = intelClearColor;
}
void intelInitState( GLcontext *ctx )
{
/* Mesa should do this for us:
*/
ctx->Driver.AlphaFunc( ctx,
ctx->Color.AlphaFunc,
ctx->Color.AlphaRef);
ctx->Driver.BlendColor( ctx,
ctx->Color.BlendColor );
ctx->Driver.BlendEquationSeparate( ctx,
ctx->Color.BlendEquationRGB,
ctx->Color.BlendEquationA);
ctx->Driver.BlendFuncSeparate( ctx,
ctx->Color.BlendSrcRGB,
ctx->Color.BlendDstRGB,
ctx->Color.BlendSrcA,
ctx->Color.BlendDstA);
ctx->Driver.ColorMask( ctx,
ctx->Color.ColorMask[RCOMP],
ctx->Color.ColorMask[GCOMP],
ctx->Color.ColorMask[BCOMP],
ctx->Color.ColorMask[ACOMP]);
ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
ctx->Driver.DepthFunc( ctx, ctx->Depth.Func );
ctx->Driver.DepthMask( ctx, ctx->Depth.Mask );
ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled );
ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag );
ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled );
ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled );
ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE );
ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE );
ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE );
ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
{
GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
}
ctx->Driver.LineWidth( ctx, ctx->Line.Width );
ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp );
ctx->Driver.PointSize( ctx, ctx->Point.Size );
ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple );
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height );
ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel );
ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT,
ctx->Stencil.Function[0],
ctx->Stencil.Ref[0],
ctx->Stencil.ValueMask[0] );
ctx->Driver.StencilFuncSeparate( ctx, GL_BACK,
ctx->Stencil.Function[1],
ctx->Stencil.Ref[1],
ctx->Stencil.ValueMask[1] );
ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
ctx->Driver.StencilOpSeparate( ctx, GL_FRONT,
ctx->Stencil.FailFunc[0],
ctx->Stencil.ZFailFunc[0],
ctx->Stencil.ZPassFunc[0]);
ctx->Driver.StencilOpSeparate( ctx, GL_BACK,
ctx->Stencil.FailFunc[1],
ctx->Stencil.ZFailFunc[1],
ctx->Stencil.ZPassFunc[1]);
ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
}

View File

@@ -140,8 +140,10 @@ void intelInitTextureFuncs(struct dd_function_table * functions)
functions->ChooseTextureFormat = intelChooseTextureFormat;
functions->TexImage1D = intelTexImage1D;
functions->TexImage2D = intelTexImage2D;
functions->TexImage3D = intelTexImage3D;
functions->TexSubImage1D = intelTexSubImage1D;
functions->TexSubImage2D = intelTexSubImage2D;
functions->TexSubImage3D = intelTexSubImage3D;
functions->CopyTexImage1D = intelCopyTexImage1D;
functions->CopyTexImage2D = intelCopyTexImage2D;
functions->CopyTexSubImage1D = intelCopyTexSubImage1D;

View File

@@ -39,6 +39,28 @@ const struct gl_texture_format *
intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
GLenum format, GLenum type );
void intelTexImage3D(GLcontext *ctx,
GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint depth,
GLint border,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage);
void intelTexSubImage3D(GLcontext *ctx,
GLenum target,
GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type,
const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage);
void intelTexImage2D(GLcontext *ctx,
GLenum target, GLint level,
GLint internalFormat,
@@ -97,20 +119,7 @@ void intelCopyTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height );
GLuint intel_validate_mipmap_tree( struct intel_context *intel,
struct intel_texture_object *intelObj );
void intel_add_texoffset_fixup( struct intel_context *intel,
GLuint unit,
GLuint *ptr );
void intel_apply_fixups( struct intel_context *intel );
GLboolean intel_prevalidate_buffers( struct intel_context *intel );
GLboolean intel_validate_buffers( struct intel_context *intel );
void intel_fence_buffers( struct intel_context *intel );
GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint unit );
void intel_tex_map_images( struct intel_context *intel,
struct intel_texture_object *intelObj );

View File

@@ -36,6 +36,8 @@
#include "intel_mipmap_tree.h"
#include "intel_regions.h"
#include "intel_tex.h"
#include "intel_blit.h"
#include "intel_pixel.h"
#include "bufmgr.h"
/* Do the best we can using the blitter. A future project is to use
@@ -107,17 +109,16 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel,
return GL_FALSE;
intelFlush(ctx);
LOCK_HARDWARE(intel);
intelInstallBatchBuffer(intel);
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
GLuint image_offset = intel_miptree_image_offset(intelImage->mt,
intelImage->face,
intelImage->level);
GLuint dst_offset = 0;
GLuint src_offset = 0;
GLint orig_x = x;
GLint orig_y = y;
GLuint window_y;
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) {
ret = GL_TRUE;
@@ -126,37 +127,38 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel,
/* Update dst for clipped src. Need to also clip the source rect.
*/
dstx = x - orig_x;
dsty = y - orig_y;
dstx += x - orig_x;
dsty += y - orig_y;
y = dPriv->h - y - height; /* convert from gl to hardware coords */
x += dPriv->x;
y += dPriv->y;
window_y = intel->intelScreen->height - (dPriv->y + dPriv->h);
y = window_y + y;
bmAddBuffer(intel->buffer_list,
intelImage->mt->region->buffer,
BM_WRITE, NULL, &dst_offset);
bmAddBuffer(intel->buffer_list,
src->buffer,
BM_READ, NULL, &src_offset);
/* A bit of fiddling to get the blitter to work with -ve
* pitches. But we get a nice inverted blit this way, so it's
* worth it:
*/
intelEmitCopyBlit( intel,
intelImage->mt->cpp,
-src->pitch,
src->buffer,
src->height * src->pitch * src->cpp,
intelImage->mt->pitch,
intelImage->mt->region->buffer,
image_offset,
x, y + height,
dstx, dsty,
width, height );
if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP)) {
ret = GL_FALSE;
goto out;
}
intelEmitCopyBlitLocked( intel,
intelImage->mt->cpp,
src->pitch, src_offset,
intelImage->mt->pitch,
dst_offset + image_offset,
x, y,
dstx, dsty,
width, height );
out:
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE);
intel_batchbuffer_flush( intel->batch );
}

View File

@@ -15,7 +15,7 @@ const struct gl_texture_format *
intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
GLenum format, GLenum type )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
struct intel_context *intel = intel_context( ctx );
const GLboolean do32bpt = (intel->intelScreen->cpp == 4);
switch ( internalFormat ) {

View File

@@ -151,9 +151,10 @@ static void intelTexImage(GLcontext *ctx,
GLint dims,
GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint border,
GLint width, GLint height, GLint depth,
GLint border,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
const struct gl_pixelstore_attrib *unpack,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
@@ -164,11 +165,15 @@ static void intelTexImage(GLcontext *ctx,
GLint postConvHeight = height;
GLint texelBytes, sizeInBytes;
GLuint dstRowStride;
GLuint dstImageStride;
DBG("%s target %s level %d %dx%d border %d\n", __FUNCTION__,
DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target),
level,
width, height, border);
width, height, depth, border);
intelFlush(ctx);
intelImage->face = target_to_face( target );
intelImage->level = level;
@@ -184,14 +189,24 @@ static void intelTexImage(GLcontext *ctx,
assert(texImage->TexFormat);
if (dims == 1) {
switch (dims) {
case 1:
texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
}
else {
break;
case 2:
texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
break;
case 3:
texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
break;
default:
assert(0);
break;
}
texelBytes = texImage->TexFormat->TexelBytes;
@@ -217,19 +232,7 @@ static void intelTexImage(GLcontext *ctx,
/* If this is the only texture image in the tree, could call
* bmBufferData with NULL data to free the old block and avoid
* waiting on any outstanding fences.
*
* XXX: this hits a malloc/free problem. fixme.
*/
#if 0
if (intelObj->mt &&
intelObj->mt->first_level == level &&
intelObj->mt->last_level == level &&
intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB) {
DBG("release it 2\n");
intel_miptree_release(intel, &intelObj->mt);
}
#endif
if (intelObj->mt &&
intelObj->mt->first_level == level &&
intelObj->mt->last_level == level &&
@@ -271,13 +274,11 @@ static void intelTexImage(GLcontext *ctx,
*/
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
format, type,
pixels, packing, "glTexImage");
pixels, unpack, "glTexImage");
if (!pixels)
return;
LOCK_HARDWARE(intel);
if (intelImage->mt) {
@@ -285,20 +286,30 @@ static void intelTexImage(GLcontext *ctx,
intelImage->mt,
intelImage->face,
intelImage->level,
&dstRowStride);
&dstRowStride,
&dstImageStride);
}
else {
/* Allocate regular memory and store the image there temporarily. */
if (texImage->IsCompressed) {
sizeInBytes = texImage->CompressedSize;
dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,width);
dstImageStride = 0; /* ? */
assert(dims != 3);
}
else {
sizeInBytes = postConvWidth * postConvHeight * texelBytes;
dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
dstRowStride = postConvWidth * texelBytes;
dstImageStride = dstRowStride * postConvHeight;
sizeInBytes = depth * dstImageStride;
}
texImage->Data = malloc(sizeInBytes);
}
fprintf(stderr,
"Upload image %dx%dx%d row_len %x "
"pitch %x depth_pitch %x\n",
width, height, depth,
width * texelBytes, dstRowStride, dstImageStride);
/* Copy data. Would like to know when it's ok for us to eg. use
* the blitter to copy. Or, use the hardware to do the format
@@ -309,13 +320,13 @@ static void intelTexImage(GLcontext *ctx,
texImage->TexFormat,
texImage->Data,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride, 0 /* dstImageStride */,
width, height, 1,
format, type, pixels, packing)) {
dstRowStride, dstImageStride,
width, height, depth,
format, type, pixels, unpack)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
}
_mesa_unmap_teximage_pbo(ctx, packing);
_mesa_unmap_teximage_pbo(ctx, unpack);
if (intelImage->mt) {
intel_miptree_image_unmap(intel, intelImage->mt);
@@ -336,20 +347,36 @@ static void intelTexImage(GLcontext *ctx,
#endif
}
void intelTexImage3D(GLcontext *ctx,
GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint depth,
GLint border,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *unpack,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
intelTexImage( ctx, 3, target, level,
internalFormat, width, height, depth, border,
format, type, pixels,
unpack, texObj, texImage );
}
void intelTexImage2D(GLcontext *ctx,
GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint border,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
const struct gl_pixelstore_attrib *unpack,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
intelTexImage( ctx, 2, target, level,
internalFormat, width, height, border,
format, type, pixels,
packing, texObj, texImage );
internalFormat, width, height, 1, border,
format, type, pixels,
unpack, texObj, texImage );
}
void intelTexImage1D(GLcontext *ctx,
@@ -357,14 +384,14 @@ void intelTexImage1D(GLcontext *ctx,
GLint internalFormat,
GLint width, GLint border,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
const struct gl_pixelstore_attrib *unpack,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
intelTexImage( ctx, 1, target, level,
internalFormat, width, 1, border,
internalFormat, width, 1, 1, border,
format, type, pixels,
packing, texObj, texImage );
unpack, texObj, texImage );
}

View File

@@ -39,8 +39,8 @@
static void intelTexSubimage (GLcontext *ctx,
GLint dims,
GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint width, GLint height,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
@@ -48,7 +48,7 @@ static void intelTexSubimage (GLcontext *ctx,
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_image *intelImage = intel_texture_image(texImage);
GLuint dstImageStride = 0;
GLuint dstImageStride;
GLuint dstRowStride;
DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
@@ -57,7 +57,9 @@ static void intelTexSubimage (GLcontext *ctx,
xoffset, yoffset,
width, height);
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, format, type,
intelFlush(ctx);
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, type,
pixels, packing, "glTexSubImage2D");
if (!pixels)
return;
@@ -72,17 +74,19 @@ static void intelTexSubimage (GLcontext *ctx,
intelImage->mt,
intelImage->face,
intelImage->level,
&dstRowStride );
&dstRowStride,
&dstImageStride );
assert(dstRowStride);
if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data,
xoffset, yoffset, 0,
xoffset, yoffset, zoffset,
dstRowStride, dstImageStride,
width, height, 1,
width, height, depth,
format, type, pixels, packing)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
_mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
}
#if 0
@@ -108,6 +112,28 @@ static void intelTexSubimage (GLcontext *ctx,
void intelTexSubImage3D(GLcontext *ctx,
GLenum target,
GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type,
const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
intelTexSubimage(ctx, 3,
target, level,
xoffset, yoffset, zoffset,
width, height, depth,
format, type, pixels, packing, texObj,
texImage);
}
void intelTexSubImage2D(GLcontext *ctx,
GLenum target,
@@ -122,8 +148,10 @@ void intelTexSubImage2D(GLcontext *ctx,
{
intelTexSubimage(ctx, 2,
target, level, xoffset, yoffset, width,
height, format, type, pixels, packing, texObj,
target, level,
xoffset, yoffset, 0,
width, height, 1,
format, type, pixels, packing, texObj,
texImage);
}
@@ -141,8 +169,10 @@ void intelTexSubImage1D(GLcontext *ctx,
struct gl_texture_image *texImage)
{
intelTexSubimage(ctx, 1,
target, level, xoffset, 0, width,
1, format, type, pixels, packing, texObj,
target, level,
xoffset, 0, 0,
width, 1, 1,
format, type, pixels, packing, texObj,
texImage);
}

View File

@@ -84,7 +84,8 @@ static void copy_image_data_to_tree( struct intel_context *intel,
intelImage->face,
intelImage->level,
intelImage->base.Data,
intelImage->base.RowStride);
intelImage->base.RowStride,
intelImage->base.RowStride * intelImage->base.Height);
free(intelImage->base.Data);
intelImage->base.Data = NULL;
@@ -96,7 +97,7 @@ static void copy_image_data_to_tree( struct intel_context *intel,
/*
*/
static GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint unit )
GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint unit )
{
struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current;
struct intel_texture_object *intelObj = intel_texture_object(tObj);
@@ -120,12 +121,14 @@ static GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint un
if (intelObj->mt) {
intel_miptree_release(intel, &intelObj->mt);
}
return 0;
return GL_FALSE;
}
/* If both firstImage and intelObj have a tree which can contain
* all active images, favour firstImage.
* all active images, favour firstImage. Note that because of the
* completeness requirement, we know that the image dimensions
* will match.
*/
if (firstImage->mt &&
firstImage->mt != intelObj->mt &&
@@ -191,113 +194,6 @@ static GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint un
return GL_TRUE;
}
void intel_add_texoffset_fixup( struct intel_context *intel,
GLuint unit,
GLuint *ptr )
{
struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current;
struct intel_texture_object *intelObj = intel_texture_object(tObj);
#if 0
struct intel_reloc *f = &intel->fixup[intel->nr_fixups++];
assert(intel->nr_fixups <= INTEL_MAX_FIXUP);
f->dest = ptr;
f->value = &intelObj->textureOffset;
f->delta = (intel->intelScreen->tex.offset +
intel_miptree_image_offset(intelObj->mt, 0, intelObj->firstLevel));
#else
*ptr = (intelObj->textureOffset +
intel_miptree_image_offset(intelObj->mt, 0, intelObj->firstLevel));
#endif
}
/* Fix up the command buffer:
*/
void intel_apply_fixups( struct intel_context *intel )
{
GLuint i;
for (i = 0; i < intel->nr_fixups; i++) {
struct intel_reloc *f = &intel->fixup[i];
*f->dest = *f->value + f->delta;
}
intel->nr_fixups = 0;
}
/* One upshot of the new manager is that it should be possible to tell
* ahead of time whether a certain set of buffers will cause a
* fallback.
*
* Unless we do this we either have to a) hold the DRI lock
* while emitting all vertices and fire after each vertex buffer, or
* b) build a fallback path that operates on i915 command streams
* rather than the state in the GLcontext.
*/
GLboolean intel_prevalidate_buffers( struct intel_context *intel )
{
return GL_TRUE; /* never fallback */
}
GLboolean intel_validate_buffers( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
GLboolean ok = GL_TRUE;
GLuint i;
DBG("%s\n", __FUNCTION__);
assert(intel->locked);
/* Add the color and depth buffers so that fences associated with
* these buffers:
*/
bmAddBuffer(intel->buffer_list,
intel->draw_region->buffer,
BM_WRITE,
NULL,
NULL);
bmAddBuffer(intel->buffer_list,
intel->depth_region->buffer,
BM_WRITE,
NULL,
NULL);
/* Add each enabled texture:
*/
for (i = 0 ; i < ctx->Const.MaxTextureUnits && ok ; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled) {
struct gl_texture_object *tObj = intel->ctx.Texture.Unit[i]._Current;
struct intel_texture_object *intelObj = intel_texture_object(tObj);
ok = intel_finalize_mipmap_tree( intel, i );
if (ok) {
bmAddBuffer(intel->buffer_list,
intelObj->mt->region->buffer,
BM_READ,
NULL,
&intelObj->textureOffset);
}
}
}
ok = bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP);
assert(ok);
return ok;
}
void intel_fence_buffers( struct intel_context *intel )
{
assert(intel->locked);
assert(intel->buffer_list);
}
void intel_tex_map_images( struct intel_context *intel,
@@ -313,13 +209,19 @@ void intel_tex_map_images( struct intel_context *intel,
struct intel_texture_image *intelImage =
intel_texture_image(intelObj->base.Image[face][i]);
/* XXX: Fallbacks will fail for 3d textures because core mesa
* doesn't have a place to put ImageStride -- assumes each
* teximage's depth slices are packed contiguously. This
* isn't true for i915.
*/
if (intelImage->mt) {
intelImage->base.Data =
intel_miptree_image_map(intel,
intelImage->mt,
intelImage->face,
intelImage->level,
&intelImage->base.RowStride);
&intelImage->base.RowStride,
NULL);
}
}
}

View File

@@ -38,6 +38,7 @@
#include "tnl/t_vertex.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_tris.h"
#include "intel_batchbuffer.h"
#include "intel_reg.h"
@@ -62,10 +63,9 @@ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
* of the locked region - vertex buffers, second batch buffer for
* primitives, relocation fixups for texture addresses.
*/
static void intel_flush_inline_primitive( GLcontext *ctx )
static void intel_flush_inline_primitive( struct intel_context *intel )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
GLuint used = intel->batch.ptr - intel->prim.start_ptr;
GLuint used = intel->batch->ptr - intel->prim.start_ptr;
assert(intel->prim.primitive != ~0);
@@ -79,9 +79,7 @@ static void intel_flush_inline_primitive( GLcontext *ctx )
goto finished;
do_discard:
intel->batch.ptr -= used;
intel->batch.space += used;
assert(intel->batch.space >= 0);
intel->batch->ptr -= used;
finished:
intel->prim.primitive = ~0;
@@ -92,17 +90,19 @@ static void intel_flush_inline_primitive( GLcontext *ctx )
/* Emit a primitive referencing vertices in a vertex buffer.
*/
void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
void intelStartInlinePrimitive( struct intel_context *intel,
GLuint prim,
GLuint batch_flags )
{
BATCH_LOCALS;
/* Emit a slot which will be filled with the inline primitive
* command later.
*/
BEGIN_BATCH(2);
BEGIN_BATCH(2, batch_flags);
OUT_BATCH( 0 );
intel->prim.start_ptr = batch_ptr;
intel->prim.start_ptr = intel->batch->ptr;
intel->prim.primitive = prim;
intel->prim.flush = intel_flush_inline_primitive;
@@ -111,31 +111,29 @@ void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
}
void intelWrapInlinePrimitive( intelContextPtr intel )
void intelWrapInlinePrimitive( struct intel_context *intel )
{
GLuint prim = intel->prim.primitive;
GLuint batchflags = intel->batch->flags;
intel_flush_inline_primitive(intel);
intel_batchbuffer_flush(intel->batch);
intel_flush_inline_primitive( &intel->ctx );
intelFlushBatch(intel, GL_TRUE);
intelInstallBatchBuffer( intel );
intel_validate_buffers( intel );
intel->vtbl.emit_state( intel );
intelStartInlinePrimitive( intel, prim );
intelStartInlinePrimitive( intel, prim, batchflags ); /* ??? */
}
GLuint *intelExtendInlinePrimitive( intelContextPtr intel,
GLuint *intelExtendInlinePrimitive( struct intel_context *intel,
GLuint dwords )
{
GLuint sz = dwords * sizeof(GLuint);
GLuint *ptr;
if (intel->batch.space < sz) {
if (intel_batchbuffer_space(intel->batch) < sz)
intelWrapInlinePrimitive( intel );
}
ptr = (GLuint *)intel->batch.ptr;
intel->batch.ptr += sz;
intel->batch.space -= sz;
ptr = (GLuint *)intel->batch->ptr;
intel->batch->ptr += sz;
return ptr;
}
@@ -159,22 +157,18 @@ do { \
#else
#define COPY_DWORDS( j, vb, vertsize, v ) \
do { \
if (0) fprintf(stderr, "\n"); \
for ( j = 0 ; j < vertsize ; j++ ) { \
if (0) fprintf(stderr, " -- v(%d): %x/%f\n",j, \
((GLuint *)v)[j], \
((GLfloat *)v)[j]); \
vb[j] = ((GLuint *)v)[j]; \
} \
vb += vertsize; \
} while (0)
#endif
static void __inline__ intel_draw_quad( intelContextPtr intel,
intelVertexPtr v0,
intelVertexPtr v1,
intelVertexPtr v2,
intelVertexPtr v3 )
static void intel_draw_quad( struct intel_context *intel,
intelVertexPtr v0,
intelVertexPtr v1,
intelVertexPtr v2,
intelVertexPtr v3 )
{
GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, 6 * vertsize );
@@ -188,10 +182,10 @@ static void __inline__ intel_draw_quad( intelContextPtr intel,
COPY_DWORDS( j, vb, vertsize, v3 );
}
static void __inline__ intel_draw_triangle( intelContextPtr intel,
intelVertexPtr v0,
intelVertexPtr v1,
intelVertexPtr v2 )
static void intel_draw_triangle( struct intel_context *intel,
intelVertexPtr v0,
intelVertexPtr v1,
intelVertexPtr v2 )
{
GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, 3 * vertsize );
@@ -203,9 +197,9 @@ static void __inline__ intel_draw_triangle( intelContextPtr intel,
}
static __inline__ void intel_draw_line( intelContextPtr intel,
intelVertexPtr v0,
intelVertexPtr v1 )
static void intel_draw_line( struct intel_context *intel,
intelVertexPtr v0,
intelVertexPtr v1 )
{
GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, 2 * vertsize );
@@ -216,8 +210,8 @@ static __inline__ void intel_draw_line( intelContextPtr intel,
}
static __inline__ void intel_draw_point( intelContextPtr intel,
intelVertexPtr v0 )
static void intel_draw_point( struct intel_context *intel,
intelVertexPtr v0 )
{
GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, vertsize );
@@ -236,7 +230,7 @@ static __inline__ void intel_draw_point( intelContextPtr intel,
* Fixup for ARB_point_parameters *
***********************************************************************/
static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 )
static void intel_atten_point( struct intel_context *intel, intelVertexPtr v0 )
{
GLcontext *ctx = &intel->ctx;
GLfloat psz[4], col[4], restore_psz, restore_alpha;
@@ -285,7 +279,7 @@ static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 )
static void intel_wpos_triangle( intelContextPtr intel,
static void intel_wpos_triangle( struct intel_context *intel,
intelVertexPtr v0,
intelVertexPtr v1,
intelVertexPtr v2 )
@@ -301,7 +295,7 @@ static void intel_wpos_triangle( intelContextPtr intel,
}
static void intel_wpos_line( intelContextPtr intel,
static void intel_wpos_line( struct intel_context *intel,
intelVertexPtr v0,
intelVertexPtr v1 )
{
@@ -315,7 +309,7 @@ static void intel_wpos_line( intelContextPtr intel,
}
static void intel_wpos_point( intelContextPtr intel,
static void intel_wpos_point( struct intel_context *intel,
intelVertexPtr v0 )
{
GLuint offset = intel->wpos_offset;
@@ -445,7 +439,7 @@ do { \
#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
#define LOCAL_VARS(n) \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
struct intel_context *intel = intel_context(ctx); \
GLuint color[n], spec[n]; \
GLuint coloroffset = intel->coloroffset; \
GLboolean specoffset = intel->specoffset; \
@@ -577,7 +571,7 @@ static void init_rast_tab( void )
* primitives.
*/
static void
intel_fallback_tri( intelContextPtr intel,
intel_fallback_tri( struct intel_context *intel,
intelVertex *v0,
intelVertex *v1,
intelVertex *v2 )
@@ -598,7 +592,7 @@ intel_fallback_tri( intelContextPtr intel,
static void
intel_fallback_line( intelContextPtr intel,
intel_fallback_line( struct intel_context *intel,
intelVertex *v0,
intelVertex *v1 )
{
@@ -632,7 +626,7 @@ intel_fallback_line( intelContextPtr intel,
#define INIT(x) intelRenderPrimitive( ctx, x )
#undef LOCAL_VARS
#define LOCAL_VARS \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
struct intel_context *intel = intel_context(ctx); \
GLubyte *vertptr = (GLubyte *)intel->verts; \
const GLuint vertsize = intel->vertex_size; \
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
@@ -658,7 +652,7 @@ intel_fallback_line( intelContextPtr intel,
static void intelRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
GLuint n )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLuint prim = intel->render_primitive;
@@ -689,7 +683,7 @@ static void intelRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
GLuint n )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
struct intel_context *intel = intel_context( ctx );
const GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, (n-2) * 3 * vertsize );
GLubyte *vertptr = (GLubyte *)intel->verts;
@@ -716,7 +710,7 @@ static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
void intelChooseRenderState(GLcontext *ctx)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
GLuint flags = ctx->_TriangleCaps;
struct fragment_program *fprog = ctx->FragmentProgram._Current;
GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS));
@@ -813,7 +807,7 @@ static const GLenum reduced_prim[GL_POLYGON+1] = {
static void intelRunPipeline( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
if (intel->NewGLState) {
if (intel->NewGLState & _NEW_TEXTURE) {
@@ -835,11 +829,7 @@ static void intelRenderStart( GLcontext *ctx )
{
struct intel_context *intel = intel_context(ctx);
intel->vtbl.render_start( INTEL_CONTEXT(ctx) );
LOCK_HARDWARE(intel);
intelInstallBatchBuffer( intel );
intel_validate_buffers( intel );
intel->vtbl.render_start( intel_context(ctx) );
intel->vtbl.emit_state( intel );
}
@@ -851,10 +841,7 @@ static void intelRenderFinish( GLcontext *ctx )
_swrast_flush( ctx );
if (intel->prim.flush)
intel->prim.flush(ctx);
intelFlushBatch(intel, GL_TRUE);
UNLOCK_HARDWARE(intel);
intel->prim.flush(intel);
}
@@ -865,7 +852,7 @@ static void intelRenderFinish( GLcontext *ctx )
*/
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
if (0)
fprintf(stderr, "%s %s %x\n", __FUNCTION__,
@@ -876,111 +863,175 @@ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
/* Start a new primitive. Arrange to have it flushed later on.
*/
if (hwprim != intel->prim.primitive)
intelStartInlinePrimitive( intel, hwprim );
intelStartInlinePrimitive( intel, hwprim, INTEL_BATCH_CLIPRECTS );
}
/*
*/
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim )
{
struct intel_context *intel = intel_context(ctx);
if (0)
fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
if (0)
fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
/* Let some clipping routines know which primitive they're dealing
* with.
*/
intel->render_primitive = prim;
/* Let some clipping routines know which primitive they're dealing
* with.
*/
intel->render_primitive = prim;
/* Shortcircuit this when called from t_dd_rendertmp.h for unfilled
* triangles. The rasterized primitive will always be reset by
* lower level functions in that case, potentially pingponging the
* state:
*/
if (reduced_prim[prim] == GL_TRIANGLES &&
(ctx->_TriangleCaps & DD_TRI_UNFILLED))
return;
/* Shortcircuit this when called from t_dd_rendertmp.h for unfilled
* triangles. The rasterized primitive will always be reset by
* lower level functions in that case, potentially pingponging the
* state:
*/
if (reduced_prim[prim] == GL_TRIANGLES &&
(ctx->_TriangleCaps & DD_TRI_UNFILLED))
return;
/* Set some primitive-dependent state and Start? a new primitive.
*/
intelRasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );
}
/* Set some primitive-dependent state and Start? a new primitive.
*/
intelRasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );
}
/**********************************************************************/
/* Transition to/from hardware rasterization. */
/**********************************************************************/
static char *fallbackStrings[] = {
"Texture",
"Draw buffer",
"Read buffer",
"Color mask",
"Render mode",
"Stencil",
"Stipple",
"User disable"
};
static char *fallbackStrings[] = {
"Texture",
"Draw buffer",
"Read buffer",
"Color mask",
"Render mode",
"Stencil",
"Stipple",
"User disable"
};
static char *getFallbackString(GLuint bit)
{
int i = 0;
while (bit > 1) {
i++;
bit >>= 1;
}
return fallbackStrings[i];
}
static char *getFallbackString(GLuint bit)
{
int i = 0;
while (bit > 1) {
i++;
bit >>= 1;
}
return fallbackStrings[i];
}
void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode )
{
GLcontext *ctx = &intel->ctx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint oldfallback = intel->Fallback;
void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode )
{
GLcontext *ctx = &intel->ctx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint oldfallback = intel->Fallback;
if (mode) {
intel->Fallback |= bit;
if (oldfallback == 0) {
intelFlush(ctx);
if (INTEL_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "ENTER FALLBACK %x: %s\n",
bit, getFallbackString( bit ));
_swsetup_Wakeup( ctx );
intel->RenderIndex = ~0;
}
}
else {
intel->Fallback &= ~bit;
if (oldfallback == bit) {
_swrast_flush( ctx );
if (INTEL_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit ));
tnl->Driver.Render.Start = intelRenderStart;
tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive;
tnl->Driver.Render.Finish = intelRenderFinish;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
if (mode) {
intel->Fallback |= bit;
if (oldfallback == 0) {
intelFlush(ctx);
if (INTEL_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "ENTER FALLBACK %x: %s\n",
bit, getFallbackString( bit ));
_swsetup_Wakeup( ctx );
intel->RenderIndex = ~0;
}
}
else {
intel->Fallback &= ~bit;
if (oldfallback == bit) {
_swrast_flush( ctx );
if (INTEL_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit ));
tnl->Driver.Render.Start = intelRenderStart;
tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive;
tnl->Driver.Render.Finish = intelRenderFinish;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
_tnl_invalidate_vertex_state( ctx, ~0 );
_tnl_invalidate_vertices( ctx, ~0 );
_tnl_install_attrs( ctx,
intel->vertex_attrs,
intel->vertex_attr_count,
intel->ViewportMatrix.m, 0 );
_tnl_invalidate_vertex_state( ctx, ~0 );
_tnl_invalidate_vertices( ctx, ~0 );
_tnl_install_attrs( ctx,
intel->vertex_attrs,
intel->vertex_attr_count,
intel->ViewportMatrix.m, 0 );
intel->NewGLState |= _INTEL_NEW_RENDERSTATE;
}
}
}
intel->NewGLState |= _INTEL_NEW_RENDERSTATE;
}
}
}
/**********************************************************************/
/* Used only with the metaops callbacks. */
/**********************************************************************/
void intel_meta_draw_quad(struct intel_context *intel,
GLfloat x0, GLfloat x1,
GLfloat y0, GLfloat y1,
GLfloat z,
GLuint color,
GLfloat s0, GLfloat s1,
GLfloat t0, GLfloat t1,
GLuint flags)
{
union fi *vb;
if (0)
fprintf(stderr, "%s: %f,%f-%f,%f 0x%x %f,%f-%f,%f\n",
__FUNCTION__,
x0,y0,x1,y1,color,s0,t0,s1,t1);
intel->vtbl.emit_state( intel );
intelStartInlinePrimitive( intel, PRIM3D_TRIFAN, flags );
vb = (union fi *)intelExtendInlinePrimitive( intel, 4 * 6 );
/* initial vertex, left bottom */
vb[0].f = x0;
vb[1].f = y0;
vb[2].f = z;
vb[3].i = color;
vb[4].f = s0;
vb[5].f = t0;
vb += 6;
/* right bottom */
vb[0].f = x1;
vb[1].f = y0;
vb[2].f = z;
vb[3].i = color;
vb[4].f = s1;
vb[5].f = t0;
vb += 6;
/* right top */
vb[0].f = x1;
vb[1].f = y1;
vb[2].f = z;
vb[3].i = color;
vb[4].f = s1;
vb[5].f = t1;
vb += 6;
/* left top */
vb[0].f = x0;
vb[1].f = y1;
vb[2].f = z;
vb[3].i = color;
vb[4].f = s0;
vb[5].f = t1;
if (intel->prim.flush)
intel->prim.flush(intel);
}
/**********************************************************************/
/* Initialization. */

View File

@@ -30,6 +30,8 @@
#include "mtypes.h"
#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE | \
@@ -40,7 +42,23 @@
extern void intelInitTriFuncs( GLcontext *ctx );
extern void intelPrintRenderState( const char *msg, GLuint state );
extern void intelChooseRenderState( GLcontext *ctx );
extern void intelStartInlinePrimitive( struct intel_context *intel, GLuint prim, GLuint flags );
extern void intelWrapInlinePrimitive( struct intel_context *intel );
GLuint *intelExtendInlinePrimitive( struct intel_context *intel,
GLuint dwords );
void intel_meta_draw_quad(struct intel_context *intel,
GLfloat x0, GLfloat x1,
GLfloat y0, GLfloat y1,
GLfloat z,
GLuint color,
GLfloat s0, GLfloat s1,
GLfloat t0, GLfloat t1,
GLuint flags );
#endif