aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndre Maasikas <[email protected]>2009-12-08 11:57:24 +0200
committerAndre Maasikas <[email protected]>2009-12-08 11:57:24 +0200
commitb5e256c76dea2182c82af2a4f66224735701d55a (patch)
tree42ab2283fc94ab3deefc30983aaa10f283897dd6 /src
parentac66598ed8bc218720cf2a1a7493b7e25ca9d962 (diff)
parent0d4a05445c6b47b93269a3829afbe509ffec4817 (diff)
Merge branch 'mesa_7_7_branch'
Conflicts: src/mesa/drivers/dri/r600/r700_assembler.c src/mesa/main/version.h
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c6
-rw-r--r--src/gallium/drivers/r300/Makefile2
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h32
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/vmw_driver.h4
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c17
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/vmw_screen.c58
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/vmw_video.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c6
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.c29
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c23
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.h4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c26
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c25
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c11
17 files changed, 185 insertions, 69 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
index fe2db04d8fa..3eb0e0c57cb 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
@@ -560,9 +560,9 @@ emit_instruction(
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
- LLVMValueRef *p_floor_log2;
- LLVMValueRef *p_exp;
- LLVMValueRef *p_log2;
+ LLVMValueRef *p_floor_log2 = NULL;
+ LLVMValueRef *p_exp = NULL;
+ LLVMValueRef *p_log2 = NULL;
src0 = emit_fetch( bld, inst, 0, CHAN_X );
src0 = lp_build_abs( &bld->base, src0 );
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index 63ae5c2766a..9c9fc6f64b3 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -36,4 +36,4 @@ include ../../Makefile.template
.PHONY : $(COMPILER_ARCHIVE)
$(COMPILER_ARCHIVE):
- cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make
+ $(MAKE) -C $(TOP)/src/mesa/drivers/dri/r300/compiler
diff --git a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
index 6bf3183ff54..56070a1ba10 100644
--- a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
+++ b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
@@ -46,6 +46,7 @@
#define DRM_VMW_FIFO_DEBUG 11
#define DRM_VMW_FENCE_WAIT 12
#define DRM_VMW_OVERLAY 13
+#define DRM_VMW_CURSOR_BYPASS 14
/*************************************************************************/
/**
@@ -503,4 +504,35 @@ struct drm_vmw_overlay_arg {
struct drm_vmw_rect dst;
};
+/*************************************************************************/
+/**
+ * DRM_VMW_CURSOR_BYPASS - Give extra information about cursor bypass.
+ *
+ */
+
+#define DRM_VMW_CURSOR_BYPASS_ALL (1 << 0)
+#define DRM_VMW_CURSOR_BYPASS_FLAGS (1)
+
+/**
+ * struct drm_vmw_cursor_bypass_arg
+ *
+ * @flags: Flags.
+ * @crtc_id: Crtc id, only used if DMR_CURSOR_BYPASS_ALL isn't passed.
+ * @xpos: X position of cursor.
+ * @ypos: Y position of cursor.
+ * @xhot: X hotspot.
+ * @yhot: Y hotspot.
+ *
+ * Argument to the DRM_VMW_CURSOR_BYPASS Ioctl.
+ */
+
+struct drm_vmw_cursor_bypass_arg {
+ uint32_t flags;
+ uint32_t crtc_id;
+ int32_t xpos;
+ int32_t ypos;
+ int32_t xhot;
+ int32_t yhot;
+};
+
#endif
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h b/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h
index 04d446a2dfb..db6b89b8bcd 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h
@@ -44,6 +44,8 @@ struct vmw_driver
{
int fd;
+ void *cursor_priv;
+
/* vmw_video.c */
void *video_priv;
};
@@ -69,6 +71,8 @@ Bool vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
* vmw_ioctl.c
*/
+int vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot);
+
struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_driver *vmw,
uint32_t size,
unsigned *handle);
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c b/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c
index 3cac5b7760c..ad6993840d2 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c
@@ -54,6 +54,23 @@ struct vmw_dma_buffer
uint32_t size;
};
+int
+vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot)
+{
+ struct drm_vmw_cursor_bypass_arg arg;
+ int ret;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.flags = DRM_VMW_CURSOR_BYPASS_ALL;
+ arg.xhot = xhot;
+ arg.yhot = yhot;
+
+ ret = drmCommandWrite(vmw->fd, DRM_VMW_CURSOR_BYPASS,
+ &arg, sizeof(arg));
+
+ return ret;
+}
+
struct vmw_dma_buffer *
vmw_ioctl_buffer_create(struct vmw_driver *vmw, uint32_t size, unsigned *handle)
{
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c b/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c
index 344ef0b3159..421906da996 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c
@@ -33,16 +33,58 @@
#include "vmw_hook.h"
#include "vmw_driver.h"
+/* modified version of crtc functions */
+xf86CrtcFuncsRec vmw_screen_crtc_funcs;
+
+static void
+vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image)
+{
+ struct vmw_driver *vmw = modesettingPTR(crtc->scrn)->winsys_priv;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ xf86CrtcFuncsPtr funcs = vmw->cursor_priv;
+ CursorPtr c = config->cursor;
+
+ /* Run the ioctl before uploading the image */
+ vmw_ioctl_cursor_bypass(vmw, c->bits->xhot, c->bits->yhot);
+
+ funcs->load_cursor_argb(crtc, image);
+}
+
+static void
+vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
+
+ /* XXX assume that all crtc's have the same function struct */
+
+ /* Save old struct need to call the old functions as well */
+ vmw->cursor_priv = (void*)(config->crtc[0]->funcs);
+ memcpy(&vmw_screen_crtc_funcs, vmw->cursor_priv, sizeof(xf86CrtcFuncsRec));
+ vmw_screen_crtc_funcs.load_cursor_argb = vmw_screen_cursor_load_argb;
+
+ for (i = 0; i < config->num_crtc; i++)
+ config->crtc[i]->funcs = &vmw_screen_crtc_funcs;
+}
+
+static void
+vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
+
+ vmw_ioctl_cursor_bypass(vmw, 0, 0);
+
+ for (i = 0; i < config->num_crtc; i++)
+ config->crtc[i]->funcs = vmw->cursor_priv;
+}
+
static Bool
vmw_screen_init(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
struct vmw_driver *vmw;
- /* if gallium is used then we don't need to do anything. */
- if (ms->screen)
- return TRUE;
-
vmw = xnfcalloc(sizeof(*vmw), 1);
if (!vmw)
return FALSE;
@@ -50,6 +92,12 @@ vmw_screen_init(ScrnInfoPtr pScrn)
vmw->fd = ms->fd;
ms->winsys_priv = vmw;
+ vmw_screen_cursor_init(pScrn, vmw);
+
+ /* if gallium is used then we don't need to do anything more. */
+ if (ms->screen)
+ return TRUE;
+
vmw_video_init(pScrn, vmw);
return TRUE;
@@ -64,6 +112,8 @@ vmw_screen_close(ScrnInfoPtr pScrn)
if (!vmw)
return TRUE;
+ vmw_screen_cursor_close(pScrn, vmw);
+
vmw_video_close(pScrn, vmw);
ms->winsys_priv = NULL;
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
index 6e34aa21f38..d62c3b7296f 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
@@ -342,6 +342,8 @@ vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
debug_printf("%s: enter\n", __func__);
video = vmw->video_priv;
+ if (!video)
+ return TRUE;
for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
vmw_video_port_cleanup(pScrn, &video->port[i]);
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index b6e0d823ed2..5615040946f 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -126,7 +126,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
case GL_RGB16:
rb->Format = MESA_FORMAT_ARGB8888;
rb->DataType = GL_UNSIGNED_BYTE;
- irb->texformat = MESA_FORMAT_XRGB8888;
+ irb->texformat = MESA_FORMAT_ARGB8888; /* XXX: Need xrgb8888 */
cpp = 4;
break;
case GL_RGBA:
@@ -314,6 +314,10 @@ intel_create_renderbuffer(gl_format format)
irb->Base.DataType = GL_UNSIGNED_BYTE;
break;
case MESA_FORMAT_XRGB8888:
+ /* XXX this is a hack since XRGB surfaces don't seem to work
+ * properly yet. Reading the alpha channel returns 0 instead of 1.
+ */
+ format = MESA_FORMAT_ARGB8888;
irb->Base._BaseFormat = GL_RGB;
irb->Base.DataType = GL_UNSIGNED_BYTE;
break;
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index 309c90fdd0c..cf64d170ed6 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.c
+++ b/src/mesa/drivers/dri/r600/r700_assembler.c
@@ -4626,22 +4626,6 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
need_barrier = GL_TRUE;
}
- switch (pAsm->pILInst[pAsm->uiCurInst].Opcode)
- {
- case OPCODE_TEX:
- break;
- case OPCODE_TXB:
- radeon_error("do not support TXB yet\n");
- return GL_FALSE;
- break;
- case OPCODE_TXP:
- break;
- default:
- radeon_error("Internal error: bad texture op (not TEX)\n");
- return GL_FALSE;
- break;
- }
-
if (pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXP)
{
GLuint tmp = gethelpr(pAsm);
@@ -4820,7 +4804,18 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
}
- pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
+ if(pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXB)
+ {
+ pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE_L;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
+ }
+
+ pAsm->is_tex = GL_TRUE;
+ if ( GL_TRUE == need_barrier )
+
pAsm->is_tex = GL_TRUE;
if ( GL_TRUE == need_barrier )
{
diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c
index 8126777bf48..d7027400146 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.c
+++ b/src/mesa/drivers/dri/r600/r700_chip.c
@@ -1306,9 +1306,9 @@ void r600InitAtoms(context_t *context)
ALLOC_STATE(poly, always, 10, r700SendPolyState);
ALLOC_STATE(cb, cb, 18, r700SendCBState);
ALLOC_STATE(clrcmp, always, 6, r700SendCBCLRCMPState);
+ ALLOC_STATE(cb_target, always, 25, r700SendRenderTargetState);
ALLOC_STATE(blnd, blnd, (6 + (R700_MAX_RENDER_TARGETS * 3)), r700SendCBBlendState);
ALLOC_STATE(blnd_clr, always, 6, r700SendCBBlendColorState);
- ALLOC_STATE(cb_target, always, 25, r700SendRenderTargetState);
ALLOC_STATE(sx, always, 9, r700SendSXState);
ALLOC_STATE(vgt, always, 41, r700SendVGTState);
ALLOC_STATE(spi, always, (59 + R700_MAX_SHADER_EXPORTS), r700SendSPIState);
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index c81e80e820e..51fa6189377 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -262,29 +262,6 @@ void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h)
}
}
-void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask )
-{
- radeonContextPtr radeon = RADEON_CONTEXT(ctx);
- GLuint i;
- drm_radeon_stipple_t stipple;
-
- /* Must flip pattern upside down.
- */
- for ( i = 0 ; i < 32 ; i++ ) {
- stipple.mask[31 - i] = ((GLuint *) mask)[i];
- }
-
- /* TODO: push this into cmd mechanism
- */
- radeon_firevertices(radeon);
- LOCK_HARDWARE( radeon );
-
- drmCommandWrite( radeon->dri.fd, DRM_RADEON_STIPPLE,
- &stipple, sizeof(stipple) );
- UNLOCK_HARDWARE( radeon );
-}
-
-
/* ================================================================
* SwapBuffers with client-side throttling
*/
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h
index def0cc17a91..0608fe2418c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common.h
@@ -10,7 +10,6 @@ void radeonRecalcScissorRects(radeonContextPtr radeon);
void radeonSetCliprects(radeonContextPtr radeon);
void radeonUpdateScissor( GLcontext *ctx );
void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h);
-void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask );
void radeonWaitForIdleLocked(radeonContextPtr radeon);
extern uint32_t radeonGetAge(radeonContextPtr radeon);
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h
index 4e2c52c835c..12ab33a009c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_context.h
@@ -331,8 +331,12 @@ struct r100_hw_state {
struct radeon_state_atom stp;
};
+struct radeon_stipple_state {
+ GLuint mask[32];
+};
struct r100_state {
+ struct radeon_stipple_state stipple;
struct radeon_texture_state texture;
};
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index 7ec641ff18a..fc21069a92c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -369,6 +369,12 @@ radeon_framebuffer_renderbuffer(GLcontext * ctx,
}
+/* TODO: According to EXT_fbo spec internal format of texture image
+ * once set during glTexImage call, should be preserved when
+ * attaching image to renderbuffer. When HW doesn't support
+ * rendering to format of attached image, set framebuffer
+ * completeness accordingly in radeon_validate_framebuffer (issue #79).
+ */
static GLboolean
radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb,
struct gl_texture_image *texImage)
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index bdbb9460bf0..a7f347202a1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -437,9 +437,12 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
+ /* TODO: bring back these assertions once the FBOs are fixed */
+#if 0
assert(image->mtlevel == level);
assert(srclvl->size == dstlvl->size);
assert(srclvl->rowstride == dstlvl->rowstride);
+#endif
radeon_bo_map(image->mt->bo, GL_FALSE);
@@ -450,23 +453,18 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
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;
+ const uint32_t srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width);
+ uint32_t rows = image->base.Height * image->base.Depth;
- 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);
+ if (_mesa_is_format_compressed(image->base.TexFormat)) {
+ uint32_t blockWidth, blockHeight;
+ _mesa_get_format_block_size(image->base.TexFormat, &blockWidth, &blockHeight);
+ rows = (rows + blockHeight - 1) / blockHeight;
}
+ copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
+ rows, srcrowstride);
+
_mesa_free_texmemory(image->base.Data);
image->base.Data = 0;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 4d0d35ee0cd..f6c733ab209 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -550,6 +550,31 @@ static void radeonPolygonOffset( GLcontext *ctx,
rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
}
+static void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask )
+{
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
+ GLuint i;
+ drm_radeon_stipple_t stipple;
+
+ /* Must flip pattern upside down.
+ */
+ for ( i = 0 ; i < 32 ; i++ ) {
+ rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i];
+ }
+
+ /* TODO: push this into cmd mechanism
+ */
+ radeon_firevertices(&rmesa->radeon);
+ LOCK_HARDWARE( &rmesa->radeon );
+
+ /* FIXME: Use window x,y offsets into stipple RAM.
+ */
+ stipple.mask = rmesa->state.stipple.mask;
+ drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
+ &stipple, sizeof(drm_radeon_stipple_t) );
+ UNLOCK_HARDWARE( &rmesa->radeon );
+}
+
static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index 0390d376ba2..28690325d12 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -515,15 +515,18 @@ static int image_matches_texture_obj(struct gl_texture_object *texObj,
struct gl_texture_image *texImage,
unsigned level)
{
- const struct gl_texture_image *baseImage = texObj->Image[0][level];
+ const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
+
+ if (!baseImage)
+ return 0;
if (level < texObj->BaseLevel || level > texObj->MaxLevel)
return 0;
const unsigned levelDiff = level - texObj->BaseLevel;
- const unsigned refWidth = baseImage->Width >> levelDiff;
- const unsigned refHeight = baseImage->Height >> levelDiff;
- const unsigned refDepth = baseImage->Depth >> levelDiff;
+ const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
+ const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
+ const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
return (texImage->Width == refWidth &&
texImage->Height == refHeight &&