/** * Add an immediate scalar to the constant list, while trying to avoid * duplicates. */ unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float data, unsigned * swizzle) { unsigned index; int free_index = -1; struct rc_constant constant; for(index = 0; index < c->Count; ++index) { if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) { unsigned comp; for(comp = 0; comp < c->Constants[index].Size; ++comp) { if (c->Constants[index].u.Immediate[comp] == data) { *swizzle = RC_MAKE_SWIZZLE(comp, comp, comp, comp); return index; } } if (c->Constants[index].Size < 4) free_index = index; } } if (free_index >= 0) { unsigned comp = c->Constants[free_index].Size++; c->Constants[free_index].u.Immediate[comp] = data; *swizzle = RC_MAKE_SWIZZLE(comp, comp, comp, comp); return free_index; } memset(&constant, 0, sizeof(constant)); constant.Type = RC_CONSTANT_IMMEDIATE; constant.Size = 1; constant.u.Immediate[0] = data; *swizzle = RC_SWIZZLE_XXXX; return rc_constants_add(c, &constant); }
/** * Introduce standard code fragment to deal with fragment.position. */ void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input, int full_vtransform) { unsigned tempregi = rc_find_free_temporary(c); struct rc_instruction * inst_rcp; struct rc_instruction * inst_mul; struct rc_instruction * inst_mad; struct rc_instruction * inst; c->Program.InputsRead &= ~(1 << wpos); c->Program.InputsRead |= 1 << new_input; /* perspective divide */ inst_rcp = rc_insert_new_instruction(c, &c->Program.Instructions); inst_rcp->U.I.Opcode = RC_OPCODE_RCP; inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY; inst_rcp->U.I.DstReg.Index = tempregi; inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W; inst_rcp->U.I.SrcReg[0].File = RC_FILE_INPUT; inst_rcp->U.I.SrcReg[0].Index = new_input; inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW; inst_mul = rc_insert_new_instruction(c, inst_rcp); inst_mul->U.I.Opcode = RC_OPCODE_MUL; inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY; inst_mul->U.I.DstReg.Index = tempregi; inst_mul->U.I.DstReg.WriteMask = RC_MASK_XYZ; inst_mul->U.I.SrcReg[0].File = RC_FILE_INPUT; inst_mul->U.I.SrcReg[0].Index = new_input; inst_mul->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; inst_mul->U.I.SrcReg[1].Index = tempregi; inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW; /* viewport transformation */ inst_mad = rc_insert_new_instruction(c, inst_mul); inst_mad->U.I.Opcode = RC_OPCODE_MAD; inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY; inst_mad->U.I.DstReg.Index = tempregi; inst_mad->U.I.DstReg.WriteMask = RC_MASK_XYZ; inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; inst_mad->U.I.SrcReg[0].Index = tempregi; inst_mad->U.I.SrcReg[0].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO); inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT; inst_mad->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO); inst_mad->U.I.SrcReg[2].File = RC_FILE_CONSTANT; inst_mad->U.I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO); if (full_vtransform) { inst_mad->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_SCALE, 0); inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_OFFSET, 0); } else { inst_mad->U.I.SrcReg[1].Index = inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_WINDOW_DIMENSION, 0); } for (inst = inst_mad->Next; inst != &c->Program.Instructions; inst = inst->Next) { const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); unsigned i; for(i = 0; i < opcode->NumSrcRegs; i++) { if (inst->U.I.SrcReg[i].File == RC_FILE_INPUT && inst->U.I.SrcReg[i].Index == wpos) { inst->U.I.SrcReg[i].File = RC_FILE_TEMPORARY; inst->U.I.SrcReg[i].Index = tempregi; } } } }
static void get_external_state( struct r300_context* r300, struct r300_fragment_program_external_state* state) { struct r300_textures_state *texstate = r300->textures_state.state; struct r300_rs_state *rs = r300->rs_state.state; unsigned i; state->frag_clamp = rs ? rs->rs.clamp_fragment_color : 0; for (i = 0; i < texstate->sampler_state_count; i++) { struct r300_sampler_state *s = texstate->sampler_states[i]; struct r300_sampler_view *v = texstate->sampler_views[i]; struct r300_resource *t; if (!s || !v) { continue; } t = r300_resource(v->base.texture); if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { state->unit[i].compare_mode_enabled = 1; /* Fortunately, no need to translate this. */ state->unit[i].texture_compare_func = s->state.compare_func; } state->unit[i].non_normalized_coords = !s->state.normalized_coords; state->unit[i].convert_unorm_to_snorm = v->base.format == PIPE_FORMAT_RGTC1_SNORM || v->base.format == PIPE_FORMAT_LATC1_SNORM; /* Pass texture swizzling to the compiler, some lowering passes need it. */ if (v->base.format == PIPE_FORMAT_RGTC1_SNORM || v->base.format == PIPE_FORMAT_LATC1_SNORM) { unsigned char swizzle[4]; util_format_compose_swizzles( util_format_description(v->base.format)->swizzle, v->swizzle, swizzle); state->unit[i].texture_swizzle = RC_MAKE_SWIZZLE(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); } else if (state->unit[i].compare_mode_enabled) { state->unit[i].texture_swizzle = RC_MAKE_SWIZZLE(v->swizzle[0], v->swizzle[1], v->swizzle[2], v->swizzle[3]); } /* XXX this should probably take into account STR, not just S. */ if (t->tex.is_npot) { switch (s->state.wrap_s) { case PIPE_TEX_WRAP_REPEAT: state->unit[i].wrap_mode = RC_WRAP_REPEAT; break; case PIPE_TEX_WRAP_MIRROR_REPEAT: state->unit[i].wrap_mode = RC_WRAP_MIRRORED_REPEAT; break; case PIPE_TEX_WRAP_MIRROR_CLAMP: case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: state->unit[i].wrap_mode = RC_WRAP_MIRRORED_CLAMP; break; default: state->unit[i].wrap_mode = RC_WRAP_NONE; } if (t->b.b.b.target == PIPE_TEXTURE_3D) state->unit[i].clamp_and_scale_before_fetch = TRUE; } } }