mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
Merge git://proxy01.pd.intel.com:9419/git/mesa/mesa into crestline
This commit is contained in:
commit
ee9bc897f8
12 changed files with 313 additions and 354 deletions
|
|
@ -13,6 +13,7 @@
|
|||
#include <math.h>
|
||||
#include <GL/glut.h>
|
||||
|
||||
static int Win = 0;
|
||||
static int Width = 400, Height = 400;
|
||||
static GLuint MyFB, ColorRb, DepthRb;
|
||||
static GLboolean Animate = GL_TRUE;
|
||||
|
|
@ -110,6 +111,7 @@ CleanUp(void)
|
|||
assert(!glIsFramebufferEXT(MyFB));
|
||||
assert(!glIsRenderbufferEXT(ColorRb));
|
||||
assert(!glIsRenderbufferEXT(DepthRb));
|
||||
glutDestroyWindow(Win);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +189,7 @@ main( int argc, char *argv[] )
|
|||
glutInitWindowPosition( 0, 0 );
|
||||
glutInitWindowSize(Width, Height);
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
glutCreateWindow(argv[0]);
|
||||
Win = glutCreateWindow(argv[0]);
|
||||
glutReshapeFunc( Reshape );
|
||||
glutKeyboardFunc( Key );
|
||||
glutDisplayFunc( Display );
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ static void recalculate_urb_fence( struct brw_context *brw )
|
|||
|
||||
brw->urb.constrained = 1;
|
||||
|
||||
if (check_urb_layout(brw)) {
|
||||
if (!check_urb_layout(brw)) {
|
||||
/* This is impossible, given the maximal sizes of urb
|
||||
* entries and the values for minimum nr of entries
|
||||
* provided above.
|
||||
|
|
|
|||
|
|
@ -934,6 +934,9 @@ static void emit_tex(struct r300_fragment_program *rp,
|
|||
int hwsrc, hwdest;
|
||||
GLuint tempreg = 0;
|
||||
|
||||
uin = cs->used_in_node;
|
||||
din = cs->dest_in_node;
|
||||
|
||||
/* Resolve source/dest to hardware registers */
|
||||
if (opcode != R300_FPITX_OP_KIL) {
|
||||
if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) {
|
||||
|
|
@ -958,6 +961,10 @@ static void emit_tex(struct r300_fragment_program *rp,
|
|||
emit_arith(rp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW,
|
||||
coord, factorreg, pfs_zero, 0);
|
||||
|
||||
/* Ensure correct node indirection */
|
||||
uin = cs->used_in_node;
|
||||
din = cs->dest_in_node;
|
||||
|
||||
hwsrc = t_hw_src(rp, tempreg, GL_TRUE);
|
||||
} else {
|
||||
hwsrc = t_hw_src(rp, coord, GL_TRUE);
|
||||
|
|
@ -986,8 +993,6 @@ static void emit_tex(struct r300_fragment_program *rp,
|
|||
hwsrc = t_hw_src(rp, coord, GL_TRUE);
|
||||
}
|
||||
|
||||
din = cs->dest_in_node;
|
||||
uin = cs->used_in_node;
|
||||
|
||||
/* Indirection if source has been written in this node, or if the
|
||||
* dest has been read/written in this node
|
||||
|
|
|
|||
|
|
@ -303,195 +303,190 @@ static void r300UploadRectSubImage(r300ContextPtr rmesa,
|
|||
* Upload the texture image associated with texture \a t at the specified
|
||||
* level at the address relative to \a start.
|
||||
*/
|
||||
static void uploadSubImage( r300ContextPtr rmesa, r300TexObjPtr t,
|
||||
static void uploadSubImage( r300ContextPtr rmesa, r300TexObjPtr t,
|
||||
GLint hwlevel,
|
||||
GLint x, GLint y, GLint width, GLint height,
|
||||
GLuint face )
|
||||
{
|
||||
struct gl_texture_image *texImage = NULL;
|
||||
GLuint offset;
|
||||
GLint imageWidth, imageHeight;
|
||||
GLint ret;
|
||||
drm_radeon_texture_t tex;
|
||||
drm_radeon_tex_image_t tmp;
|
||||
const int level = hwlevel + t->base.firstLevel;
|
||||
struct gl_texture_image *texImage = NULL;
|
||||
GLuint offset;
|
||||
GLint imageWidth, imageHeight;
|
||||
GLint ret;
|
||||
drm_radeon_texture_t tex;
|
||||
drm_radeon_tex_image_t tmp;
|
||||
const int level = hwlevel + t->base.firstLevel;
|
||||
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
|
||||
__FUNCTION__, (void *)t, (void *)t->base.tObj,
|
||||
level, width, height, face );
|
||||
}
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
|
||||
__FUNCTION__, (void *)t, (void *)t->base.tObj,
|
||||
level, width, height, face );
|
||||
}
|
||||
|
||||
ASSERT(face < 6);
|
||||
ASSERT(face < 6);
|
||||
|
||||
/* Ensure we have a valid texture to upload */
|
||||
if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {
|
||||
_mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
/* Ensure we have a valid texture to upload */
|
||||
if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {
|
||||
_mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
texImage = t->base.tObj->Image[face][level];
|
||||
texImage = t->base.tObj->Image[face][level];
|
||||
|
||||
if ( !texImage ) {
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
|
||||
return;
|
||||
}
|
||||
if ( !texImage->Data ) {
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
|
||||
return;
|
||||
}
|
||||
if ( !texImage ) {
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
|
||||
return;
|
||||
}
|
||||
if ( !texImage->Data ) {
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
assert(level == 0);
|
||||
assert(hwlevel == 0);
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);
|
||||
r300UploadRectSubImage( rmesa, t, texImage, x, y, width, height );
|
||||
return;
|
||||
}
|
||||
else if (texImage->IsClientData) {
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is in GART client storage\n",
|
||||
__FUNCTION__);
|
||||
r300UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,
|
||||
x, y, width, height );
|
||||
return;
|
||||
}
|
||||
else if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is in normal memory\n",
|
||||
__FUNCTION__);
|
||||
|
||||
if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
assert(level == 0);
|
||||
assert(hwlevel == 0);
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);
|
||||
r300UploadRectSubImage( rmesa, t, texImage, x, y, width, height );
|
||||
return;
|
||||
} else if (texImage->IsClientData) {
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is in GART client storage\n",
|
||||
__FUNCTION__);
|
||||
r300UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,
|
||||
x, y, width, height );
|
||||
return;
|
||||
} else if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is in normal memory\n",
|
||||
__FUNCTION__);
|
||||
|
||||
imageWidth = texImage->Width;
|
||||
imageHeight = texImage->Height;
|
||||
|
||||
offset = t->bufAddr + t->base.totalSize / 6 * face;
|
||||
imageWidth = texImage->Width;
|
||||
imageHeight = texImage->Height;
|
||||
|
||||
if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
|
||||
GLint imageX = 0;
|
||||
GLint imageY = 0;
|
||||
GLint blitX = t->image[face][hwlevel].x;
|
||||
GLint blitY = t->image[face][hwlevel].y;
|
||||
GLint blitWidth = t->image[face][hwlevel].width;
|
||||
GLint blitHeight = t->image[face][hwlevel].height;
|
||||
fprintf( stderr, " upload image: %d,%d at %d,%d\n",
|
||||
imageWidth, imageHeight, imageX, imageY );
|
||||
fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
|
||||
blitWidth, blitHeight, blitX, blitY );
|
||||
fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n",
|
||||
(GLuint)offset, hwlevel, level );
|
||||
}
|
||||
offset = t->bufAddr + t->base.totalSize / 6 * face;
|
||||
|
||||
t->image[face][hwlevel].data = texImage->Data;
|
||||
if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
|
||||
GLint imageX = 0;
|
||||
GLint imageY = 0;
|
||||
GLint blitX = t->image[face][hwlevel].x;
|
||||
GLint blitY = t->image[face][hwlevel].y;
|
||||
GLint blitWidth = t->image[face][hwlevel].width;
|
||||
GLint blitHeight = t->image[face][hwlevel].height;
|
||||
fprintf( stderr, " upload image: %d,%d at %d,%d\n",
|
||||
imageWidth, imageHeight, imageX, imageY );
|
||||
fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
|
||||
blitWidth, blitHeight, blitX, blitY );
|
||||
fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n",
|
||||
(GLuint)offset, hwlevel, level );
|
||||
}
|
||||
|
||||
/* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
|
||||
* NOTE: we're always use a 1KB-wide blit and I8 texture format.
|
||||
* We used to use 1, 2 and 4-byte texels and used to use the texture
|
||||
* width to dictate the blit width - but that won't work for compressed
|
||||
* textures. (Brian)
|
||||
* NOTE: can't do that with texture tiling. (sroland)
|
||||
*/
|
||||
tex.offset = offset;
|
||||
tex.image = &tmp;
|
||||
/* copy (x,y,width,height,data) */
|
||||
memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );
|
||||
|
||||
if (texImage->TexFormat->TexelBytes > 4) {
|
||||
const int log2TexelBytes = (3 + (texImage->TexFormat->TexelBytes >> 4));
|
||||
tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
|
||||
tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
|
||||
tex.height = imageHeight;
|
||||
tex.width = imageWidth << log2TexelBytes;
|
||||
tex.offset += (tmp.x << log2TexelBytes) & ~1023;
|
||||
tmp.x = tmp.x % (1024 >> log2TexelBytes);
|
||||
tmp.width = tmp.width << log2TexelBytes;
|
||||
}
|
||||
else if (texImage->TexFormat->TexelBytes) {
|
||||
/* use multi-byte upload scheme */
|
||||
tex.height = imageHeight;
|
||||
tex.width = imageWidth;
|
||||
switch(texImage->TexFormat->TexelBytes) {
|
||||
case 1:
|
||||
tex.format = RADEON_TXFORMAT_I8;
|
||||
break;
|
||||
case 2:
|
||||
tex.format = RADEON_TXFORMAT_AI88;
|
||||
break;
|
||||
case 4:
|
||||
tex.format = RADEON_TXFORMAT_ARGB8888;
|
||||
break;
|
||||
}
|
||||
tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
|
||||
tex.offset += tmp.x & ~1023;
|
||||
tmp.x = tmp.x % 1024;
|
||||
t->image[face][hwlevel].data = texImage->Data;
|
||||
|
||||
/* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
|
||||
* NOTE: we're always use a 1KB-wide blit and I8 texture format.
|
||||
* We used to use 1, 2 and 4-byte texels and used to use the texture
|
||||
* width to dictate the blit width - but that won't work for compressed
|
||||
* textures. (Brian)
|
||||
* NOTE: can't do that with texture tiling. (sroland)
|
||||
*/
|
||||
tex.offset = offset;
|
||||
tex.image = &tmp;
|
||||
/* copy (x,y,width,height,data) */
|
||||
memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );
|
||||
|
||||
if (texImage->TexFormat->TexelBytes > 4) {
|
||||
const int log2TexelBytes = (3 + (texImage->TexFormat->TexelBytes >> 4));
|
||||
tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
|
||||
tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
|
||||
tex.height = imageHeight;
|
||||
tex.width = imageWidth << log2TexelBytes;
|
||||
tex.offset += (tmp.x << log2TexelBytes) & ~1023;
|
||||
tmp.x = tmp.x % (1024 >> log2TexelBytes);
|
||||
tmp.width = tmp.width << log2TexelBytes;
|
||||
} else if (texImage->TexFormat->TexelBytes) {
|
||||
/* use multi-byte upload scheme */
|
||||
tex.height = imageHeight;
|
||||
tex.width = imageWidth;
|
||||
switch(texImage->TexFormat->TexelBytes) {
|
||||
case 1:
|
||||
tex.format = RADEON_TXFORMAT_I8;
|
||||
break;
|
||||
case 2:
|
||||
tex.format = RADEON_TXFORMAT_AI88;
|
||||
break;
|
||||
case 4:
|
||||
tex.format = RADEON_TXFORMAT_ARGB8888;
|
||||
break;
|
||||
}
|
||||
tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
|
||||
tex.offset += tmp.x & ~1023;
|
||||
tmp.x = tmp.x % 1024;
|
||||
|
||||
if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
||||
/* need something like "tiled coordinates" ? */
|
||||
tmp.y = tmp.x / (tex.pitch * 128) * 2;
|
||||
tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;
|
||||
tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
|
||||
} else {
|
||||
tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
|
||||
}
|
||||
#if 1
|
||||
if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
||||
/* need something like "tiled coordinates" ? */
|
||||
tmp.y = tmp.x / (tex.pitch * 128) * 2;
|
||||
tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;
|
||||
tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
|
||||
}
|
||||
else
|
||||
if ((t->tile_bits & R300_TXO_MACRO_TILE) &&
|
||||
(texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&
|
||||
((!(t->tile_bits & R300_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||
|
||||
(texImage->Height >= 16))) {
|
||||
/* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
|
||||
OR if height is smaller than 8 automatically, but if micro tiling is active
|
||||
the limit is height 16 instead ? */
|
||||
tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
|
||||
}
|
||||
#if 1
|
||||
if ((t->tile_bits & R300_TXO_MACRO_TILE) &&
|
||||
(texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&
|
||||
((!(t->tile_bits & R300_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||
|
||||
(texImage->Height >= 16))) {
|
||||
/* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
|
||||
OR if height is smaller than 8 automatically, but if micro tiling is active
|
||||
the limit is height 16 instead ? */
|
||||
tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is
|
||||
needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
|
||||
/* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed
|
||||
so the kernel module reads the right amount of data. */
|
||||
tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
|
||||
tex.pitch = (R300_BLIT_WIDTH_BYTES / 64);
|
||||
tex.height = (imageHeight + 3) / 4;
|
||||
tex.width = (imageWidth + 3) / 4;
|
||||
if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1)
|
||||
{
|
||||
tex.width *= 8;
|
||||
} else {
|
||||
tex.width *= 16;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* In case of for instance 8x8 texture (2x2 dxt blocks),
|
||||
padding after the first two blocks is needed (only
|
||||
with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
|
||||
/* set tex.height to 1/4 since 1 "macropixel" (dxt-block)
|
||||
has 4 real pixels. Needed so the kernel module reads
|
||||
the right amount of data. */
|
||||
tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
|
||||
tex.pitch = (R300_BLIT_WIDTH_BYTES / 64);
|
||||
tex.height = (imageHeight + 3) / 4;
|
||||
tex.width = (imageWidth + 3) / 4;
|
||||
if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1)
|
||||
{
|
||||
tex.width *= 8;
|
||||
} else {
|
||||
tex.width *= 16;
|
||||
}
|
||||
}
|
||||
|
||||
LOCK_HARDWARE( &rmesa->radeon );
|
||||
do {
|
||||
ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
|
||||
&tex, sizeof(drm_radeon_texture_t) );
|
||||
if (ret) {
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
|
||||
usleep(1);
|
||||
}
|
||||
} while ( ret == -EAGAIN );
|
||||
LOCK_HARDWARE( &rmesa->radeon );
|
||||
do {
|
||||
ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
|
||||
&tex, sizeof(drm_radeon_texture_t) );
|
||||
if (ret) {
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
|
||||
usleep(1);
|
||||
}
|
||||
} while ( ret == -EAGAIN );
|
||||
|
||||
UNLOCK_HARDWARE( &rmesa->radeon );
|
||||
UNLOCK_HARDWARE( &rmesa->radeon );
|
||||
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );
|
||||
fprintf( stderr, " offset=0x%08x\n",
|
||||
offset );
|
||||
fprintf( stderr, " image width=%d height=%d\n",
|
||||
imageWidth, imageHeight );
|
||||
fprintf( stderr, " blit width=%d height=%d data=%p\n",
|
||||
t->image[face][hwlevel].width, t->image[face][hwlevel].height,
|
||||
t->image[face][hwlevel].data );
|
||||
exit( 1 );
|
||||
}
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );
|
||||
fprintf( stderr, " offset=0x%08x\n",
|
||||
offset );
|
||||
fprintf( stderr, " image width=%d height=%d\n",
|
||||
imageWidth, imageHeight );
|
||||
fprintf( stderr, " blit width=%d height=%d data=%p\n",
|
||||
t->image[face][hwlevel].width, t->image[face][hwlevel].height,
|
||||
t->image[face][hwlevel].data );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
|||
if (rmesa->texmicrotile && (tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&
|
||||
/* texrect might be able to use micro tiling too in theory? */
|
||||
(baseImage->Height > 1)) {
|
||||
|
||||
|
||||
/* allow 32 (bytes) x 1 mip (which will use two times the space
|
||||
the non-tiled version would use) max if base texture is large enough */
|
||||
if ((numLevels == 1) ||
|
||||
|
|
@ -228,7 +228,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
|||
t->tile_bits |= R300_TXO_MICRO_TILE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
|
||||
/* we can set macro tiling even for small textures, they will be untiled anyway */
|
||||
t->tile_bits |= R300_TXO_MACRO_TILE;
|
||||
|
|
@ -237,91 +237,85 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
|||
#endif
|
||||
|
||||
for (i = 0; i < numLevels; i++) {
|
||||
const struct gl_texture_image *texImage;
|
||||
GLuint size;
|
||||
|
||||
texImage = tObj->Image[0][i + t->base.firstLevel];
|
||||
if (!texImage)
|
||||
break;
|
||||
|
||||
/* find image size in bytes */
|
||||
if (texImage->IsCompressed) {
|
||||
if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
|
||||
// fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
|
||||
if ((texImage->Width + 3) < 8) /* width one block */
|
||||
size = texImage->CompressedSize * 4;
|
||||
else if ((texImage->Width + 3) < 16)
|
||||
size = texImage->CompressedSize * 2;
|
||||
else size = texImage->CompressedSize;
|
||||
}
|
||||
else /* DXT3/5, 16 bytes per block */
|
||||
{
|
||||
WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
|
||||
// fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
|
||||
if ((texImage->Width + 3) < 8)
|
||||
size = texImage->CompressedSize * 2;
|
||||
else size = texImage->CompressedSize;
|
||||
}
|
||||
|
||||
} else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
|
||||
blitWidth = 64 / texelBytes;
|
||||
} else if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
||||
/* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
|
||||
though the actual offset may be different (if texture is less than
|
||||
32 bytes width) to the untiled case */
|
||||
int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
|
||||
size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
|
||||
blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
||||
} else {
|
||||
int w = (texImage->Width * texelBytes + 31) & ~31;
|
||||
size = w * texImage->Height * texImage->Depth;
|
||||
blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
||||
}
|
||||
assert(size > 0);
|
||||
|
||||
if(0)
|
||||
fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage->Width, texImage->Height,
|
||||
texImage->Depth, texImage->TexFormat->TexelBytes,
|
||||
texImage->InternalFormat);
|
||||
|
||||
/* Align to 32-byte offset. It is faster to do this unconditionally
|
||||
* (no branch penalty).
|
||||
*/
|
||||
|
||||
curOffset = (curOffset + 0x1f) & ~0x1f;
|
||||
|
||||
if (texelBytes) {
|
||||
t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */
|
||||
t->image[0][i].y = 0;
|
||||
t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
|
||||
t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
|
||||
} else {
|
||||
t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
|
||||
t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
|
||||
t->image[0][i].width = MIN2(size, R300_BLIT_WIDTH_BYTES);
|
||||
t->image[0][i].height = size / t->image[0][i].width;
|
||||
}
|
||||
#if 0
|
||||
/* for debugging only and only applicable to non-rectangle targets */
|
||||
assert(size % t->image[0][i].width == 0);
|
||||
assert(t->image[0][i].x == 0
|
||||
|| (size < R300_BLIT_WIDTH_BYTES
|
||||
&& t->image[0][i].height == 1));
|
||||
#endif
|
||||
|
||||
if (0)
|
||||
fprintf(stderr,
|
||||
"level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
|
||||
i, texImage->Width, texImage->Height,
|
||||
t->image[0][i].x, t->image[0][i].y,
|
||||
t->image[0][i].width, t->image[0][i].height,
|
||||
size, curOffset);
|
||||
|
||||
curOffset += size;
|
||||
|
||||
const struct gl_texture_image *texImage;
|
||||
GLuint size;
|
||||
|
||||
texImage = tObj->Image[0][i + t->base.firstLevel];
|
||||
if (!texImage)
|
||||
break;
|
||||
|
||||
/* find image size in bytes */
|
||||
if (texImage->IsCompressed) {
|
||||
if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
|
||||
// fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
|
||||
if ((texImage->Width + 3) < 8) /* width one block */
|
||||
size = texImage->CompressedSize * 4;
|
||||
else if ((texImage->Width + 3) < 16)
|
||||
size = texImage->CompressedSize * 2;
|
||||
else
|
||||
size = texImage->CompressedSize;
|
||||
} else {
|
||||
/* DXT3/5, 16 bytes per block */
|
||||
WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
|
||||
// fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
|
||||
if ((texImage->Width + 3) < 8)
|
||||
size = texImage->CompressedSize * 2;
|
||||
else
|
||||
size = texImage->CompressedSize;
|
||||
}
|
||||
} else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
|
||||
blitWidth = 64 / texelBytes;
|
||||
} else if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
||||
/* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
|
||||
though the actual offset may be different (if texture is less than
|
||||
32 bytes width) to the untiled case */
|
||||
int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
|
||||
size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
|
||||
blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
||||
} else {
|
||||
int w = (texImage->Width * texelBytes + 31) & ~31;
|
||||
size = w * texImage->Height * texImage->Depth;
|
||||
blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
||||
}
|
||||
assert(size > 0);
|
||||
|
||||
if(0)
|
||||
fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
|
||||
texImage->Width, texImage->Height,
|
||||
texImage->Depth, texImage->TexFormat->TexelBytes,
|
||||
texImage->InternalFormat);
|
||||
|
||||
/* Align to 32-byte offset. It is faster to do this unconditionally
|
||||
* (no branch penalty).
|
||||
*/
|
||||
|
||||
curOffset = (curOffset + 0x1f) & ~0x1f;
|
||||
|
||||
if (texelBytes) {
|
||||
/* fix x and y coords up later together with offset */
|
||||
t->image[0][i].x = curOffset;
|
||||
t->image[0][i].y = 0;
|
||||
t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
|
||||
t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
|
||||
} else {
|
||||
t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
|
||||
t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
|
||||
t->image[0][i].width = MIN2(size, R300_BLIT_WIDTH_BYTES);
|
||||
t->image[0][i].height = size / t->image[0][i].width;
|
||||
}
|
||||
|
||||
if (0)
|
||||
fprintf(stderr,
|
||||
"level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
|
||||
i, texImage->Width, texImage->Height,
|
||||
t->image[0][i].x, t->image[0][i].y,
|
||||
t->image[0][i].width, t->image[0][i].height,
|
||||
size, curOffset);
|
||||
|
||||
curOffset += size;
|
||||
}
|
||||
|
||||
|
||||
/* Align the total size of texture memory block.
|
||||
*/
|
||||
t->base.totalSize =
|
||||
|
|
@ -361,7 +355,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
|||
} else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
|
||||
ASSERT(log2Width == log2Height);
|
||||
t->format |= R300_TX_FORMAT_CUBIC_MAP;
|
||||
|
||||
|
||||
t->format_x |= R200_TEXCOORD_CUBIC_ENV;
|
||||
t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
|
||||
(log2Height << R200_FACE_HEIGHT_1_SHIFT) |
|
||||
|
|
@ -377,7 +371,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
|
|||
ASSERT(log2Width == log2Height);
|
||||
t->format |= R300_TX_FORMAT_CUBIC_MAP;
|
||||
}
|
||||
|
||||
|
||||
t->size = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
|
||||
|((tObj->Image[0][t->base.firstLevel]->Height - 1) << R300_TX_HEIGHTMASK_SHIFT))
|
||||
|((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT);
|
||||
|
|
|
|||
|
|
@ -422,18 +422,6 @@ xmesa_delete_framebuffer(struct gl_framebuffer *fb)
|
|||
XMesaDestroyImage( b->rowimage );
|
||||
}
|
||||
|
||||
/* Note that XMesaBuffer renderbuffers normally have a refcount of 2
|
||||
* (creation + binding) so we need to explicitly delete/unbind them here.
|
||||
*/
|
||||
if (b->frontxrb) {
|
||||
_mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->frontxrb);
|
||||
ASSERT(b->frontxrb == NULL);
|
||||
}
|
||||
if (b->backxrb) {
|
||||
_mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->backxrb);
|
||||
ASSERT(b->backxrb == NULL);
|
||||
}
|
||||
|
||||
_mesa_free_framebuffer_data(fb);
|
||||
_mesa_free(fb);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ static void GLAPIENTRY
|
|||
loopback_Color3iv_f( const GLint *v )
|
||||
{
|
||||
COLORF( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]),
|
||||
INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]) );
|
||||
INT_TO_FLOAT(v[2]), 1.0 );
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
|
|
|
|||
|
|
@ -559,7 +559,7 @@ _mesa_IsRenderbufferEXT(GLuint renderbuffer)
|
|||
void GLAPIENTRY
|
||||
_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
|
||||
{
|
||||
struct gl_renderbuffer *newRb, *oldRb;
|
||||
struct gl_renderbuffer *newRb;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
|
@ -593,21 +593,16 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
|
|||
}
|
||||
ASSERT(newRb->AllocStorage);
|
||||
_mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
|
||||
newRb->RefCount = 1; /* referenced by hash table */
|
||||
}
|
||||
newRb->RefCount++;
|
||||
}
|
||||
else {
|
||||
newRb = NULL;
|
||||
}
|
||||
|
||||
oldRb = ctx->CurrentRenderbuffer;
|
||||
if (oldRb) {
|
||||
_mesa_unreference_renderbuffer(&oldRb);
|
||||
}
|
||||
|
||||
ASSERT(newRb != &DummyRenderbuffer);
|
||||
|
||||
ctx->CurrentRenderbuffer = newRb;
|
||||
_mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -632,14 +627,15 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
|
|||
_mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
/* remove from hash table immediately, to free the ID */
|
||||
/* Remove from hash table immediately, to free the ID.
|
||||
* But the object will not be freed until it's no longer
|
||||
* referenced anywhere else.
|
||||
*/
|
||||
_mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
|
||||
|
||||
if (rb != &DummyRenderbuffer) {
|
||||
/* But the object will not be freed until it's no longer
|
||||
* bound in any context.
|
||||
*/
|
||||
_mesa_unreference_renderbuffer(&rb);
|
||||
/* no longer referenced by hash table */
|
||||
_mesa_reference_renderbuffer(&rb, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,42 +69,6 @@ compute_depth_max(struct gl_framebuffer *fb)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the framebuffer's _DepthBuffer field, taking care of
|
||||
* reference counts, etc.
|
||||
*/
|
||||
static void
|
||||
set_depth_renderbuffer(struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer *rb)
|
||||
{
|
||||
if (fb->_DepthBuffer) {
|
||||
_mesa_unreference_renderbuffer(&fb->_DepthBuffer);
|
||||
}
|
||||
fb->_DepthBuffer = rb;
|
||||
if (rb) {
|
||||
rb->RefCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the framebuffer's _StencilBuffer field, taking care of
|
||||
* reference counts, etc.
|
||||
*/
|
||||
static void
|
||||
set_stencil_renderbuffer(struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer *rb)
|
||||
{
|
||||
if (fb->_StencilBuffer) {
|
||||
_mesa_unreference_renderbuffer(&fb->_StencilBuffer);
|
||||
}
|
||||
fb->_StencilBuffer = rb;
|
||||
if (rb) {
|
||||
rb->RefCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create and initialize a gl_framebuffer object.
|
||||
* This is intended for creating _window_system_ framebuffers, not generic
|
||||
|
|
@ -223,7 +187,7 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
|
|||
for (i = 0; i < BUFFER_COUNT; i++) {
|
||||
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
|
||||
if (att->Renderbuffer) {
|
||||
_mesa_unreference_renderbuffer(&att->Renderbuffer);
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
|
||||
}
|
||||
if (att->Texture) {
|
||||
/* render to texture */
|
||||
|
|
@ -239,9 +203,9 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
|
|||
att->Texture = NULL;
|
||||
}
|
||||
|
||||
/* unbind depth/stencil to decr ref counts */
|
||||
set_depth_renderbuffer(fb, NULL);
|
||||
set_stencil_renderbuffer(fb, NULL);
|
||||
/* unbind _Depth/_StencilBuffer to decr ref counts */
|
||||
_mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL);
|
||||
_mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -569,13 +533,13 @@ _mesa_update_depth_buffer(GLcontext *ctx,
|
|||
/* need to update wrapper */
|
||||
struct gl_renderbuffer *wrapper
|
||||
= _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
|
||||
set_depth_renderbuffer(fb, wrapper);
|
||||
_mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);
|
||||
ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* depthRb may be null */
|
||||
set_depth_renderbuffer(fb, depthRb);
|
||||
_mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -610,13 +574,13 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
|
|||
/* need to update wrapper */
|
||||
struct gl_renderbuffer *wrapper
|
||||
= _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
|
||||
set_stencil_renderbuffer(fb, wrapper);
|
||||
_mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper);
|
||||
ASSERT(fb->_StencilBuffer->Wrapped == stencilRb);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* stencilRb may be null */
|
||||
set_stencil_renderbuffer(fb, stencilRb);
|
||||
_mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ Delete_wrapper(struct gl_renderbuffer *rb)
|
|||
/* Decrement reference count on the buffer we're wrapping and delete
|
||||
* it if refcount hits zero.
|
||||
*/
|
||||
_mesa_unreference_renderbuffer(&rb->Wrapped);
|
||||
_mesa_reference_renderbuffer(&rb->Wrapped, NULL);
|
||||
|
||||
/* delete myself */
|
||||
_mesa_delete_renderbuffer(rb);
|
||||
|
|
|
|||
|
|
@ -1473,7 +1473,7 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
|
|||
|
||||
rb->ClassID = 0;
|
||||
rb->Name = name;
|
||||
rb->RefCount = 1;
|
||||
rb->RefCount = 0;
|
||||
rb->Delete = _mesa_delete_renderbuffer;
|
||||
|
||||
/* The rest of these should be set later by the caller of this function or
|
||||
|
|
@ -2105,9 +2105,7 @@ _mesa_add_renderbuffer(struct gl_framebuffer *fb,
|
|||
|
||||
fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
|
||||
fb->Attachment[bufferName].Complete = GL_TRUE;
|
||||
fb->Attachment[bufferName].Renderbuffer = rb;
|
||||
|
||||
rb->RefCount++;
|
||||
_mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2125,40 +2123,57 @@ _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName)
|
|||
if (!rb)
|
||||
return;
|
||||
|
||||
_mesa_unreference_renderbuffer(&rb);
|
||||
_mesa_reference_renderbuffer(&rb, NULL);
|
||||
|
||||
fb->Attachment[bufferName].Renderbuffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decrement a renderbuffer object's reference count and delete it when
|
||||
* the refcount hits zero.
|
||||
* Note: we pass the address of a pointer.
|
||||
* Set *ptr to point to rb. If *ptr points to another renderbuffer,
|
||||
* dereference that buffer first. The new renderbuffer's refcount will
|
||||
* be incremented. The old renderbuffer's refcount will be decremented.
|
||||
*/
|
||||
void
|
||||
_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb)
|
||||
_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
|
||||
struct gl_renderbuffer *rb)
|
||||
{
|
||||
assert(rb);
|
||||
if (*rb) {
|
||||
GLboolean deleteFlag = GL_FALSE;
|
||||
assert(ptr);
|
||||
if (*ptr == rb) {
|
||||
/* no change */
|
||||
return;
|
||||
}
|
||||
|
||||
_glthread_LOCK_MUTEX((*rb)->Mutex);
|
||||
ASSERT((*rb)->RefCount > 0);
|
||||
(*rb)->RefCount--;
|
||||
deleteFlag = ((*rb)->RefCount == 0);
|
||||
_glthread_UNLOCK_MUTEX((*rb)->Mutex);
|
||||
if (*ptr) {
|
||||
/* Unreference the old renderbuffer */
|
||||
GLboolean deleteFlag = GL_FALSE;
|
||||
struct gl_renderbuffer *oldRb = *ptr;
|
||||
|
||||
_glthread_LOCK_MUTEX(oldRb->Mutex);
|
||||
ASSERT(oldRb->RefCount > 0);
|
||||
oldRb->RefCount--;
|
||||
/*printf("RB DECR %p to %d\n", (void*) oldRb, oldRb->RefCount);*/
|
||||
deleteFlag = (oldRb->RefCount == 0);
|
||||
_glthread_UNLOCK_MUTEX(oldRb->Mutex);
|
||||
|
||||
if (deleteFlag)
|
||||
(*rb)->Delete(*rb);
|
||||
oldRb->Delete(oldRb);
|
||||
|
||||
*rb = NULL;
|
||||
*ptr = NULL;
|
||||
}
|
||||
assert(!*ptr);
|
||||
|
||||
if (rb) {
|
||||
/* reference new renderbuffer */
|
||||
_glthread_LOCK_MUTEX(rb->Mutex);
|
||||
rb->RefCount++;
|
||||
/*printf("RB REF %p to %d\n", (void*)rb, rb->RefCount);*/
|
||||
_glthread_UNLOCK_MUTEX(rb->Mutex);
|
||||
*ptr = rb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a new combined depth/stencil renderbuffer for implementing
|
||||
* the GL_EXT_packed_depth_stencil extension.
|
||||
|
|
@ -2180,4 +2195,3 @@ _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
|
|||
|
||||
return dsrb;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@ extern void
|
|||
_mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName);
|
||||
|
||||
extern void
|
||||
_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb);
|
||||
_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
|
||||
struct gl_renderbuffer *rb);
|
||||
|
||||
extern struct gl_renderbuffer *
|
||||
_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue