mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
Merge branch 'radeon-texrewrite-clean' into mesa_7_7_branch
This commit is contained in:
commit
cefee4e327
26 changed files with 624 additions and 621 deletions
|
|
@ -640,7 +640,7 @@ static void tex_emit(GLcontext *ctx, struct radeon_state_atom *atom)
|
|||
OUT_BATCH_TABLE(atom->cmd, 10);
|
||||
|
||||
if (t && t->mt && !t->image_override) {
|
||||
OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
|
||||
OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, get_base_teximage_offset(t),
|
||||
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
|
||||
} else if (!t) {
|
||||
/* workaround for old CS mechanism */
|
||||
|
|
|
|||
|
|
@ -385,16 +385,7 @@ static void r200TexParameter( GLcontext *ctx, GLenum target,
|
|||
case GL_TEXTURE_MAX_LEVEL:
|
||||
case GL_TEXTURE_MIN_LOD:
|
||||
case GL_TEXTURE_MAX_LOD:
|
||||
/* This isn't the most efficient solution but there doesn't appear to
|
||||
* be a nice alternative. Since there's no LOD clamping,
|
||||
* we just have to rely on loading the right subset of mipmap levels
|
||||
* to simulate a clamped LOD.
|
||||
*/
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
t->validated = GL_FALSE;
|
||||
}
|
||||
t->validated = GL_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -413,7 +404,7 @@ static void r200DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|||
(void *)texObj,
|
||||
_mesa_lookup_enum_by_nr(texObj->Target));
|
||||
}
|
||||
|
||||
|
||||
if (rmesa) {
|
||||
int i;
|
||||
radeon_firevertices(&rmesa->radeon);
|
||||
|
|
@ -425,11 +416,9 @@ static void r200DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
}
|
||||
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
|
||||
_mesa_delete_texture_object(ctx, texObj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -824,14 +824,10 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
|
|||
radeon_bo_unref(rImage->bo);
|
||||
rImage->bo = NULL;
|
||||
}
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = NULL;
|
||||
}
|
||||
if (rImage->mt) {
|
||||
radeon_miptree_unreference(rImage->mt);
|
||||
rImage->mt = NULL;
|
||||
}
|
||||
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
radeon_miptree_unreference(&rImage->mt);
|
||||
|
||||
_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
|
||||
rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
|
||||
texImage->RowStride = rb->pitch / rb->cpp;
|
||||
|
|
@ -1423,10 +1419,9 @@ void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d )
|
|||
*/
|
||||
static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
|
||||
{
|
||||
int firstlevel = t->mt ? t->mt->firstLevel : 0;
|
||||
const struct gl_texture_image *firstImage = t->base.Image[0][firstlevel];
|
||||
const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
|
||||
GLint log2Width, log2Height, log2Depth, texelBytes;
|
||||
|
||||
|
||||
if ( t->bo ) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1454,9 +1449,9 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
|
||||
t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << R200_MAX_MIP_LEVEL_SHIFT;
|
||||
t->pp_txfilter |= (t->maxLod - t->minLod) << R200_MAX_MIP_LEVEL_SHIFT;
|
||||
|
||||
t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
|
||||
R200_TXFORMAT_HEIGHT_MASK |
|
||||
|
|
|
|||
|
|
@ -46,14 +46,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#include "r300_context.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "r300_reg.h"
|
||||
#include "r300_cmdbuf.h"
|
||||
#include "r300_emit.h"
|
||||
#include "radeon_bocs_wrapper.h"
|
||||
#include "radeon_mipmap_tree.h"
|
||||
#include "r300_state.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "radeon_queryobj.h"
|
||||
|
||||
/** # of dwords reserved for additional instructions that may need to be written
|
||||
|
|
@ -171,7 +169,7 @@ static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom)
|
|||
if (t && !t->image_override) {
|
||||
BEGIN_BATCH_NO_AUTOSTATE(4);
|
||||
OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
|
||||
OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
|
||||
OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, get_base_teximage_offset(t),
|
||||
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
|
||||
END_BATCH();
|
||||
} else if (!t) {
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ static void r300InitGLExtensions(GLcontext *ctx)
|
|||
if (r300->options.stencil_two_side_disabled)
|
||||
_mesa_disable_extension(ctx, "GL_EXT_stencil_two_side");
|
||||
|
||||
if (r300->options.s3tc_force_enabled) {
|
||||
if (ctx->Mesa_DXTn || r300->options.s3tc_force_enabled) {
|
||||
_mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
|
||||
_mesa_enable_extension(ctx, "GL_S3_s3tc");
|
||||
} else if (r300->options.s3tc_force_disabled) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
#include "main/glheader.h"
|
||||
#include "r300_context.h"
|
||||
#include "r300_cmdbuf.h"
|
||||
#include "radeon_reg.h"
|
||||
|
||||
static INLINE uint32_t cmdpacket0(struct radeon_screen *rscrn,
|
||||
int reg, int count)
|
||||
|
|
|
|||
|
|
@ -67,8 +67,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include "vbo/vbo_split.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_vp_build.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "radeon_macros.h"
|
||||
#include "r300_context.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "r300_state.h"
|
||||
|
|
|
|||
|
|
@ -1741,7 +1741,8 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
|
|||
r300SetPolygonOffsetState(ctx, state);
|
||||
break;
|
||||
case GL_SCISSOR_TEST:
|
||||
radeon_firevertices(&rmesa->radeon);
|
||||
if (!rmesa->radeon.radeonScreen->kernel_mm)
|
||||
radeon_firevertices(&rmesa->radeon);
|
||||
rmesa->radeon.state.scissor.enabled = state;
|
||||
radeonUpdateScissor( ctx );
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -223,16 +223,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
|
|||
case GL_TEXTURE_MAX_LEVEL:
|
||||
case GL_TEXTURE_MIN_LOD:
|
||||
case GL_TEXTURE_MAX_LOD:
|
||||
/* This isn't the most efficient solution but there doesn't appear to
|
||||
* be a nice alternative. Since there's no LOD clamping,
|
||||
* we just have to rely on loading the right subset of mipmap levels
|
||||
* to simulate a clamped LOD.
|
||||
*/
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
t->validated = GL_FALSE;
|
||||
}
|
||||
t->validated = GL_FALSE;
|
||||
break;
|
||||
|
||||
case GL_DEPTH_TEXTURE_MODE:
|
||||
|
|
@ -270,7 +261,11 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|||
|
||||
if (rmesa) {
|
||||
int i;
|
||||
radeon_firevertices(&rmesa->radeon);
|
||||
struct radeon_bo *bo;
|
||||
bo = !t->mt ? t->bo : t->mt->bo;
|
||||
if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->radeon.cmdbuf.cs)) {
|
||||
radeon_firevertices(&rmesa->radeon);
|
||||
}
|
||||
|
||||
for(i = 0; i < R300_MAX_TEXTURE_UNITS; ++i)
|
||||
if (rmesa->hw.textures[i] == t)
|
||||
|
|
@ -282,10 +277,8 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|||
t->bo = NULL;
|
||||
}
|
||||
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
}
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
|
||||
_mesa_delete_texture_object(ctx, texObj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ static const struct tx_table {
|
|||
_ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
|
||||
_ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
|
||||
#endif
|
||||
_ASSIGN(XRGB8888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
|
||||
_ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
|
||||
_ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
|
||||
_ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
|
||||
|
|
@ -202,9 +203,7 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
|
|||
static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t)
|
||||
{
|
||||
const struct gl_texture_image *firstImage;
|
||||
int firstlevel = t->mt ? t->mt->firstLevel : 0;
|
||||
|
||||
firstImage = t->base.Image[0][firstlevel];
|
||||
firstImage = t->base.Image[0][t->minLod];
|
||||
|
||||
if (!t->image_override
|
||||
&& VALID_FORMAT(firstImage->TexFormat)) {
|
||||
|
|
@ -227,7 +226,7 @@ static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t)
|
|||
t->pp_txsize = (((R300_TX_WIDTHMASK_MASK & ((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)))
|
||||
| ((R300_TX_HEIGHTMASK_MASK & ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT)))
|
||||
| ((R300_TX_DEPTHMASK_MASK & ((firstImage->DepthLog2) << R300_TX_DEPTHMASK_SHIFT)))
|
||||
| ((R300_TX_MAX_MIP_LEVEL_MASK & ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT))));
|
||||
| ((R300_TX_MAX_MIP_LEVEL_MASK & ((t->maxLod - t->minLod) << R300_TX_MAX_MIP_LEVEL_SHIFT))));
|
||||
|
||||
t->tile_bits = 0;
|
||||
|
||||
|
|
@ -238,7 +237,7 @@ static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t)
|
|||
|
||||
|
||||
if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
unsigned int align = (64 / t->mt->bpp) - 1;
|
||||
unsigned int align = (64 / _mesa_get_format_bytes(firstImage->TexFormat)) - 1;
|
||||
t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
|
||||
if (!t->image_override)
|
||||
t->pp_txpitch = ((firstImage->Width + align) & ~align) - 1;
|
||||
|
|
@ -437,14 +436,10 @@ void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
|
|||
radeon_bo_unref(rImage->bo);
|
||||
rImage->bo = NULL;
|
||||
}
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = NULL;
|
||||
}
|
||||
if (rImage->mt) {
|
||||
radeon_miptree_unreference(rImage->mt);
|
||||
rImage->mt = NULL;
|
||||
}
|
||||
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
radeon_miptree_unreference(&rImage->mt);
|
||||
|
||||
_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
|
||||
rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
|
||||
texImage->RowStride = rb->pitch / rb->cpp;
|
||||
|
|
|
|||
|
|
@ -312,16 +312,7 @@ static void r600TexParameter(GLcontext * ctx, GLenum target,
|
|||
case GL_TEXTURE_MAX_LEVEL:
|
||||
case GL_TEXTURE_MIN_LOD:
|
||||
case GL_TEXTURE_MAX_LOD:
|
||||
/* This isn't the most efficient solution but there doesn't appear to
|
||||
* be a nice alternative. Since there's no LOD clamping,
|
||||
* we just have to rely on loading the right subset of mipmap levels
|
||||
* to simulate a clamped LOD.
|
||||
*/
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
t->validated = GL_FALSE;
|
||||
}
|
||||
t->validated = GL_FALSE;
|
||||
break;
|
||||
|
||||
case GL_DEPTH_TEXTURE_MODE:
|
||||
|
|
@ -369,10 +360,8 @@ static void r600DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|||
t->bo = NULL;
|
||||
}
|
||||
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
}
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
|
||||
_mesa_delete_texture_object(ctx, texObj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -649,7 +649,6 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex
|
|||
{
|
||||
radeonTexObj *t = radeon_tex_obj(texObj);
|
||||
const struct gl_texture_image *firstImage;
|
||||
int firstlevel = t->mt ? t->mt->firstLevel : 0;
|
||||
GLuint uTexelPitch, row_align;
|
||||
|
||||
if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled &&
|
||||
|
|
@ -657,7 +656,7 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex
|
|||
t->bo)
|
||||
return;
|
||||
|
||||
firstImage = t->base.Image[0][firstlevel];
|
||||
firstImage = t->base.Image[0][t->minLod];
|
||||
|
||||
if (!t->image_override) {
|
||||
if (!r600GetTexFormat(texObj, firstImage->TexFormat)) {
|
||||
|
|
@ -692,7 +691,8 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex
|
|||
}
|
||||
|
||||
row_align = rmesa->radeon.texture_row_align - 1;
|
||||
uTexelPitch = ((firstImage->Width * t->mt->bpp + row_align) & ~row_align) / t->mt->bpp;
|
||||
uTexelPitch = (_mesa_format_row_stride(firstImage->TexFormat, firstImage->Width) + row_align) & ~row_align;
|
||||
uTexelPitch = uTexelPitch / _mesa_get_format_bytes(firstImage->TexFormat);
|
||||
uTexelPitch = (uTexelPitch + R700_TEXEL_PITCH_ALIGNMENT_MASK)
|
||||
& ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
|
||||
|
||||
|
|
@ -706,10 +706,10 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex
|
|||
SETfield(t->SQ_TEX_RESOURCE1, firstImage->Height - 1,
|
||||
TEX_HEIGHT_shift, TEX_HEIGHT_mask);
|
||||
|
||||
if ((t->mt->lastLevel - t->mt->firstLevel) > 0) {
|
||||
t->SQ_TEX_RESOURCE3 = t->mt->levels[0].size / 256;
|
||||
SETfield(t->SQ_TEX_RESOURCE4, t->mt->firstLevel, BASE_LEVEL_shift, BASE_LEVEL_mask);
|
||||
SETfield(t->SQ_TEX_RESOURCE5, t->mt->lastLevel, LAST_LEVEL_shift, LAST_LEVEL_mask);
|
||||
if ((t->maxLod - t->minLod) > 0) {
|
||||
t->SQ_TEX_RESOURCE3 = t->mt->levels[t->minLod].size / 256;
|
||||
SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask);
|
||||
SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -808,9 +808,8 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
|
|||
struct gl_texture_object *tObj =
|
||||
_mesa_lookup_texture(rmesa->radeon.glCtx, texname);
|
||||
radeonTexObjPtr t = radeon_tex_obj(tObj);
|
||||
int firstlevel = t->mt ? t->mt->firstLevel : 0;
|
||||
const struct gl_texture_image *firstImage;
|
||||
uint32_t pitch_val, size, row_align, bpp;
|
||||
uint32_t pitch_val, size, row_align;
|
||||
|
||||
if (!tObj)
|
||||
return;
|
||||
|
|
@ -820,13 +819,9 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
|
|||
if (!offset)
|
||||
return;
|
||||
|
||||
bpp = depth / 8;
|
||||
if (bpp == 3)
|
||||
bpp = 4;
|
||||
|
||||
firstImage = t->base.Image[0][firstlevel];
|
||||
firstImage = t->base.Image[0][t->minLod];
|
||||
row_align = rmesa->radeon.texture_row_align - 1;
|
||||
size = ((firstImage->Width * bpp + row_align) & ~row_align) * firstImage->Height;
|
||||
size = ((_mesa_format_row_stride(firstImage->TexFormat, firstImage->Width) + row_align) & ~row_align) * firstImage->Height;
|
||||
if (t->bo) {
|
||||
radeon_bo_unref(t->bo);
|
||||
t->bo = NULL;
|
||||
|
|
@ -949,14 +944,10 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
|
|||
radeon_bo_unref(rImage->bo);
|
||||
rImage->bo = NULL;
|
||||
}
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = NULL;
|
||||
}
|
||||
if (rImage->mt) {
|
||||
radeon_miptree_unreference(rImage->mt);
|
||||
rImage->mt = NULL;
|
||||
}
|
||||
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
radeon_miptree_unreference(&rImage->mt);
|
||||
|
||||
_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
|
||||
rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
|
||||
texImage->RowStride = rb->pitch / rb->cpp;
|
||||
|
|
|
|||
|
|
@ -54,11 +54,15 @@ static void r700SendTexState(GLcontext *ctx, struct radeon_state_atom *atom)
|
|||
for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
|
||||
if (ctx->Texture.Unit[i]._ReallyEnabled) {
|
||||
radeonTexObj *t = r700->textures[i];
|
||||
uint32_t offset;
|
||||
if (t) {
|
||||
if (!t->image_override)
|
||||
if (!t->image_override) {
|
||||
bo = t->mt->bo;
|
||||
else
|
||||
offset = get_base_teximage_offset(t);
|
||||
} else {
|
||||
bo = t->bo;
|
||||
offset = 0;
|
||||
}
|
||||
if (bo) {
|
||||
|
||||
r700SyncSurf(context, bo,
|
||||
|
|
@ -77,7 +81,7 @@ static void r700SendTexState(GLcontext *ctx, struct radeon_state_atom *atom)
|
|||
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
|
||||
R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2,
|
||||
bo,
|
||||
0,
|
||||
offset,
|
||||
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
|
||||
R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE3,
|
||||
bo,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#define RADEON_BO_FLAGS_MICRO_TILE 2
|
||||
|
||||
struct radeon_bo_manager;
|
||||
struct radeon_cs;
|
||||
|
||||
struct radeon_bo {
|
||||
uint32_t alignment;
|
||||
|
|
@ -74,6 +75,7 @@ struct radeon_bo_funcs {
|
|||
int (*bo_get_tiling)(struct radeon_bo *bo, uint32_t *tiling_flags,
|
||||
uint32_t *pitch);
|
||||
int (*bo_is_busy)(struct radeon_bo *bo, uint32_t *domain);
|
||||
int (*bo_is_referenced_by_cs)(struct radeon_bo *bo, struct radeon_cs *cs);
|
||||
};
|
||||
|
||||
struct radeon_bo_manager {
|
||||
|
|
@ -199,6 +201,15 @@ static inline int radeon_bo_is_static(struct radeon_bo *bo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int _radeon_bo_is_referenced_by_cs(struct radeon_bo *bo,
|
||||
struct radeon_cs *cs,
|
||||
const char *file,
|
||||
const char *func,
|
||||
unsigned line)
|
||||
{
|
||||
return bo->cref > 1;
|
||||
}
|
||||
|
||||
#define radeon_bo_open(bom, h, s, a, d, f)\
|
||||
_radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__)
|
||||
#define radeon_bo_ref(bo)\
|
||||
|
|
@ -215,5 +226,7 @@ static inline int radeon_bo_is_static(struct radeon_bo *bo)
|
|||
_radeon_bo_wait(bo, __FILE__, __func__, __LINE__)
|
||||
#define radeon_bo_is_busy(bo, domain) \
|
||||
_radeon_bo_is_busy(bo, domain, __FILE__, __func__, __LINE__)
|
||||
#define radeon_bo_is_referenced_by_cs(bo, cs) \
|
||||
_radeon_bo_is_referenced_by_cs(bo, cs, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -136,8 +136,13 @@ radeonBufferSubData(GLcontext * ctx,
|
|||
const GLvoid * data,
|
||||
struct gl_buffer_object *obj)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
|
||||
|
||||
if (radeon_bo_is_referenced_by_cs(radeon_obj->bo, radeon->cmdbuf.cs)) {
|
||||
radeon_firevertices(radeon);
|
||||
}
|
||||
|
||||
radeon_bo_map(radeon_obj->bo, GL_TRUE);
|
||||
|
||||
_mesa_memcpy(radeon_obj->bo->ptr + offset, data, size);
|
||||
|
|
|
|||
|
|
@ -257,7 +257,9 @@ void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
|||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
if (ctx->Scissor.Enabled) {
|
||||
/* We don't pipeline cliprect changes */
|
||||
radeon_firevertices(radeon);
|
||||
if (!radeon->radeonScreen->kernel_mm) {
|
||||
radeon_firevertices(radeon);
|
||||
}
|
||||
radeonUpdateScissor(ctx);
|
||||
}
|
||||
}
|
||||
|
|
@ -1123,8 +1125,6 @@ void radeonFlush(GLcontext *ctx)
|
|||
if (radeon->dma.flush)
|
||||
radeon->dma.flush( ctx );
|
||||
|
||||
radeonEmitState(radeon);
|
||||
|
||||
if (radeon->cmdbuf.cs->cdw)
|
||||
rcommonFlushCmdBuf(radeon, __FUNCTION__);
|
||||
|
||||
|
|
@ -1147,9 +1147,6 @@ void radeonFlush(GLcontext *ctx)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
make_empty_list(&radeon->query.not_flushed_head);
|
||||
|
||||
}
|
||||
|
||||
/* Make sure all commands have been sent to the hardware and have
|
||||
|
|
|
|||
|
|
@ -265,7 +265,6 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
|
|||
radeon->texture_compressed_row_align = 64;
|
||||
}
|
||||
|
||||
make_empty_list(&radeon->query.not_flushed_head);
|
||||
radeon_init_dma(radeon);
|
||||
|
||||
return GL_TRUE;
|
||||
|
|
|
|||
|
|
@ -208,6 +208,10 @@ struct radeon_tex_obj {
|
|||
* and so on.
|
||||
*/
|
||||
GLboolean validated;
|
||||
/* Minimum LOD to be used during rendering */
|
||||
unsigned minLod;
|
||||
/* Miximum LOD to be used during rendering */
|
||||
unsigned maxLod;
|
||||
|
||||
GLuint override_offset;
|
||||
GLboolean image_override; /* Image overridden by GLX_EXT_tfp */
|
||||
|
|
@ -502,7 +506,6 @@ struct radeon_context {
|
|||
|
||||
struct {
|
||||
struct radeon_query_object *current;
|
||||
struct radeon_query_object not_flushed_head;
|
||||
struct radeon_state_atom queryobj;
|
||||
} query;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Maciej Cencora.
|
||||
* Copyright (C) 2008 Nicolai Haehnle.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
|
|
@ -32,10 +33,13 @@
|
|||
|
||||
#include "main/simple_list.h"
|
||||
#include "main/texcompress.h"
|
||||
#include "main/teximage.h"
|
||||
#include "main/texobj.h"
|
||||
#include "radeon_texture.h"
|
||||
|
||||
static GLuint radeon_compressed_texture_size(GLcontext *ctx,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLuint mesaFormat)
|
||||
gl_format mesaFormat)
|
||||
{
|
||||
GLuint size = _mesa_format_image_size(mesaFormat, width, height, depth);
|
||||
|
||||
|
|
@ -55,29 +59,6 @@ static GLuint radeon_compressed_texture_size(GLcontext *ctx,
|
|||
return size;
|
||||
}
|
||||
|
||||
|
||||
static int radeon_compressed_num_bytes(GLuint mesaFormat)
|
||||
{
|
||||
int bytes = 0;
|
||||
switch(mesaFormat) {
|
||||
|
||||
case MESA_FORMAT_RGB_FXT1:
|
||||
case MESA_FORMAT_RGBA_FXT1:
|
||||
case MESA_FORMAT_RGB_DXT1:
|
||||
case MESA_FORMAT_RGBA_DXT1:
|
||||
bytes = 2;
|
||||
break;
|
||||
|
||||
case MESA_FORMAT_RGBA_DXT3:
|
||||
case MESA_FORMAT_RGBA_DXT5:
|
||||
bytes = 4;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute sizes and fill in offset and blit information for the given
|
||||
* image (determined by \p face and \p level).
|
||||
|
|
@ -92,25 +73,24 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
|
|||
uint32_t row_align;
|
||||
|
||||
/* Find image size in bytes */
|
||||
if (mt->compressed) {
|
||||
if (_mesa_is_format_compressed(mt->mesaFormat)) {
|
||||
/* TODO: Is this correct? Need test cases for compressed textures! */
|
||||
row_align = rmesa->texture_compressed_row_align - 1;
|
||||
lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
|
||||
lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx,
|
||||
lvl->width, lvl->height, lvl->depth, mt->compressed);
|
||||
lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
|
||||
lvl->size = radeon_compressed_texture_size(rmesa->glCtx, lvl->width, lvl->height, lvl->depth, mt->mesaFormat);
|
||||
} else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
row_align = rmesa->texture_rect_row_align - 1;
|
||||
lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
|
||||
lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
|
||||
lvl->size = lvl->rowstride * lvl->height;
|
||||
} else if (mt->tilebits & RADEON_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 */
|
||||
lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31;
|
||||
lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) * 2 + 31) & ~31;
|
||||
lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth;
|
||||
} else {
|
||||
row_align = rmesa->texture_row_align - 1;
|
||||
lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
|
||||
lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
|
||||
lvl->size = lvl->rowstride * lvl->height * lvl->depth;
|
||||
}
|
||||
assert(lvl->size > 0);
|
||||
|
|
@ -138,17 +118,15 @@ static GLuint minify(GLuint size, GLuint levels)
|
|||
static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
|
||||
{
|
||||
GLuint curOffset;
|
||||
GLuint numLevels;
|
||||
GLuint i;
|
||||
GLuint face;
|
||||
|
||||
numLevels = mt->lastLevel - mt->firstLevel + 1;
|
||||
assert(numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
|
||||
assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
|
||||
|
||||
curOffset = 0;
|
||||
for(face = 0; face < mt->faces; face++) {
|
||||
|
||||
for(i = 0; i < numLevels; i++) {
|
||||
for(i = 0; i < mt->numLevels; i++) {
|
||||
mt->levels[i].width = minify(mt->width0, i);
|
||||
mt->levels[i].height = minify(mt->height0, i);
|
||||
mt->levels[i].depth = minify(mt->depth0, i);
|
||||
|
|
@ -163,14 +141,12 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_
|
|||
static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
|
||||
{
|
||||
GLuint curOffset;
|
||||
GLuint numLevels;
|
||||
GLuint i;
|
||||
|
||||
numLevels = mt->lastLevel - mt->firstLevel + 1;
|
||||
assert(numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
|
||||
assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
|
||||
|
||||
curOffset = 0;
|
||||
for(i = 0; i < numLevels; i++) {
|
||||
for(i = 0; i < mt->numLevels; i++) {
|
||||
GLuint face;
|
||||
|
||||
mt->levels[i].width = minify(mt->width0, i);
|
||||
|
|
@ -188,27 +164,22 @@ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_
|
|||
/**
|
||||
* Create a new mipmap tree, calculate its layout and allocate memory.
|
||||
*/
|
||||
radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t,
|
||||
GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel,
|
||||
GLuint width0, GLuint height0, GLuint depth0,
|
||||
GLuint bpp, GLuint tilebits, GLuint compressed)
|
||||
static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa,
|
||||
GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
|
||||
GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits)
|
||||
{
|
||||
radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree);
|
||||
|
||||
mt->radeon = rmesa;
|
||||
mt->internal_format = internal_format;
|
||||
mt->mesaFormat = mesaFormat;
|
||||
mt->refcount = 1;
|
||||
mt->t = t;
|
||||
mt->target = target;
|
||||
mt->faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||
mt->firstLevel = firstLevel;
|
||||
mt->lastLevel = lastLevel;
|
||||
mt->baseLevel = baseLevel;
|
||||
mt->numLevels = numLevels;
|
||||
mt->width0 = width0;
|
||||
mt->height0 = height0;
|
||||
mt->depth0 = depth0;
|
||||
mt->bpp = compressed ? radeon_compressed_num_bytes(compressed) : bpp;
|
||||
mt->tilebits = tilebits;
|
||||
mt->compressed = compressed;
|
||||
|
||||
if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_R300)
|
||||
calculate_miptree_layout_r300(rmesa, mt);
|
||||
|
|
@ -223,53 +194,43 @@ radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *
|
|||
return mt;
|
||||
}
|
||||
|
||||
void radeon_miptree_reference(radeon_mipmap_tree *mt)
|
||||
void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr)
|
||||
{
|
||||
assert(!*ptr);
|
||||
|
||||
mt->refcount++;
|
||||
assert(mt->refcount > 0);
|
||||
|
||||
*ptr = mt;
|
||||
}
|
||||
|
||||
void radeon_miptree_unreference(radeon_mipmap_tree *mt)
|
||||
void radeon_miptree_unreference(radeon_mipmap_tree **ptr)
|
||||
{
|
||||
radeon_mipmap_tree *mt = *ptr;
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
assert(mt->refcount > 0);
|
||||
|
||||
mt->refcount--;
|
||||
if (!mt->refcount) {
|
||||
radeon_bo_unref(mt->bo);
|
||||
free(mt);
|
||||
}
|
||||
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate first and last mip levels for the given texture object,
|
||||
* where the dimensions are taken from the given texture image at
|
||||
* the given level.
|
||||
*
|
||||
* Note: level is the OpenGL level number, which is not necessarily the same
|
||||
* as the first level that is actually present.
|
||||
*
|
||||
* The base level image of the given texture face must be non-null,
|
||||
* or this will fail.
|
||||
* Calculate min and max LOD for the given texture object.
|
||||
* @param[in] tObj texture object whose LOD values to calculate
|
||||
* @param[out] pminLod minimal LOD
|
||||
* @param[out] pmaxLod maximal LOD
|
||||
*/
|
||||
static void calculate_first_last_level(struct gl_texture_object *tObj,
|
||||
GLuint *pfirstLevel, GLuint *plastLevel,
|
||||
GLuint face, GLuint level)
|
||||
static void calculate_min_max_lod(struct gl_texture_object *tObj,
|
||||
unsigned *pminLod, unsigned *pmaxLod)
|
||||
{
|
||||
const struct gl_texture_image * const baseImage =
|
||||
tObj->Image[face][level];
|
||||
|
||||
assert(baseImage);
|
||||
|
||||
/* These must be signed values. MinLod and MaxLod can be negative numbers,
|
||||
* and having firstLevel and lastLevel as signed prevents the need for
|
||||
* extra sign checks.
|
||||
*/
|
||||
int firstLevel;
|
||||
int lastLevel;
|
||||
|
||||
int minLod, maxLod;
|
||||
/* Yes, this looks overly complicated, but it's all needed.
|
||||
*/
|
||||
switch (tObj->Target) {
|
||||
|
|
@ -280,55 +241,46 @@ static void calculate_first_last_level(struct gl_texture_object *tObj,
|
|||
if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
|
||||
/* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
|
||||
*/
|
||||
firstLevel = lastLevel = tObj->BaseLevel;
|
||||
minLod = maxLod = tObj->BaseLevel;
|
||||
} else {
|
||||
firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
|
||||
firstLevel = MAX2(firstLevel, tObj->BaseLevel);
|
||||
firstLevel = MIN2(firstLevel, level + baseImage->MaxLog2);
|
||||
lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
|
||||
lastLevel = MAX2(lastLevel, tObj->BaseLevel);
|
||||
lastLevel = MIN2(lastLevel, level + baseImage->MaxLog2);
|
||||
lastLevel = MIN2(lastLevel, tObj->MaxLevel);
|
||||
lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
|
||||
minLod = tObj->BaseLevel + (GLint)(tObj->MinLod);
|
||||
minLod = MAX2(minLod, tObj->BaseLevel);
|
||||
minLod = MIN2(minLod, tObj->MaxLevel);
|
||||
maxLod = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
|
||||
maxLod = MIN2(maxLod, tObj->MaxLevel);
|
||||
maxLod = MIN2(maxLod, tObj->Image[0][minLod]->MaxLog2 + minLod);
|
||||
maxLod = MAX2(maxLod, minLod); /* need at least one level */
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_NV:
|
||||
case GL_TEXTURE_4D_SGIS:
|
||||
firstLevel = lastLevel = 0;
|
||||
minLod = maxLod = 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* save these values */
|
||||
*pfirstLevel = firstLevel;
|
||||
*plastLevel = lastLevel;
|
||||
*pminLod = minLod;
|
||||
*pmaxLod = maxLod;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the given miptree can hold the given texture image at the
|
||||
* given face and level.
|
||||
*/
|
||||
GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
|
||||
struct gl_texture_image *texImage, GLuint face, GLuint level)
|
||||
struct gl_texture_image *texImage, GLuint face, GLuint mtLevel)
|
||||
{
|
||||
GLboolean isCompressed = _mesa_is_format_compressed(texImage->TexFormat);
|
||||
radeon_mipmap_level *lvl;
|
||||
|
||||
if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel)
|
||||
if (face >= mt->faces || mtLevel > mt->numLevels)
|
||||
return GL_FALSE;
|
||||
|
||||
if (texImage->InternalFormat != mt->internal_format ||
|
||||
isCompressed != mt->compressed)
|
||||
if (texImage->TexFormat != mt->mesaFormat)
|
||||
return GL_FALSE;
|
||||
|
||||
if (!isCompressed &&
|
||||
!mt->compressed &&
|
||||
_mesa_get_format_bytes(texImage->TexFormat) != mt->bpp)
|
||||
return GL_FALSE;
|
||||
|
||||
lvl = &mt->levels[level - mt->firstLevel];
|
||||
lvl = &mt->levels[mtLevel];
|
||||
if (lvl->width != texImage->Width ||
|
||||
lvl->height != texImage->Height ||
|
||||
lvl->depth != texImage->Depth)
|
||||
|
|
@ -337,64 +289,72 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
|
|||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the given miptree has the right format to store the given texture object.
|
||||
*/
|
||||
GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj)
|
||||
static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj)
|
||||
{
|
||||
struct gl_texture_image *firstImage;
|
||||
GLuint compressed;
|
||||
GLuint numfaces = 1;
|
||||
GLuint firstLevel, lastLevel;
|
||||
GLuint texelBytes;
|
||||
unsigned numLevels;
|
||||
radeon_mipmap_level *mtBaseLevel;
|
||||
|
||||
calculate_first_last_level(texObj, &firstLevel, &lastLevel, 0, texObj->BaseLevel);
|
||||
if (texObj->Target == GL_TEXTURE_CUBE_MAP)
|
||||
numfaces = 6;
|
||||
if (texObj->BaseLevel < mt->baseLevel)
|
||||
return GL_FALSE;
|
||||
|
||||
firstImage = texObj->Image[0][firstLevel];
|
||||
compressed = _mesa_is_format_compressed(firstImage->TexFormat) ? firstImage->TexFormat : 0;
|
||||
texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
|
||||
mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel];
|
||||
firstImage = texObj->Image[0][texObj->BaseLevel];
|
||||
numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1);
|
||||
|
||||
return (mt->firstLevel == firstLevel &&
|
||||
mt->lastLevel == lastLevel &&
|
||||
mt->width0 == firstImage->Width &&
|
||||
mt->height0 == firstImage->Height &&
|
||||
mt->depth0 == firstImage->Depth &&
|
||||
mt->compressed == compressed &&
|
||||
(!mt->compressed ? (mt->bpp == texelBytes) : 1));
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE) {
|
||||
fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj);
|
||||
fprintf(stderr, "target %d vs %d\n", mt->target, texObj->Target);
|
||||
fprintf(stderr, "format %d vs %d\n", mt->mesaFormat, firstImage->TexFormat);
|
||||
fprintf(stderr, "numLevels %d vs %d\n", mt->numLevels, numLevels);
|
||||
fprintf(stderr, "width0 %d vs %d\n", mtBaseLevel->width, firstImage->Width);
|
||||
fprintf(stderr, "height0 %d vs %d\n", mtBaseLevel->height, firstImage->Height);
|
||||
fprintf(stderr, "depth0 %d vs %d\n", mtBaseLevel->depth, firstImage->Depth);
|
||||
if (mt->target == texObj->Target &&
|
||||
mt->mesaFormat == firstImage->TexFormat &&
|
||||
mt->numLevels >= numLevels &&
|
||||
mtBaseLevel->width == firstImage->Width &&
|
||||
mtBaseLevel->height == firstImage->Height &&
|
||||
mtBaseLevel->depth == firstImage->Depth) {
|
||||
fprintf(stderr, "MATCHED\n");
|
||||
} else {
|
||||
fprintf(stderr, "NOT MATCHED\n");
|
||||
}
|
||||
}
|
||||
|
||||
return (mt->target == texObj->Target &&
|
||||
mt->mesaFormat == firstImage->TexFormat &&
|
||||
mt->numLevels >= numLevels &&
|
||||
mtBaseLevel->width == firstImage->Width &&
|
||||
mtBaseLevel->height == firstImage->Height &&
|
||||
mtBaseLevel->depth == firstImage->Depth);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to allocate a mipmap tree for the given texture that will fit the
|
||||
* given image in the given position.
|
||||
* Try to allocate a mipmap tree for the given texture object.
|
||||
* @param[in] rmesa radeon context
|
||||
* @param[in] t radeon texture object
|
||||
*/
|
||||
void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
|
||||
radeon_texture_image *image, GLuint face, GLuint level)
|
||||
void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t)
|
||||
{
|
||||
GLuint compressed = _mesa_is_format_compressed(image->base.TexFormat) ? image->base.TexFormat : 0;
|
||||
GLuint numfaces = 1;
|
||||
GLuint firstLevel, lastLevel;
|
||||
GLuint texelBytes;
|
||||
struct gl_texture_object *texObj = &t->base;
|
||||
struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];
|
||||
GLuint numLevels;
|
||||
|
||||
assert(!t->mt);
|
||||
|
||||
calculate_first_last_level(&t->base, &firstLevel, &lastLevel, face, level);
|
||||
if (t->base.Target == GL_TEXTURE_CUBE_MAP)
|
||||
numfaces = 6;
|
||||
|
||||
if (level != firstLevel || face >= numfaces)
|
||||
if (!texImg)
|
||||
return;
|
||||
|
||||
texelBytes = _mesa_get_format_bytes(image->base.TexFormat);
|
||||
numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxLog2 + 1);
|
||||
|
||||
t->mt = radeon_miptree_create(rmesa, t, t->base.Target,
|
||||
image->base.InternalFormat,
|
||||
firstLevel, lastLevel,
|
||||
image->base.Width, image->base.Height, image->base.Depth,
|
||||
texelBytes, t->tile_bits, compressed);
|
||||
t->mt = radeon_miptree_create(rmesa, t->base.Target,
|
||||
texImg->TexFormat, texObj->BaseLevel,
|
||||
numLevels, texImg->Width, texImg->Height,
|
||||
texImg->Depth, t->tile_bits);
|
||||
}
|
||||
|
||||
/* Although we use the image_offset[] array to store relative offsets
|
||||
|
|
@ -406,21 +366,239 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
|
|||
void
|
||||
radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets)
|
||||
{
|
||||
if (mt->target != GL_TEXTURE_3D || mt->faces == 1)
|
||||
offsets[0] = 0;
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < 6; i++)
|
||||
offsets[i] = mt->levels[level].faces[i].offset;
|
||||
}
|
||||
if (mt->target != GL_TEXTURE_3D || mt->faces == 1) {
|
||||
offsets[0] = 0;
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < 6; i++) {
|
||||
offsets[i] = mt->levels[level].faces[i].offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLuint
|
||||
radeon_miptree_image_offset(radeon_mipmap_tree *mt,
|
||||
GLuint face, GLuint level)
|
||||
{
|
||||
if (mt->target == GL_TEXTURE_CUBE_MAP_ARB)
|
||||
return (mt->levels[level].faces[face].offset);
|
||||
else
|
||||
return mt->levels[level].faces[0].offset;
|
||||
if (mt->target == GL_TEXTURE_CUBE_MAP_ARB)
|
||||
return (mt->levels[level].faces[face].offset);
|
||||
else
|
||||
return mt->levels[level].faces[0].offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert radeon miptree texture level to GL texture level
|
||||
* @param[in] tObj texture object whom level is to be converted
|
||||
* @param[in] level radeon miptree texture level
|
||||
* @return GL texture level
|
||||
*/
|
||||
unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level)
|
||||
{
|
||||
return level + tObj->BaseLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GL texture level to radeon miptree texture level
|
||||
* @param[in] tObj texture object whom level is to be converted
|
||||
* @param[in] level GL texture level
|
||||
* @return radeon miptree texture level
|
||||
*/
|
||||
unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level)
|
||||
{
|
||||
return level - tObj->BaseLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the given image is stored in the given miptree from now on.
|
||||
*/
|
||||
static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
|
||||
radeon_texture_image *image,
|
||||
int face, int mtLevel)
|
||||
{
|
||||
radeon_mipmap_level *dstlvl = &mt->levels[mtLevel];
|
||||
unsigned char *dest;
|
||||
|
||||
assert(image->mt != mt);
|
||||
assert(dstlvl->width == image->base.Width);
|
||||
assert(dstlvl->height == image->base.Height);
|
||||
assert(dstlvl->depth == image->base.Depth);
|
||||
|
||||
radeon_bo_map(mt->bo, GL_TRUE);
|
||||
dest = mt->bo->ptr + dstlvl->faces[face].offset;
|
||||
|
||||
if (image->mt) {
|
||||
/* Format etc. should match, so we really just need a memcpy().
|
||||
* In fact, that memcpy() could be done by the hardware in many
|
||||
* cases, provided that we have a proper memory manager.
|
||||
*/
|
||||
assert(mt->mesaFormat == image->base.TexFormat);
|
||||
|
||||
radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
|
||||
|
||||
assert(srclvl->size == dstlvl->size);
|
||||
assert(srclvl->rowstride == dstlvl->rowstride);
|
||||
|
||||
radeon_bo_map(image->mt->bo, GL_FALSE);
|
||||
|
||||
memcpy(dest,
|
||||
image->mt->bo->ptr + srclvl->faces[face].offset,
|
||||
dstlvl->size);
|
||||
radeon_bo_unmap(image->mt->bo);
|
||||
|
||||
radeon_miptree_unreference(&image->mt);
|
||||
} else {
|
||||
/* need to confirm this value is correct */
|
||||
if (_mesa_is_format_compressed(image->base.TexFormat)) {
|
||||
unsigned size = _mesa_format_image_size(image->base.TexFormat,
|
||||
image->base.Width,
|
||||
image->base.Height,
|
||||
image->base.Depth);
|
||||
memcpy(dest, image->base.Data, size);
|
||||
} else {
|
||||
uint32_t srcrowstride;
|
||||
uint32_t height;
|
||||
|
||||
height = image->base.Height * image->base.Depth;
|
||||
srcrowstride = image->base.Width * _mesa_get_format_bytes(image->base.TexFormat);
|
||||
copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
|
||||
height, srcrowstride);
|
||||
}
|
||||
|
||||
_mesa_free_texmemory(image->base.Data);
|
||||
image->base.Data = 0;
|
||||
}
|
||||
|
||||
radeon_bo_unmap(mt->bo);
|
||||
|
||||
radeon_miptree_reference(mt, &image->mt);
|
||||
image->mtface = face;
|
||||
image->mtlevel = mtLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter matching miptrees, and select one with the most of data.
|
||||
* @param[in] texObj radeon texture object
|
||||
* @param[in] firstLevel first texture level to check
|
||||
* @param[in] lastLevel last texture level to check
|
||||
*/
|
||||
static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj,
|
||||
unsigned firstLevel,
|
||||
unsigned lastLevel)
|
||||
{
|
||||
const unsigned numLevels = lastLevel - firstLevel;
|
||||
unsigned *mtSizes = calloc(numLevels, sizeof(unsigned));
|
||||
radeon_mipmap_tree **mts = calloc(numLevels, sizeof(radeon_mipmap_tree *));
|
||||
unsigned mtCount = 0;
|
||||
unsigned maxMtIndex = 0;
|
||||
|
||||
for (unsigned level = firstLevel; level <= lastLevel; ++level) {
|
||||
radeon_texture_image *img = get_radeon_texture_image(texObj->base.Image[0][level]);
|
||||
unsigned found = 0;
|
||||
// TODO: why this hack??
|
||||
if (!img)
|
||||
break;
|
||||
|
||||
if (!img->mt || !radeon_miptree_matches_texture(img->mt, &texObj->base))
|
||||
continue;
|
||||
|
||||
for (int i = 0; i < mtCount; ++i) {
|
||||
if (mts[i] == img->mt) {
|
||||
found = 1;
|
||||
mtSizes[i] += img->mt->levels[img->mtlevel].size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
mtSizes[mtCount] += img->mt->levels[img->mtlevel].size;
|
||||
mts[mtCount++] = img->mt;
|
||||
mtCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (mtCount == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 1; i < mtCount; ++i) {
|
||||
if (mtSizes[i] > mtSizes[maxMtIndex]) {
|
||||
maxMtIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
return mts[maxMtIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate texture mipmap tree.
|
||||
* If individual images are stored in different mipmap trees
|
||||
* use the mipmap tree that has the most of the correct data.
|
||||
*/
|
||||
int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObj *t = radeon_tex_obj(texObj);
|
||||
|
||||
if (t->validated || t->image_override) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
if (texObj->Image[0][texObj->BaseLevel]->Border > 0)
|
||||
return GL_FALSE;
|
||||
|
||||
_mesa_test_texobj_completeness(rmesa->glCtx, texObj);
|
||||
if (!texObj->_Complete) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod);
|
||||
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE)
|
||||
fprintf(stderr, "%s: Validating texture %p now, minLod = %d, maxLod = %d\n",
|
||||
__FUNCTION__, texObj ,t->minLod, t->maxLod);
|
||||
|
||||
radeon_mipmap_tree *dst_miptree;
|
||||
dst_miptree = get_biggest_matching_miptree(t, t->minLod, t->maxLod);
|
||||
|
||||
if (!dst_miptree) {
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
radeon_try_alloc_miptree(rmesa, t);
|
||||
dst_miptree = t->mt;
|
||||
}
|
||||
|
||||
const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
|
||||
unsigned face, level;
|
||||
radeon_texture_image *img;
|
||||
/* Validate only the levels that will actually be used during rendering */
|
||||
for (face = 0; face < faces; ++face) {
|
||||
for (level = t->minLod; level <= t->maxLod; ++level) {
|
||||
img = get_radeon_texture_image(texObj->Image[face][level]);
|
||||
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE) {
|
||||
fprintf(stderr, "Checking image level %d, face %d, mt %p ... ", level, face, img->mt);
|
||||
}
|
||||
|
||||
if (img->mt != dst_miptree) {
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE) {
|
||||
fprintf(stderr, "MIGRATING\n");
|
||||
}
|
||||
migrate_image_to_miptree(dst_miptree, img, face, radeon_gl_level_to_miptree_level(texObj, level));
|
||||
} else if (RADEON_DEBUG & RADEON_TEXTURE) {
|
||||
fprintf(stderr, "OK\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t->validated = GL_TRUE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
uint32_t get_base_teximage_offset(radeonTexObj *texObj)
|
||||
{
|
||||
if (!texObj->mt) {
|
||||
return 0;
|
||||
} else {
|
||||
return radeon_miptree_image_offset(texObj->mt, 0, texObj->minLod);
|
||||
}
|
||||
}
|
||||
|
|
@ -59,43 +59,38 @@ struct _radeon_mipmap_level {
|
|||
* changed.
|
||||
*/
|
||||
struct _radeon_mipmap_tree {
|
||||
radeonContextPtr radeon;
|
||||
radeonTexObj *t;
|
||||
struct radeon_bo *bo;
|
||||
GLuint refcount;
|
||||
|
||||
GLuint totalsize; /** total size of the miptree, in bytes */
|
||||
|
||||
GLenum target; /** GL_TEXTURE_xxx */
|
||||
GLenum internal_format;
|
||||
GLenum mesaFormat; /** MESA_FORMAT_xxx */
|
||||
GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */
|
||||
GLuint firstLevel; /** First mip level stored in this mipmap tree */
|
||||
GLuint lastLevel; /** Last mip level stored in this mipmap tree */
|
||||
GLuint baseLevel; /** gl_texture_object->baseLevel it was created for */
|
||||
GLuint numLevels; /** Number of mip levels stored in this mipmap tree */
|
||||
|
||||
GLuint width0; /** Width of firstLevel image */
|
||||
GLuint height0; /** Height of firstLevel image */
|
||||
GLuint depth0; /** Depth of firstLevel image */
|
||||
|
||||
GLuint bpp; /** Bytes per texel */
|
||||
GLuint tilebits; /** RADEON_TXO_xxx_TILE */
|
||||
GLuint compressed; /** MESA_FORMAT_xxx indicating a compressed format, or 0 if uncompressed */
|
||||
|
||||
radeon_mipmap_level levels[RADEON_MIPTREE_MAX_TEXTURE_LEVELS];
|
||||
};
|
||||
|
||||
radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t,
|
||||
GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel,
|
||||
GLuint width0, GLuint height0, GLuint depth0,
|
||||
GLuint bpp, GLuint tilebits, GLuint compressed);
|
||||
void radeon_miptree_reference(radeon_mipmap_tree *mt);
|
||||
void radeon_miptree_unreference(radeon_mipmap_tree *mt);
|
||||
void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr);
|
||||
void radeon_miptree_unreference(radeon_mipmap_tree **ptr);
|
||||
|
||||
GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
|
||||
struct gl_texture_image *texImage, GLuint face, GLuint level);
|
||||
GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj);
|
||||
void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
|
||||
radeon_texture_image *texImage, GLuint face, GLuint level);
|
||||
void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t);
|
||||
GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt,
|
||||
GLuint face, GLuint level);
|
||||
void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets);
|
||||
|
||||
unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level);
|
||||
unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level);
|
||||
|
||||
uint32_t get_base_teximage_offset(radeonTexObj *texObj);
|
||||
#endif /* __RADEON_MIPMAP_TREE_H_ */
|
||||
|
|
|
|||
|
|
@ -31,20 +31,6 @@
|
|||
#include "main/imports.h"
|
||||
#include "main/simple_list.h"
|
||||
|
||||
static int radeonQueryIsFlushed(GLcontext *ctx, struct gl_query_object *q)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
|
||||
|
||||
foreach(tmp, &radeon->query.not_flushed_head) {
|
||||
if (tmp == query) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
|
|
@ -122,10 +108,11 @@ static void radeonDeleteQuery(GLcontext *ctx, struct gl_query_object *q)
|
|||
|
||||
static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
struct radeon_query_object *query = (struct radeon_query_object *)q;
|
||||
|
||||
/* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
|
||||
if (!radeonQueryIsFlushed(ctx, q))
|
||||
if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs))
|
||||
ctx->Driver.Flush(ctx);
|
||||
|
||||
radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
|
||||
|
|
@ -157,8 +144,6 @@ static void radeonBeginQuery(GLcontext *ctx, struct gl_query_object *q)
|
|||
|
||||
radeon->query.queryobj.dirty = GL_TRUE;
|
||||
radeon->hw.is_dirty = GL_TRUE;
|
||||
insert_at_tail(&radeon->query.not_flushed_head, query);
|
||||
|
||||
}
|
||||
|
||||
void radeonEmitQueryEnd(GLcontext *ctx)
|
||||
|
|
@ -206,7 +191,7 @@ static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q)
|
|||
uint32_t domain;
|
||||
|
||||
/* Need to perform a flush, as per ARB_occlusion_query spec */
|
||||
if (!radeonQueryIsFlushed(ctx, q)) {
|
||||
if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs)) {
|
||||
ctx->Driver.Flush(ctx);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -645,11 +645,11 @@ static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
|
|||
OUT_BATCH(CP_PACKET0(RADEON_PP_TXOFFSET_0 + (24 * i), 0));
|
||||
if (t->mt && !t->image_override) {
|
||||
if ((ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) {
|
||||
lvl = &t->mt->levels[0];
|
||||
lvl = &t->mt->levels[t->minLod];
|
||||
OUT_BATCH_RELOC(lvl->faces[5].offset, t->mt->bo, lvl->faces[5].offset,
|
||||
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
|
||||
} else {
|
||||
OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
|
||||
OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, get_base_teximage_offset(t),
|
||||
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -348,17 +348,7 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target,
|
|||
case GL_TEXTURE_MAX_LEVEL:
|
||||
case GL_TEXTURE_MIN_LOD:
|
||||
case GL_TEXTURE_MAX_LOD:
|
||||
|
||||
/* This isn't the most efficient solution but there doesn't appear to
|
||||
* be a nice alternative. Since there's no LOD clamping,
|
||||
* we just have to rely on loading the right subset of mipmap levels
|
||||
* to simulate a clamped LOD.
|
||||
*/
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
t->validated = GL_FALSE;
|
||||
}
|
||||
t->validated = GL_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -388,10 +378,8 @@ static void radeonDeleteTexture( GLcontext *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
}
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
|
||||
/* Free mipmap images and the texture object itself */
|
||||
_mesa_delete_texture_object(ctx, texObj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -699,14 +699,10 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_
|
|||
radeon_bo_unref(rImage->bo);
|
||||
rImage->bo = NULL;
|
||||
}
|
||||
if (t->mt) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = NULL;
|
||||
}
|
||||
if (rImage->mt) {
|
||||
radeon_miptree_unreference(rImage->mt);
|
||||
rImage->mt = NULL;
|
||||
}
|
||||
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
radeon_miptree_unreference(&rImage->mt);
|
||||
|
||||
_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
|
||||
rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
|
||||
texImage->RowStride = rb->pitch / rb->cpp;
|
||||
|
|
@ -1021,7 +1017,7 @@ static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int
|
|||
return GL_TRUE;
|
||||
}
|
||||
|
||||
firstImage = t->base.Image[0][t->mt->firstLevel];
|
||||
firstImage = t->base.Image[0][t->minLod];
|
||||
|
||||
if (firstImage->Border > 0) {
|
||||
fprintf(stderr, "%s: border\n", __FUNCTION__);
|
||||
|
|
@ -1049,9 +1045,9 @@ static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int
|
|||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
|
||||
t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << RADEON_MAX_MIP_LEVEL_SHIFT;
|
||||
t->pp_txfilter |= (t->maxLod - t->minLod) << RADEON_MAX_MIP_LEVEL_SHIFT;
|
||||
|
||||
t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
|
||||
RADEON_TXFORMAT_HEIGHT_MASK |
|
||||
|
|
@ -1060,9 +1056,9 @@ static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int
|
|||
RADEON_TXFORMAT_F5_HEIGHT_MASK);
|
||||
t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
|
||||
(log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
|
||||
|
||||
|
||||
t->tile_bits = 0;
|
||||
|
||||
|
||||
if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
|
||||
ASSERT(log2Width == log2Height);
|
||||
t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Maciej Cencora.
|
||||
* Copyright (C) 2008 Nicolai Haehnle.
|
||||
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
*
|
||||
|
|
@ -46,7 +47,7 @@
|
|||
#include "radeon_mipmap_tree.h"
|
||||
|
||||
|
||||
static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
|
||||
void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
|
||||
GLuint numrows, GLuint rowsize)
|
||||
{
|
||||
assert(rowsize <= dststride);
|
||||
|
|
@ -81,8 +82,7 @@ void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
|
|||
radeon_texture_image* image = get_radeon_texture_image(timage);
|
||||
|
||||
if (image->mt) {
|
||||
radeon_miptree_unreference(image->mt);
|
||||
image->mt = 0;
|
||||
radeon_miptree_unreference(&image->mt);
|
||||
assert(!image->base.Data);
|
||||
} else {
|
||||
_mesa_free_texture_image_data(ctx, timage);
|
||||
|
|
@ -108,7 +108,7 @@ static void teximage_set_map_data(radeon_texture_image *image)
|
|||
lvl = &image->mt->levels[image->mtlevel];
|
||||
|
||||
image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
|
||||
image->base.RowStride = lvl->rowstride / image->mt->bpp;
|
||||
image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.TexFormat);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
|
|||
|
||||
radeon_bo_map(t->mt->bo, GL_FALSE);
|
||||
for(face = 0; face < t->mt->faces; ++face) {
|
||||
for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
|
||||
for(level = t->minLod; level <= t->maxLod; ++level)
|
||||
teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
|
||||
}
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
|
|||
return;
|
||||
|
||||
for(face = 0; face < t->mt->faces; ++face) {
|
||||
for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
|
||||
for(level = t->minLod; level <= t->maxLod; ++level)
|
||||
texObj->Image[face][level]->Data = 0;
|
||||
}
|
||||
radeon_bo_unmap(t->mt->bo);
|
||||
|
|
@ -240,8 +240,7 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
|
|||
image->mtlevel = i;
|
||||
image->mtface = face;
|
||||
|
||||
radeon_miptree_unreference(image->mt);
|
||||
image->mt = NULL;
|
||||
radeon_miptree_unreference(&image->mt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -510,6 +509,135 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx,
|
|||
return MESA_FORMAT_NONE; /* never get here */
|
||||
}
|
||||
|
||||
static void teximage_assign_miptree(radeonContextPtr rmesa,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage,
|
||||
unsigned face,
|
||||
unsigned level)
|
||||
{
|
||||
radeonTexObj *t = radeon_tex_obj(texObj);
|
||||
radeon_texture_image* image = get_radeon_texture_image(texImage);
|
||||
|
||||
/* Try using current miptree, or create new if there isn't any */
|
||||
if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face,
|
||||
radeon_gl_level_to_miptree_level(texObj, level))) {
|
||||
radeon_miptree_unreference(&t->mt);
|
||||
radeon_try_alloc_miptree(rmesa, t);
|
||||
}
|
||||
|
||||
/* Miptree alocation may have failed,
|
||||
* when there was no image for baselevel specified */
|
||||
if (t->mt) {
|
||||
image->mtface = face;
|
||||
image->mtlevel = radeon_gl_level_to_miptree_level(texObj, level);
|
||||
radeon_miptree_reference(t->mt, &image->mt);
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint * allocate_image_offsets(GLcontext *ctx,
|
||||
unsigned alignedWidth,
|
||||
unsigned height,
|
||||
unsigned depth)
|
||||
{
|
||||
int i;
|
||||
GLuint *offsets;
|
||||
|
||||
offsets = _mesa_malloc(depth * sizeof(GLuint)) ;
|
||||
if (!offsets) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < depth; ++i) {
|
||||
offsets[i] = alignedWidth * height * i;
|
||||
}
|
||||
|
||||
return offsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a subregion of the given texture image.
|
||||
*/
|
||||
static void radeon_store_teximage(GLcontext* ctx, int dims,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLsizei imageSize,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid * pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage,
|
||||
int compressed)
|
||||
{
|
||||
radeonTexObj *t = radeon_tex_obj(texObj);
|
||||
radeon_texture_image* image = get_radeon_texture_image(texImage);
|
||||
|
||||
GLuint dstRowStride;
|
||||
GLuint *dstImageOffsets;
|
||||
|
||||
if (image->mt) {
|
||||
dstRowStride = image->mt->levels[image->mtlevel].rowstride;
|
||||
} else if (t->bo) {
|
||||
/* TFP case */
|
||||
/* TODO */
|
||||
assert(0);
|
||||
} else {
|
||||
dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
|
||||
}
|
||||
|
||||
if (dims == 3) {
|
||||
unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat);
|
||||
dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, height, depth);
|
||||
if (!dstImageOffsets) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
dstImageOffsets = texImage->ImageOffsets;
|
||||
}
|
||||
|
||||
radeon_teximage_map(image, GL_TRUE);
|
||||
|
||||
if (compressed) {
|
||||
uint32_t srcRowStride, bytesPerRow, rows;
|
||||
GLubyte *img_start;
|
||||
if (!image->mt) {
|
||||
dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
|
||||
img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
|
||||
texImage->TexFormat,
|
||||
texImage->Width, texImage->Data);
|
||||
}
|
||||
else {
|
||||
uint32_t blocks_x, block_width, block_height;
|
||||
_mesa_get_format_block_size(image->mt->mesaFormat, &block_width, &block_height);
|
||||
blocks_x = dstRowStride / block_width;
|
||||
img_start = texImage->Data + _mesa_get_format_bytes(image->mt->mesaFormat) * 4 * (blocks_x * (yoffset / 4) + xoffset / 4);
|
||||
}
|
||||
srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
|
||||
bytesPerRow = srcRowStride;
|
||||
rows = (height + 3) / 4;
|
||||
|
||||
copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
|
||||
|
||||
}
|
||||
else {
|
||||
if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
|
||||
texImage->TexFormat, texImage->Data,
|
||||
xoffset, yoffset, zoffset,
|
||||
dstRowStride,
|
||||
dstImageOffsets,
|
||||
width, height, depth,
|
||||
format, type, pixels, packing)) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
|
||||
}
|
||||
}
|
||||
|
||||
if (dims == 3) {
|
||||
_mesa_free(dstImageOffsets);
|
||||
}
|
||||
|
||||
radeon_teximage_unmap(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* All glTexImage calls go through this function.
|
||||
*/
|
||||
|
|
@ -528,13 +656,17 @@ static void radeon_teximage(
|
|||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObj* t = radeon_tex_obj(texObj);
|
||||
radeon_texture_image* image = get_radeon_texture_image(texImage);
|
||||
GLuint dstRowStride;
|
||||
GLint postConvWidth = width;
|
||||
GLint postConvHeight = height;
|
||||
GLuint texelBytes;
|
||||
GLuint face = radeon_face_for_target(target);
|
||||
|
||||
radeon_firevertices(rmesa);
|
||||
{
|
||||
struct radeon_bo *bo;
|
||||
bo = !image->mt ? image->bo : image->mt->bo;
|
||||
if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
|
||||
radeon_firevertices(rmesa);
|
||||
}
|
||||
}
|
||||
|
||||
t->validated = GL_FALSE;
|
||||
|
||||
|
|
@ -543,53 +675,30 @@ static void radeon_teximage(
|
|||
&postConvHeight);
|
||||
}
|
||||
|
||||
if (_mesa_is_format_compressed(texImage->TexFormat)) {
|
||||
texelBytes = 0;
|
||||
} else {
|
||||
texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
|
||||
if (!_mesa_is_format_compressed(texImage->TexFormat)) {
|
||||
GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
|
||||
/* Minimum pitch of 32 bytes */
|
||||
if (postConvWidth * texelBytes < 32) {
|
||||
postConvWidth = 32 / texelBytes;
|
||||
texImage->RowStride = postConvWidth;
|
||||
postConvWidth = 32 / texelBytes;
|
||||
texImage->RowStride = postConvWidth;
|
||||
}
|
||||
if (!image->mt) {
|
||||
if (!image->mt) {
|
||||
assert(texImage->RowStride == postConvWidth);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory for image */
|
||||
radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
|
||||
/* Mesa core only clears texImage->Data but not image->mt */
|
||||
radeonFreeTexImageData(ctx, texImage);
|
||||
|
||||
if (t->mt &&
|
||||
t->mt->firstLevel == level &&
|
||||
t->mt->lastLevel == level &&
|
||||
t->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
|
||||
!radeon_miptree_matches_image(t->mt, texImage, face, level)) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = NULL;
|
||||
}
|
||||
|
||||
if (!t->mt)
|
||||
radeon_try_alloc_miptree(rmesa, t, image, face, level);
|
||||
if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
|
||||
radeon_mipmap_level *lvl;
|
||||
image->mt = t->mt;
|
||||
image->mtlevel = level - t->mt->firstLevel;
|
||||
image->mtface = face;
|
||||
radeon_miptree_reference(t->mt);
|
||||
lvl = &image->mt->levels[image->mtlevel];
|
||||
dstRowStride = lvl->rowstride;
|
||||
} else {
|
||||
int size;
|
||||
if (_mesa_is_format_compressed(texImage->TexFormat)) {
|
||||
size = _mesa_format_image_size(texImage->TexFormat,
|
||||
texImage->Width,
|
||||
texImage->Height,
|
||||
texImage->Depth);
|
||||
} else {
|
||||
size = texImage->Width * texImage->Height * texImage->Depth * _mesa_get_format_bytes(texImage->TexFormat);
|
||||
if (!t->bo) {
|
||||
teximage_assign_miptree(rmesa, texObj, texImage, face, level);
|
||||
if (!t->mt) {
|
||||
int size = _mesa_format_image_size(texImage->TexFormat,
|
||||
texImage->Width,
|
||||
texImage->Height,
|
||||
texImage->Depth);
|
||||
texImage->Data = _mesa_alloc_texmemory(size);
|
||||
}
|
||||
texImage->Data = _mesa_alloc_texmemory(size);
|
||||
}
|
||||
|
||||
/* Upload texture image; note that the spec allows pixels to be NULL */
|
||||
|
|
@ -603,65 +712,16 @@ static void radeon_teximage(
|
|||
}
|
||||
|
||||
if (pixels) {
|
||||
radeon_teximage_map(image, GL_TRUE);
|
||||
if (compressed) {
|
||||
if (image->mt) {
|
||||
uint32_t srcRowStride, bytesPerRow, rows;
|
||||
srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
|
||||
bytesPerRow = srcRowStride;
|
||||
rows = (height + 3) / 4;
|
||||
copy_rows(texImage->Data, image->mt->levels[level].rowstride,
|
||||
pixels, srcRowStride, rows, bytesPerRow);
|
||||
} else {
|
||||
memcpy(texImage->Data, pixels, imageSize);
|
||||
}
|
||||
} else {
|
||||
GLuint dstRowStride;
|
||||
GLuint *dstImageOffsets;
|
||||
|
||||
if (image->mt) {
|
||||
radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
|
||||
dstRowStride = lvl->rowstride;
|
||||
} else {
|
||||
dstRowStride = texImage->Width * _mesa_get_format_bytes(texImage->TexFormat);
|
||||
}
|
||||
|
||||
if (dims == 3) {
|
||||
int i;
|
||||
|
||||
dstImageOffsets = _mesa_malloc(depth * sizeof(GLuint)) ;
|
||||
if (!dstImageOffsets)
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
|
||||
|
||||
for (i = 0; i < depth; ++i) {
|
||||
dstImageOffsets[i] = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat) * height * i;
|
||||
}
|
||||
} else {
|
||||
dstImageOffsets = texImage->ImageOffsets;
|
||||
}
|
||||
|
||||
if (!_mesa_texstore(ctx, dims,
|
||||
texImage->_BaseFormat,
|
||||
texImage->TexFormat,
|
||||
texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
|
||||
dstRowStride,
|
||||
dstImageOffsets,
|
||||
width, height, depth,
|
||||
format, type, pixels, packing)) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
|
||||
}
|
||||
|
||||
if (dims == 3)
|
||||
_mesa_free(dstImageOffsets);
|
||||
}
|
||||
radeon_store_teximage(ctx, dims,
|
||||
0, 0, 0,
|
||||
width, height, depth,
|
||||
imageSize, format, type,
|
||||
pixels, packing,
|
||||
texObj, texImage,
|
||||
compressed);
|
||||
}
|
||||
|
||||
_mesa_unmap_teximage_pbo(ctx, packing);
|
||||
|
||||
if (pixels)
|
||||
radeon_teximage_unmap(image);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
|
||||
|
|
@ -714,7 +774,7 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
|
|||
}
|
||||
|
||||
/**
|
||||
* Update a subregion of the given texture image.
|
||||
* All glTexSubImage calls go through this function.
|
||||
*/
|
||||
static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
|
|
@ -731,66 +791,34 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
|
|||
radeonTexObj* t = radeon_tex_obj(texObj);
|
||||
radeon_texture_image* image = get_radeon_texture_image(texImage);
|
||||
|
||||
radeon_firevertices(rmesa);
|
||||
{
|
||||
struct radeon_bo *bo;
|
||||
bo = !image->mt ? image->bo : image->mt->bo;
|
||||
if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
|
||||
radeon_firevertices(rmesa);
|
||||
}
|
||||
}
|
||||
|
||||
t->validated = GL_FALSE;
|
||||
if (compressed) {
|
||||
pixels = _mesa_validate_pbo_compressed_teximage(
|
||||
ctx, imageSize, pixels, packing, "glCompressedTexImage");
|
||||
ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
|
||||
} else {
|
||||
pixels = _mesa_validate_pbo_teximage(ctx, dims,
|
||||
width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
|
||||
width, height, depth, format, type, pixels, packing, "glTexSubImage");
|
||||
}
|
||||
|
||||
if (pixels) {
|
||||
GLint dstRowStride;
|
||||
radeon_teximage_map(image, GL_TRUE);
|
||||
|
||||
if (image->mt) {
|
||||
radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
|
||||
dstRowStride = lvl->rowstride;
|
||||
} else {
|
||||
dstRowStride = texImage->RowStride * _mesa_get_format_bytes(texImage->TexFormat);
|
||||
}
|
||||
|
||||
if (compressed) {
|
||||
uint32_t srcRowStride, bytesPerRow, rows;
|
||||
GLubyte *img_start;
|
||||
if (!image->mt) {
|
||||
dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
|
||||
img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
|
||||
texImage->TexFormat,
|
||||
texImage->Width, texImage->Data);
|
||||
}
|
||||
else {
|
||||
uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4);
|
||||
img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4);
|
||||
}
|
||||
srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
|
||||
bytesPerRow = srcRowStride;
|
||||
rows = (height + 3) / 4;
|
||||
|
||||
copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
|
||||
|
||||
}
|
||||
else {
|
||||
if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
|
||||
texImage->TexFormat, texImage->Data,
|
||||
xoffset, yoffset, zoffset,
|
||||
dstRowStride,
|
||||
texImage->ImageOffsets,
|
||||
width, height, depth,
|
||||
format, type, pixels, packing)) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
|
||||
}
|
||||
}
|
||||
radeon_store_teximage(ctx, dims,
|
||||
xoffset, yoffset, zoffset,
|
||||
width, height, depth,
|
||||
imageSize, format, type,
|
||||
pixels, packing,
|
||||
texObj, texImage,
|
||||
compressed);
|
||||
}
|
||||
|
||||
radeon_teximage_unmap(image);
|
||||
|
||||
_mesa_unmap_teximage_pbo(ctx, packing);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
|
||||
|
|
@ -846,143 +874,6 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
|
|||
format, type, pixels, packing, texObj, texImage, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Ensure that the given image is stored in the given miptree from now on.
|
||||
*/
|
||||
static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
|
||||
{
|
||||
radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
|
||||
unsigned char *dest;
|
||||
|
||||
assert(image->mt != mt);
|
||||
assert(dstlvl->width == image->base.Width);
|
||||
assert(dstlvl->height == image->base.Height);
|
||||
assert(dstlvl->depth == image->base.Depth);
|
||||
|
||||
|
||||
radeon_bo_map(mt->bo, GL_TRUE);
|
||||
dest = mt->bo->ptr + dstlvl->faces[face].offset;
|
||||
|
||||
if (image->mt) {
|
||||
/* Format etc. should match, so we really just need a memcpy().
|
||||
* In fact, that memcpy() could be done by the hardware in many
|
||||
* cases, provided that we have a proper memory manager.
|
||||
*/
|
||||
radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel-image->mt->firstLevel];
|
||||
|
||||
assert(srclvl->size == dstlvl->size);
|
||||
assert(srclvl->rowstride == dstlvl->rowstride);
|
||||
|
||||
radeon_bo_map(image->mt->bo, GL_FALSE);
|
||||
|
||||
memcpy(dest,
|
||||
image->mt->bo->ptr + srclvl->faces[face].offset,
|
||||
dstlvl->size);
|
||||
radeon_bo_unmap(image->mt->bo);
|
||||
|
||||
radeon_miptree_unreference(image->mt);
|
||||
} else {
|
||||
uint32_t srcrowstride;
|
||||
uint32_t height;
|
||||
/* need to confirm this value is correct */
|
||||
if (mt->compressed) {
|
||||
height = (image->base.Height + 3) / 4;
|
||||
srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width);
|
||||
} else {
|
||||
height = image->base.Height * image->base.Depth;
|
||||
srcrowstride = image->base.Width * _mesa_get_format_bytes(image->base.TexFormat);
|
||||
}
|
||||
|
||||
// if (mt->tilebits)
|
||||
// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
|
||||
|
||||
copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
|
||||
height, srcrowstride);
|
||||
|
||||
_mesa_free_texmemory(image->base.Data);
|
||||
image->base.Data = 0;
|
||||
}
|
||||
|
||||
radeon_bo_unmap(mt->bo);
|
||||
|
||||
image->mt = mt;
|
||||
image->mtface = face;
|
||||
image->mtlevel = level;
|
||||
radeon_miptree_reference(image->mt);
|
||||
}
|
||||
|
||||
int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObj *t = radeon_tex_obj(texObj);
|
||||
radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
|
||||
int face, level;
|
||||
|
||||
if (t->validated || t->image_override)
|
||||
return GL_TRUE;
|
||||
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE)
|
||||
fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
|
||||
|
||||
if (baseimage->base.Border > 0)
|
||||
return GL_FALSE;
|
||||
|
||||
/* Ensure a matching miptree exists.
|
||||
*
|
||||
* Differing mipmap trees can result when the app uses TexImage to
|
||||
* change texture dimensions.
|
||||
*
|
||||
* Prefer to use base image's miptree if it
|
||||
* exists, since that most likely contains more valid data (remember
|
||||
* that the base level is usually significantly larger than the rest
|
||||
* of the miptree, so cubemaps are the only possible exception).
|
||||
*/
|
||||
if (baseimage->mt &&
|
||||
baseimage->mt != t->mt &&
|
||||
radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = baseimage->mt;
|
||||
radeon_miptree_reference(t->mt);
|
||||
} else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
|
||||
radeon_miptree_unreference(t->mt);
|
||||
t->mt = 0;
|
||||
}
|
||||
|
||||
if (!t->mt) {
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE)
|
||||
fprintf(stderr, " Allocate new miptree\n");
|
||||
radeon_try_alloc_miptree(rmesa, t, baseimage, 0, texObj->BaseLevel);
|
||||
if (!t->mt) {
|
||||
_mesa_problem(ctx, "radeon_validate_texture failed to alloc miptree");
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure all images are stored in the single main miptree */
|
||||
for(face = 0; face < t->mt->faces; ++face) {
|
||||
for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
|
||||
radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE)
|
||||
fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
|
||||
if (t->mt == image->mt || (!image->mt && !image->base.Data)) {
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE)
|
||||
fprintf(stderr, "OK\n");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RADEON_DEBUG & RADEON_TEXTURE)
|
||||
fprintf(stderr, "migrating\n");
|
||||
migrate_image_to_miptree(t->mt, image, face, level);
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Need to map texture image into memory before copying image data,
|
||||
* then unmap it.
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@
|
|||
|
||||
#include "main/formats.h"
|
||||
|
||||
|
||||
void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
|
||||
GLuint numrows, GLuint rowsize);
|
||||
struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx);
|
||||
void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue