mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 09:28:07 +02:00
Another texture manager checkpoint:
- Add code to validate textures before use. - Simplify vertex paths for now. - Make vertex paths validate textures. This is done pretty with some pretty heavy-handed use of the dri lock - fixing this is a priority. - Add lots of debug statements demos/texobj renders, but textures are incorrect.
This commit is contained in:
parent
dcfe55539f
commit
696ba32779
21 changed files with 440 additions and 389 deletions
|
|
@ -86,8 +86,11 @@ static struct block *alloc_agp( struct bufmgr *bm,
|
|||
if (!block)
|
||||
return NULL;
|
||||
|
||||
_mesa_printf("alloc_agp 0x%x\n", size);
|
||||
|
||||
block->mem = mmAllocMem(bm->pool.heap, size, align, 0);
|
||||
if (!block->mem) {
|
||||
_mesa_printf("\t- failed\n");
|
||||
free(block);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -96,6 +99,7 @@ static struct block *alloc_agp( struct bufmgr *bm,
|
|||
block->memType = BM_MEM_AGP;
|
||||
block->virtual = bm->pool.virtual + block->mem->ofs;
|
||||
|
||||
_mesa_printf("\t- offset 0x%x\n", block->mem->ofs);
|
||||
return block;
|
||||
}
|
||||
|
||||
|
|
@ -106,6 +110,8 @@ static struct block *alloc_local( unsigned size )
|
|||
if (!block)
|
||||
return NULL;
|
||||
|
||||
_mesa_printf("alloc_local 0x%x\n", size);
|
||||
|
||||
block->memType = BM_MEM_LOCAL;
|
||||
block->virtual = malloc(size);
|
||||
if (!block->virtual) {
|
||||
|
|
@ -136,12 +142,15 @@ static int bmAllocMem( struct bufmgr *bm,
|
|||
struct buffer *buf,
|
||||
unsigned flags ) /* unused */
|
||||
{
|
||||
if (buf->block == 0)
|
||||
if (buf->block == NULL)
|
||||
buf->block = alloc_block(bm, buf->size, 4, BM_MEM_AGP);
|
||||
|
||||
if (buf->block == 0)
|
||||
if (buf->block == NULL)
|
||||
buf->block = alloc_block(bm, buf->size, 4, BM_MEM_LOCAL);
|
||||
|
||||
if (buf->block)
|
||||
buf->block->buf = buf;
|
||||
|
||||
return buf->block != NULL;
|
||||
}
|
||||
|
||||
|
|
@ -212,6 +221,9 @@ static int move_buffers( struct bufmgr *bm,
|
|||
if (flags & BM_NO_UPLOAD)
|
||||
goto cleanup;
|
||||
|
||||
_mesa_printf("try to move buffer size 0x%x to pool %d\n",
|
||||
buffers[i]->size, newMemType);
|
||||
|
||||
newMem[i] = alloc_block(bm,
|
||||
buffers[i]->size,
|
||||
buffers[i]->alignment,
|
||||
|
|
@ -219,6 +231,8 @@ static int move_buffers( struct bufmgr *bm,
|
|||
|
||||
if (!newMem[i])
|
||||
goto cleanup;
|
||||
|
||||
newMem[i]->buf = buffers[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -346,6 +360,9 @@ void bmInitPool( struct bufmgr *bm,
|
|||
{
|
||||
if (pool > 0 || low_offset >= high_offset)
|
||||
return;
|
||||
|
||||
_mesa_printf("bmInitPool %d %x..%x\n",
|
||||
pool, low_offset, high_offset);
|
||||
|
||||
bm->pool.size = high_offset - low_offset;
|
||||
bm->pool.heap = mmInit( low_offset, bm->pool.size );
|
||||
|
|
@ -362,7 +379,7 @@ void bmGenBuffers(struct bufmgr *bm, unsigned n, unsigned *buffers)
|
|||
unsigned i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
buffers[i] = bm->buf_nr++;
|
||||
buffers[i] = ++bm->buf_nr;
|
||||
_mesa_HashInsert(bm->hash, buffers[i], calloc(sizeof(struct buffer), 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -393,6 +410,8 @@ void bmBufferData(struct bufmgr *bm,
|
|||
{
|
||||
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||
|
||||
_mesa_printf("bmBufferData %d sz 0x%x data: %p\n", buffer, size, data);
|
||||
|
||||
if (buf->block) {
|
||||
if ((buf->block->memType == BM_MEM_AGP && !bmTestFence(bm, buf->block->fence)) ||
|
||||
(buf->size && buf->size != size) ||
|
||||
|
|
@ -420,6 +439,8 @@ void bmBufferSubData(struct bufmgr *bm,
|
|||
{
|
||||
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||
|
||||
_mesa_printf("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buffer, offset, size);
|
||||
|
||||
if (buf->block == 0)
|
||||
bmAllocMem(bm, buf, 0);
|
||||
|
||||
|
|
@ -438,6 +459,8 @@ void *bmMapBuffer( struct bufmgr *bm,
|
|||
{
|
||||
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||
|
||||
_mesa_printf("bmMapBuffer %d\n", buffer);
|
||||
|
||||
if (buf->mapped)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -457,6 +480,8 @@ void *bmMapBuffer( struct bufmgr *bm,
|
|||
void bmUnmapBuffer( struct bufmgr *bm, unsigned buffer )
|
||||
{
|
||||
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||
|
||||
_mesa_printf("bmUnmapBuffer %d\n", buffer);
|
||||
buf->mapped = 0;
|
||||
}
|
||||
|
||||
|
|
@ -485,6 +510,7 @@ void bm_fake_SetFixedBufferParams( struct bufmgr *bm
|
|||
struct bm_buffer_list *bmNewBufferList( void )
|
||||
{
|
||||
struct bm_buffer_list *list = calloc(sizeof(*list), 1);
|
||||
_mesa_printf("bmNewBufferList\n");
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
@ -497,6 +523,8 @@ void bmAddBuffer( struct bufmgr *bm,
|
|||
{
|
||||
assert(list->nr < BM_LIST_MAX);
|
||||
|
||||
_mesa_printf("bmAddBuffer %d\n", buffer);
|
||||
|
||||
list->buffer[list->nr] = _mesa_HashLookup(bm->hash, buffer);
|
||||
list->offset_return[list->nr] = offset_return;
|
||||
list->nr++;
|
||||
|
|
@ -528,11 +556,14 @@ int bmValidateBufferList( struct bufmgr *bm,
|
|||
unsigned i;
|
||||
unsigned total = 0;
|
||||
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (list->nr > BM_LIST_MAX)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < list->nr; i++) {
|
||||
assert(!list->buffer[i]->mapped);
|
||||
assert(list->buffer[i]->block);
|
||||
total += list->buffer[i]->size;
|
||||
}
|
||||
|
||||
|
|
@ -568,9 +599,14 @@ void bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list )
|
|||
{
|
||||
unsigned i;
|
||||
|
||||
_mesa_printf("%s (%d bufs)\n", __FUNCTION__, list->nr);
|
||||
|
||||
assert(list->need_fence);
|
||||
list->need_fence = 0;
|
||||
|
||||
if (!list->nr)
|
||||
return;
|
||||
|
||||
bm->last_fence = bmSetFence( bm );
|
||||
|
||||
/* Move all buffers to head of resident list and set their fences
|
||||
|
|
@ -635,7 +671,7 @@ void bmFlushReadCaches( struct bufmgr *bm )
|
|||
* have to emit another fence and wait for the hw queue to drain to be
|
||||
* sure the caches had flushed.
|
||||
*
|
||||
* Strategy:
|
||||
* A possible strategy:
|
||||
* - every once in a while, when there is no last_draw_flush_fence outstanding,
|
||||
* emit a draw-cache flush just prior to the fence.
|
||||
* - note the fence (last_draw_flush_fence)
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ static void draw_quad(i830ContextPtr i830,
|
|||
GLfloat s0, GLfloat s1,
|
||||
GLfloat t0, GLfloat t1 )
|
||||
{
|
||||
#if 0
|
||||
GLuint vertex_size = 8;
|
||||
GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel,
|
||||
PRIM3D_TRIFAN,
|
||||
|
|
@ -350,6 +351,7 @@ static void draw_quad(i830ContextPtr i830,
|
|||
|
||||
/* fprintf(stderr, "%s: DV1: %x\n", */
|
||||
/* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
|
|||
|
||||
if (!i915) return GL_FALSE;
|
||||
|
||||
_mesa_printf( "\ntexmem branch\n\n");
|
||||
|
||||
i915InitVtbl( i915 );
|
||||
|
||||
i915InitDriverFunctions( &functions );
|
||||
|
|
@ -129,9 +131,6 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
|
|||
intel->intelScreen->tex.size, /* high offset */
|
||||
intel->intelScreen->tex.map); /* virtual base */
|
||||
|
||||
/* AGP allocation won't work:
|
||||
*/
|
||||
intel->intelScreen->allow_batchbuffer = GL_FALSE;
|
||||
|
||||
ctx->Const.MaxTextureLevels = 11;
|
||||
ctx->Const.Max3DTextureLevels = 8;
|
||||
|
|
|
|||
|
|
@ -387,6 +387,7 @@ static void draw_quad(i915ContextPtr i915,
|
|||
GLfloat s0, GLfloat s1,
|
||||
GLfloat t0, GLfloat t1 )
|
||||
{
|
||||
#if 0
|
||||
GLuint vertex_size = 8;
|
||||
GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel,
|
||||
PRIM3D_TRIFAN,
|
||||
|
|
@ -440,6 +441,7 @@ static void draw_quad(i915ContextPtr i915,
|
|||
tmp.v.u0 = s0;
|
||||
for (i = 0 ; i < vertex_size ; i++)
|
||||
vb[i] = tmp.ui[i];
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ static GLuint minify( GLuint d )
|
|||
GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
|
||||
{
|
||||
GLint i;
|
||||
GLint numLevels = mt->last_level - mt->first_level + 1;
|
||||
|
||||
switch (mt->target) {
|
||||
case GL_TEXTURE_CUBE_MAP: {
|
||||
|
|
@ -71,12 +70,12 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
|
|||
GLuint y = initial_offsets[face][1] * dim;
|
||||
GLuint d = dim;
|
||||
|
||||
for (i = 0; i < numLevels; i++) {
|
||||
for (i = mt->first_level; i <= mt->last_level; i++) {
|
||||
mt->offset[face][i].x = x;
|
||||
mt->offset[face][i].y = y;
|
||||
mt->offset[face][i].width = d;
|
||||
mt->offset[face][i].height = d;
|
||||
mt->offset[face][i].depth = 0;
|
||||
mt->offset[face][i].depth = 1;
|
||||
|
||||
d >>= 1;
|
||||
assert(d > 0);
|
||||
|
|
@ -91,7 +90,6 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
|
|||
GLuint width = mt->width0;
|
||||
GLuint height = mt->height0;
|
||||
GLuint depth = mt->depth0;
|
||||
GLuint tmp_numLevels = MAX2(numLevels, 9);
|
||||
|
||||
/* Calculate the size of a single slice. Hardware demands a
|
||||
* minimum of 8 mipmaps, some of which might ultimately not be
|
||||
|
|
@ -100,7 +98,9 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
|
|||
mt->pitch = (mt->width0 * mt->cpp + 3) & ~3;
|
||||
mt->total_height = 0;
|
||||
|
||||
for ( i = 0 ; i < tmp_numLevels ; i++ ) {
|
||||
/* XXX: fixme! hardware expects/requires 9 levels at minimum.
|
||||
*/
|
||||
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||
mt->offset[0][i].x = 0;
|
||||
mt->offset[0][i].y = mt->total_height;
|
||||
mt->offset[0][i].width = width;
|
||||
|
|
@ -131,12 +131,12 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
|
|||
mt->pitch = (mt->width0 * mt->cpp + 3) & ~3;
|
||||
mt->total_height = 0;
|
||||
|
||||
for ( i = 0 ; i < numLevels ; i++ ) {
|
||||
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||
mt->offset[0][i].x = 0;
|
||||
mt->offset[0][i].y = mt->total_height;
|
||||
mt->offset[0][i].height = height;
|
||||
mt->offset[0][i].width = width;
|
||||
mt->offset[0][i].depth = 0;
|
||||
mt->offset[0][i].depth = 1;
|
||||
|
||||
|
||||
if (mt->compressed)
|
||||
|
|
@ -157,7 +157,6 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
|
|||
|
||||
GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
|
||||
{
|
||||
GLint numLevels = mt->last_level - mt->first_level + 1;
|
||||
GLint i;
|
||||
|
||||
switch (mt->target) {
|
||||
|
|
@ -191,12 +190,12 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
|
|||
x = face * 8;
|
||||
}
|
||||
|
||||
for (i = 0; i < numLevels; i++) {
|
||||
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||
mt->offset[face][i].x = x;
|
||||
mt->offset[face][i].y = y;
|
||||
mt->offset[face][i].width = d;
|
||||
mt->offset[face][i].height = d;
|
||||
mt->offset[face][i].depth = 0;
|
||||
mt->offset[face][i].depth = 1;
|
||||
|
||||
d >>= 1;
|
||||
assert(d > 0);
|
||||
|
|
@ -251,7 +250,7 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
|
|||
|
||||
depth_pack_pitch = mt->pitch;
|
||||
|
||||
for ( i = 0 ; i < numLevels ; i++ ) {
|
||||
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||
|
||||
mt->offset[0][i].x = 0;
|
||||
mt->offset[0][i].y = mt->total_height;
|
||||
|
|
@ -291,12 +290,12 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
|
|||
mt->pitch = (mt->width0 * mt->cpp + 3) & ~3;
|
||||
mt->total_height = 0;
|
||||
|
||||
for ( i = 0 ; i < numLevels ; i++ ) {
|
||||
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||
mt->offset[0][i].x = x;
|
||||
mt->offset[0][i].y = y;
|
||||
mt->offset[0][i].height = height;
|
||||
mt->offset[0][i].width = width;
|
||||
mt->offset[0][i].depth = 0;
|
||||
mt->offset[0][i].depth = 1;
|
||||
|
||||
|
||||
/* LPT change: step right after second mipmap.
|
||||
|
|
|
|||
|
|
@ -118,23 +118,11 @@ static GLboolean i915_update_tex_unit( GLcontext *ctx,
|
|||
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;
|
||||
GLuint firstImageOffset;
|
||||
struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel];
|
||||
|
||||
memset(state, 0, sizeof(state));
|
||||
|
||||
/* Will return the offset for the image at intelObj->firstLevel
|
||||
* (firstLevel and lastLevel are calculated in
|
||||
* validate_mipmap_tree). We will program the hardware as if this
|
||||
* is level 0.
|
||||
*/
|
||||
firstImageOffset = intel_validate_mipmap_tree( intel_context(ctx), intelObj );
|
||||
firstImage = tObj->Image[0][intelObj->firstLevel];
|
||||
|
||||
if (!firstImageOffset)
|
||||
return GL_FALSE;
|
||||
|
||||
state[I915_TEXREG_MS2] = firstImageOffset;
|
||||
state[I915_TEXREG_MS2] = 0; /* will fixup later */
|
||||
state[I915_TEXREG_MS3] =
|
||||
(((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
|
||||
((firstImage->Width - 1) << MS3_WIDTH_SHIFT) |
|
||||
|
|
@ -264,17 +252,27 @@ static GLboolean i915_update_tex_unit( GLcontext *ctx,
|
|||
tObj->_BorderChan[3]);
|
||||
|
||||
|
||||
I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE);
|
||||
|
||||
if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) {
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
_mesa_printf("state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]);
|
||||
_mesa_printf("state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]);
|
||||
_mesa_printf("state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]);
|
||||
|
||||
_mesa_printf("state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]);
|
||||
_mesa_printf("state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]);
|
||||
_mesa_printf("state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void i915UpdateTextureState( intelContextPtr intel )
|
||||
{
|
||||
GLcontext *ctx = &intel->ctx;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "tnl/t_vertex.h"
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
#include "intel_tex.h"
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_context.h"
|
||||
|
|
@ -271,7 +272,10 @@ static void i915_emit_state( intelContextPtr intel )
|
|||
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)) {
|
||||
OUT_BATCH(state->Tex[i][I915_TEXREG_MS2]);
|
||||
/* Emit zero texture offset, will fixup before firing */
|
||||
intel_add_texoffset_fixup(intel, i, (GLuint *)batch_ptr);
|
||||
_mesa_printf("MS2: %x\n", *(GLuint *)batch_ptr);
|
||||
batch_ptr += 4;
|
||||
OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]);
|
||||
OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,280 +40,6 @@
|
|||
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Performance monitoring functions
|
||||
*/
|
||||
|
||||
static void intel_fill_box( intelContextPtr intel,
|
||||
GLshort x, GLshort y,
|
||||
GLshort w, GLshort h,
|
||||
GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
intelEmitFillBlitLocked( intel,
|
||||
intel->intelScreen->cpp,
|
||||
intel->intelScreen->back.pitch,
|
||||
intel->intelScreen->front.offset,
|
||||
x, y, w, h,
|
||||
INTEL_PACKCOLOR(intel->intelScreen->fbFormat,
|
||||
r,g,b,0xff));
|
||||
}
|
||||
|
||||
static void intel_draw_performance_boxes( intelContextPtr intel )
|
||||
{
|
||||
/* Purple box for page flipping
|
||||
*/
|
||||
if ( intel->perf_boxes & I830_BOX_FLIP )
|
||||
intel_fill_box( intel, 4, 4, 8, 8, 255, 0, 255 );
|
||||
|
||||
/* Red box if we have to wait for idle at any point
|
||||
*/
|
||||
if ( intel->perf_boxes & I830_BOX_WAIT )
|
||||
intel_fill_box( intel, 16, 4, 8, 8, 255, 0, 0 );
|
||||
|
||||
/* Blue box: lost context?
|
||||
*/
|
||||
if ( intel->perf_boxes & I830_BOX_LOST_CONTEXT )
|
||||
intel_fill_box( intel, 28, 4, 8, 8, 0, 0, 255 );
|
||||
|
||||
/* Yellow box for texture swaps
|
||||
*/
|
||||
if ( intel->perf_boxes & I830_BOX_TEXTURE_LOAD )
|
||||
intel_fill_box( intel, 40, 4, 8, 8, 255, 255, 0 );
|
||||
|
||||
/* Green box if hardware never idles (as far as we can tell)
|
||||
*/
|
||||
if ( !(intel->perf_boxes & I830_BOX_RING_EMPTY) )
|
||||
intel_fill_box( intel, 64, 4, 8, 8, 0, 255, 0 );
|
||||
|
||||
|
||||
/* Draw bars indicating number of buffers allocated
|
||||
* (not a great measure, easily confused)
|
||||
*/
|
||||
#if 0
|
||||
if (intel->dma_used) {
|
||||
int bar = intel->dma_used / 10240;
|
||||
if (bar > 100) bar = 100;
|
||||
if (bar < 1) bar = 1;
|
||||
intel_fill_box( intel, 4, 16, bar, 4, 196, 128, 128 );
|
||||
intel->dma_used = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
intel->perf_boxes = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int bad_prim_vertex_nr( int primitive, int nr )
|
||||
{
|
||||
switch (primitive & PRIM3D_MASK) {
|
||||
case PRIM3D_POINTLIST:
|
||||
return nr < 1;
|
||||
case PRIM3D_LINELIST:
|
||||
return (nr & 1) || nr == 0;
|
||||
case PRIM3D_LINESTRIP:
|
||||
return nr < 2;
|
||||
case PRIM3D_TRILIST:
|
||||
case PRIM3D_RECTLIST:
|
||||
return nr % 3 || nr == 0;
|
||||
case PRIM3D_POLY:
|
||||
case PRIM3D_TRIFAN:
|
||||
case PRIM3D_TRISTRIP:
|
||||
case PRIM3D_TRISTRIP_RVRSE:
|
||||
return nr < 3;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_flush_inline_primitive( GLcontext *ctx )
|
||||
{
|
||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
||||
GLuint used = intel->batch.ptr - intel->prim.start_ptr;
|
||||
GLuint vertcount;
|
||||
|
||||
assert(intel->prim.primitive != ~0);
|
||||
|
||||
if (1) {
|
||||
/* Check vertex size against the vertex we're specifying to
|
||||
* hardware. If it's wrong, ditch the primitive.
|
||||
*/
|
||||
if (!intel->vtbl.check_vertex_size( intel, intel->vertex_size ))
|
||||
goto do_discard;
|
||||
|
||||
vertcount = (used - 4)/ (intel->vertex_size * 4);
|
||||
|
||||
if (!vertcount)
|
||||
goto do_discard;
|
||||
|
||||
if (vertcount * intel->vertex_size * 4 != used - 4) {
|
||||
fprintf(stderr, "vertex size confusion %d %d\n", used,
|
||||
intel->vertex_size * vertcount * 4);
|
||||
goto do_discard;
|
||||
}
|
||||
|
||||
if (bad_prim_vertex_nr( intel->prim.primitive, vertcount )) {
|
||||
fprintf(stderr, "bad_prim_vertex_nr %x %d\n", intel->prim.primitive,
|
||||
vertcount);
|
||||
goto do_discard;
|
||||
}
|
||||
}
|
||||
|
||||
if (used < 8)
|
||||
goto do_discard;
|
||||
|
||||
*(int *)intel->prim.start_ptr = (_3DPRIMITIVE |
|
||||
intel->prim.primitive |
|
||||
(used/4-2));
|
||||
|
||||
goto finished;
|
||||
|
||||
do_discard:
|
||||
intel->batch.ptr -= used;
|
||||
intel->batch.space += used;
|
||||
assert(intel->batch.space >= 0);
|
||||
|
||||
finished:
|
||||
intel->prim.primitive = ~0;
|
||||
intel->prim.start_ptr = 0;
|
||||
intel->prim.flush = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Emit a primitive referencing vertices in a vertex buffer.
|
||||
*/
|
||||
void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
|
||||
{
|
||||
BATCH_LOCALS;
|
||||
|
||||
if (0)
|
||||
fprintf(stderr, "%s %x\n", __FUNCTION__, prim);
|
||||
|
||||
|
||||
/* Finish any in-progress primitive:
|
||||
*/
|
||||
INTEL_FIREVERTICES( intel );
|
||||
|
||||
/* Emit outstanding state:
|
||||
*/
|
||||
intel->vtbl.emit_state( intel );
|
||||
|
||||
/* Make sure there is some space in this buffer:
|
||||
*/
|
||||
if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space)
|
||||
intelFlushBatch(intel, GL_TRUE);
|
||||
|
||||
|
||||
#if 1
|
||||
if (((int)intel->batch.ptr) & 0x4) {
|
||||
BEGIN_BATCH(1);
|
||||
OUT_BATCH(0);
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Emit a slot which will be filled with the inline primitive
|
||||
* command later.
|
||||
*/
|
||||
BEGIN_BATCH(2);
|
||||
OUT_BATCH( 0 );
|
||||
|
||||
intel->prim.start_ptr = batch_ptr;
|
||||
intel->prim.primitive = prim;
|
||||
intel->prim.flush = intel_flush_inline_primitive;
|
||||
|
||||
OUT_BATCH( 0 );
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
|
||||
|
||||
void intelRestartInlinePrimitive( intelContextPtr intel )
|
||||
{
|
||||
GLuint prim = intel->prim.primitive;
|
||||
|
||||
intel_flush_inline_primitive( &intel->ctx );
|
||||
if (1) intelFlushBatch(intel, GL_TRUE); /* GL_TRUE - is critical */
|
||||
intelStartInlinePrimitive( intel, prim );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void intelWrapInlinePrimitive( intelContextPtr intel )
|
||||
{
|
||||
GLuint prim = intel->prim.primitive;
|
||||
|
||||
if (0)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
intel_flush_inline_primitive( &intel->ctx );
|
||||
intelFlushBatch(intel, GL_TRUE);
|
||||
intelStartInlinePrimitive( intel, prim );
|
||||
}
|
||||
|
||||
|
||||
/* Emit a primitive with space for inline vertices.
|
||||
*/
|
||||
GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
|
||||
int primitive,
|
||||
int dwords,
|
||||
int vertex_size )
|
||||
{
|
||||
GLuint *tmp = 0;
|
||||
BATCH_LOCALS;
|
||||
|
||||
if (0)
|
||||
fprintf(stderr, "%s 0x%x %d\n", __FUNCTION__, primitive, dwords);
|
||||
|
||||
/* Emit outstanding state:
|
||||
*/
|
||||
intel->vtbl.emit_state( intel );
|
||||
|
||||
|
||||
if (1) {
|
||||
int used = dwords * 4;
|
||||
int vertcount;
|
||||
|
||||
/* Check vertex size against the vertex we're specifying to
|
||||
* hardware. If it's wrong, ditch the primitive.
|
||||
*/
|
||||
if (!intel->vtbl.check_vertex_size( intel, vertex_size ))
|
||||
goto do_discard;
|
||||
|
||||
vertcount = dwords / vertex_size;
|
||||
|
||||
if (dwords % vertex_size) {
|
||||
fprintf(stderr, "did not request a whole number of vertices\n");
|
||||
goto do_discard;
|
||||
}
|
||||
|
||||
if (bad_prim_vertex_nr( primitive, vertcount )) {
|
||||
fprintf(stderr, "bad_prim_vertex_nr %x %d\n", primitive, vertcount);
|
||||
goto do_discard;
|
||||
}
|
||||
|
||||
if (used < 8)
|
||||
goto do_discard;
|
||||
}
|
||||
|
||||
/* Emit 3D_PRIMITIVE commands:
|
||||
*/
|
||||
BEGIN_BATCH(1 + dwords);
|
||||
OUT_BATCH( _3DPRIMITIVE |
|
||||
primitive |
|
||||
(dwords-1) );
|
||||
|
||||
tmp = (GLuint *)batch_ptr;
|
||||
batch_ptr += dwords * 4;
|
||||
|
||||
ADVANCE_BATCH();
|
||||
|
||||
do_discard:
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Copy the back buffer to the front buffer.
|
||||
|
|
@ -360,9 +86,6 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
|
|||
break;
|
||||
}
|
||||
|
||||
if (0)
|
||||
intel_draw_performance_boxes( intel );
|
||||
|
||||
for (i = 0 ; i < nbox; i++, pbox++)
|
||||
{
|
||||
if (pbox->x1 > pbox->x2 ||
|
||||
|
|
@ -646,7 +369,9 @@ void intelInitBatchBuffer( GLcontext *ctx )
|
|||
{
|
||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
||||
|
||||
if (!intel->intelScreen->allow_batchbuffer || getenv("INTEL_NO_BATCH")) {
|
||||
/* AGP allocation won't work:
|
||||
*/
|
||||
if (1 || !intel->intelScreen->allow_batchbuffer || getenv("INTEL_NO_BATCH")) {
|
||||
intel->alloc.size = 8 * 1024;
|
||||
intel->alloc.ptr = malloc( intel->alloc.size );
|
||||
intel->alloc.offset = 0;
|
||||
|
|
|
|||
|
|
@ -34,10 +34,7 @@
|
|||
|
||||
#define BATCH_LOCALS GLubyte *batch_ptr;
|
||||
|
||||
/* #define VERBOSE 0 */
|
||||
#ifndef VERBOSE
|
||||
extern int VERBOSE;
|
||||
#endif
|
||||
#define VERBOSE 1
|
||||
|
||||
|
||||
#define BEGIN_BATCH(n) \
|
||||
|
|
@ -70,7 +67,6 @@ extern void intelDestroyBatchBuffer( GLcontext *ctx );
|
|||
|
||||
extern void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim );
|
||||
extern void intelWrapInlinePrimitive( intelContextPtr intel );
|
||||
extern void intelRestartInlinePrimitive( intelContextPtr intel );
|
||||
extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
|
||||
int primitive, int dwords,
|
||||
int vertex_size);
|
||||
|
|
@ -99,25 +95,7 @@ extern void intelEmitFillBlitLocked( intelContextPtr intel,
|
|||
|
||||
|
||||
|
||||
static __inline GLuint *intelExtendInlinePrimitive( intelContextPtr intel,
|
||||
GLuint dwords )
|
||||
{
|
||||
GLuint sz = dwords * sizeof(GLuint);
|
||||
GLuint *ptr;
|
||||
|
||||
if (intel->batch.space < sz) {
|
||||
intelWrapInlinePrimitive( intel );
|
||||
/* assert(intel->batch.space >= sz); */
|
||||
}
|
||||
|
||||
/* assert(intel->prim.primitive != ~0); */
|
||||
ptr = (GLuint *)intel->batch.ptr;
|
||||
intel->batch.ptr += sz;
|
||||
intel->batch.space -= sz;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
GLuint *intelExtendInlinePrimitive( intelContextPtr intel,
|
||||
GLuint dwords );
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ static const struct tnl_pipeline_stage *intel_pipeline[] = {
|
|||
&_tnl_point_attenuation_stage,
|
||||
&_tnl_arb_vertex_program_stage,
|
||||
&_tnl_vertex_program_stage,
|
||||
#if 1
|
||||
#if 0
|
||||
&_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */
|
||||
#endif
|
||||
&_tnl_render_stage,
|
||||
|
|
|
|||
|
|
@ -81,6 +81,10 @@ struct intel_texture_object
|
|||
GLuint firstLevel;
|
||||
GLuint lastLevel;
|
||||
|
||||
/* Offset for firstLevel image:
|
||||
*/
|
||||
GLuint textureOffset;
|
||||
|
||||
/* On validation any active images held in main memory or in other
|
||||
* regions will be copied to this region and the old storage freed.
|
||||
*/
|
||||
|
|
@ -97,10 +101,22 @@ struct intel_texture_image {
|
|||
GLuint level;
|
||||
GLuint face;
|
||||
|
||||
/* If intelImage->mt != NULL, image data is stored here.
|
||||
* Else if intelImage->base.Data != NULL, image is stored there.
|
||||
* Else there is no image data.
|
||||
*/
|
||||
struct intel_mipmap_tree *mt;
|
||||
};
|
||||
|
||||
|
||||
struct intel_reloc {
|
||||
GLuint *value;
|
||||
GLuint delta;
|
||||
GLuint *dest;
|
||||
};
|
||||
|
||||
#define INTEL_MAX_FIXUP 64
|
||||
|
||||
struct intel_context
|
||||
{
|
||||
GLcontext ctx; /* the parent class */
|
||||
|
|
@ -182,8 +198,11 @@ 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;
|
||||
|
||||
struct intel_texture_object *CurrentTexObj[MAX_TEXTURE_UNITS];
|
||||
|
||||
/* State for intelvb.c and inteltris.c.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ void intelFlushBatchLocked( intelContextPtr intel,
|
|||
}
|
||||
}
|
||||
|
||||
if (0)
|
||||
if (1)
|
||||
intel_dump_batchbuffer( batch.start,
|
||||
(int *)(intel->batch.ptr - batch.used),
|
||||
batch.used );
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "intel_mipmap_tree.h"
|
||||
#include "intel_regions.h"
|
||||
#include "bufmgr.h"
|
||||
#include "enums.h"
|
||||
|
||||
static GLenum target_to_target( GLenum target )
|
||||
{
|
||||
|
|
@ -59,6 +60,12 @@ struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel,
|
|||
GLboolean ok;
|
||||
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
|
||||
|
||||
_mesa_printf("%s target %s format %s level %d..%d\n", __FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
_mesa_lookup_enum_by_nr(internal_format),
|
||||
first_level,
|
||||
last_level);
|
||||
|
||||
mt->target = target_to_target(target);
|
||||
mt->internal_format = internal_format;
|
||||
mt->first_level = first_level;
|
||||
|
|
@ -125,6 +132,11 @@ GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt,
|
|||
GLuint face,
|
||||
GLuint level )
|
||||
{
|
||||
_mesa_printf("%s %d %d/%d %d/%d\n", __FUNCTION__,
|
||||
image->Border,
|
||||
image->InternalFormat, mt->internal_format,
|
||||
image->IsCompressed, mt->compressed);
|
||||
|
||||
/* Images with borders are never pulled into mipmap trees.
|
||||
*/
|
||||
if (image->Border)
|
||||
|
|
@ -134,6 +146,11 @@ GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt,
|
|||
image->IsCompressed != mt->compressed)
|
||||
return GL_FALSE;
|
||||
|
||||
_mesa_printf("%s: %d/%d %d/%d %d/%d\n", __FUNCTION__,
|
||||
image->Width, mt->offset[face][level].width,
|
||||
image->Height, mt->offset[face][level].height,
|
||||
image->Depth, mt->offset[face][level].depth);
|
||||
|
||||
/* Test image dimensions against the base level image adjusted for
|
||||
* minification. This will also catch images not present in the
|
||||
* tree, changed targets, etc.
|
||||
|
|
@ -143,34 +160,47 @@ GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt,
|
|||
image->Depth != mt->offset[face][level].depth)
|
||||
return GL_FALSE;
|
||||
|
||||
|
||||
_mesa_printf("%s: success\n", __FUNCTION__);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt,
|
||||
GLuint face,
|
||||
GLuint level)
|
||||
{
|
||||
return (mt->offset[face][level].x +
|
||||
mt->offset[face][level].y * mt->pitch) * mt->cpp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
GLubyte *intel_miptree_image_map(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt,
|
||||
GLuint face,
|
||||
GLuint level,
|
||||
GLuint *stride)
|
||||
{
|
||||
GLubyte *img = intel_region_map(intel, mt->region);
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (stride)
|
||||
*stride = mt->pitch * mt->cpp;
|
||||
|
||||
return img + (mt->offset[face][level].x +
|
||||
mt->offset[face][level].y * mt->pitch) * mt->cpp;
|
||||
return (intel_region_map(intel, mt->region) +
|
||||
intel_miptree_image_offset(mt, face, level));
|
||||
}
|
||||
|
||||
void intel_miptree_image_unmap(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt)
|
||||
{
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
intel_region_unmap(intel, mt->region);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Upload data for a particular image.
|
||||
*
|
||||
* TODO: 3D textures
|
||||
|
|
@ -181,6 +211,7 @@ void intel_miptree_image_data(struct intel_context *intel,
|
|||
GLuint level,
|
||||
void *src, GLuint src_pitch )
|
||||
{
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
intel_region_data(intel,
|
||||
dst->region,
|
||||
dst->offset[face][level].x,
|
||||
|
|
@ -199,6 +230,7 @@ void intel_miptree_image_copy( struct intel_context *intel,
|
|||
GLuint face, GLuint level,
|
||||
struct intel_mipmap_tree *src )
|
||||
{
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
assert(src->offset[face][level].width ==
|
||||
dst->offset[face][level].width);
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,16 @@ GLubyte *intel_miptree_image_map( struct intel_context *intel,
|
|||
void intel_miptree_image_unmap( struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt );
|
||||
|
||||
|
||||
/* Return the linear offset of an image relative to the start of the
|
||||
* tree:
|
||||
*/
|
||||
GLuint intel_miptree_image_offset( struct intel_mipmap_tree *mt,
|
||||
GLuint face,
|
||||
GLuint level );
|
||||
|
||||
|
||||
|
||||
/* Upload an image into a tree
|
||||
*/
|
||||
void intel_miptree_image_data(struct intel_context *intel,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
*/
|
||||
GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *region)
|
||||
{
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
if (!region->map_refcount++) {
|
||||
region->map = bmMapBuffer(intel->bm, region->buffer, 0);
|
||||
}
|
||||
|
|
@ -58,6 +59,7 @@ GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *regi
|
|||
void intel_region_unmap(struct intel_context *intel,
|
||||
struct intel_region *region)
|
||||
{
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
if (!--region->map_refcount) {
|
||||
bmUnmapBuffer(intel->bm, region->buffer);
|
||||
}
|
||||
|
|
@ -70,6 +72,8 @@ struct intel_region *intel_region_alloc( struct intel_context *intel,
|
|||
{
|
||||
struct intel_region *region = calloc(sizeof(*region), 1);
|
||||
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
|
||||
region->cpp = cpp;
|
||||
region->pitch = pitch;
|
||||
region->height = height; /* needed? */
|
||||
|
|
@ -201,6 +205,8 @@ void intel_region_data(struct intel_context *intel,
|
|||
GLuint srcx, GLuint srcy,
|
||||
GLuint width, GLuint height)
|
||||
{
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
|
||||
LOCK_HARDWARE(intel);
|
||||
|
||||
_mesa_copy_rect(intel_region_map(intel, dst),
|
||||
|
|
@ -232,6 +238,8 @@ void intel_region_copy( struct intel_context *intel,
|
|||
unsigned src_offset;
|
||||
struct bm_buffer_list *list = bmNewBufferList();
|
||||
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
|
||||
assert(src->cpp == dst->cpp);
|
||||
|
||||
LOCK_HARDWARE(intel);
|
||||
|
|
@ -282,6 +290,8 @@ void intel_region_fill( struct intel_context *intel,
|
|||
unsigned dst_offset;
|
||||
struct bm_buffer_list *list = bmNewBufferList();
|
||||
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
|
||||
LOCK_HARDWARE(intel);
|
||||
bmAddBuffer(intel->bm, list, dst->buffer, BM_WRITE, NULL, &dst_offset);
|
||||
|
||||
|
|
|
|||
|
|
@ -199,6 +199,10 @@ static GLboolean intel_run_render( GLcontext *ctx,
|
|||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i;
|
||||
|
||||
/* disabled
|
||||
*/
|
||||
return GL_TRUE;
|
||||
|
||||
/* Don't handle clipping or indexed vertices.
|
||||
*/
|
||||
if (intel->RenderIndex != 0 ||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,14 @@ void intelTexSubImage1D(GLcontext *ctx,
|
|||
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 );
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ static void guess_and_alloc_mipmap_tree( struct intel_context *intel,
|
|||
GLuint l2width, l2height, l2depth;
|
||||
GLuint i;
|
||||
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (intelImage->base.Border)
|
||||
return;
|
||||
|
||||
|
|
@ -121,6 +123,8 @@ static void guess_and_alloc_mipmap_tree( struct intel_context *intel,
|
|||
depth,
|
||||
intelImage->base.TexFormat->TexelBytes,
|
||||
intelImage->base.IsCompressed );
|
||||
|
||||
_mesa_printf("%s - success\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -161,6 +165,11 @@ static void intelTexImage(GLcontext *ctx,
|
|||
GLint texelBytes, sizeInBytes;
|
||||
GLuint dstRowStride;
|
||||
|
||||
_mesa_printf("%s target %s level %d %dx%d border %d\n", __FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
level,
|
||||
width, height, border);
|
||||
|
||||
intelImage->face = target_to_face( target );
|
||||
intelImage->level = level;
|
||||
|
||||
|
|
@ -219,15 +228,23 @@ static void intelTexImage(GLcontext *ctx,
|
|||
LOCK_HARDWARE(intel);
|
||||
|
||||
if (intelObj->mt &&
|
||||
intelObj->mt != intelImage->mt &&
|
||||
intel_miptree_match_image(intelObj->mt, &intelImage->base,
|
||||
intelImage->face, intelImage->level)) {
|
||||
|
||||
if (intelImage->mt)
|
||||
intel_miptree_release(intel, intelImage->mt);
|
||||
|
||||
intelImage->mt = intel_miptree_reference(intelObj->mt);
|
||||
}
|
||||
|
||||
if (intelImage->mt) {
|
||||
texImage->Data = intel_miptree_image_map(intel,
|
||||
intelObj->mt,
|
||||
intelImage->mt,
|
||||
intelImage->face,
|
||||
intelImage->level,
|
||||
&dstRowStride);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Allocate regular memory and store the image there temporarily. */
|
||||
if (texImage->IsCompressed) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "mtypes.h"
|
||||
#include "texobj.h"
|
||||
#include "texstore.h"
|
||||
#include "enums.h"
|
||||
|
||||
#include "intel_context.h"
|
||||
#include "intel_tex.h"
|
||||
|
|
@ -24,6 +25,12 @@ static void intelTexSubimage (GLcontext *ctx,
|
|||
GLuint dstImageStride = 0;
|
||||
GLuint dstRowStride;
|
||||
|
||||
_mesa_printf("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
level,
|
||||
xoffset, yoffset,
|
||||
width, height);
|
||||
|
||||
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, format, type,
|
||||
pixels, packing, "glTexSubImage2D");
|
||||
if (!pixels)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#include "intel_context.h"
|
||||
#include "intel_mipmap_tree.h"
|
||||
#include "intel_tex.h"
|
||||
|
||||
#include "bufmgr.h"
|
||||
|
||||
/**
|
||||
* Compute which mipmap levels that really need to be sent to the hardware.
|
||||
|
|
@ -96,9 +96,11 @@ static void copy_image_data_to_tree( struct intel_context *intel,
|
|||
|
||||
/*
|
||||
*/
|
||||
GLuint intel_validate_mipmap_tree( struct intel_context *intel,
|
||||
struct intel_texture_object *intelObj )
|
||||
static 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);
|
||||
|
||||
GLuint face, i;
|
||||
GLuint nr_faces = 0;
|
||||
struct intel_texture_image *firstImage;
|
||||
|
|
@ -139,6 +141,12 @@ GLuint intel_validate_mipmap_tree( struct intel_context *intel,
|
|||
|
||||
/* Check tree can hold all active levels. Check tree matches
|
||||
* target, imageFormat, etc.
|
||||
*
|
||||
* XXX: For some layouts (eg i945?), the test might have to be
|
||||
* first_level == firstLevel, as the tree isn't valid except at the
|
||||
* original start level. Hope to get around this by
|
||||
* programming minLod, maxLod, baseLevel into the hardware and
|
||||
* leaving the tree alone.
|
||||
*/
|
||||
if (intelObj->mt &&
|
||||
((intelObj->mt->first_level > intelObj->firstLevel) ||
|
||||
|
|
@ -152,7 +160,6 @@ GLuint intel_validate_mipmap_tree( struct intel_context *intel,
|
|||
/* May need to create a new tree:
|
||||
*/
|
||||
if (!intelObj->mt) {
|
||||
assert(!firstImage->mt);
|
||||
intelObj->mt = intel_miptree_create(intel,
|
||||
intelObj->base.Target,
|
||||
firstImage->base.InternalFormat,
|
||||
|
|
@ -165,13 +172,9 @@ GLuint intel_validate_mipmap_tree( struct intel_context *intel,
|
|||
firstImage->base.IsCompressed);
|
||||
}
|
||||
|
||||
assert(intelObj->mt);
|
||||
|
||||
assert(firstImage->mt == intelObj->mt ||
|
||||
firstImage->mt == NULL);
|
||||
|
||||
/* Pull in any images not in the object's tree:
|
||||
*/
|
||||
nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||
|
||||
for (face = 0; face < nr_faces; face++) {
|
||||
for (i = intelObj->firstLevel; i < intelObj->lastLevel; i++) {
|
||||
struct intel_texture_image *intelImage =
|
||||
|
|
@ -190,9 +193,105 @@ GLuint intel_validate_mipmap_tree( struct intel_context *intel,
|
|||
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->intelScreen->tex.offset +
|
||||
intel_miptree_image_offset(intelObj->mt, 0, intelObj->firstLevel));
|
||||
*ptr = 9999;
|
||||
#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;
|
||||
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
|
||||
assert(intel->locked);
|
||||
assert (!intel->buffer_list);
|
||||
|
||||
intel->buffer_list = bmNewBufferList();
|
||||
|
||||
/* Add the color and depth buffers:
|
||||
*/
|
||||
|
||||
/* 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->bm,
|
||||
intel->buffer_list,
|
||||
intelObj->mt->region->buffer,
|
||||
BM_READ,
|
||||
NULL,
|
||||
&intelObj->textureOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok = bmValidateBufferList(intel->bm, intel->buffer_list, 0);
|
||||
assert(ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
void intel_fence_buffers( struct intel_context *intel )
|
||||
{
|
||||
assert(intel->locked);
|
||||
assert(intel->buffer_list);
|
||||
bmFenceBufferList(intel->bm, intel->buffer_list);
|
||||
bmFreeBufferList(intel->buffer_list);
|
||||
intel->buffer_list = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,131 @@
|
|||
#include "intel_batchbuffer.h"
|
||||
#include "intel_reg.h"
|
||||
#include "intel_span.h"
|
||||
#include "intel_tex.h"
|
||||
|
||||
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim );
|
||||
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
|
||||
|
||||
/* The simplest but least-good technique for integrating new buffer
|
||||
* management:
|
||||
*
|
||||
* LOCK_HARDWARE
|
||||
* validate_buffers
|
||||
* emit_state to batch
|
||||
* emit_vertices to batch
|
||||
* flush batch
|
||||
* fence_buffers
|
||||
* UNLOCK_HARDWARE
|
||||
*
|
||||
* Will look later at ways to get the emit_state and emit_vertices out
|
||||
* of the locked region - vertex buffers, second batch buffer for
|
||||
* primitives, relocation fixups for texture addresses.
|
||||
*/
|
||||
static void intel_flush_inline_primitive( GLcontext *ctx )
|
||||
{
|
||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
||||
GLuint used = intel->batch.ptr - intel->prim.start_ptr;
|
||||
|
||||
assert(intel->prim.primitive != ~0);
|
||||
|
||||
if (used < 8)
|
||||
goto do_discard;
|
||||
|
||||
*(int *)intel->prim.start_ptr = (_3DPRIMITIVE |
|
||||
intel->prim.primitive |
|
||||
(used/4-2));
|
||||
|
||||
goto finished;
|
||||
|
||||
do_discard:
|
||||
intel->batch.ptr -= used;
|
||||
intel->batch.space += used;
|
||||
assert(intel->batch.space >= 0);
|
||||
|
||||
finished:
|
||||
intel->prim.primitive = ~0;
|
||||
intel->prim.start_ptr = 0;
|
||||
intel->prim.flush = 0;
|
||||
|
||||
intelFlushBatch(intel, GL_TRUE);
|
||||
intel_fence_buffers(intel);
|
||||
UNLOCK_HARDWARE(intel);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Emit a primitive referencing vertices in a vertex buffer.
|
||||
*/
|
||||
void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
|
||||
{
|
||||
BATCH_LOCALS;
|
||||
|
||||
fprintf(stderr, "%s %x\n", __FUNCTION__, prim);
|
||||
|
||||
|
||||
/* Finish any in-progress primitive:
|
||||
*/
|
||||
INTEL_FIREVERTICES( intel );
|
||||
|
||||
LOCK_HARDWARE(intel);
|
||||
intel_validate_buffers( intel );
|
||||
intel->vtbl.emit_state( intel );
|
||||
|
||||
/* Make sure there is some space in this buffer:
|
||||
*/
|
||||
if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space)
|
||||
intelFlushBatch(intel, GL_TRUE);
|
||||
|
||||
if (((int)intel->batch.ptr) & 0x4) {
|
||||
BEGIN_BATCH(1);
|
||||
OUT_BATCH(0);
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
|
||||
/* Emit a slot which will be filled with the inline primitive
|
||||
* command later.
|
||||
*/
|
||||
BEGIN_BATCH(2);
|
||||
OUT_BATCH( 0 );
|
||||
|
||||
intel->prim.start_ptr = batch_ptr;
|
||||
intel->prim.primitive = prim;
|
||||
intel->prim.flush = intel_flush_inline_primitive;
|
||||
|
||||
OUT_BATCH( 0 );
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
|
||||
|
||||
void intelWrapInlinePrimitive( intelContextPtr intel )
|
||||
{
|
||||
GLuint prim = intel->prim.primitive;
|
||||
|
||||
intel_flush_inline_primitive( &intel->ctx );
|
||||
intelFlushBatch(intel, GL_TRUE);
|
||||
intelStartInlinePrimitive( intel, prim );
|
||||
}
|
||||
|
||||
GLuint *intelExtendInlinePrimitive( intelContextPtr intel,
|
||||
GLuint dwords )
|
||||
{
|
||||
GLuint sz = dwords * sizeof(GLuint);
|
||||
GLuint *ptr;
|
||||
|
||||
if (intel->batch.space < sz) {
|
||||
intelWrapInlinePrimitive( intel );
|
||||
}
|
||||
|
||||
ptr = (GLuint *)intel->batch.ptr;
|
||||
intel->batch.ptr += sz;
|
||||
intel->batch.space -= sz;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Emit primitives as inline vertices *
|
||||
***********************************************************************/
|
||||
|
|
@ -520,22 +641,6 @@ intel_fallback_line( intelContextPtr intel,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
intel_fallback_point( intelContextPtr intel,
|
||||
intelVertex *v0 )
|
||||
{
|
||||
GLcontext *ctx = &intel->ctx;
|
||||
SWvertex v[1];
|
||||
|
||||
if (0)
|
||||
fprintf(stderr, "\n%s\n", __FUNCTION__);
|
||||
|
||||
_swsetup_Translate( ctx, v0, &v[0] );
|
||||
intelSpanRenderStart( ctx );
|
||||
_swrast_Point( ctx, &v[0] );
|
||||
intelSpanRenderFinish( ctx );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
|
|
@ -630,12 +735,8 @@ static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
|
|||
|
||||
|
||||
|
||||
#define POINT_FALLBACK (0)
|
||||
#define LINE_FALLBACK (DD_LINE_STIPPLE)
|
||||
#define TRI_FALLBACK (0)
|
||||
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\
|
||||
DD_TRI_STIPPLE|DD_POINT_ATTEN)
|
||||
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
|
||||
#define ANY_FALLBACK_FLAGS (DD_LINE_STIPPLE | DD_TRI_STIPPLE | DD_POINT_ATTEN)
|
||||
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_TRI_UNFILLED)
|
||||
|
||||
void intelChooseRenderState(GLcontext *ctx)
|
||||
{
|
||||
|
|
@ -672,19 +773,14 @@ void intelChooseRenderState(GLcontext *ctx)
|
|||
intel->draw_tri = intel_draw_triangle;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Hook in fallbacks for specific primitives.
|
||||
*/
|
||||
if (flags & ANY_FALLBACK_FLAGS)
|
||||
{
|
||||
if (flags & POINT_FALLBACK)
|
||||
intel->draw_point = intel_fallback_point;
|
||||
|
||||
if (flags & LINE_FALLBACK)
|
||||
if (flags & DD_LINE_STIPPLE)
|
||||
intel->draw_line = intel_fallback_line;
|
||||
|
||||
if (flags & TRI_FALLBACK)
|
||||
intel->draw_tri = intel_fallback_tri;
|
||||
|
||||
if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple)
|
||||
intel->draw_tri = intel_fallback_tri;
|
||||
|
||||
|
|
@ -693,6 +789,8 @@ void intelChooseRenderState(GLcontext *ctx)
|
|||
|
||||
index |= INTEL_FALLBACK_BIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (intel->RenderIndex != index) {
|
||||
|
|
@ -765,8 +863,13 @@ static void intelRenderStart( GLcontext *ctx )
|
|||
|
||||
static void intelRenderFinish( GLcontext *ctx )
|
||||
{
|
||||
if (INTEL_CONTEXT(ctx)->RenderIndex & INTEL_FALLBACK_BIT)
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
|
||||
if (intel->RenderIndex & INTEL_FALLBACK_BIT)
|
||||
_swrast_flush( ctx );
|
||||
|
||||
if (intel->prim.flush)
|
||||
intel->prim.flush(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue