summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_fbo.c24
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_screen.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_program.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_urb.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c2
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_screen.c2
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_swtcl.c9
-rw-r--r--src/mesa/drivers/dri/nouveau/nv20_state.c21
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c37
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h7
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c44
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h9
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c165
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c284
-rw-r--r--src/mesa/drivers/dri/r300/r300_texmem.c361
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c170
-rw-r--r--src/mesa/drivers/x11/xm_api.c12
-rw-r--r--src/mesa/drivers/x11/xm_buffer.c12
-rw-r--r--src/mesa/drivers/x11/xmesaP.h1
-rw-r--r--src/mesa/main/api_loopback.c2
-rw-r--r--src/mesa/main/fbobject.c22
-rw-r--r--src/mesa/main/framebuffer.c52
-rw-r--r--src/mesa/main/rbadaptors.c2
-rw-r--r--src/mesa/main/renderbuffer.c88
-rw-r--r--src/mesa/main/renderbuffer.h6
-rw-r--r--src/mesa/main/texenvprogram.c7
-rw-r--r--src/mesa/main/teximage.c12
-rw-r--r--src/mesa/tnl/t_vp_build.c5
28 files changed, 671 insertions, 694 deletions
diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c
index 8d43055382..9b84faaeb7 100644
--- a/src/mesa/drivers/dri/i915tex/intel_fbo.c
+++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c
@@ -80,21 +80,33 @@ intel_flip_renderbuffers(struct intel_framebuffer *intel_fb)
{
int current_page = intel_fb->pf_current_page;
int next_page = (current_page + 1) % intel_fb->pf_num_pages;
+ struct gl_renderbuffer *tmp_rb;
+ /* Exchange renderbuffers if necessary but make sure their reference counts
+ * are preserved.
+ */
if (intel_fb->color_rb[current_page] &&
intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer !=
&intel_fb->color_rb[current_page]->Base) {
- _mesa_remove_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT);
- _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT,
- &intel_fb->color_rb[current_page]->Base);
+ tmp_rb = NULL;
+ _mesa_reference_renderbuffer(&tmp_rb,
+ intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ tmp_rb = &intel_fb->color_rb[current_page]->Base;
+ _mesa_reference_renderbuffer(
+ &intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer, tmp_rb);
+ _mesa_reference_renderbuffer(&tmp_rb, NULL);
}
if (intel_fb->color_rb[next_page] &&
intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer !=
&intel_fb->color_rb[next_page]->Base) {
- _mesa_remove_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT);
- _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT,
- &intel_fb->color_rb[next_page]->Base);
+ tmp_rb = NULL;
+ _mesa_reference_renderbuffer(&tmp_rb,
+ intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+ tmp_rb = &intel_fb->color_rb[next_page]->Base;
+ _mesa_reference_renderbuffer(
+ &intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer, tmp_rb);
+ _mesa_reference_renderbuffer(&tmp_rb, NULL);
}
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c
index a6342046b5..9034ee1b22 100644
--- a/src/mesa/drivers/dri/i915tex/intel_screen.c
+++ b/src/mesa/drivers/dri/i915tex/intel_screen.c
@@ -613,6 +613,8 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
&intel_fb->color_rb[1]->Base);
if (screen->third.handle) {
+ struct gl_renderbuffer *tmp_rb = NULL;
+
intel_fb->color_rb[2]
= intel_create_renderbuffer(rgbFormat,
screen->width, screen->height,
@@ -621,6 +623,7 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
screen->cpp,
screen->third.map);
intel_set_span_functions(&intel_fb->color_rb[2]->Base);
+ _mesa_reference_renderbuffer(&tmp_rb, &intel_fb->color_rb[2]->Base);
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index 1ae065b10d..5d98176dce 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -117,7 +117,7 @@ static void brwProgramStringNotify( GLcontext *ctx,
if (p == fp)
brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
p->id = brw->program_id++;
- p->param_state = brw_parameter_list_state_flags(p->program.Base.Parameters);
+ p->param_state = p->program.Base.Parameters->StateFlags;
}
else if (target == GL_VERTEX_PROGRAM_ARB) {
struct brw_context *brw = brw_context(ctx);
@@ -126,7 +126,7 @@ static void brwProgramStringNotify( GLcontext *ctx,
if (p == vp)
brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
p->id = brw->program_id++;
- p->param_state = brw_parameter_list_state_flags(p->program.Base.Parameters);
+ p->param_state = p->program.Base.Parameters->StateFlags;
/* Also tell tnl about it:
*/
diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c
index 79ff2b2d4d..64f5904ac6 100644
--- a/src/mesa/drivers/dri/i965/brw_urb.c
+++ b/src/mesa/drivers/dri/i965/brw_urb.c
@@ -131,7 +131,7 @@ static void recalculate_urb_fence( struct brw_context *brw )
brw->urb.constrained = 1;
- if (check_urb_layout(brw)) {
+ if (!check_urb_layout(brw)) {
/* This is impossible, given the maximal sizes of urb
* entries and the values for minimum nr of entries
* provided above.
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 47ddcd0f05..ff97d87dc4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -397,7 +397,7 @@ static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
/* Recalculate state dependency:
*/
- c->fp->param_state = brw_parameter_list_state_flags( paramList );
+ c->fp->param_state = paramList->StateFlags;
return src_reg(PROGRAM_STATE_VAR, idx);
}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
index 65bde99671..7a4b9f1cd0 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -328,7 +328,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc
static const __DRIversion ddx_expected = { 1, 2, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
-#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 5
+#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 6
#error nouveau_drm.h version doesn't match expected version
#endif
dri_interface = interface;
diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
index 32da40661b..3bc84d862d 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
@@ -315,6 +315,9 @@ static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2)
GLuint vertsize = nmesa->vertex_size;
GLuint size_dword = vertsize*(2)/4;
+ /* OUT_RINGp wants size in DWORDS */
+ vertsize >>= 2;
+
nv10ExtendPrimitive(nmesa, size_dword);
nv10StartPrimitive(nmesa,GL_LINES+1,size_dword);
OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
@@ -329,6 +332,9 @@ static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuin
GLuint vertsize = nmesa->vertex_size;
GLuint size_dword = vertsize*(3)/4;
+ /* OUT_RINGp wants size in DWORDS */
+ vertsize >>= 2;
+
nv10ExtendPrimitive(nmesa, size_dword);
nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword);
OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
@@ -344,6 +350,9 @@ static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3
GLuint vertsize = nmesa->vertex_size;
GLuint size_dword = vertsize*(4)/4;
+ /* OUT_RINGp wants size in DWORDS */
+ vertsize >>= 2;
+
nv10ExtendPrimitive(nmesa, size_dword);
nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword);
OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c
index 030713c0db..3d8d83a865 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_state.c
+++ b/src/mesa/drivers/dri/nouveau/nv20_state.c
@@ -78,7 +78,18 @@ static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac
static void nv20Clear(GLcontext *ctx, GLbitfield mask)
{
- /* TODO */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLuint hw_bufs = 0;
+
+ if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT))
+ hw_bufs |= 0xf0;
+ if (mask & (BUFFER_BIT_DEPTH))
+ hw_bufs |= 0x03;
+
+ if (hw_bufs) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1);
+ OUT_RING_CACHE(hw_bufs);
+ }
}
static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4])
@@ -557,9 +568,11 @@ static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
y += nmesa->drawY;
}
- BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 2);
- OUT_RING_CACHE(((x+w-1) << 16) | x);
- OUT_RING_CACHE(((y+h-1) << 16) | y);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 1);
+ OUT_RING_CACHE((w << 16) | x );
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1, 1);
+ OUT_RING_CACHE((h << 16) | y );
+
}
/** Select flat or smooth shading */
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 8aaf50b6d8..1f8d95078f 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -133,7 +133,6 @@ const struct dri_extension stencil_two_side[] = {
extern struct tnl_pipeline_stage _r300_render_stage;
extern const struct tnl_pipeline_stage _r300_tcl_stage;
-extern const struct tnl_pipeline_stage _r300_texrect_stage;
static const struct tnl_pipeline_stage *r300_pipeline[] = {
@@ -164,8 +163,6 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = {
/* Else do them here.
*/
- /* scale texture rectangle to 0..1. */
- &_r300_texrect_stage,
&_r300_render_stage,
&_tnl_render_stage, /* FALLBACK */
0,
@@ -204,7 +201,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
"def_max_anisotropy");
//r300->texmicrotile = GL_TRUE;
-
+
/* Init default driver functions then plug in our R300-specific functions
* (the texture functions are especially important)
*/
@@ -213,7 +210,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
r300InitStateFuncs(&functions);
r300InitTextureFuncs(&functions);
r300InitShaderFuncs(&functions);
-
+
#ifdef USER_BUFFERS
radeon_mm_init(r300);
#endif
@@ -221,7 +218,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
if (hw_tcl_on) {
r300_init_vbo_funcs(&functions);
}
-#endif
+#endif
if (!radeonInitContext(&r300->radeon, &functions,
glVisual, driContextPriv, sharedContextPrivate)) {
FREE(r300);
@@ -264,8 +261,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
* texturable memory at once.
*/
- ctx = r300->radeon.glCtx;
-
+ ctx = r300->radeon.glCtx;
+
ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache,
"texture_image_units");
ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache,
@@ -283,7 +280,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = R300_LINESIZE_MAX;
ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX;
-
+
#ifdef USER_BUFFERS
/* Needs further modifications */
#if 0
@@ -337,10 +334,10 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
driInitExtensions(ctx, card_extensions, GL_TRUE);
-
+
if (driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side") == 0)
driInitSingleExtension(ctx, stencil_two_side);
-
+
if (r300->radeon.glCtx->Mesa_DXTn && !driQueryOptionb (&r300->radeon.optionCache, "disable_s3tc")) {
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
_mesa_enable_extension( ctx, "GL_S3_s3tc" );
@@ -354,7 +351,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
radeonInitSpanFuncs(ctx);
r300InitCmdBuf(r300);
r300InitState(r300);
-
+
#ifdef RADEON_VTXFMT_A
radeon_init_vtxfmt_a(r300);
#endif
@@ -407,9 +404,9 @@ static void r300FreeGartAllocations(r300ContextPtr r300)
/* Cannot flush/lock if no context exists. */
if (in_use)
r300FlushCmdBuf(r300, __FUNCTION__);
-
+
done_age = radeonGetAge((radeonContextPtr)r300);
-
+
for (i = r300->rmm->u_last; i > 0; i--) {
if (r300->rmm->u_list[i].ptr == NULL) {
continue;
@@ -421,7 +418,7 @@ static void r300FreeGartAllocations(r300ContextPtr r300)
}
assert(r300->rmm->u_list[i].h_pending == 0);
-
+
tries = 0;
while(r300->rmm->u_list[i].age > done_age && tries++ < 1000) {
usleep(10);
@@ -430,10 +427,10 @@ static void r300FreeGartAllocations(r300ContextPtr r300)
if (tries >= 1000) {
WARN_ONCE("Failed to idle region!");
}
-
+
memfree.region_offset = (char *)r300->rmm->u_list[i].ptr -
(char *)r300->radeon.radeonScreen->gartTextures.map;
-
+
ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd,
DRM_RADEON_FREE, &memfree, sizeof(memfree));
if (ret) {
@@ -442,7 +439,7 @@ static void r300FreeGartAllocations(r300ContextPtr r300)
} else {
if (i == r300->rmm->u_last)
r300->rmm->u_last--;
-
+
r300->rmm->u_list[i].pending = 0;
r300->rmm->u_list[i].ptr = NULL;
if (r300->rmm->u_list[i].fb) {
@@ -490,12 +487,12 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
_tnl_DestroyContext(r300->radeon.glCtx);
_vbo_DestroyContext(r300->radeon.glCtx);
_swrast_DestroyContext(r300->radeon.glCtx);
-
+
if (r300->dma.current.buf) {
r300ReleaseDmaRegion(r300, &r300->dma.current, __FUNCTION__ );
#ifndef USER_BUFFERS
r300FlushCmdBuf(r300, __FUNCTION__);
-#endif
+#endif
}
r300FreeGartAllocations(r300);
r300DestroyCmdBuf(r300);
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index fe261dbbc6..c8b81d9849 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -553,6 +553,7 @@ struct r300_stencilbuffer_state {
#define VSF_MAX_FRAGMENT_TEMPS (14)
#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
+#define STATE_R300_TEXRECT_FACTOR (STATE_INTERNAL_DRIVER+1)
struct r300_vertex_shader_fragment {
int length;
@@ -602,12 +603,6 @@ extern int hw_tcl_on;
/* Should but doesnt work */
//#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->curr_vp)
-//#define TMU_ENABLED(ctx, unit) (hw_tcl_on ? ctx->Texture.Unit[unit]._ReallyEnabled && (OutputsWritten & (1<<(VERT_RESULT_TEX0+(unit)))) :
-// (r300->state.render_inputs & (_TNL_BIT_TEX0<<(unit))))
-//#define TMU_ENABLED(ctx, unit) (hw_tcl_on ? ctx->Texture.Unit[unit]._ReallyEnabled && OutputsWritten & (1<<(VERT_RESULT_TEX0+(unit))) :
-// ctx->Texture.Unit[unit]._ReallyEnabled && r300->state.render_inputs & (_TNL_BIT_TEX0<<(unit)))
-
-#define TMU_ENABLED(ctx, unit) (ctx->Texture.Unit[unit]._ReallyEnabled)
/* r300_vertex_shader_state and r300_vertex_program should probably be merged together someday.
* Keeping them them seperate for now should ensure fixed pipeline keeps functioning properly.
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index c407dfb5b0..77f95605e4 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -930,13 +930,47 @@ static void emit_tex(struct r300_fragment_program *rp,
COMPILE_STATE;
GLuint coord = t_src(rp, fpi->SrcReg[0]);
GLuint dest = undef, rdest = undef;
- GLuint din = cs->dest_in_node, uin = cs->used_in_node;
+ GLuint din, uin;
int unit = fpi->TexSrcUnit;
int hwsrc, hwdest;
+ GLuint tempreg = 0;
+
+ uin = cs->used_in_node;
+ din = cs->dest_in_node;
/* Resolve source/dest to hardware registers */
- hwsrc = t_hw_src(rp, coord, GL_TRUE);
if (opcode != R300_FPITX_OP_KIL) {
+ if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) {
+ /**
+ * Hardware uses [0..1]x[0..1] range for rectangle textures
+ * instead of [0..Width]x[0..Height].
+ * Add a scaling instruction.
+ *
+ * \todo Refactor this once we have proper rewriting/optimization
+ * support for programs.
+ */
+ GLint tokens[6] = { STATE_INTERNAL, STATE_R300_TEXRECT_FACTOR, 0, 0, 0, 0 };
+ int factor_index;
+ GLuint factorreg;
+
+ tokens[2] = unit;
+ factor_index = _mesa_add_state_reference(rp->mesa_program.Base.Parameters, tokens);
+ factorreg = emit_const4fv(rp,
+ rp->mesa_program.Base.Parameters->ParameterValues[factor_index]);
+ tempreg = keep(get_temp_reg(rp));
+
+ emit_arith(rp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW,
+ coord, factorreg, pfs_zero, 0);
+
+ /* Ensure correct node indirection */
+ uin = cs->used_in_node;
+ din = cs->dest_in_node;
+
+ hwsrc = t_hw_src(rp, tempreg, GL_TRUE);
+ } else {
+ hwsrc = t_hw_src(rp, coord, GL_TRUE);
+ }
+
dest = t_dst(rp, fpi->DstReg);
/* r300 doesn't seem to be able to do TEX->output reg */
@@ -957,8 +991,10 @@ static void emit_tex(struct r300_fragment_program *rp,
} else {
hwdest = 0;
unit = 0;
+ hwsrc = t_hw_src(rp, coord, GL_TRUE);
}
+
/* Indirection if source has been written in this node, or if the
* dest has been read/written in this node
*/
@@ -1010,6 +1046,10 @@ static void emit_tex(struct r300_fragment_program *rp,
pfs_one, pfs_zero, 0);
free_temp(rp, dest);
}
+
+ /* Free temp register */
+ if (tempreg != 0)
+ free_temp(rp, tempreg);
}
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index 1f4a2d2e64..1f65f9a7e7 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -325,7 +325,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* Most likely this is used to ignore rest of the program in cases
* where group of verts arent visible. For some reason this "section"
* is sometimes accepted other instruction that have no relationship with
- *position calculations.
+ *position calculations.
*/
#define R300_VAP_PVS_CNTL_1 0x22D0
# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0
@@ -566,8 +566,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R300_RE_FOG_SCALE 0x4294
#define R300_RE_FOG_START 0x4298
-/* Not sure why there are duplicate of factor and constant values.
- * My best guess so far is that there are seperate zbiases for test and write.
+/* Not sure why there are duplicate of factor and constant values.
+ * My best guess so far is that there are seperate zbiases for test and write.
* Ordering might be wrong.
* Some of the tests indicate that fgl has a fallback implementation of zbias
* via pixel shaders.
@@ -909,7 +909,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* 32 bit chroma key */
#define R300_TX_CHROMA_KEY_0 0x4580
/* ff00ff00 == { 0, 1.0, 0, 1.0 } */
-#define R300_TX_BORDER_COLOR_0 0x45C0
+#define R300_TX_BORDER_COLOR_0 0x45C0
/* END: Texture specification */
@@ -999,6 +999,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_FPITX_OP_KIL 2
# define R300_FPITX_OP_TXP 3
# define R300_FPITX_OP_TXB 4
+# define R300_FPITX_OPCODE_MASK (7 << 15)
/* ALU
* The ALU instructions register blocks are enumerated according to the order
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 0864558e8d..63b21b9379 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -202,23 +202,23 @@ static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_
unsigned long t_addr;
unsigned long magic_1, magic_2;
GLcontext *ctx;
- ctx = rmesa->radeon.glCtx;
-
+ ctx = rmesa->radeon.glCtx;
+
assert(elt_size == 2 || elt_size == 4);
-
+
if(addr & (elt_size-1)){
WARN_ONCE("Badly aligned buffer\n");
return ;
}
#ifdef OPTIMIZE_ELTS
addr_a = 0;
-
+
magic_1 = (addr % 32) / 4;
t_addr = addr & (~0x1d);
magic_2 = (vertex_count + 1 + (t_addr & 0x2)) / 2 + magic_1;
-
+
check_space(6);
-
+
start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
if(elt_size == 4){
e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
@@ -234,7 +234,7 @@ static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_
e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2);
e32(t_addr);
}
-
+
if(elt_size == 4){
e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */
} else {
@@ -249,11 +249,11 @@ static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_
#endif
#else
(void)magic_2, (void)magic_1, (void)t_addr;
-
+
addr_a = 0;
-
+
check_space(6);
-
+
start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
if(elt_size == 4){
e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
@@ -264,14 +264,14 @@ static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_
start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
e32(addr /*& 0xffffffe3*/);
-
+
if(elt_size == 4){
e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */
} else {
e32((vertex_count+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */
}
//cp_delay(rmesa, 1);
-#endif
+#endif
}
static void r300_render_vb_primitive(r300ContextPtr rmesa,
@@ -303,12 +303,12 @@ static void r300_render_vb_primitive(r300ContextPtr rmesa,
//e32(rmesa->state.Elts[start]);
return;
}
-
+
if(num_verts > 65535){ /* not implemented yet */
WARN_ONCE("Too many elts\n");
return;
}
-
+
r300EmitElts(ctx, rmesa->state.VB.Elts, num_verts, rmesa->state.VB.elt_size);
fire_EB(rmesa, rmesa->state.elt_dma.aos_offset, num_verts, type, rmesa->state.VB.elt_size);
#endif
@@ -328,7 +328,7 @@ GLboolean r300_run_vb_render(GLcontext *ctx,
int cmd_written = 0;
drm_radeon_cmd_header_t *cmd = NULL;
-
+
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -336,26 +336,26 @@ GLboolean r300_run_vb_render(GLcontext *ctx,
TNLcontext *tnl = TNL_CONTEXT(ctx);
radeon_vb_to_rvb(rmesa, VB, &tnl->vb);
}
-
+
r300UpdateShaders(rmesa);
if (r300EmitArrays(ctx))
return GL_TRUE;
r300UpdateShaderStates(rmesa);
-
+
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
e32(R300_RB3D_DSTCACHE_UNKNOWN_0A);
reg_start(R300_RB3D_ZCACHE_CTLSTAT,0);
e32(R300_RB3D_ZCACHE_UNKNOWN_03);
-
+
r300EmitState(rmesa);
-
+
for(i=0; i < VB->PrimitiveCount; i++){
GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;
-
+
r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
}
@@ -453,11 +453,6 @@ int r300Fallback(GLcontext *ctx)
/* GL_POINT_SPRITE_NV */
FALLBACK_IF(ctx->Point.PointSprite);
- /* Fallback for rectangular texture */
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
- if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT)
- return R300_FALLBACK_TCL;
-
return R300_FALLBACK_NONE;
}
@@ -494,19 +489,19 @@ static GLboolean r300_run_tcl_render(GLcontext *ctx,
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_vertex_program *vp;
-
+
hw_tcl_on=future_hw_tcl_on;
-
+
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
if(hw_tcl_on == GL_FALSE)
return GL_TRUE;
-
+
if (r300Fallback(ctx) >= R300_FALLBACK_TCL) {
hw_tcl_on = GL_FALSE;
return GL_TRUE;
}
-
+
r300UpdateShaders(rmesa);
vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
@@ -520,13 +515,13 @@ static GLboolean r300_run_tcl_render(GLcontext *ctx,
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct tnl_cache *cache;
struct tnl_cache_item *c;
-
+
cache = tnl->vp_cache;
c = cache->items[0xc000cc0e % cache->size];
-
+
if(c && c->data == vp)
vp->native = GL_FALSE;
-
+
#endif
#if 0
vp->native = GL_FALSE;
@@ -536,7 +531,7 @@ static GLboolean r300_run_tcl_render(GLcontext *ctx,
return GL_TRUE;
}
//r300UpdateShaderStates(rmesa);
-
+
return r300_run_vb_render(ctx, stage);
}
@@ -549,107 +544,3 @@ const struct tnl_pipeline_stage _r300_tcl_stage = {
r300_run_tcl_render /* run */
};
-/* R300 texture rectangle expects coords in 0..1 range, not 0..dimension
- * as in the extension spec. Need to translate here.
- *
- * Note that swrast expects 0..dimension, so if a fallback is active,
- * don't do anything. (Maybe need to configure swrast to match hw)
- */
-struct texrect_stage_data {
- GLvector4f texcoord[MAX_TEXTURE_UNITS];
-};
-
-#define TEXRECT_STAGE_DATA(stage) ((struct texrect_stage_data *)stage->privatePtr)
-
-
-static GLboolean run_texrect_stage( GLcontext *ctx,
- struct tnl_pipeline_stage *stage )
-{
- struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage);
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *VB = &tnl->vb;
- GLuint i;
-
- if (rmesa->radeon.Fallback)
- return GL_TRUE;
-
- for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
- if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT) {
- struct gl_texture_object *texObj = ctx->Texture.Unit[i].CurrentRect;
- struct gl_texture_image *texImage = texObj->Image[0][texObj->BaseLevel];
- const GLfloat iw = 1.0/texImage->Width;
- const GLfloat ih = 1.0/texImage->Height;
- GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;
- GLint instride = VB->TexCoordPtr[i]->stride;
- GLfloat (*out)[4] = store->texcoord[i].data;
- GLint j;
-
- store->texcoord[i].size = VB->TexCoordPtr[i]->size;
- for (j = 0 ; j < VB->Count ; j++) {
- switch (VB->TexCoordPtr[i]->size) {
- case 4:
- out[j][3] = in[3];
- /* fallthrough */
- case 3:
- out[j][2] = in[2];
- /* fallthrough */
- default:
- out[j][0] = in[0] * iw;
- out[j][1] = in[1] * ih;
- }
- in = (GLfloat *)((GLubyte *)in + instride);
- }
-
- VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i];
- }
- }
-
- return GL_TRUE;
-}
-
-
-/* Called the first time stage->run() is invoked.
- */
-static GLboolean alloc_texrect_data( GLcontext *ctx,
- struct tnl_pipeline_stage *stage )
-{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- struct texrect_stage_data *store;
- GLuint i;
-
- stage->privatePtr = CALLOC(sizeof(*store));
- store = TEXRECT_STAGE_DATA(stage);
- if (!store)
- return GL_FALSE;
-
- for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
- _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
-
- return GL_TRUE;
-}
-
-static void free_texrect_data( struct tnl_pipeline_stage *stage )
-{
- struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage);
- GLuint i;
-
- if (store) {
- for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
- if (store->texcoord[i].data)
- _mesa_vector4f_free( &store->texcoord[i] );
- FREE( store );
- stage->privatePtr = NULL;
- }
-}
-
-const struct tnl_pipeline_stage _r300_texrect_stage =
-{
- "r300 texrect stage", /* name */
- NULL,
- alloc_texrect_data,
- free_texrect_data,
- NULL,
- run_texrect_stage
-};
-
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index fff11653de..ff3c51c5ed 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -359,7 +359,7 @@ static void update_alpha(GLcontext *ctx)
GLboolean really_enabled = ctx->Color.AlphaEnabled;
CLAMPED_FLOAT_TO_UBYTE(refByte, ctx->Color.AlphaRef);
-
+
switch (ctx->Color.AlphaFunc) {
case GL_NEVER:
pp_misc |= R300_ALPHA_TEST_FAIL;
@@ -387,15 +387,15 @@ static void update_alpha(GLcontext *ctx)
really_enabled = GL_FALSE;
break;
}
-
+
if (really_enabled) {
pp_misc |= R300_ALPHA_TEST_ENABLE;
pp_misc |= (refByte & R300_REF_ALPHA_MASK);
} else {
pp_misc = 0x0;
}
-
-
+
+
R300_STATECHANGE(r300, at);
r300->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
update_early_z(ctx);
@@ -438,19 +438,19 @@ static void update_depth(GLcontext* ctx)
R300_STATECHANGE(r300, zs);
r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_RB3D_STENCIL_ENABLE;
r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
-
+
if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER) {
if (ctx->Depth.Mask)
r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_TEST_AND_WRITE;
else
r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_TEST;
-
+
r300->hw.zs.cmd[R300_ZS_CNTL_1] |= translate_func(ctx->Depth.Func) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
} else {
r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_DISABLED_1;
r300->hw.zs.cmd[R300_ZS_CNTL_1] |= translate_func(GL_NEVER) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
}
-
+
update_early_z(ctx);
}
@@ -481,7 +481,7 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
if (state) {
r300->hw.fogs.cmd[R300_FOGS_STATE] |=
R300_FOG_ENABLE;
-
+
ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL );
ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
@@ -491,7 +491,7 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
r300->hw.fogs.cmd[R300_FOGS_STATE] &=
~R300_FOG_ENABLE;
}
-
+
break;
case GL_ALPHA_TEST:
@@ -520,7 +520,7 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
} else {
#if R200_MERGED
FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
-#endif
+#endif
}
break;
@@ -555,7 +555,7 @@ static void r300UpdatePolygonMode(GLcontext *ctx)
if (ctx->Polygon.FrontMode != GL_FILL ||
ctx->Polygon.BackMode != GL_FILL) {
GLenum f, b;
-
+
if (ctx->Polygon.FrontFace == GL_CCW) {
f = ctx->Polygon.FrontMode;
b = ctx->Polygon.BackMode;
@@ -673,9 +673,9 @@ static void r300Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
union { int i; float f; } fogScale, fogStart;
-
+
(void) param;
-
+
fogScale.i = r300->hw.fogp.cmd[R300_FOGP_SCALE];
fogStart.i = r300->hw.fogp.cmd[R300_FOGP_START];
@@ -771,7 +771,7 @@ static void r300PointSize(GLcontext * ctx, GLfloat size)
size = ctx->Point._Size;
R300_STATECHANGE(r300, ps);
- r300->hw.ps.cmd[R300_PS_POINTSIZE] =
+ r300->hw.ps.cmd[R300_PS_POINTSIZE] =
((int)(size * 6) << R300_POINTSIZE_X_SHIFT) |
((int)(size * 6) << R300_POINTSIZE_Y_SHIFT);
}
@@ -794,7 +794,7 @@ static void r300PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
{
(void)face;
(void)mode;
-
+
r300UpdatePolygonMode(ctx);
}
@@ -831,7 +831,7 @@ static int translate_stencil_op(int op)
static void r300ShadeModel(GLcontext * ctx, GLenum mode)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
-
+
R300_STATECHANGE(rmesa, shade);
switch (mode) {
case GL_FLAT:
@@ -851,7 +851,7 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
r300ContextPtr rmesa = R300_CONTEXT(ctx);
GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
((ctx->Stencil.ValueMask[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
-
+
GLuint flag;
R300_STATECHANGE(rmesa, zs);
@@ -859,16 +859,16 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(
(R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
| (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT));
-
+
rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~((R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
(R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
-
+
flag = translate_func(ctx->Stencil.Function[0]);
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT);
-
+
if (ctx->Stencil._TestTwoSide)
flag = translate_func(ctx->Stencil.Function[1]);
-
+
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
}
@@ -890,16 +890,16 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail,
R300_STATECHANGE(rmesa, zs);
/* It is easier to mask what's left.. */
- rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &=
- (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT) |
- (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) |
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &=
+ (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT) |
+ (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) |
(R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT)
|(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT)
|(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT);
-
+
if (ctx->Stencil._TestTwoSide) {
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
(translate_stencil_op(ctx->Stencil.FailFunc[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
@@ -994,7 +994,7 @@ void r300UpdateViewportOffset( GLcontext *ctx )
R300_STATECHANGE( rmesa, vpt );
rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
-
+
}
radeonUpdateScissor( ctx );
@@ -1030,16 +1030,16 @@ r300UpdateDrawBuffer(GLcontext *ctx)
R300_STATECHANGE( rmesa, cb );
-
+
r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset + //r300->radeon.state.color.drawOffset +
r300->radeon.radeonScreen->fbLocation;
r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch;//r300->radeon.state.color.drawPitch;
-
+
if (r300->radeon.radeonScreen->cpp == 4)
r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
else
r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
-
+
if (r300->radeon.sarea->tiling_enabled)
r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
#if 0
@@ -1050,7 +1050,7 @@ r300UpdateDrawBuffer(GLcontext *ctx)
= ((drb->flippedOffset + rmesa->r200Screen->fbLocation)
& R200_COLOROFFSET_MASK);
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch;
-
+
if (rmesa->sarea->tiling_enabled) {
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
}
@@ -1062,23 +1062,41 @@ r300FetchStateParameter(GLcontext *ctx,
const gl_state_index state[STATE_LENGTH],
GLfloat *value)
{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
- switch(state[0])
- {
- case STATE_INTERNAL:
- switch(state[1])
- {
- case STATE_R300_WINDOW_DIMENSION:
- value[0] = r300->radeon.dri.drawable->w*0.5f;/* width*0.5 */
- value[1] = r300->radeon.dri.drawable->h*0.5f;/* height*0.5 */
- value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */
- value[3] = 1.0F; /* not used */
- break;
- default:;
+ switch(state[0]) {
+ case STATE_INTERNAL:
+ switch(state[1]) {
+ case STATE_R300_WINDOW_DIMENSION:
+ value[0] = r300->radeon.dri.drawable->w*0.5f;/* width*0.5 */
+ value[1] = r300->radeon.dri.drawable->h*0.5f;/* height*0.5 */
+ value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */
+ value[3] = 1.0F; /* not used */
+ break;
+
+ case STATE_R300_TEXRECT_FACTOR: {
+ struct gl_texture_object* t = ctx->Texture.Unit[state[2]].CurrentRect;
+
+ if (t && t->Image[0][t->BaseLevel]) {
+ struct gl_texture_image* image = t->Image[0][t->BaseLevel];
+ value[0] = 1.0 / image->Width2;
+ value[1] = 1.0 / image->Height2;
+ } else {
+ value[0] = 1.0;
+ value[1] = 1.0;
+ }
+ value[2] = 1.0;
+ value[3] = 1.0;
+ break; }
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
}
- default:;
- }
}
/**
@@ -1119,7 +1137,7 @@ static void r300PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
GLfloat constant = units;
-
+
switch (ctx->Visual.depthBits) {
case 16:
constant *= 4.0;
@@ -1214,7 +1232,7 @@ void r300_setup_textures(GLcontext *ctx)
r300ContextPtr r300 = R300_CONTEXT(ctx);
int hw_tmu=0;
int last_hw_tmu=-1; /* -1 translates into no setup costs for fields */
- int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1 };
+ int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, };
struct r300_fragment_program *rp =
(struct r300_fragment_program *)
(char *)ctx->FragmentProgram._Current;
@@ -1228,7 +1246,7 @@ void r300_setup_textures(GLcontext *ctx)
R300_STATECHANGE(r300, tex.offset);
R300_STATECHANGE(r300, tex.chroma_key);
R300_STATECHANGE(r300, tex.border_color);
-
+
r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
@@ -1243,24 +1261,24 @@ void r300_setup_textures(GLcontext *ctx)
/* We cannot let disabled tmu offsets pass DRM */
for(i=0; i < mtu; i++) {
- if(TMU_ENABLED(ctx, i)) {
-
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+
#if 0 /* Enables old behaviour */
hw_tmu = i;
#endif
tmu_mappings[i] = hw_tmu;
-
+
t=r300->state.texture.unit[i].texobj;
-
+
if((t->format & 0xffffff00)==0xffffff00) {
WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t->format & 0xff);
}
-
+
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "Activating texture unit %d\n", i);
-
+
r300->hw.txe.cmd[R300_TXE_ENABLE] |= (1 << hw_tmu);
-
+
r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 + hw_tmu] = gen_fixed_filter(t->filter) | (hw_tmu << 28);
/* Currently disabled! */
r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; //0x20501f80;
@@ -1268,24 +1286,24 @@ void r300_setup_textures(GLcontext *ctx)
r300->hw.tex.format.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->format;
r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->pitch_reg;
r300->hw.tex.offset.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->offset;
-
+
if(t->offset & R300_TXO_MACRO_TILE) {
WARN_ONCE("macro tiling enabled!\n");
}
-
+
if(t->offset & R300_TXO_MICRO_TILE) {
WARN_ONCE("micro tiling enabled!\n");
}
-
+
r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0;
r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->pp_border_color;
-
+
last_hw_tmu = hw_tmu;
-
+
hw_tmu++;
}
}
-
+
r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FILTER_0, last_hw_tmu + 1);
r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FILTER1_0, last_hw_tmu + 1);
r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_SIZE_0, last_hw_tmu + 1);
@@ -1294,31 +1312,41 @@ void r300_setup_textures(GLcontext *ctx)
r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_OFFSET_0, last_hw_tmu + 1);
r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_CHROMA_KEY_0, last_hw_tmu + 1);
r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
-
-
+
+
if (!rp) /* should only happenen once, just after context is created */
return;
-
+
R300_STATECHANGE(r300, fpt);
-
+
for(i = 0; i < rp->tex.length; i++){
int unit;
+ int opcode;
unsigned long val;
-
+
unit = rp->tex.inst[i] >> R300_FPITX_IMAGE_SHIFT;
unit &= 15;
-
+
val = rp->tex.inst[i];
val &= ~R300_FPITX_IMAGE_MASK;
-
- assert(tmu_mappings[unit] >= 0);
-
- val |= tmu_mappings[unit] << R300_FPITX_IMAGE_SHIFT;
- r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val;
+
+ opcode = (val & R300_FPITX_OPCODE_MASK) >> R300_FPITX_OPCODE_SHIFT;
+ if (opcode == R300_FPITX_OP_KIL) {
+ r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val;
+ } else {
+ if (tmu_mappings[unit] >= 0) {
+ val |= tmu_mappings[unit] << R300_FPITX_IMAGE_SHIFT;
+ r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val;
+ } else {
+ // We get here when the corresponding texture image is incomplete
+ // (e.g. incomplete mipmaps etc.)
+ r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val;
+ }
+ }
}
-
+
r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(R300_PFS_TEXI_0, rp->tex.length);
-
+
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], last_hw_tmu);
}
@@ -1367,11 +1395,11 @@ void r300_setup_rs_unit(GLcontext *ctx)
R300_STATECHANGE(r300, ri);
R300_STATECHANGE(r300, rc);
R300_STATECHANGE(r300, rr);
-
+
fp_reg = in_texcoords = col_interp_nr = high_rr = 0;
r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0;
-
+
if (InputsRead & FRAG_BIT_WPOS){
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
@@ -1385,7 +1413,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
InputsRead |= (FRAG_BIT_TEX0 << i);
InputsRead &= ~FRAG_BIT_WPOS;
}
-
+
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0
| R300_RS_INTERP_USED
@@ -1409,7 +1437,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
}
InputsRead &= ~(FRAG_BIT_TEX0<<i);
fp_reg++;
- }
+ }
/* Need to count all coords enabled at vof */
if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten, VERT_RESULT_TEX0+i, _TNL_ATTRIB_TEX(i) ))
in_texcoords++;
@@ -1430,7 +1458,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
col_interp_nr++;
}
out:
-
+
if (InputsRead & FRAG_BIT_COL1) {
if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1 )) {
WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
@@ -1444,7 +1472,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
if (high_rr < 1) high_rr = 1;
col_interp_nr++;
}
-
+
/* Need at least one. This might still lock as the values are undefined... */
if (in_texcoords == 0 && col_interp_nr == 0) {
r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0
@@ -1452,7 +1480,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
| (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
col_interp_nr++;
}
-
+
r300->hw.rc.cmd[1] = 0
| (in_texcoords << R300_RS_CNTL_TC_CNT_SHIFT)
| (col_interp_nr << R300_RS_CNTL_CI_CNT_SHIFT)
@@ -1517,8 +1545,8 @@ void r300SetupVertexProgram(r300ContextPtr rmesa);
/* just a skeleton for now.. */
/* Generate a vertex shader that simply transforms vertex and texture coordinates,
- while leaving colors intact. Nothing fancy (like lights)
-
+ while leaving colors intact. Nothing fancy (like lights)
+
If implementing lights make a copy first, so it is easy to switch between the two versions */
static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
{
@@ -1529,14 +1557,14 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
r300->state.vap_param.transform_offset=0x0; /* transform matrix */
r300->state.vertex_shader.param_offset=0x0;
r300->state.vertex_shader.param_count=0x4; /* 4 vector values - 4x4 matrix */
-
+
r300->state.vertex_shader.program_start=0x0;
r300->state.vertex_shader.unknown_ptr1=0x4; /* magic value ? */
r300->state.vertex_shader.program_end=0x0;
-
+
r300->state.vertex_shader.unknown_ptr2=0x0; /* magic value */
r300->state.vertex_shader.unknown_ptr3=0x4; /* magic value */
-
+
/* Initialize matrix and vector parameters.. these should really be restructured */
/* TODO: fix vertex_shader structure */
r300->state.vertex_shader.matrix[0].length=16;
@@ -1546,7 +1574,7 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
r300->state.vertex_shader.vector[1].length=0;
r300->state.vertex_shader.unknown1.length=0;
r300->state.vertex_shader.unknown2.length=0;
-
+
#define WRITE_OP(oper,source1,source2,source3) {\
r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
@@ -1556,35 +1584,35 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
}
/* Multiply vertex coordinates with transform matrix */
-
+
WRITE_OP(
EASY_VSF_OP(MUL, 0, ALL, TMP),
VSF_PARAM(3),
VSF_ATTR_W(0),
EASY_VSF_SOURCE(0, W, W, W, W, NONE, NONE)
)
-
+
WRITE_OP(
EASY_VSF_OP(MUL, 1, ALL, RESULT),
VSF_REG(1),
VSF_ATTR_UNITY(1),
VSF_UNITY(1)
)
-
+
WRITE_OP(
EASY_VSF_OP(MAD, 0, ALL, TMP),
VSF_PARAM(2),
VSF_ATTR_Z(0),
VSF_TMP(0)
)
-
+
WRITE_OP(
EASY_VSF_OP(MAD, 0, ALL, TMP),
VSF_PARAM(1),
VSF_ATTR_Y(0),
VSF_TMP(0)
)
-
+
WRITE_OP(
EASY_VSF_OP(MAD, 0, ALL, RESULT),
VSF_PARAM(0),
@@ -1592,7 +1620,7 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
VSF_TMP(0)
)
o_reg += 2;
-
+
for (i = VERT_ATTRIB_COLOR1; i < VERT_ATTRIB_MAX; i++)
if (r300->state.sw_tcl_inputs[i] != -1) {
WRITE_OP(
@@ -1601,16 +1629,16 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
VSF_ATTR_UNITY(r300->state.sw_tcl_inputs[i]),
VSF_UNITY(r300->state.sw_tcl_inputs[i])
)
-
+
}
-
+
r300->state.vertex_shader.program_end--; /* r300 wants program length to be one more - no idea why */
r300->state.vertex_shader.program.length=(r300->state.vertex_shader.program_end+1)*4;
-
+
r300->state.vertex_shader.unknown_ptr1=r300->state.vertex_shader.program_end; /* magic value ? */
r300->state.vertex_shader.unknown_ptr2=r300->state.vertex_shader.program_end; /* magic value ? */
r300->state.vertex_shader.unknown_ptr3=r300->state.vertex_shader.program_end; /* magic value ? */
-
+
}
@@ -1688,14 +1716,14 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
int inst_count;
int param_count;
struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
-
+
((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
R300_STATECHANGE(rmesa, vpp);
param_count = r300VertexProgUpdateParams(ctx, (struct r300_vertex_program_cont *)ctx->VertexProgram._Current/*prog*/, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
param_count /= 4;
-
+
/* Reset state, in case we don't use something */
((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
@@ -1734,23 +1762,23 @@ void r300UpdateShaders(r300ContextPtr rmesa)
GLcontext *ctx;
struct r300_vertex_program *vp;
int i;
-
+
ctx = rmesa->radeon.glCtx;
-
+
if (rmesa->NewGLState && hw_tcl_on) {
rmesa->NewGLState = 0;
-
+
for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &rmesa->dummy_attrib[i];
}
-
+
_tnl_UpdateFixedFunctionProgram(ctx);
-
+
for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
}
-
+
r300_select_vertex_shader(rmesa);
vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
/*if (vp->translated == GL_FALSE)
@@ -1764,26 +1792,26 @@ void r300UpdateShaders(r300ContextPtr rmesa)
}
r300UpdateStateParameters(ctx, _NEW_PROGRAM);
}
-
+
}
void r300UpdateShaderStates(r300ContextPtr rmesa)
{
GLcontext *ctx;
ctx = rmesa->radeon.glCtx;
-
+
r300UpdateTextureState(ctx);
r300SetupPixelShader(rmesa);
r300_setup_textures(ctx);
-
+
r300SetupVertexShader(rmesa);
r300_setup_rs_unit(ctx);
}
/* This is probably wrong for some values, I need to test this
* some more. Range checking would be a good idea also..
- *
+ *
* But it works for most things. I'll fix it later if someone
* else with a better clue doesn't
*/
@@ -1821,13 +1849,13 @@ void r300SetupPixelShader(r300ContextPtr rmesa)
if (!rp) /* should only happenen once, just after context is created */
return;
-
+
r300_translate_fragment_shader(rmesa, rp);
if (!rp->translated) {
fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__);
return;
}
-
+
#define OUTPUT_FIELD(st, reg, field) \
R300_STATECHANGE(rmesa, st); \
for(i=0;i<=rp->alu_end;i++) \
@@ -1884,7 +1912,7 @@ void r300SetupPixelShader(r300ContextPtr rmesa)
static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
-
+
_swrast_InvalidateState(ctx, new_state);
_swsetup_InvalidateState(ctx, new_state);
_vbo_InvalidateState(ctx, new_state);
@@ -1945,7 +1973,7 @@ void r300ResetHwState(r300ContextPtr r300)
r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
r300DepthMask(ctx, ctx->Depth.Mask);
r300DepthFunc(ctx, ctx->Depth.Func);
-
+
/* stencil */
r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
r300StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);
@@ -1957,7 +1985,7 @@ void r300ResetHwState(r300ContextPtr r300)
r300UpdateTextureState(ctx);
// r300_setup_routing(ctx, GL_TRUE);
-
+
#if 0 /* Done in prior to rendering */
if(hw_tcl_on == GL_FALSE){
r300EmitArrays(ctx, GL_TRUE); /* Just do the routing */
@@ -1973,7 +2001,7 @@ void r300ResetHwState(r300ContextPtr r300)
r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
-
+
/* Initialize magic registers
TODO : learn what they really do, or get rid of
those we don't have to touch */
@@ -2038,7 +2066,7 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
- if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) ||
+ if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) ||
(r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R350))
r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_R300
@@ -2097,7 +2125,7 @@ void r300ResetHwState(r300ContextPtr r300)
r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor, ctx->Polygon.OffsetUnits);
r300Enable(ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
-
+
r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
r300->hw.unk42C0.cmd[2] = 0x00000000;
@@ -2153,20 +2181,20 @@ void r300ResetHwState(r300ContextPtr r300)
r300BlendColor(ctx, ctx->Color.BlendColor);
r300->hw.blend_color.cmd[2] = 0;
r300->hw.blend_color.cmd[3] = 0;
-
+
/* Again, r300ClearBuffer uses this */
r300->hw.cb.cmd[R300_CB_OFFSET] = r300->radeon.state.color.drawOffset +
r300->radeon.radeonScreen->fbLocation;
r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.state.color.drawPitch;
-
+
if (r300->radeon.radeonScreen->cpp == 4)
r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
else
r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
-
+
if (r300->radeon.sarea->tiling_enabled)
r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
-
+
r300->hw.unk4E50.cmd[1] = 0;
r300->hw.unk4E50.cmd[2] = 0;
r300->hw.unk4E50.cmd[3] = 0;
@@ -2193,11 +2221,11 @@ void r300ResetHwState(r300ContextPtr r300)
fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
ctx->Visual.depthBits);
exit(-1);
-
+
}
/* z compress? */
//r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
-
+
r300->hw.zstencil_format.cmd[3] = 0x00000003;
r300->hw.zstencil_format.cmd[4] = 0x00000000;
@@ -2205,15 +2233,15 @@ void r300ResetHwState(r300ContextPtr r300)
r300->radeon.radeonScreen->depthOffset +
r300->radeon.radeonScreen->fbLocation;
r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
-
+
if (r300->radeon.sarea->tiling_enabled) {
/* Turn off when clearing buffers ? */
r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTH_TILE_ENABLE;
-
+
if (ctx->Visual.depthBits == 24)
r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTH_MICROTILE_ENABLE;
}
-
+
r300->hw.unk4F28.cmd[1] = 0;
r300->hw.unk4F30.cmd[1] = 0;
@@ -2283,7 +2311,7 @@ void r300InitState(r300ContextPtr r300)
ctx->Visual.depthBits == 24);
memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
-
+
r300ResetHwState(r300);
}
@@ -2329,7 +2357,7 @@ void r300InitStateFuncs(struct dd_function_table* functions)
functions->PolygonOffset = r300PolygonOffset;
functions->PolygonMode = r300PolygonMode;
-
+
functions->RenderMode = r300RenderMode;
}
diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c
index f531b54d11..c527677cd0 100644
--- a/src/mesa/drivers/dri/r300/r300_texmem.c
+++ b/src/mesa/drivers/dri/r300/r300_texmem.c
@@ -303,195 +303,190 @@ static void r300UploadRectSubImage(r300ContextPtr rmesa,
* Upload the texture image associated with texture \a t at the specified
* level at the address relative to \a start.
*/
-static void uploadSubImage( r300ContextPtr rmesa, r300TexObjPtr t,
+static void uploadSubImage( r300ContextPtr rmesa, r300TexObjPtr t,
GLint hwlevel,
GLint x, GLint y, GLint width, GLint height,
GLuint face )
{
- struct gl_texture_image *texImage = NULL;
- GLuint offset;
- GLint imageWidth, imageHeight;
- GLint ret;
- drm_radeon_texture_t tex;
- drm_radeon_tex_image_t tmp;
- const int level = hwlevel + t->base.firstLevel;
-
- if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
- fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
- __FUNCTION__, (void *)t, (void *)t->base.tObj,
- level, width, height, face );
- }
-
- ASSERT(face < 6);
-
- /* Ensure we have a valid texture to upload */
- if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {
- _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);
- return;
- }
-
- texImage = t->base.tObj->Image[face][level];
-
- if ( !texImage ) {
- if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
- return;
- }
- if ( !texImage->Data ) {
- if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
- return;
- }
-
-
- if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
- assert(level == 0);
- assert(hwlevel == 0);
- if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);
- r300UploadRectSubImage( rmesa, t, texImage, x, y, width, height );
- return;
- }
- else if (texImage->IsClientData) {
- if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: image data is in GART client storage\n",
- __FUNCTION__);
- r300UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,
- x, y, width, height );
- return;
- }
- else if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: image data is in normal memory\n",
- __FUNCTION__);
-
-
- imageWidth = texImage->Width;
- imageHeight = texImage->Height;
-
- offset = t->bufAddr + t->base.totalSize / 6 * face;
-
- if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
- GLint imageX = 0;
- GLint imageY = 0;
- GLint blitX = t->image[face][hwlevel].x;
- GLint blitY = t->image[face][hwlevel].y;
- GLint blitWidth = t->image[face][hwlevel].width;
- GLint blitHeight = t->image[face][hwlevel].height;
- fprintf( stderr, " upload image: %d,%d at %d,%d\n",
- imageWidth, imageHeight, imageX, imageY );
- fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
- blitWidth, blitHeight, blitX, blitY );
- fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n",
- (GLuint)offset, hwlevel, level );
- }
-
- t->image[face][hwlevel].data = texImage->Data;
-
- /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
- * NOTE: we're always use a 1KB-wide blit and I8 texture format.
- * We used to use 1, 2 and 4-byte texels and used to use the texture
- * width to dictate the blit width - but that won't work for compressed
- * textures. (Brian)
- * NOTE: can't do that with texture tiling. (sroland)
- */
- tex.offset = offset;
- tex.image = &tmp;
- /* copy (x,y,width,height,data) */
- memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );
-
- if (texImage->TexFormat->TexelBytes > 4) {
- const int log2TexelBytes = (3 + (texImage->TexFormat->TexelBytes >> 4));
- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
- tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
- tex.height = imageHeight;
- tex.width = imageWidth << log2TexelBytes;
- tex.offset += (tmp.x << log2TexelBytes) & ~1023;
- tmp.x = tmp.x % (1024 >> log2TexelBytes);
- tmp.width = tmp.width << log2TexelBytes;
- }
- else if (texImage->TexFormat->TexelBytes) {
- /* use multi-byte upload scheme */
- tex.height = imageHeight;
- tex.width = imageWidth;
- switch(texImage->TexFormat->TexelBytes) {
- case 1:
- tex.format = RADEON_TXFORMAT_I8;
- break;
- case 2:
- tex.format = RADEON_TXFORMAT_AI88;
- break;
- case 4:
- tex.format = RADEON_TXFORMAT_ARGB8888;
- break;
- }
- tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
- tex.offset += tmp.x & ~1023;
- tmp.x = tmp.x % 1024;
-#if 1
- if (t->tile_bits & R300_TXO_MICRO_TILE) {
- /* need something like "tiled coordinates" ? */
- tmp.y = tmp.x / (tex.pitch * 128) * 2;
- tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;
- tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
- }
- else
-#endif
- {
- tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
- }
+ struct gl_texture_image *texImage = NULL;
+ GLuint offset;
+ GLint imageWidth, imageHeight;
+ GLint ret;
+ drm_radeon_texture_t tex;
+ drm_radeon_tex_image_t tmp;
+ const int level = hwlevel + t->base.firstLevel;
+
+ if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
+ fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
+ __FUNCTION__, (void *)t, (void *)t->base.tObj,
+ level, width, height, face );
+ }
+
+ ASSERT(face < 6);
+
+ /* Ensure we have a valid texture to upload */
+ if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {
+ _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);
+ return;
+ }
+
+ texImage = t->base.tObj->Image[face][level];
+
+ if ( !texImage ) {
+ if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
+ return;
+ }
+ if ( !texImage->Data ) {
+ if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
+ return;
+ }
+
+
+ if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
+ assert(level == 0);
+ assert(hwlevel == 0);
+ if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);
+ r300UploadRectSubImage( rmesa, t, texImage, x, y, width, height );
+ return;
+ } else if (texImage->IsClientData) {
+ if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: image data is in GART client storage\n",
+ __FUNCTION__);
+ r300UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,
+ x, y, width, height );
+ return;
+ } else if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: image data is in normal memory\n",
+ __FUNCTION__);
+
+
+ imageWidth = texImage->Width;
+ imageHeight = texImage->Height;
+
+ offset = t->bufAddr + t->base.totalSize / 6 * face;
+
+ if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
+ GLint imageX = 0;
+ GLint imageY = 0;
+ GLint blitX = t->image[face][hwlevel].x;
+ GLint blitY = t->image[face][hwlevel].y;
+ GLint blitWidth = t->image[face][hwlevel].width;
+ GLint blitHeight = t->image[face][hwlevel].height;
+ fprintf( stderr, " upload image: %d,%d at %d,%d\n",
+ imageWidth, imageHeight, imageX, imageY );
+ fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
+ blitWidth, blitHeight, blitX, blitY );
+ fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n",
+ (GLuint)offset, hwlevel, level );
+ }
+
+ t->image[face][hwlevel].data = texImage->Data;
+
+ /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
+ * NOTE: we're always use a 1KB-wide blit and I8 texture format.
+ * We used to use 1, 2 and 4-byte texels and used to use the texture
+ * width to dictate the blit width - but that won't work for compressed
+ * textures. (Brian)
+ * NOTE: can't do that with texture tiling. (sroland)
+ */
+ tex.offset = offset;
+ tex.image = &tmp;
+ /* copy (x,y,width,height,data) */
+ memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );
+
+ if (texImage->TexFormat->TexelBytes > 4) {
+ const int log2TexelBytes = (3 + (texImage->TexFormat->TexelBytes >> 4));
+ tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
+ tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
+ tex.height = imageHeight;
+ tex.width = imageWidth << log2TexelBytes;
+ tex.offset += (tmp.x << log2TexelBytes) & ~1023;
+ tmp.x = tmp.x % (1024 >> log2TexelBytes);
+ tmp.width = tmp.width << log2TexelBytes;
+ } else if (texImage->TexFormat->TexelBytes) {
+ /* use multi-byte upload scheme */
+ tex.height = imageHeight;
+ tex.width = imageWidth;
+ switch(texImage->TexFormat->TexelBytes) {
+ case 1:
+ tex.format = RADEON_TXFORMAT_I8;
+ break;
+ case 2:
+ tex.format = RADEON_TXFORMAT_AI88;
+ break;
+ case 4:
+ tex.format = RADEON_TXFORMAT_ARGB8888;
+ break;
+ }
+ tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
+ tex.offset += tmp.x & ~1023;
+ tmp.x = tmp.x % 1024;
+
+ if (t->tile_bits & R300_TXO_MICRO_TILE) {
+ /* need something like "tiled coordinates" ? */
+ tmp.y = tmp.x / (tex.pitch * 128) * 2;
+ tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;
+ tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
+ } else {
+ tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
+ }
#if 1
- if ((t->tile_bits & R300_TXO_MACRO_TILE) &&
- (texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&
- ((!(t->tile_bits & R300_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||
- (texImage->Height >= 16))) {
- /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
- OR if height is smaller than 8 automatically, but if micro tiling is active
- the limit is height 16 instead ? */
- tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
- }
+ if ((t->tile_bits & R300_TXO_MACRO_TILE) &&
+ (texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&
+ ((!(t->tile_bits & R300_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||
+ (texImage->Height >= 16))) {
+ /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
+ OR if height is smaller than 8 automatically, but if micro tiling is active
+ the limit is height 16 instead ? */
+ tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
+ }
#endif
- }
- else {
- /* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is
- needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
- /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed
- so the kernel module reads the right amount of data. */
- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
- tex.pitch = (R300_BLIT_WIDTH_BYTES / 64);
- tex.height = (imageHeight + 3) / 4;
- tex.width = (imageWidth + 3) / 4;
- if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1)
- {
- tex.width *= 8;
- } else {
- tex.width *= 16;
- }
- }
-
- LOCK_HARDWARE( &rmesa->radeon );
- do {
- ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
- &tex, sizeof(drm_radeon_texture_t) );
- if (ret) {
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
- usleep(1);
- }
- } while ( ret == -EAGAIN );
-
- UNLOCK_HARDWARE( &rmesa->radeon );
-
- if ( ret ) {
- fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );
- fprintf( stderr, " offset=0x%08x\n",
- offset );
- fprintf( stderr, " image width=%d height=%d\n",
- imageWidth, imageHeight );
- fprintf( stderr, " blit width=%d height=%d data=%p\n",
- t->image[face][hwlevel].width, t->image[face][hwlevel].height,
- t->image[face][hwlevel].data );
- exit( 1 );
- }
+ } else {
+ /* In case of for instance 8x8 texture (2x2 dxt blocks),
+ padding after the first two blocks is needed (only
+ with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
+ /* set tex.height to 1/4 since 1 "macropixel" (dxt-block)
+ has 4 real pixels. Needed so the kernel module reads
+ the right amount of data. */
+ tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
+ tex.pitch = (R300_BLIT_WIDTH_BYTES / 64);
+ tex.height = (imageHeight + 3) / 4;
+ tex.width = (imageWidth + 3) / 4;
+ if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1)
+ {
+ tex.width *= 8;
+ } else {
+ tex.width *= 16;
+ }
+ }
+
+ LOCK_HARDWARE( &rmesa->radeon );
+ do {
+ ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
+ &tex, sizeof(drm_radeon_texture_t) );
+ if (ret) {
+ if (RADEON_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
+ usleep(1);
+ }
+ } while ( ret == -EAGAIN );
+
+ UNLOCK_HARDWARE( &rmesa->radeon );
+
+ if ( ret ) {
+ fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );
+ fprintf( stderr, " offset=0x%08x\n",
+ offset );
+ fprintf( stderr, " image width=%d height=%d\n",
+ imageWidth, imageHeight );
+ fprintf( stderr, " blit width=%d height=%d data=%p\n",
+ t->image[face][hwlevel].width, t->image[face][hwlevel].height,
+ t->image[face][hwlevel].data );
+ exit( 1 );
+ }
}
/**
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 4bc0ea14f8..14b0c6063b 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -218,7 +218,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
if (rmesa->texmicrotile && (tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&
/* texrect might be able to use micro tiling too in theory? */
(baseImage->Height > 1)) {
-
+
/* allow 32 (bytes) x 1 mip (which will use two times the space
the non-tiled version would use) max if base texture is large enough */
if ((numLevels == 1) ||
@@ -228,7 +228,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
t->tile_bits |= R300_TXO_MICRO_TILE;
}
}
-
+
if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
/* we can set macro tiling even for small textures, they will be untiled anyway */
t->tile_bits |= R300_TXO_MACRO_TILE;
@@ -237,91 +237,85 @@ static void r300SetTexImages(r300ContextPtr rmesa,
#endif
for (i = 0; i < numLevels; i++) {
- const struct gl_texture_image *texImage;
- GLuint size;
-
- texImage = tObj->Image[0][i + t->base.firstLevel];
- if (!texImage)
- break;
-
- /* find image size in bytes */
- if (texImage->IsCompressed) {
- if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
- // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
- if ((texImage->Width + 3) < 8) /* width one block */
- size = texImage->CompressedSize * 4;
- else if ((texImage->Width + 3) < 16)
- size = texImage->CompressedSize * 2;
- else size = texImage->CompressedSize;
- }
- else /* DXT3/5, 16 bytes per block */
- {
- WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
- // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
- if ((texImage->Width + 3) < 8)
- size = texImage->CompressedSize * 2;
- else size = texImage->CompressedSize;
- }
-
- } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
- size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
- blitWidth = 64 / texelBytes;
- } else if (t->tile_bits & R300_TXO_MICRO_TILE) {
- /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
- though the actual offset may be different (if texture is less than
- 32 bytes width) to the untiled case */
- int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
- size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
- blitWidth = MAX2(texImage->Width, 64 / texelBytes);
- } else {
- int w = (texImage->Width * texelBytes + 31) & ~31;
- size = w * texImage->Height * texImage->Depth;
- blitWidth = MAX2(texImage->Width, 64 / texelBytes);
- }
- assert(size > 0);
-
- if(0)
- fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage->Width, texImage->Height,
- texImage->Depth, texImage->TexFormat->TexelBytes,
- texImage->InternalFormat);
-
- /* Align to 32-byte offset. It is faster to do this unconditionally
- * (no branch penalty).
- */
-
- curOffset = (curOffset + 0x1f) & ~0x1f;
-
- if (texelBytes) {
- t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */
- t->image[0][i].y = 0;
- t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
- t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
- } else {
- t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
- t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
- t->image[0][i].width = MIN2(size, R300_BLIT_WIDTH_BYTES);
- t->image[0][i].height = size / t->image[0][i].width;
- }
-#if 0
- /* for debugging only and only applicable to non-rectangle targets */
- assert(size % t->image[0][i].width == 0);
- assert(t->image[0][i].x == 0
- || (size < R300_BLIT_WIDTH_BYTES
- && t->image[0][i].height == 1));
-#endif
-
- if (0)
- fprintf(stderr,
- "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
- i, texImage->Width, texImage->Height,
- t->image[0][i].x, t->image[0][i].y,
- t->image[0][i].width, t->image[0][i].height,
- size, curOffset);
-
- curOffset += size;
-
+ const struct gl_texture_image *texImage;
+ GLuint size;
+
+ texImage = tObj->Image[0][i + t->base.firstLevel];
+ if (!texImage)
+ break;
+
+ /* find image size in bytes */
+ if (texImage->IsCompressed) {
+ if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
+ // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
+ if ((texImage->Width + 3) < 8) /* width one block */
+ size = texImage->CompressedSize * 4;
+ else if ((texImage->Width + 3) < 16)
+ size = texImage->CompressedSize * 2;
+ else
+ size = texImage->CompressedSize;
+ } else {
+ /* DXT3/5, 16 bytes per block */
+ WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
+ // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
+ if ((texImage->Width + 3) < 8)
+ size = texImage->CompressedSize * 2;
+ else
+ size = texImage->CompressedSize;
+ }
+ } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
+ size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
+ blitWidth = 64 / texelBytes;
+ } else if (t->tile_bits & R300_TXO_MICRO_TILE) {
+ /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
+ though the actual offset may be different (if texture is less than
+ 32 bytes width) to the untiled case */
+ int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
+ size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
+ blitWidth = MAX2(texImage->Width, 64 / texelBytes);
+ } else {
+ int w = (texImage->Width * texelBytes + 31) & ~31;
+ size = w * texImage->Height * texImage->Depth;
+ blitWidth = MAX2(texImage->Width, 64 / texelBytes);
+ }
+ assert(size > 0);
+
+ if(0)
+ fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
+ texImage->Width, texImage->Height,
+ texImage->Depth, texImage->TexFormat->TexelBytes,
+ texImage->InternalFormat);
+
+ /* Align to 32-byte offset. It is faster to do this unconditionally
+ * (no branch penalty).
+ */
+
+ curOffset = (curOffset + 0x1f) & ~0x1f;
+
+ if (texelBytes) {
+ /* fix x and y coords up later together with offset */
+ t->image[0][i].x = curOffset;
+ t->image[0][i].y = 0;
+ t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
+ t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
+ } else {
+ t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
+ t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
+ t->image[0][i].width = MIN2(size, R300_BLIT_WIDTH_BYTES);
+ t->image[0][i].height = size / t->image[0][i].width;
+ }
+
+ if (0)
+ fprintf(stderr,
+ "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
+ i, texImage->Width, texImage->Height,
+ t->image[0][i].x, t->image[0][i].y,
+ t->image[0][i].width, t->image[0][i].height,
+ size, curOffset);
+
+ curOffset += size;
}
-
+
/* Align the total size of texture memory block.
*/
t->base.totalSize =
@@ -361,7 +355,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
} else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
ASSERT(log2Width == log2Height);
t->format |= R300_TX_FORMAT_CUBIC_MAP;
-
+
t->format_x |= R200_TEXCOORD_CUBIC_ENV;
t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
(log2Height << R200_FACE_HEIGHT_1_SHIFT) |
@@ -377,7 +371,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
ASSERT(log2Width == log2Height);
t->format |= R300_TX_FORMAT_CUBIC_MAP;
}
-
+
t->size = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
|((tObj->Image[0][t->base.firstLevel]->Height - 1) << R300_TX_HEIGHTMASK_SHIFT))
|((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT);
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index b513dc8d40..24b19d8eb5 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -363,7 +363,6 @@ static XMesaBuffer
create_xmesa_buffer(XMesaDrawable d, BufferType type,
XMesaVisual vis, XMesaColormap cmap)
{
- GLboolean swAlpha;
XMesaBuffer b;
ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
@@ -421,10 +420,10 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
/* Visual has alpha, but pixel format doesn't support it.
* We'll use an alpha renderbuffer wrapper.
*/
- swAlpha = GL_TRUE;
+ b->swAlpha = GL_TRUE;
}
else {
- swAlpha = GL_FALSE;
+ b->swAlpha = GL_FALSE;
}
/*
@@ -435,9 +434,9 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
vis->mesa_visual.haveDepthBuffer,
vis->mesa_visual.haveStencilBuffer,
vis->mesa_visual.haveAccumBuffer,
- swAlpha,
+ b->swAlpha,
vis->mesa_visual.numAuxBuffers > 0 );
-
+
/* insert buffer into linked list */
b->Next = XMesaBufferList;
XMesaBufferList = b;
@@ -2211,6 +2210,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
);
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
}
+
+ if (b->swAlpha)
+ _mesa_copy_soft_alpha_renderbuffers(ctx, &b->mesa_buffer);
}
#if !defined(XFree86Server)
XSync( b->xm_visual->display, False );
diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c
index c1fa23328f..bb8fe31ce8 100644
--- a/src/mesa/drivers/x11/xm_buffer.c
+++ b/src/mesa/drivers/x11/xm_buffer.c
@@ -422,18 +422,6 @@ xmesa_delete_framebuffer(struct gl_framebuffer *fb)
XMesaDestroyImage( b->rowimage );
}
- /* Note that XMesaBuffer renderbuffers normally have a refcount of 2
- * (creation + binding) so we need to explicitly delete/unbind them here.
- */
- if (b->frontxrb) {
- _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->frontxrb);
- ASSERT(b->frontxrb == NULL);
- }
- if (b->backxrb) {
- _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->backxrb);
- ASSERT(b->backxrb == NULL);
- }
-
_mesa_free_framebuffer_data(fb);
_mesa_free(fb);
}
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index 5516031ffe..85cb6b6636 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -224,6 +224,7 @@ struct xmesa_buffer {
GLint db_mode; /* 0 = single buffered */
/* BACK_PIXMAP = use Pixmap for back buffer */
/* BACK_XIMAGE = use XImage for back buffer */
+ GLboolean swAlpha;
GLuint shm; /* X Shared Memory extension status: */
/* 0 = not available */
diff --git a/src/mesa/main/api_loopback.c b/src/mesa/main/api_loopback.c
index 717ef1fc8f..efe5a77d58 100644
--- a/src/mesa/main/api_loopback.c
+++ b/src/mesa/main/api_loopback.c
@@ -146,7 +146,7 @@ static void GLAPIENTRY
loopback_Color3iv_f( const GLint *v )
{
COLORF( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]),
- INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]) );
+ INT_TO_FLOAT(v[2]), 1.0 );
}
static void GLAPIENTRY
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index f7e870b49c..fefa14e503 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -559,7 +559,7 @@ _mesa_IsRenderbufferEXT(GLuint renderbuffer)
void GLAPIENTRY
_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
{
- struct gl_renderbuffer *newRb, *oldRb;
+ struct gl_renderbuffer *newRb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -593,21 +593,16 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
}
ASSERT(newRb->AllocStorage);
_mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
+ newRb->RefCount = 1; /* referenced by hash table */
}
- newRb->RefCount++;
}
else {
newRb = NULL;
}
- oldRb = ctx->CurrentRenderbuffer;
- if (oldRb) {
- _mesa_unreference_renderbuffer(&oldRb);
- }
-
ASSERT(newRb != &DummyRenderbuffer);
- ctx->CurrentRenderbuffer = newRb;
+ _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
}
@@ -632,14 +627,15 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
_mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
- /* remove from hash table immediately, to free the ID */
+ /* Remove from hash table immediately, to free the ID.
+ * But the object will not be freed until it's no longer
+ * referenced anywhere else.
+ */
_mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
if (rb != &DummyRenderbuffer) {
- /* But the object will not be freed until it's no longer
- * bound in any context.
- */
- _mesa_unreference_renderbuffer(&rb);
+ /* no longer referenced by hash table */
+ _mesa_reference_renderbuffer(&rb, NULL);
}
}
}
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index cd4f594aa2..1fd31a5321 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -70,42 +70,6 @@ compute_depth_max(struct gl_framebuffer *fb)
/**
- * Set the framebuffer's _DepthBuffer field, taking care of
- * reference counts, etc.
- */
-static void
-set_depth_renderbuffer(struct gl_framebuffer *fb,
- struct gl_renderbuffer *rb)
-{
- if (fb->_DepthBuffer) {
- _mesa_unreference_renderbuffer(&fb->_DepthBuffer);
- }
- fb->_DepthBuffer = rb;
- if (rb) {
- rb->RefCount++;
- }
-}
-
-
-/**
- * Set the framebuffer's _StencilBuffer field, taking care of
- * reference counts, etc.
- */
-static void
-set_stencil_renderbuffer(struct gl_framebuffer *fb,
- struct gl_renderbuffer *rb)
-{
- if (fb->_StencilBuffer) {
- _mesa_unreference_renderbuffer(&fb->_StencilBuffer);
- }
- fb->_StencilBuffer = rb;
- if (rb) {
- rb->RefCount++;
- }
-}
-
-
-/**
* Create and initialize a gl_framebuffer object.
* This is intended for creating _window_system_ framebuffers, not generic
* framebuffer objects ala GL_EXT_framebuffer_object.
@@ -223,7 +187,7 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
if (att->Renderbuffer) {
- _mesa_unreference_renderbuffer(&att->Renderbuffer);
+ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
}
if (att->Texture) {
/* render to texture */
@@ -239,9 +203,9 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
att->Texture = NULL;
}
- /* unbind depth/stencil to decr ref counts */
- set_depth_renderbuffer(fb, NULL);
- set_stencil_renderbuffer(fb, NULL);
+ /* unbind _Depth/_StencilBuffer to decr ref counts */
+ _mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL);
+ _mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL);
}
@@ -569,13 +533,13 @@ _mesa_update_depth_buffer(GLcontext *ctx,
/* need to update wrapper */
struct gl_renderbuffer *wrapper
= _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
- set_depth_renderbuffer(fb, wrapper);
+ _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);
ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
}
}
else {
/* depthRb may be null */
- set_depth_renderbuffer(fb, depthRb);
+ _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb);
}
}
@@ -610,13 +574,13 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
/* need to update wrapper */
struct gl_renderbuffer *wrapper
= _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
- set_stencil_renderbuffer(fb, wrapper);
+ _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper);
ASSERT(fb->_StencilBuffer->Wrapped == stencilRb);
}
}
else {
/* stencilRb may be null */
- set_stencil_renderbuffer(fb, stencilRb);
+ _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb);
}
}
diff --git a/src/mesa/main/rbadaptors.c b/src/mesa/main/rbadaptors.c
index 60f4948bec..c1ac0606c8 100644
--- a/src/mesa/main/rbadaptors.c
+++ b/src/mesa/main/rbadaptors.c
@@ -45,7 +45,7 @@ Delete_wrapper(struct gl_renderbuffer *rb)
/* Decrement reference count on the buffer we're wrapping and delete
* it if refcount hits zero.
*/
- _mesa_unreference_renderbuffer(&rb->Wrapped);
+ _mesa_reference_renderbuffer(&rb->Wrapped, NULL);
/* delete myself */
_mesa_delete_renderbuffer(rb);
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index e387c42c34..49706b5251 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -1435,6 +1435,17 @@ put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
}
+static void
+copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
+{
+ ASSERT(dst->_ActualFormat == GL_ALPHA8);
+ ASSERT(src->_ActualFormat == GL_ALPHA8);
+ ASSERT(dst->Width == src->Width);
+ ASSERT(dst->Height == src->Height);
+
+ _mesa_memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte));
+}
+
/**********************************************************************/
/**********************************************************************/
@@ -1462,7 +1473,7 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
rb->ClassID = 0;
rb->Name = name;
- rb->RefCount = 1;
+ rb->RefCount = 0;
rb->Delete = _mesa_delete_renderbuffer;
/* The rest of these should be set later by the caller of this function or
@@ -1766,6 +1777,27 @@ _mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
/**
+ * For framebuffers that use a software alpha channel wrapper
+ * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
+ * copy the back buffer alpha channel into the front buffer alpha channel.
+ */
+void
+_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
+ copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+
+ if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
+ copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
+}
+
+
+/**
* Add a software-based depth renderbuffer to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
@@ -2073,9 +2105,7 @@ _mesa_add_renderbuffer(struct gl_framebuffer *fb,
fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
fb->Attachment[bufferName].Complete = GL_TRUE;
- fb->Attachment[bufferName].Renderbuffer = rb;
-
- rb->RefCount++;
+ _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
}
@@ -2093,38 +2123,55 @@ _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName)
if (!rb)
return;
- _mesa_unreference_renderbuffer(&rb);
+ _mesa_reference_renderbuffer(&rb, NULL);
fb->Attachment[bufferName].Renderbuffer = NULL;
}
/**
- * Decrement a renderbuffer object's reference count and delete it when
- * the refcount hits zero.
- * Note: we pass the address of a pointer.
+ * Set *ptr to point to rb. If *ptr points to another renderbuffer,
+ * dereference that buffer first. The new renderbuffer's refcount will
+ * be incremented. The old renderbuffer's refcount will be decremented.
*/
void
-_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb)
+_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
+ struct gl_renderbuffer *rb)
{
- assert(rb);
- if (*rb) {
+ assert(ptr);
+ if (*ptr == rb) {
+ /* no change */
+ return;
+ }
+
+ if (*ptr) {
+ /* Unreference the old renderbuffer */
GLboolean deleteFlag = GL_FALSE;
+ struct gl_renderbuffer *oldRb = *ptr;
- _glthread_LOCK_MUTEX((*rb)->Mutex);
- ASSERT((*rb)->RefCount > 0);
- (*rb)->RefCount--;
- deleteFlag = ((*rb)->RefCount == 0);
- _glthread_UNLOCK_MUTEX((*rb)->Mutex);
+ _glthread_LOCK_MUTEX(oldRb->Mutex);
+ ASSERT(oldRb->RefCount > 0);
+ oldRb->RefCount--;
+ /*printf("RB DECR %p to %d\n", (void*) oldRb, oldRb->RefCount);*/
+ deleteFlag = (oldRb->RefCount == 0);
+ _glthread_UNLOCK_MUTEX(oldRb->Mutex);
if (deleteFlag)
- (*rb)->Delete(*rb);
+ oldRb->Delete(oldRb);
- *rb = NULL;
+ *ptr = NULL;
}
-}
-
+ assert(!*ptr);
+ if (rb) {
+ /* reference new renderbuffer */
+ _glthread_LOCK_MUTEX(rb->Mutex);
+ rb->RefCount++;
+ /*printf("RB REF %p to %d\n", (void*)rb, rb->RefCount);*/
+ _glthread_UNLOCK_MUTEX(rb->Mutex);
+ *ptr = rb;
+ }
+}
/**
@@ -2148,4 +2195,3 @@ _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
return dsrb;
}
-
diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h
index e1a0a55979..c9bf888548 100644
--- a/src/mesa/main/renderbuffer.h
+++ b/src/mesa/main/renderbuffer.h
@@ -64,6 +64,9 @@ _mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
GLboolean frontLeft, GLboolean backLeft,
GLboolean frontRight, GLboolean backRight);
+extern void
+_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb);
+
extern GLboolean
_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint depthBits);
@@ -99,7 +102,8 @@ extern void
_mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName);
extern void
-_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb);
+_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
+ struct gl_renderbuffer *rb);
extern struct gl_renderbuffer *
_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name);
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 54ae7ce0a1..0c6fa82f11 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -1014,7 +1014,7 @@ create_new_program(GLcontext *ctx, struct state_key *key,
p.program->Base.NumTexIndirections = 1; /* correct? */
p.program->Base.NumTexInstructions = 0;
p.program->Base.NumAluInstructions = 0;
- p.program->Base.String = 0;
+ p.program->Base.String = NULL;
p.program->Base.NumInstructions =
p.program->Base.NumTemporaries =
p.program->Base.NumParameters =
@@ -1103,9 +1103,8 @@ create_new_program(GLcontext *ctx, struct state_key *key,
"generating tex env program");
return;
}
- _mesa_memcpy(program->Base.Instructions, instBuffer,
- sizeof(struct prog_instruction)
- * program->Base.NumInstructions);
+ _mesa_copy_instructions(program->Base.Instructions, instBuffer,
+ program->Base.NumInstructions);
/* Notify driver the fragment program has (actually) changed.
*/
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 543d6efc98..706d346695 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2061,12 +2061,6 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
}
if (teximage->IsCompressed) {
- if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexSubImage%dD(missing readbuffer)", dimensions);
- return GL_TRUE;
- }
-
if (target != GL_TEXTURE_2D) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexSubImage%d(target)", dimensions);
@@ -2096,6 +2090,12 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
+ if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage%dD(missing readbuffer)", dimensions);
+ return GL_TRUE;
+ }
+
if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) {
if (!ctx->ReadBuffer->_DepthBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c
index 8b8bb3a173..63c99ee6ca 100644
--- a/src/mesa/tnl/t_vp_build.c
+++ b/src/mesa/tnl/t_vp_build.c
@@ -1419,9 +1419,8 @@ create_new_program( const struct state_key *key,
else
p.temp_reserved = ~((1<<max_temps)-1);
- p.program->Base.Instructions
- = (struct prog_instruction*) MALLOC(sizeof(struct prog_instruction) * MAX_INSN);
- p.program->Base.String = 0;
+ p.program->Base.Instructions = _mesa_alloc_instructions(MAX_INSN);
+ p.program->Base.String = NULL;
p.program->Base.NumInstructions =
p.program->Base.NumTemporaries =
p.program->Base.NumParameters =