소스 검색

Introduce fixup/relocation lists for dma buffers.

tags/texman_0_1_pre_ttm
Keith Whitwell 20 년 전
부모
커밋
9c02649d18
50개의 변경된 파일2587개의 추가작업 그리고 2761개의 파일을 삭제
  1. 6
    2
      src/mesa/drivers/dri/i915/Makefile
  2. 18
    3
      src/mesa/drivers/dri/i915/bufmgr.h
  3. 48
    60
      src/mesa/drivers/dri/i915/bufmgr_fake.c
  4. 1
    1
      src/mesa/drivers/dri/i915/i830_context.c
  5. 2
    4
      src/mesa/drivers/dri/i915/i830_context.h
  6. 11
    453
      src/mesa/drivers/dri/i915/i830_metaops.c
  7. 2
    2
      src/mesa/drivers/dri/i915/i830_reg.h
  8. 1
    2
      src/mesa/drivers/dri/i915/i830_state.c
  9. 1
    1
      src/mesa/drivers/dri/i915/i830_texblend.c
  10. 2
    2
      src/mesa/drivers/dri/i915/i830_texstate.c
  11. 14
    14
      src/mesa/drivers/dri/i915/i830_vtbl.c
  12. 4
    47
      src/mesa/drivers/dri/i915/i915_context.c
  13. 15
    31
      src/mesa/drivers/dri/i915/i915_context.h
  14. 5
    5
      src/mesa/drivers/dri/i915/i915_fragprog.c
  15. 93
    187
      src/mesa/drivers/dri/i915/i915_metaops.c
  16. 2
    2
      src/mesa/drivers/dri/i915/i915_program.c
  17. 4
    4
      src/mesa/drivers/dri/i915/i915_program.h
  18. 2
    2
      src/mesa/drivers/dri/i915/i915_reg.h
  19. 23
    28
      src/mesa/drivers/dri/i915/i915_state.c
  20. 1
    1
      src/mesa/drivers/dri/i915/i915_tex.c
  21. 3
    3
      src/mesa/drivers/dri/i915/i915_texprog.c
  22. 25
    14
      src/mesa/drivers/dri/i915/i915_texstate.c
  23. 97
    71
      src/mesa/drivers/dri/i915/i915_vtbl.c
  24. 233
    49
      src/mesa/drivers/dri/i915/intel_batchbuffer.c
  25. 95
    58
      src/mesa/drivers/dri/i915/intel_batchbuffer.h
  26. 57
    65
      src/mesa/drivers/dri/i915/intel_blit.c
  27. 19
    16
      src/mesa/drivers/dri/i915/intel_blit.h
  28. 505
    0
      src/mesa/drivers/dri/i915/intel_buffers.c
  29. 82
    253
      src/mesa/drivers/dri/i915/intel_context.c
  30. 76
    87
      src/mesa/drivers/dri/i915/intel_context.h
  31. 34
    270
      src/mesa/drivers/dri/i915/intel_ioctl.c
  32. 6
    18
      src/mesa/drivers/dri/i915/intel_ioctl.h
  33. 55
    555
      src/mesa/drivers/dri/i915/intel_pixel.c
  34. 63
    0
      src/mesa/drivers/dri/i915/intel_pixel.h
  35. 196
    0
      src/mesa/drivers/dri/i915/intel_pixel_copy.c
  36. 242
    0
      src/mesa/drivers/dri/i915/intel_pixel_draw.c
  37. 249
    0
      src/mesa/drivers/dri/i915/intel_pixel_read.c
  38. 17
    121
      src/mesa/drivers/dri/i915/intel_regions.c
  39. 4
    4
      src/mesa/drivers/dri/i915/intel_render.c
  40. 1
    1
      src/mesa/drivers/dri/i915/intel_screen.c
  41. 6
    31
      src/mesa/drivers/dri/i915/intel_span.c
  42. 105
    64
      src/mesa/drivers/dri/i915/intel_state.c
  43. 1
    14
      src/mesa/drivers/dri/i915/intel_tex.h
  44. 17
    25
      src/mesa/drivers/dri/i915/intel_tex_copy.c
  45. 1
    1
      src/mesa/drivers/dri/i915/intel_tex_format.c
  46. 11
    10
      src/mesa/drivers/dri/i915/intel_tex_image.c
  47. 2
    0
      src/mesa/drivers/dri/i915/intel_tex_subimage.c
  48. 2
    109
      src/mesa/drivers/dri/i915/intel_tex_validate.c
  49. 114
    64
      src/mesa/drivers/dri/i915/intel_tris.c
  50. 14
    7
      src/mesa/drivers/dri/i915/intel_tris.h

+ 6
- 2
src/mesa/drivers/dri/i915/Makefile 파일 보기

@@ -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,11 @@ 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 \
@@ -26,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 \

+ 18
- 3
src/mesa/drivers/dri/i915/bufmgr.h 파일 보기

@@ -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)


+ 48
- 60
src/mesa/drivers/dri/i915/bufmgr_fake.c 파일 보기

@@ -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,14 +606,14 @@ void *bmMapBuffer( struct bufmgr *bm,
if (buf->mapped)
return NULL;

buf->mapped = 1;

if (buf->block == 0)
bmAllocMem(bm, buf);
bmAllocMem(bm, buf, flags);

if (buf->block == 0)
return NULL;

buf->mapped = 1;

/* Finish any outstanding operations to/from this memory:
*/
if (buf->block->mem_type != BM_MEM_LOCAL)
@@ -731,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);
}

@@ -739,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;
@@ -791,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 );

+ 1
- 1
src/mesa/drivers/dri/i915/i830_context.c 파일 보기

@@ -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;


+ 2
- 4
src/mesa/drivers/dri/i915/i830_context.h 파일 보기

@@ -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);



+ 11
- 453
src/mesa/drivers/dri/i915/i830_metaops.c 파일 보기

@@ -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;
}


+ 2
- 2
src/mesa/drivers/dri/i915/i830_reg.h 파일 보기

@@ -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))

+ 1
- 2
src/mesa/drivers/dri/i915/i830_state.c 파일 보기

@@ -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 */

+ 1
- 1
src/mesa/drivers/dri/i915/i830_texblend.c 파일 보기

@@ -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;

+ 2
- 2
src/mesa/drivers/dri/i915/i830_texstate.c 파일 보기

@@ -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;

+ 14
- 14
src/mesa/drivers/dri/i915/i830_vtbl.c 파일 보기

@@ -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();

+ 4
- 47
src/mesa/drivers/dri/i915/i915_context.c 파일 보기

@@ -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,9 +103,8 @@ 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;
@@ -113,6 +112,7 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
_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:

+ 15
- 31
src/mesa/drivers/dri/i915/i915_context.h 파일 보기

@@ -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 );

/*======================================================================

+ 5
- 5
src/mesa/drivers/dri/i915/i915_fragprog.c 파일 보기

@@ -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;


+ 93
- 187
src/mesa/drivers/dri/i915/i915_metaops.c 파일 보기

@@ -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 )
{
#if 0
GLuint vertex_size = 8;
GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel,
PRIM3D_TRIFAN,
4 * vertex_size,
vertex_size );
intelVertex tmp;
int i;

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
}

void
i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch)
/* 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 )
{
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 );
struct i915_context *i915 = i915_context(&intel->ctx);
memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) );
i915->meta.active = ACTIVE;
i915->meta.emitted = 0;

draw_quad(i915, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
SET_STATE(i915, meta);
set_vertex_format(intel);
meta_no_texture(intel);
}

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? */
static void leave_meta_state( struct intel_context *intel )
{
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);
}

draw_quad( i915, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
}

UNLOCK_HARDWARE(intel);

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;
}



+ 2
- 2
src/mesa/drivers/dri/i915/i915_program.c 파일 보기

@@ -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;

+ 4
- 4
src/mesa/drivers/dri/i915/i915_program.h 파일 보기

@@ -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 );

+ 2
- 2
src/mesa/drivers/dri/i915/i915_reg.h 파일 보기

@@ -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))

+ 23
- 28
src/mesa/drivers/dri/i915/i915_state.c 파일 보기

@@ -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;


+ 1
- 1
src/mesa/drivers/dri/i915/i915_tex.c 파일 보기

@@ -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 */

+ 3
- 3
src/mesa/drivers/dri/i915/i915_texprog.c 파일 보기

@@ -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;

+ 25
- 14
src/mesa/drivers/dri/i915/i915_texstate.c 파일 보기

@@ -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 );
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;

+ 97
- 71
src/mesa/drivers/dri/i915/i915_vtbl.c 파일 보기

@@ -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];
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;
}
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;
}
struct i915_context *i915 = i915_context(&intel->ctx);
GLuint st1 = i915->state.Stipple[I915_STPREG_ST1];
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;
}
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;
}
}


/* 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,63 +318,69 @@ 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 void i915_emit_flush( struct intel_context *intel )
{
BATCH_LOCALS;

BEGIN_BATCH(2);
BEGIN_BATCH(2, 0);
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE );
OUT_BATCH( 0 );
ADVANCE_BATCH();
}


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;
}

+ 233
- 49
src/mesa/drivers/dri/i915/intel_batchbuffer.c 파일 보기

@@ -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,79 +25,263 @@
*
**************************************************************************/

#include "intel_batchbuffer.h"
#include "intel_ioctl.h"
#include "bufmgr.h"

#include <stdio.h>
#include <errno.h>
/* 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.
*
*/

#include "mtypes.h"
#include "context.h"
#include "enums.h"
/* 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 ???
*/

#include "intel_reg.h"
#include "intel_batchbuffer.h"
#include "intel_context.h"
static void intel_dump_batchbuffer( unsigned offset,
int *ptr,
int count )
{
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");
}

#include "bufmgr.h"

static void intel_batchbuffer_reset( struct intel_batchbuffer *batch )
{
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]);

void intelDestroyBatchBuffer( struct intel_context *intel )
batch->map = bmMapBuffer(batch->bm, batch->buffer,
BM_MEM_AGP|BM_MEM_LOCAL|BM_CLIENT|BM_WRITE);
batch->ptr = batch->map;
}

/*======================================================================
* Public functions
*/
struct intel_batchbuffer *intel_batchbuffer_alloc( struct intel_context *intel )
{
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 (0)
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);
}


void intelInstallBatchBuffer( struct intel_context *intel )

GLuint intel_batchbuffer_flush( struct intel_batchbuffer *batch )
{
assert(!intel->batch.ptr);
struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;

intel->alloc.current++;
intel->alloc.current %= INTEL_ALLOC_NR;
if (used == 0)
return batch->last_fence;

DBG("%s: %d\n", __FUNCTION__, intel->alloc.current);
/* Add the MI_BATCH_BUFFER_END:
*/
if (intel_batchbuffer_space(batch) & 4) {
((int *)batch->ptr)[0] = MI_BATCH_BUFFER_END;
used += 4;
}
else {
((int *)batch->ptr)[0] = 0;
((int *)batch->ptr)[1] = MI_BATCH_BUFFER_END;
used += 8;
}

intel->batch.size = INTEL_ALLOC_SIZE;
intel->batch.space = intel->batch.size;
intel->batch.start_offset = 0;
bmUnmapBuffer(batch->bm, batch->buffer);
batch->ptr = NULL;
batch->map = NULL;

intel->batch.ptr = bmMapBuffer( intel->bm,
intel->alloc.buffer[intel->alloc.current],
BM_WRITE | BM_MEM_AGP );
/* 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));

assert(!intel->buffer_list);
intel->buffer_list = bmNewBufferList();
/* Add the batchbuffer
do_flush_locked(batch, used, GL_TRUE);
}
/* Reset the buffer:
*/
bmAddBuffer(intel->buffer_list,
intel->alloc.buffer[intel->alloc.current],
BM_READ,
NULL,
&intel->batch.start_offset);
intel_batchbuffer_reset( batch );
return batch->last_fence;
}

void intel_batchbuffer_finish( struct intel_batchbuffer *batch )
{
bmFinishFence(batch->bm,
intel_batchbuffer_flush(batch));
}

void intelInitBatchBuffer( struct intel_context *intel )
/* 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 )
{
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);
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 intelValidateBuffers( struct intel_context *intel )

void intel_batchbuffer_data(struct intel_batchbuffer *batch,
const void *data,
GLuint bytes,
GLuint flags)
{
if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP))
assert(0);
assert((bytes & 3) == 0);
intel_batchbuffer_require_space(batch, bytes, flags);
__memcpy(batch->ptr, data, bytes);
batch->ptr += bytes;
}


+ 95
- 58
src/mesa/drivers/dri/i915/intel_batchbuffer.h 파일 보기

@@ -1,74 +1,111 @@
/**************************************************************************
*
* 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 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 );


void intel_batchbuffer_finish( struct intel_batchbuffer *batch );

GLuint intel_batchbuffer_flush( struct intel_batchbuffer *batch );

#define BATCH_LOCALS GLubyte *batch_ptr;

#define VERBOSE 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);

void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
GLuint bytes);

#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)
GLboolean intel_batchbuffer_emit_reloc( struct intel_batchbuffer *batch,
GLuint buffer,
GLuint flags,
GLuint offset );

#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)
/* 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 - 8) - (batch->ptr - batch->map);
}

#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)

extern void intelInitBatchBuffer( struct intel_context *intel );
extern void intelDestroyBatchBuffer( struct intel_context *intel );
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;
}

void intelInstallBatchBuffer( struct intel_context *intel );
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;
}

/* 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)

void intelValidateBuffers( struct intel_context *intel );

#endif

+ 57
- 65
src/mesa/drivers/dri/i915/intel_blit.c 파일 보기

@@ -37,6 +37,7 @@
#include "intel_batchbuffer.h"
#include "intel_context.h"
#include "intel_blit.h"
#include "intel_regions.h"

#include "bufmgr.h"

@@ -48,7 +49,7 @@
*/
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
{
intelContextPtr intel;
struct intel_context *intel;

if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -57,13 +58,13 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);

intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;

intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
intelInstallBatchBuffer(intel);
intelValidateBuffers( intel );

/* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
* should work regardless.
*/
LOCK_HARDWARE( intel );
{
intelScreenPrivate *intelScreen = intel->intelScreen;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
@@ -71,24 +72,18 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
drm_clip_rect_t *pbox = dPriv->pClipRects;
int pitch = intelScreen->front.pitch;
int cpp = intelScreen->cpp;
int BR13, CMD;
int i;
GLuint CMD, BR13;
BATCH_LOCALS;

switch(cpp) {
case 2:

if (cpp == 2) {
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
}
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);
break;
default:
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
}

for (i = 0 ; i < nbox; i++, pbox++)
@@ -99,44 +94,44 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
pbox->y2 > intelScreen->height)
continue;
BEGIN_BATCH( 8);
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_BATCH( intelScreen->front.offset );
OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
else
OUT_BATCH( intelScreen->back.offset );
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_BATCH( intelScreen->back.offset );
OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_READ, 0 );
else
OUT_BATCH( intelScreen->front.offset );
OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_READ, 0 );

ADVANCE_BATCH();
}
}
intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE );
assert(intel->buffer_list == NULL);

intel_batchbuffer_flush( intel->batch );
UNLOCK_HARDWARE( intel );
}




void intelEmitFillBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort dst_pitch,
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color )
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;
@@ -159,12 +154,12 @@ void intelEmitFillBlitLocked( intelContextPtr intel,
return;
}

BEGIN_BATCH( 6);
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_BATCH( dst_offset );
OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset );
OUT_BATCH( color );
ADVANCE_BATCH();
}
@@ -172,15 +167,17 @@ void intelEmitFillBlitLocked( intelContextPtr intel,

/* 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 )
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;
@@ -188,11 +185,11 @@ void intelEmitCopyBlitLocked( intelContextPtr intel,
BATCH_LOCALS;


if (0)
_mesa_printf("%s src:0x%x/%d %d,%d dst:0x%x/%d %d,%d sz:%dx%d\n",
if (1)
_mesa_printf("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d\n",
__FUNCTION__,
src_offset, src_pitch, src_x, src_y,
dst_offset, dst_pitch, dst_x, dst_y,
src_buffer, src_pitch, src_x, src_y,
dst_buffer, dst_pitch, dst_x, dst_y,
w,h);

src_pitch *= cpp;
@@ -223,30 +220,27 @@ void intelEmitCopyBlitLocked( intelContextPtr intel,
* we adjust the offsets manually (below), it seems to work fine.
*/
if (0) {
BEGIN_BATCH(8);
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_BATCH( dst_offset );
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_BATCH( src_offset );
OUT_RELOC( src_buffer, BM_MEM_AGP|BM_READ, src_offset );
ADVANCE_BATCH();
}
else {
src_offset += src_y * src_pitch;
dst_offset += dst_y * dst_pitch;

BEGIN_BATCH(8);
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_BATCH( dst_offset );
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_BATCH( src_offset );
OUT_RELOC( src_buffer, BM_MEM_AGP|BM_READ, src_offset + src_y * src_pitch );
ADVANCE_BATCH();
}
}
@@ -256,7 +250,7 @@ void intelEmitCopyBlitLocked( intelContextPtr intel,
void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch)
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
struct intel_context *intel = intel_context( ctx );
intelScreenPrivate *intelScreen = intel->intelScreen;
GLuint clear_depth, clear_color;
GLint cx, cy;
@@ -300,8 +294,6 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,

intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
intelInstallBatchBuffer(intel);
intelValidateBuffers( intel );
{
/* flip top to bottom */
cy = intel->driDrawable->h-cy1-ch;
@@ -351,40 +343,40 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
continue;

if ( flags & BUFFER_BIT_FRONT_LEFT ) {
BEGIN_BATCH( 6);
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_BATCH( intelScreen->front.offset );
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);
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_BATCH( intelScreen->back.offset );
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);
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_BATCH( intelScreen->depth.offset );
OUT_RELOC( intel->depth_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
OUT_BATCH( clear_depth );
ADVANCE_BATCH();
}
}
}
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
intel_batchbuffer_flush( intel->batch );
UNLOCK_HARDWARE( intel );
}


+ 19
- 16
src/mesa/drivers/dri/i915/intel_blit.h 파일 보기

@@ -35,23 +35,26 @@ 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 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 );
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 intelEmitFillBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort dst_pitch,
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color );
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

+ 505
- 0
src/mesa/drivers/dri/i915/intel_buffers.c 파일 보기

@@ -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;
}

+ 82
- 253
src/mesa/drivers/dri/i915/intel_context.c 파일 보기

@@ -55,6 +55,8 @@
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "intel_pixel.h"
#include "intel_regions.h"

#include "bufmgr.h"

@@ -80,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;
@@ -95,7 +94,7 @@ int prevLockLine;

#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];
@@ -106,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:
@@ -133,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.
@@ -252,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 );
}


@@ -261,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;
@@ -275,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,
@@ -379,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" );
@@ -393,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);
}
@@ -420,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) {
@@ -437,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 ) {
@@ -452,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;
@@ -559,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? */
@@ -579,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;
@@ -611,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] );
}

+ 76
- 87
src/mesa/drivers/dri/i915/intel_context.h 파일 보기

@@ -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,59 @@ 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 (*emit_flush)( struct intel_context *intel );

void (*reduced_primitive_state)( intelContextPtr intel, GLenum rprim );
void (*reduced_primitive_state)( struct intel_context *intel, GLenum rprim );

GLboolean (*check_vertex_size)( intelContextPtr intel, GLuint expected );
GLboolean (*check_vertex_size)( struct intel_context *intel, GLuint expected );

void (*clear_with_tris)( intelContextPtr intel, GLbitfield mask,
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;
@@ -148,42 +172,24 @@ struct intel_context
GLuint last_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 +207,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 +233,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 +348,7 @@ do { \

#define INTEL_FIREVERTICES(intel) \
do { \
if ((intel)->prim.flush) \
(intel)->prim.flush(&(intel)->ctx); \
assert(!(intel)->prim.flush); \
} while (0)

/* ================================================================
@@ -382,7 +382,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 +443,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 +515,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 +525,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 +559,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


+ 34
- 270
src/mesa/drivers/dri/i915/intel_ioctl.c 파일 보기

@@ -44,7 +44,7 @@
#include "bufmgr.h"


int intelEmitIrqLocked( intelContextPtr intel )
int intelEmitIrqLocked( struct intel_context *intel )
{
drmI830IrqEmit ie;
int ret, seq = 0;
@@ -54,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 );
@@ -69,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;
@@ -79,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);
@@ -88,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 (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 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 );
}

+ 6
- 18
src/mesa/drivers/dri/i915/intel_ioctl.h 파일 보기

@@ -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

+ 55
- 555
src/mesa/drivers/dri/i915/intel_pixel.c 파일 보기

@@ -1,78 +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_blit.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 )
{
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 0
struct intel_client_region *intel_pack_region( struct intel_context *intel,
const struct gl_pixelstore_attrib *pack,
GLenum format,
GLenum type,
GLvoid *pixels )
{
}

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__);
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.
*/

return GL_FALSE;
}

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 ||
@@ -88,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,
@@ -124,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);
}
}



@@ -635,3 +134,4 @@ void intelInitPixelFuncs( struct dd_function_table *functions )
functions->DrawPixels = _swrast_DrawPixels;
}
}


+ 63
- 0
src/mesa/drivers/dri/i915/intel_pixel.h 파일 보기

@@ -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

+ 196
- 0
src/mesa/drivers/dri/i915/intel_pixel_copy.c 파일 보기

@@ -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);
}



+ 242
- 0
src/mesa/drivers/dri/i915/intel_pixel_draw.c 파일 보기

@@ -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 );
}


+ 249
- 0
src/mesa/drivers/dri/i915/intel_pixel_read.c 파일 보기

@@ -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);
}


+ 17
- 121
src/mesa/drivers/dri/i915/intel_regions.c 파일 보기

@@ -90,6 +90,7 @@ void intel_region_reference( struct intel_region **dst,
struct intel_region *src)
{
src->refcount++;
assert(*dst == NULL);
*dst = src;
}

@@ -151,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,
@@ -186,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
@@ -283,47 +231,17 @@ void intel_region_copy( struct intel_context *intel,
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, 0,
dst->pitch, dst->buffer, 0,
srcx, srcy,
dstx, dsty,
width, height);
}

/* Fill a rectangular sub-region. Need better logic about when to
@@ -335,37 +253,15 @@ void intel_region_fill( struct intel_context *intel,
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,
0,
dstx, dsty,
width, height,
color );
}


+ 4
- 4
src/mesa/drivers/dri/i915/intel_render.c 파일 보기

@@ -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;

+ 1
- 1
src/mesa/drivers/dri/i915/intel_screen.c 파일 보기

@@ -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;

+ 6
- 31
src/mesa/drivers/dri/i915/intel_span.c 파일 보기

@@ -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 {

+ 105
- 64
src/mesa/drivers/dri/i915/intel_state.c 파일 보기

@@ -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] );
}

+ 1
- 14
src/mesa/drivers/dri/i915/intel_tex.h 파일 보기

@@ -97,20 +97,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 );

+ 17
- 25
src/mesa/drivers/dri/i915/intel_tex_copy.c 파일 보기

@@ -37,6 +37,7 @@
#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
@@ -108,15 +109,13 @@ 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;
@@ -138,35 +137,28 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel,
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);

if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP)) {
ret = GL_FALSE;
goto out;
}

/* 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:
*/
intelEmitCopyBlitLocked( intel,
intelImage->mt->cpp,
-src->pitch,
src_offset + intel->intelScreen->height * src->pitch * src->cpp,
intelImage->mt->pitch,
dst_offset + image_offset,
x, y + height,
dstx, dsty,
width, height );
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 );

out:
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE);
intel_batchbuffer_flush( intel->batch );
}


+ 1
- 1
src/mesa/drivers/dri/i915/intel_tex_format.c 파일 보기

@@ -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 ) {

+ 11
- 10
src/mesa/drivers/dri/i915/intel_tex_image.c 파일 보기

@@ -153,7 +153,7 @@ static void intelTexImage(GLcontext *ctx,
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)
{
@@ -165,11 +165,14 @@ static void intelTexImage(GLcontext *ctx,
GLint texelBytes, sizeInBytes;
GLuint dstRowStride;


DBG("%s target %s level %d %dx%d border %d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target),
level,
width, height, border);

intelFlush(ctx);

intelImage->face = target_to_face( target );
intelImage->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) {
@@ -311,11 +312,11 @@ static void intelTexImage(GLcontext *ctx,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride, 0 /* dstImageStride */,
width, height, 1,
format, type, pixels, packing)) {
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);
@@ -342,14 +343,14 @@ void intelTexImage2D(GLcontext *ctx,
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 );
unpack, texObj, texImage );
}

void intelTexImage1D(GLcontext *ctx,
@@ -357,14 +358,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,
format, type, pixels,
packing, texObj, texImage );
unpack, texObj, texImage );
}



+ 2
- 0
src/mesa/drivers/dri/i915/intel_tex_subimage.c 파일 보기

@@ -57,6 +57,8 @@ static void intelTexSubimage (GLcontext *ctx,
xoffset, yoffset,
width, height);

intelFlush(ctx);

pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, format, type,
pixels, packing, "glTexSubImage2D");
if (!pixels)

+ 2
- 109
src/mesa/drivers/dri/i915/intel_tex_validate.c 파일 보기

@@ -96,7 +96,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,7 +120,7 @@ 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;
}


@@ -191,113 +191,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,

+ 114
- 64
src/mesa/drivers/dri/i915/intel_tris.c 파일 보기

@@ -63,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);

@@ -80,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;
@@ -93,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;

@@ -112,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;
}
@@ -160,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 );
@@ -189,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 );
@@ -204,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 );
@@ -217,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 );
@@ -237,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;
@@ -286,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 )
@@ -302,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 )
{
@@ -316,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;
@@ -446,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; \
@@ -578,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 )
@@ -599,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 )
{
@@ -633,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; \
@@ -659,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;
@@ -690,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;
@@ -717,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));
@@ -814,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) {
@@ -836,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 );
}

@@ -852,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);
}


@@ -866,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__,
@@ -877,7 +863,7 @@ 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 );
}


@@ -885,7 +871,7 @@ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
*/
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);

if (0)
fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
@@ -938,7 +924,7 @@ static char *getFallbackString(GLuint bit)



void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode )
void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode )
{
GLcontext *ctx = &intel->ctx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
@@ -982,6 +968,70 @@ void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode )



/**********************************************************************/
/* 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. */

+ 14
- 7
src/mesa/drivers/dri/i915/intel_tris.h 파일 보기

@@ -42,16 +42,23 @@

extern void intelInitTriFuncs( GLcontext *ctx );

extern void intelPrintRenderState( const char *msg, GLuint state );
extern void intelChooseRenderState( GLcontext *ctx );

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 intelStartInlinePrimitive( struct intel_context *intel, GLuint prim, GLuint flags );
extern void intelWrapInlinePrimitive( struct intel_context *intel );

GLuint *intelExtendInlinePrimitive( intelContextPtr 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

Loading…
취소
저장