Initial multitexturing support. Old behaviour can be re-enabled by changing ifdefs in r300_setup_rs_unit and r300SetupPixelShader in r300_state.c\nRequires DRM update.
This commit is contained in:
parent
7457a648d2
commit
34dd4843d7
|
@ -630,7 +630,12 @@ struct r300_pixel_shader_program {
|
||||||
#define MAX_PIXEL_SHADER_PARAMS 32
|
#define MAX_PIXEL_SHADER_PARAMS 32
|
||||||
struct r300_pixel_shader_state {
|
struct r300_pixel_shader_state {
|
||||||
struct r300_pixel_shader_program program;
|
struct r300_pixel_shader_program program;
|
||||||
|
|
||||||
|
int translated;
|
||||||
|
int have_sample;
|
||||||
|
GLuint color_reg;
|
||||||
|
GLuint src_previous;
|
||||||
|
|
||||||
/* parameters */
|
/* parameters */
|
||||||
int param_length; /* to limit the number of unnecessary writes */
|
int param_length; /* to limit the number of unnecessary writes */
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -536,8 +536,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||||
// the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
|
// the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
|
||||||
// color register index. */
|
// color register index. */
|
||||||
# define R300_RS_ROUTE_0_COLOR (1 << 14)
|
# define R300_RS_ROUTE_0_COLOR (1 << 14)
|
||||||
# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT (1 << 17)
|
# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17
|
||||||
# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 6) /* GUESS */
|
# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */
|
||||||
/* END */
|
/* END */
|
||||||
|
|
||||||
/* BEGIN: Scissors and cliprects
|
/* BEGIN: Scissors and cliprects
|
||||||
|
|
|
@ -61,6 +61,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include "r300_fixed_pipelines.h"
|
#include "r300_fixed_pipelines.h"
|
||||||
#include "r300_tex.h"
|
#include "r300_tex.h"
|
||||||
#include "r300_maos.h"
|
#include "r300_maos.h"
|
||||||
|
#include "r300_texprog.h"
|
||||||
|
|
||||||
static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
|
static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
|
||||||
{
|
{
|
||||||
|
@ -1380,7 +1381,7 @@ void r300_setup_textures(GLcontext *ctx)
|
||||||
max_texture_unit=i;
|
max_texture_unit=i;
|
||||||
r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
|
r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
|
||||||
|
|
||||||
r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=gen_fixed_filter(t->filter);
|
r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=gen_fixed_filter(t->filter) | (i << 28);
|
||||||
r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=0x0;
|
r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=0x0;
|
||||||
|
|
||||||
/* No idea why linear filtered textures shake when puting random data */
|
/* No idea why linear filtered textures shake when puting random data */
|
||||||
|
@ -1409,14 +1410,57 @@ void r300_setup_textures(GLcontext *ctx)
|
||||||
void r300_setup_rs_unit(GLcontext *ctx)
|
void r300_setup_rs_unit(GLcontext *ctx)
|
||||||
{
|
{
|
||||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||||
int i;
|
int i, cur_reg;
|
||||||
|
GLuint interp_magic[8] = {
|
||||||
|
0x00,
|
||||||
|
0x40,
|
||||||
|
0x80,
|
||||||
|
0xC0,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00
|
||||||
|
};
|
||||||
|
|
||||||
/* This needs to be rewritten - it is a hack at best */
|
/* This needs to be rewritten - it is a hack at best */
|
||||||
|
|
||||||
R300_STATECHANGE(r300, ri);
|
R300_STATECHANGE(r300, ri);
|
||||||
R300_STATECHANGE(r300, rc);
|
R300_STATECHANGE(r300, rc);
|
||||||
R300_STATECHANGE(r300, rr);
|
R300_STATECHANGE(r300, rr);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
cur_reg = 0;
|
||||||
|
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
|
||||||
|
r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0
|
||||||
|
| R300_RS_INTERP_USED
|
||||||
|
| (cur_reg << R300_RS_INTERP_SRC_SHIFT)
|
||||||
|
| interp_magic[i];
|
||||||
|
// fprintf(stderr, "RS_INTERP[%d] = 0x%x\n", i, r300->hw.ri.cmd[R300_RI_INTERP_0+i]);
|
||||||
|
|
||||||
|
if (r300->state.render_inputs & (_TNL_BIT_TEX0<<i)) {
|
||||||
|
r300->hw.rr.cmd[R300_RR_ROUTE_0 + cur_reg] = 0
|
||||||
|
| R300_RS_ROUTE_ENABLE
|
||||||
|
| i /* source INTERP */
|
||||||
|
| (cur_reg << R300_RS_ROUTE_DEST_SHIFT);
|
||||||
|
// fprintf(stderr, "RS_ROUTE[%d] = 0x%x\n", cur_reg, r300->hw.rr.cmd[R300_RR_ROUTE_0 + cur_reg]);
|
||||||
|
cur_reg++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r300->state.render_inputs & _TNL_BIT_COLOR0)
|
||||||
|
r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0
|
||||||
|
| R300_RS_ROUTE_0_COLOR
|
||||||
|
| (cur_reg << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
|
||||||
|
r300->hw.rr.cmd[R300_RR_CMD_0] = cmducs(R300_RS_ROUTE_0, cur_reg);
|
||||||
|
// fprintf(stderr, "ADJ_RR0 = 0x%x\n", r300->hw.rr.cmd[R300_RR_ROUTE_0]);
|
||||||
|
|
||||||
|
// fprintf(stderr, "rendering with %d texture co-ordinate sets\n", cur_reg);
|
||||||
|
|
||||||
|
r300->hw.rc.cmd[1] = 0
|
||||||
|
| (cur_reg /* count */ << R300_RS_CNTL_TC_CNT_SHIFT)
|
||||||
|
| R300_RS_CNTL_0_UNKNOWN_7
|
||||||
|
| R300_RS_CNTL_0_UNKNOWN_18;
|
||||||
|
r300->hw.rc.cmd[2] = (0xC0 | (cur_reg-1) /* index of highest */ );
|
||||||
|
#else
|
||||||
for(i = 1; i <= 8; ++i)
|
for(i = 1; i <= 8; ++i)
|
||||||
r300->hw.ri.cmd[i] = 0x00d10000;
|
r300->hw.ri.cmd[i] = 0x00d10000;
|
||||||
r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
|
r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
|
||||||
|
@ -1455,6 +1499,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
|
||||||
r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
|
r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
|
#define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
|
||||||
|
@ -1815,7 +1860,7 @@ void r300GenerateTexturePixelShader(r300ContextPtr r300)
|
||||||
|
|
||||||
alu_inst++;
|
alu_inst++;
|
||||||
}
|
}
|
||||||
|
|
||||||
r300->state.pixel_shader.program.tex.length=tex_inst;
|
r300->state.pixel_shader.program.tex.length=tex_inst;
|
||||||
r300->state.pixel_shader.program.tex_offset=0;
|
r300->state.pixel_shader.program.tex_offset=0;
|
||||||
r300->state.pixel_shader.program.tex_end=tex_inst-1;
|
r300->state.pixel_shader.program.tex_end=tex_inst-1;
|
||||||
|
@ -1839,12 +1884,16 @@ int i,k;
|
||||||
|
|
||||||
/* textures enabled ? */
|
/* textures enabled ? */
|
||||||
if(rmesa->state.texture.tc_count>0){
|
if(rmesa->state.texture.tc_count>0){
|
||||||
|
#if 1
|
||||||
|
r300GenerateTextureFragmentShader(rmesa);
|
||||||
|
#else
|
||||||
rmesa->state.pixel_shader=SINGLE_TEXTURE_PIXEL_SHADER;
|
rmesa->state.pixel_shader=SINGLE_TEXTURE_PIXEL_SHADER;
|
||||||
r300GenerateTexturePixelShader(rmesa);
|
r300GenerateTexturePixelShader(rmesa);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
rmesa->state.pixel_shader=FLAT_COLOR_PIXEL_SHADER;
|
rmesa->state.pixel_shader=FLAT_COLOR_PIXEL_SHADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
R300_STATECHANGE(rmesa, fpt);
|
R300_STATECHANGE(rmesa, fpt);
|
||||||
for(i=0;i<rmesa->state.pixel_shader.program.tex.length;i++)
|
for(i=0;i<rmesa->state.pixel_shader.program.tex.length;i++)
|
||||||
rmesa->hw.fpt.cmd[R300_FPT_INSTR_0+i]=rmesa->state.pixel_shader.program.tex.inst[i];
|
rmesa->hw.fpt.cmd[R300_FPT_INSTR_0+i]=rmesa->state.pixel_shader.program.tex.inst[i];
|
||||||
|
|
|
@ -0,0 +1,264 @@
|
||||||
|
#include "glheader.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "imports.h"
|
||||||
|
#include "enums.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "dd.h"
|
||||||
|
#include "simple_list.h"
|
||||||
|
|
||||||
|
#include "api_arrayelt.h"
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
#include "swrast_setup/swrast_setup.h"
|
||||||
|
#include "array_cache/acache.h"
|
||||||
|
#include "tnl/tnl.h"
|
||||||
|
#include "texformat.h"
|
||||||
|
|
||||||
|
#include "radeon_ioctl.h"
|
||||||
|
#include "radeon_state.h"
|
||||||
|
#include "r300_context.h"
|
||||||
|
#include "r300_ioctl.h"
|
||||||
|
#include "r300_state.h"
|
||||||
|
#include "r300_reg.h"
|
||||||
|
#include "r300_program.h"
|
||||||
|
#include "r300_emit.h"
|
||||||
|
#include "r300_fixed_pipelines.h"
|
||||||
|
#include "r300_tex.h"
|
||||||
|
#include "pixel_shader.h"
|
||||||
|
#include "r300_texprog.h"
|
||||||
|
|
||||||
|
/* TODO: we probably should have a better way to emit alu instructions */
|
||||||
|
#define INST0 p->alu.inst[p->alu.length].inst0 =
|
||||||
|
#define INST1 p->alu.inst[p->alu.length].inst1 =
|
||||||
|
#define INST2 p->alu.inst[p->alu.length].inst2 =
|
||||||
|
#define INST3 p->alu.inst[p->alu.length].inst3 =
|
||||||
|
#define EMIT_INST p->alu.length++
|
||||||
|
|
||||||
|
void emit_tex(struct r300_pixel_shader_program *p, GLuint dest, GLuint unit, GLuint src)
|
||||||
|
{
|
||||||
|
p->tex.inst[p->tex.length++] = 0
|
||||||
|
| (src << R300_FPITX_SRC_SHIFT)
|
||||||
|
| (dest << R300_FPITX_DST_SHIFT)
|
||||||
|
| (unit << R300_FPITX_IMAGE_SHIFT)
|
||||||
|
/* I don't know if this is needed, but the hardcoded 0x18000 set it, so I will too */
|
||||||
|
| (3 << 15);
|
||||||
|
// fprintf(stderr, "emit texinst: 0x%x\n", p->tex.inst[p->tex.length-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint get_source(struct r300_pixel_shader_state *ps, GLenum src, GLuint unit, GLuint tc_reg) {
|
||||||
|
switch (src) {
|
||||||
|
case GL_TEXTURE:
|
||||||
|
if (!ps->have_sample) {
|
||||||
|
emit_tex(&ps->program, tc_reg, unit, tc_reg);
|
||||||
|
ps->have_sample = 1;
|
||||||
|
}
|
||||||
|
return tc_reg;
|
||||||
|
case GL_CONSTANT:
|
||||||
|
WARN_ONCE("TODO: Implement envcolor\n");
|
||||||
|
return ps->color_reg;
|
||||||
|
case GL_PRIMARY_COLOR:
|
||||||
|
return ps->color_reg;
|
||||||
|
case GL_PREVIOUS:
|
||||||
|
return ps->src_previous;
|
||||||
|
default:
|
||||||
|
WARN_ONCE("Unknown source enum\n");
|
||||||
|
return ps->src_previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint get_temp(struct r300_pixel_shader_program *p)
|
||||||
|
{
|
||||||
|
return p->temp_register_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void emit_texenv_color(r300ContextPtr r300, struct r300_pixel_shader_state *ps,
|
||||||
|
GLuint out, GLenum envmode, GLenum format, GLuint unit, GLuint tc_reg) {
|
||||||
|
struct r300_pixel_shader_program *p = &ps->program;
|
||||||
|
|
||||||
|
const GLuint Cp = get_source(ps, GL_PREVIOUS, unit, tc_reg);
|
||||||
|
const GLuint Cs = get_source(ps, GL_TEXTURE, unit, tc_reg);
|
||||||
|
|
||||||
|
switch(envmode) {
|
||||||
|
case GL_DECAL: /* TODO */
|
||||||
|
case GL_BLEND: /* TODO */
|
||||||
|
case GL_REPLACE:
|
||||||
|
INST0 EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, ZERO);
|
||||||
|
switch (format) {
|
||||||
|
case GL_ALPHA:
|
||||||
|
// Cv = Cp
|
||||||
|
INST1 EASY_PFS_INSTR1(out, Cp, PFS_FLAG_CONST, PFS_FLAG_CONST, ALL, NONE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Cv = Cs
|
||||||
|
INST1 EASY_PFS_INSTR1(out, Cs, PFS_FLAG_CONST, PFS_FLAG_CONST, ALL, NONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_MODULATE:
|
||||||
|
switch (format) {
|
||||||
|
case GL_ALPHA:
|
||||||
|
// Cv = Cp
|
||||||
|
INST0 EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, ZERO);
|
||||||
|
INST1 EASY_PFS_INSTR1(out, Cp, PFS_FLAG_CONST, PFS_FLAG_CONST, ALL, NONE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Cv = CpCs
|
||||||
|
INST0 EASY_PFS_INSTR0(MAD, SRC0C_XYZ, SRC1C_XYZ, ZERO);
|
||||||
|
INST1 EASY_PFS_INSTR1(out, Cp, Cs, PFS_FLAG_CONST, ALL, NONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_ADD:
|
||||||
|
switch (format) {
|
||||||
|
case GL_ALPHA:
|
||||||
|
// Cv = Cp
|
||||||
|
INST0 EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, ZERO);
|
||||||
|
INST1 EASY_PFS_INSTR1(out, Cp, PFS_FLAG_CONST, PFS_FLAG_CONST, ALL, NONE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Cv = Cp + Cs
|
||||||
|
INST0 EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, SRC1C_XYZ);
|
||||||
|
INST1 EASY_PFS_INSTR1(out, Cp, Cs, PFS_FLAG_CONST, ALL, NONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "%s: should never get here!\n", __func__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void emit_texenv_alpha(r300ContextPtr r300, struct r300_pixel_shader_state *ps,
|
||||||
|
GLuint out, GLenum envmode, GLenum format, GLuint unit, GLuint tc_reg) {
|
||||||
|
struct r300_pixel_shader_program *p = &ps->program;
|
||||||
|
|
||||||
|
const GLuint Ap = get_source(ps, GL_PREVIOUS, unit, tc_reg);
|
||||||
|
const GLuint As = get_source(ps, GL_TEXTURE, unit, tc_reg);
|
||||||
|
|
||||||
|
switch(envmode) {
|
||||||
|
case GL_DECAL: /* TODO */
|
||||||
|
case GL_BLEND: /* TODO */
|
||||||
|
case GL_REPLACE:
|
||||||
|
INST2 EASY_PFS_INSTR2(MAD, SRC0A, ONE, ZERO);
|
||||||
|
switch (format) {
|
||||||
|
case GL_LUMINANCE:
|
||||||
|
case GL_RGB:
|
||||||
|
// Av = Ap
|
||||||
|
INST3 EASY_PFS_INSTR3(out, Ap, PFS_FLAG_CONST, PFS_FLAG_CONST, REG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
INST3 EASY_PFS_INSTR3(out, As, PFS_FLAG_CONST, PFS_FLAG_CONST, REG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_MODULATE:
|
||||||
|
case GL_ADD:
|
||||||
|
switch (format) {
|
||||||
|
case GL_LUMINANCE:
|
||||||
|
case GL_RGB:
|
||||||
|
// Av = Ap
|
||||||
|
INST2 EASY_PFS_INSTR2(MAD, SRC0A, ONE, ZERO);
|
||||||
|
INST3 EASY_PFS_INSTR3(out, Ap, PFS_FLAG_CONST, PFS_FLAG_CONST, REG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Av = ApAs
|
||||||
|
INST2 EASY_PFS_INSTR2(MAD, SRC0A, SRC1A, ZERO);
|
||||||
|
INST3 EASY_PFS_INSTR3(out, Ap, As, PFS_FLAG_CONST, REG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "%s: should never get here!\n", __func__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint emit_texenv(r300ContextPtr r300, GLuint tc_reg, GLuint unit)
|
||||||
|
{
|
||||||
|
struct r300_pixel_shader_state *ps = &r300->state.pixel_shader;
|
||||||
|
struct r300_pixel_shader_program *p = &ps->program;
|
||||||
|
GLcontext *ctx = r300->radeon.glCtx;
|
||||||
|
struct gl_texture_object *texobj = ctx->Texture.Unit[unit]._Current;
|
||||||
|
GLenum envmode = ctx->Texture.Unit[unit].EnvMode;
|
||||||
|
GLenum format = texobj->Image[0][texobj->BaseLevel]->Format;
|
||||||
|
|
||||||
|
const GLuint out = tc_reg;
|
||||||
|
const GLuint Cf = get_source(ps, GL_PRIMARY_COLOR, unit, tc_reg);
|
||||||
|
|
||||||
|
WARN_ONCE("Texture environments are currently incomplete / wrong! Help me!\n");
|
||||||
|
// fprintf(stderr, "EnvMode = %s\n", _mesa_lookup_enum_by_nr(ctx->Texture.Unit[unit].EnvMode));
|
||||||
|
|
||||||
|
switch (envmode) {
|
||||||
|
case GL_REPLACE:
|
||||||
|
case GL_MODULATE:
|
||||||
|
case GL_DECAL:
|
||||||
|
case GL_BLEND:
|
||||||
|
case GL_ADD:
|
||||||
|
/* Maybe these should be combined? I thought it'd be messy */
|
||||||
|
emit_texenv_color(r300, ps, out, envmode, format, unit, tc_reg);
|
||||||
|
emit_texenv_alpha(r300, ps, out, envmode, format, unit, tc_reg);
|
||||||
|
EMIT_INST;
|
||||||
|
return out;
|
||||||
|
break;
|
||||||
|
case GL_COMBINE:
|
||||||
|
WARN_ONCE("EnvMode == GL_COMBINE unsupported! Help Me!!\n");
|
||||||
|
return Cf;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ONCE("Unknown EnvMode == %d, name=%d\n", envmode,
|
||||||
|
_mesa_lookup_enum_by_nr(envmode));
|
||||||
|
return Cf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void r300GenerateTextureFragmentShader(r300ContextPtr r300)
|
||||||
|
{
|
||||||
|
struct r300_pixel_shader_state *ps = &r300->state.pixel_shader;
|
||||||
|
struct r300_pixel_shader_program *p = &ps->program;
|
||||||
|
GLcontext *ctx = r300->radeon.glCtx;
|
||||||
|
int i, tc_reg;
|
||||||
|
|
||||||
|
p->tex.length = 0;
|
||||||
|
p->alu.length = 0;
|
||||||
|
p->active_nodes = 1;
|
||||||
|
p->first_node_has_tex = 1;
|
||||||
|
p->temp_register_count = r300->state.texture.tc_count + 1; /* texcoords and colour reg */
|
||||||
|
|
||||||
|
ps->color_reg = r300->state.texture.tc_count;
|
||||||
|
ps->src_previous = ps->color_reg;
|
||||||
|
|
||||||
|
tc_reg = 0;
|
||||||
|
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
|
||||||
|
if (r300->state.render_inputs & (_TNL_BIT_TEX0<<i)) {
|
||||||
|
ps->have_sample = 0;
|
||||||
|
ps->src_previous = emit_texenv(r300, tc_reg, i);
|
||||||
|
tc_reg++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do a MOV from last output, to destination reg.. This won't be needed when we
|
||||||
|
* have a better way of emitting alu instructions
|
||||||
|
*/
|
||||||
|
INST0 EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, ZERO);
|
||||||
|
INST1 EASY_PFS_INSTR1(0, ps->src_previous, PFS_FLAG_CONST, PFS_FLAG_CONST, NONE, ALL);
|
||||||
|
INST2 EASY_PFS_INSTR2(MAD, SRC0A, ONE, ZERO);
|
||||||
|
INST3 EASY_PFS_INSTR3(0, ps->src_previous, PFS_FLAG_CONST, PFS_FLAG_CONST, OUTPUT);
|
||||||
|
EMIT_INST;
|
||||||
|
|
||||||
|
p->node[3].tex_end = ps->program.tex.length - 1;
|
||||||
|
p->node[3].tex_offset = 0;
|
||||||
|
p->node[3].alu_end = ps->program.alu.length - 1;
|
||||||
|
p->node[3].alu_offset = 0;
|
||||||
|
|
||||||
|
p->tex_end = ps->program.tex.length - 1;
|
||||||
|
p->tex_offset = 0;
|
||||||
|
p->alu_end = ps->program.alu.length - 1;
|
||||||
|
p->alu_offset = 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef __R300_TEXPROG_H_
|
||||||
|
#define __R300_TEXPROG_H_
|
||||||
|
|
||||||
|
#include "r300_context.h"
|
||||||
|
|
||||||
|
void r300GenerateTextureFragmentShader(r300ContextPtr r300);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue