#include "brw_wm.h"
#include "brw_util.h"
- #include "shader/program.h"
- #include "shader/program_instruction.h"
- #include "shader/arbprogparse.h"
+ #include "shader/prog_parameter.h"
+ #include "shader/prog_print.h"
+ #include "shader/prog_statevars.h"
+
#define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS
* harm and it's not as if the parameter handling isn't a big hack
* anyway.
*/
- static struct prog_src_register search_or_add_param6( struct brw_wm_compile *c,
- GLint s0,
- GLint s1,
- GLint s2,
- GLint s3,
- GLint s4,
- GLint s5)
+ static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
+ GLint s0,
+ GLint s1,
+ GLint s2,
+ GLint s3,
+ GLint s4)
{
struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
- GLint tokens[6];
+ gl_state_index tokens[STATE_LENGTH];
GLuint idx;
tokens[0] = s0;
tokens[1] = s1;
tokens[2] = s2;
tokens[3] = s3;
tokens[4] = s4;
- tokens[5] = s5;
for (idx = 0; idx < paramList->NumParameters; idx++) {
if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR &&
/* 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);
}
struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
GLfloat values[4];
GLuint idx;
+ GLuint swizzle;
values[0] = s0;
values[1] = s1;
return src_reg(PROGRAM_STATE_VAR, idx);
}
- idx = _mesa_add_unnamed_constant( paramList, values, 4 );
-
+ idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
+ /* XXX what about swizzle? */
return src_reg(PROGRAM_STATE_VAR, idx);
}
if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
struct prog_src_register scale =
- search_or_add_param6( c,
+ search_or_add_param5( c,
STATE_INTERNAL,
STATE_TEXRECT_SCALE,
inst->TexSrcUnit,
- 0,0,0 );
+ 0,0 );
tmpcoord = get_temp(c);
struct prog_src_register fog_factor )
{
struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
- struct prog_src_register fogcolor = search_or_add_param6( c, STATE_FOG_COLOR, 0,0,0,0,0 );
+ struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 );
/* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */
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[] = {
/* Else do them here.
*/
- /* scale texture rectangle to 0..1. */
- &_r300_texrect_stage,
&_r300_render_stage,
&_tnl_render_stage, /* FALLBACK */
0,
"def_max_anisotropy");
//r300->texmicrotile = GL_TRUE;
-
+
/* Init default driver functions then plug in our R300-specific functions
* (the texture functions are especially important)
*/
r300InitStateFuncs(&functions);
r300InitTextureFuncs(&functions);
r300InitShaderFuncs(&functions);
-
+
#ifdef USER_BUFFERS
radeon_mm_init(r300);
#endif
if (hw_tcl_on) {
r300_init_vbo_funcs(&functions);
}
-#endif
+#endif
if (!radeonInitContext(&r300->radeon, &functions,
glVisual, driContextPriv, sharedContextPrivate)) {
FREE(r300);
* 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,
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
ctx->Const.FragmentProgram.MaxNativeTexIndirections = PFS_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
_tnl_ProgramCacheInit(ctx);
- ctx->_MaintainTexEnvProgram = GL_TRUE;
+ 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" );
radeonInitSpanFuncs(ctx);
r300InitCmdBuf(r300);
r300InitState(r300);
-
+
#ifdef RADEON_VTXFMT_A
radeon_init_vtxfmt_a(r300);
#endif
/* 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;
}
assert(r300->rmm->u_list[i].h_pending == 0);
-
+
tries = 0;
while(r300->rmm->u_list[i].age > done_age && tries++ < 1000) {
usleep(10);
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) {
} 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) {
_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);
#include "glheader.h"
#include "macros.h"
#include "enums.h"
+ #include "shader/prog_instruction.h"
+ #include "shader/prog_parameter.h"
+ #include "shader/prog_print.h"
- #include "program.h"
- #include "program_instruction.h"
#include "r300_context.h"
#include "r300_fragprog.h"
#include "r300_reg.h"
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 */
} 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
*/
pfs_one, pfs_zero, 0);
free_temp(rp, dest);
}
+
+ /* Free temp register */
+ if (tempreg != 0)
+ free_temp(rp, tempreg);
}
#include "api_arrayelt.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
+ #include "shader/prog_parameter.h"
+ #include "shader/prog_statevars.h"
#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "texformat.h"
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;
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);
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);
}
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 );
r300->hw.fogs.cmd[R300_FOGS_STATE] &=
~R300_FOG_ENABLE;
}
-
+
break;
case GL_ALPHA_TEST:
} else {
#if R200_MERGED
FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
-#endif
+#endif
}
break;
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;
{
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];
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);
}
{
(void)face;
(void)mode;
-
+
r300UpdatePolygonMode(ctx);
}
static void r300ShadeModel(GLcontext * ctx, GLenum mode)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
-
+
R300_STATECHANGE(rmesa, shade);
switch (mode) {
case GL_FLAT:
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);
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;
}
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)
R300_STATECHANGE( rmesa, vpt );
rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
-
+
}
radeonUpdateScissor( 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
= ((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;
}
#endif
}
- static void r300FetchStateParameter(GLcontext *ctx, const enum state_index state[],
- GLfloat *value)
+ static void
+ 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:;
- }
}
/**
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
GLfloat constant = units;
-
+
switch (ctx->Visual.depthBits) {
case 16:
constant *= 4.0;
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;
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;
/* 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;
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);
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);
}
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)))
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
}
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++;
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");
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
| (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)
/* 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)
{
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;
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); \
}
/* 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),
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(
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 ? */
-
+
}
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;
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)
}
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
*/
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++) \
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);
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]);
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 */
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 */
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
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;
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;
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;
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;
ctx->Visual.depthBits == 24);
memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
-
+
r300ResetHwState(r300);
}
functions->PolygonOffset = r300PolygonOffset;
functions->PolygonMode = r300PolygonMode;
-
+
functions->RenderMode = r300RenderMode;
}
#include "glheader.h"
#include "macros.h"
#include "enums.h"
+ #include "prog_parameter.h"
+ #include "prog_instruction.h"
+ #include "prog_print.h"
+ #include "prog_statevars.h"
#include "texenvprogram.h"
- #include "shader/program.h"
- #include "shader/program_instruction.h"
-
/**
* According to Glean's texCombine test, no more than 21 instructions
* are needed. Allow a few extra just in case.
}
- static struct ureg register_param6( struct texenv_fragment_program *p,
+ static struct ureg register_param5( struct texenv_fragment_program *p,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
- GLint s4,
- GLint s5)
+ GLint s4)
{
- GLint tokens[6];
+ gl_state_index tokens[STATE_LENGTH];
GLuint idx;
tokens[0] = s0;
tokens[1] = s1;
tokens[2] = s2;
tokens[3] = s3;
tokens[4] = s4;
- tokens[5] = s5;
idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
return make_ureg(PROGRAM_STATE_VAR, idx);
}
- #define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0)
- #define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0)
- #define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0)
- #define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
+ #define register_param1(p,s0) register_param5(p,s0,0,0,0,0)
+ #define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0)
+ #define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0)
+ #define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0)
static struct ureg register_input( struct texenv_fragment_program *p, GLuint input )
if (dest.file == PROGRAM_TEMPORARY)
p->alu_temps |= 1 << dest.idx;
- p->program->NumAluInstructions++;
+ p->program->Base.NumAluInstructions++;
return dest;
}
inst->TexSrcTarget = tex_idx;
inst->TexSrcUnit = tex_unit;
- p->program->NumTexInstructions++;
+ p->program->Base.NumTexInstructions++;
/* Is this a texture indirection?
*/
(p->temps_output & (1<<coord.idx))) ||
(dest.file == PROGRAM_TEMPORARY &&
(p->alu_temps & (1<<dest.idx)))) {
- p->program->NumTexIndirections++;
+ p->program->Base.NumTexIndirections++;
p->temps_output = 1<<coord.idx;
p->alu_temps = 0;
assert(0); /* KW: texture env crossbar */
GLfloat s3)
{
GLfloat values[4];
- GLuint idx;
+ GLuint idx, swizzle;
values[0] = s0;
values[1] = s1;
values[2] = s2;
values[3] = s3;
- idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 );
+ idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
+ &swizzle );
+ ASSERT(swizzle == SWIZZLE_NOOP);
return make_ureg(PROGRAM_STATE_VAR, idx);
}
*/
p.program->Base.Instructions = instBuffer;
p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
- p.program->NumTexIndirections = 1; /* correct? */
- p.program->NumTexInstructions = 0;
- p.program->NumAluInstructions = 0;
+ 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 =
} else
p.program->FogOption = GL_NONE;
- if (p.program->NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections)
+ if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections)
program_error(&p, "Exceeded max nr indirect texture lookups");
- if (p.program->NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
+ if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
program_error(&p, "Exceeded max TEX instructions");
- if (p.program->NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
+ if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
program_error(&p, "Exceeded max ALU instructions");
ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS);
"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.
*/
return hash;
}
- void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
+
+ /**
+ * If _MaintainTexEnvProgram is set we'll generate a fragment program that
+ * implements the current texture env/combine mode.
+ * This function generates that program and puts it into effect.
+ */
+ void
+ _mesa_UpdateTexEnvProgram( GLcontext *ctx )
{
struct state_key key;
GLuint hash;
const struct gl_fragment_program *prev = ctx->FragmentProgram._Current;
- if (!ctx->FragmentProgram._Enabled) {
+ ASSERT(ctx->FragmentProgram._MaintainTexEnvProgram);
+
+ /* If a conventional fragment program/shader isn't in effect... */
+ if (!ctx->FragmentProgram._Enabled &&
+ !ctx->Shader.CurrentProgram) {
make_state_key(ctx, &key);
hash = hash_key(&key);
ctx->FragmentProgram._Current =
- ctx->_TexEnvProgram =
- search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
-
- if (!ctx->_TexEnvProgram) {
- if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash);
-
- ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
- (struct gl_fragment_program *)
- ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
-
- create_new_program(ctx, &key, ctx->_TexEnvProgram);
+ ctx->FragmentProgram._TexEnvProgram =
+ search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
+
+ if (!ctx->FragmentProgram._TexEnvProgram) {
+ if (0)
+ _mesa_printf("Building new texenv proggy for key %x\n", hash);
+
+ /* create new tex env program */
+ ctx->FragmentProgram._Current =
+ ctx->FragmentProgram._TexEnvProgram =
+ (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
- cache_item(&ctx->Texture.env_fp_cache, hash, &key, ctx->_TexEnvProgram);
- } else {
- if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
+ create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram);
+
+ cache_item(&ctx->Texture.env_fp_cache, hash, &key,
+ ctx->FragmentProgram._TexEnvProgram);
+ }
+ else {
+ if (0)
+ _mesa_printf("Found existing texenv program for key %x\n", hash);
}
}
else {
*/
if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) {
ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
- (struct gl_program *) ctx->FragmentProgram._Current);
+ (struct gl_program *) ctx->FragmentProgram._Current);
}
}
#include "glheader.h"
#include "macros.h"
#include "enums.h"
+ #include "program.h"
+ #include "prog_instruction.h"
+ #include "prog_parameter.h"
+ #include "prog_print.h"
+ #include "prog_statevars.h"
#include "t_context.h" /* NOTE: very light dependency on this */
#include "t_vp_build.h"
- #include "shader/program.h"
- #include "shader/program_instruction.h"
struct state_key {
unsigned light_global_enabled:1;
{
GLfloat values[4];
GLint idx;
+ GLuint swizzle;
values[0] = s0;
values[1] = s1;
values[2] = s2;
values[3] = s3;
- idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 );
+ idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
+ &swizzle );
+ ASSERT(swizzle == SWIZZLE_NOOP);
return make_ureg(PROGRAM_STATE_VAR, idx);
}
return p->identity;
}
- static struct ureg register_param6( struct tnl_program *p,
+ static struct ureg register_param5(struct tnl_program *p,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
- GLint s4,
- GLint s5)
+ GLint s4)
{
- GLint tokens[6];
+ gl_state_index tokens[STATE_LENGTH];
GLint idx;
tokens[0] = s0;
tokens[1] = s1;
tokens[2] = s2;
tokens[3] = s3;
tokens[4] = s4;
- tokens[5] = s5;
idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
return make_ureg(PROGRAM_STATE_VAR, idx);
}
- #define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0)
- #define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0)
- #define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0)
- #define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
+ #define register_param1(p,s0) register_param5(p,s0,0,0,0,0)
+ #define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0)
+ #define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0)
+ #define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0)
- static void register_matrix_param6( struct tnl_program *p,
- GLint s0,
- GLint s1,
- GLint s2,
- GLint s3,
- GLint s4,
- GLint s5,
+ static void register_matrix_param5( struct tnl_program *p,
+ GLint s0, /* modelview, projection, etc */
+ GLint s1, /* texture matrix number */
+ GLint s2, /* first row */
+ GLint s3, /* last row */
+ GLint s4, /* inverse, transpose, etc */
struct ureg *matrix )
{
GLint i;
/* This is a bit sad as the support is there to pull the whole
* matrix out in one go:
*/
- for (i = 0; i <= s4 - s3; i++)
- matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 );
+ for (i = 0; i <= s3 - s2; i++)
+ matrix[i] = register_param5( p, s0, s1, i, i, s4 );
}
p->eye_position = reserve_temp(p);
if (PREFER_DP4) {
- register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3,
- STATE_MATRIX, modelview );
+ register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,
+ 0, modelview );
emit_matrix_transform_vec4(p, p->eye_position, modelview, pos);
}
else {
- register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3,
+ register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,
STATE_MATRIX_TRANSPOSE, modelview );
emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos);
struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL );
struct ureg mvinv[3];
- register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2,
+ register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2,
STATE_MATRIX_INVTRANS, mvinv );
p->eye_normal = reserve_temp(p);
struct ureg mvp[4];
if (PREFER_DP4) {
- register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3,
- STATE_MATRIX, mvp );
+ register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3,
+ 0, mvp );
emit_matrix_transform_vec4( p, hpos, mvp, pos );
}
else {
- register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3,
+ register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3,
STATE_MATRIX_TRANSPOSE, mvp );
emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos );
}
/* Need to add some addtional parameters to allow lighting in object
- * space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye
+ * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye
* space lighting.
*/
static void build_lighting( struct tnl_program *p )
emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
emit_normalize_vec3(p, half, half);
} else {
- half = register_param3(p, STATE_LIGHT, i, STATE_HALF);
+ half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR);
}
}
else {
for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
- if (!(p->state->fragprog_inputs_read & (FRAG_BIT_TEX0<<i)))
+ if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i)))
continue;
if (p->state->unit[i].texgen_enabled ||
out_texgen :
register_input(p, VERT_ATTRIB_TEX0+i));
if (PREFER_DP4) {
- register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i,
- 0, 3, STATE_MATRIX, texmat );
+ register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,
+ 0, texmat );
emit_matrix_transform_vec4( p, out, texmat, in );
}
else {
- register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i,
- 0, 3, STATE_MATRIX_TRANSPOSE, texmat );
+ register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,
+ STATE_MATRIX_TRANSPOSE, texmat );
emit_transpose_matrix_transform_vec4( p, out, texmat, in );
}
}
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 =
GLuint hash;
const struct gl_vertex_program *prev = ctx->VertexProgram._Current;
- if (ctx->VertexProgram._Enabled == GL_FALSE) {
+ if (!ctx->VertexProgram._Current) {
/* Grab all the relevent state and put it in a single structure:
*/
key = make_state_key(ctx);
/* Look for an already-prepared program for this state:
*/
- ctx->_TnlProgram = (struct gl_vertex_program *)
+ ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *)
search_cache( tnl->vp_cache, hash, key, sizeof(*key) );
/* OK, we'll have to build a new one:
*/
- if (!ctx->_TnlProgram) {
+ if (!ctx->VertexProgram._TnlProgram) {
if (0)
_mesa_printf("Build new TNL program\n");
- ctx->_TnlProgram = (struct gl_vertex_program *)
+ ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *)
ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
- create_new_program( key, ctx->_TnlProgram,
+ create_new_program( key, ctx->VertexProgram._TnlProgram,
ctx->Const.VertexProgram.MaxTemps );
if (ctx->Driver.ProgramStringNotify)
ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB,
- &ctx->_TnlProgram->Base );
+ &ctx->VertexProgram._TnlProgram->Base );
- cache_item(tnl->vp_cache, hash, key, ctx->_TnlProgram );
+ cache_item(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram );
}
else {
FREE(key);
if (0)
_mesa_printf("Found existing TNL program for key %x\n", hash);
}
- ctx->VertexProgram._Current = ctx->_TnlProgram;
- }
- else {
- ctx->VertexProgram._Current = ctx->VertexProgram.Current;
+ ctx->VertexProgram._Current = ctx->VertexProgram._TnlProgram;
}
/* Tell the driver about the change. Could define a new target for
* this?
*/
- if (ctx->VertexProgram._Current != prev &&
- ctx->Driver.BindProgram)
+ if (ctx->VertexProgram._Current != prev && ctx->Driver.BindProgram) {
ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
(struct gl_program *) ctx->VertexProgram._Current);
+ }
}
void _tnl_ProgramCacheInit( GLcontext *ctx )