Browse Source

r300: Detangle fragment program compiler from driver-specific structure

This is in preparation of sharing the fragment program compiler with Gallium:
Compiler code is moved into its own directory and modified so that it no
longer depends on driver structures.

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
tags/mesa_7_6_rc1
Nicolai Hähnle 16 years ago
parent
commit
e5bed439be
27 changed files with 669 additions and 577 deletions
  1. 13
    9
      src/mesa/drivers/dri/r300/Makefile
  2. 7
    8
      src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
  3. 49
    0
      src/mesa/drivers/dri/r300/compiler/r300_fragprog.h
  4. 9
    8
      src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
  5. 0
    0
      src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
  6. 0
    0
      src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.h
  7. 315
    0
      src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
  8. 8
    6
      src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
  9. 3
    3
      src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
  10. 8
    6
      src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
  11. 162
    0
      src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
  12. 0
    0
      src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.c
  13. 0
    0
      src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.h
  14. 0
    0
      src/mesa/drivers/dri/r300/compiler/radeon_program.c
  15. 0
    0
      src/mesa/drivers/dri/r300/compiler/radeon_program.h
  16. 0
    0
      src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
  17. 0
    0
      src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h
  18. 0
    0
      src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
  19. 0
    0
      src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
  20. 5
    131
      src/mesa/drivers/dri/r300/r300_context.h
  21. 0
    111
      src/mesa/drivers/dri/r300/r300_fragprog.h
  22. 10
    270
      src/mesa/drivers/dri/r300/r300_fragprog_common.c
  23. 61
    2
      src/mesa/drivers/dri/r300/r300_ioctl.c
  24. 5
    11
      src/mesa/drivers/dri/r300/r300_state.c
  25. 4
    4
      src/mesa/drivers/dri/r300/r300_swtcl.c
  26. 7
    7
      src/mesa/drivers/dri/r300/r300_vertprog.c
  27. 3
    1
      src/mesa/drivers/dri/radeon/radeon_screen.c

+ 13
- 9
src/mesa/drivers/dri/r300/Makefile View File

@@ -38,6 +38,18 @@ RADEON_COMMON_SOURCES = \
radeon_span.c \
radeon_fbo.c

RADEON_COMPILER_SOURCES = \
compiler/radeon_nqssadce.c \
compiler/radeon_program.c \
compiler/radeon_program_alu.c \
compiler/radeon_program_pair.c \
compiler/r3xx_fragprog.c \
compiler/r300_fragprog.c \
compiler/r300_fragprog_swizzle.c \
compiler/r300_fragprog_emit.c \
compiler/r500_fragprog.c \
compiler/r500_fragprog_emit.c \

DRIVER_SOURCES = \
radeon_screen.c \
r300_context.c \
@@ -48,21 +60,13 @@ DRIVER_SOURCES = \
r300_render.c \
r300_tex.c \
r300_texstate.c \
radeon_program.c \
radeon_program_alu.c \
radeon_program_pair.c \
radeon_nqssadce.c \
r300_vertprog.c \
r300_fragprog_common.c \
r300_fragprog.c \
r300_fragprog_swizzle.c \
r300_fragprog_emit.c \
r500_fragprog.c \
r500_fragprog_emit.c \
r300_shader.c \
r300_emit.c \
r300_swtcl.c \
$(RADEON_COMMON_SOURCES) \
$(RADEON_COMPILER_SOURCES) \
$(EGL_SOURCES) \
$(CS_SOURCES)


src/mesa/drivers/dri/r300/r300_fragprog.c → src/mesa/drivers/dri/r300/compiler/r300_fragprog.c View File

@@ -25,12 +25,11 @@
*
*/

#include "r300_fragprog.h"
#include "compiler/r300_fragprog.h"

#include "shader/prog_parameter.h"

#include "r300_context.h"
#include "r300_fragprog_swizzle.h"
#include "r300_reg.h"

static void reset_srcreg(struct prog_src_register* reg)
{
@@ -79,7 +78,7 @@ GLboolean r300_transform_TEX(

if (inst.Opcode != OPCODE_KIL &&
t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
GLuint comparefunc = GL_NEVER + compiler->state.unit[inst.TexSrcUnit].texture_compare_func;

if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
tgt = radeonAppendInstructions(t->Program, 1);
@@ -163,8 +162,8 @@ GLboolean r300_transform_TEX(

if (inst.Opcode != OPCODE_KIL &&
t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
GLuint depthmode = compiler->fp->state.unit[inst.TexSrcUnit].depth_texture_mode;
GLuint comparefunc = GL_NEVER + compiler->state.unit[inst.TexSrcUnit].texture_compare_func;
GLuint depthmode = compiler->state.unit[inst.TexSrcUnit].depth_texture_mode;
int rcptemp = radeonFindFreeTemporary(t);
int pass, fail;

@@ -230,9 +229,9 @@ GLboolean r300_transform_TEX(
}

/* just some random things... */
void r300FragmentProgramDump(union rX00_fragment_program_code *c)
void r300FragmentProgramDump(struct rX00_fragment_program_code *c)
{
struct r300_fragment_program_code *code = &c->r300;
struct r300_fragment_program_code *code = &c->code.r300;
int n, i, j;
static int pc = 0;


+ 49
- 0
src/mesa/drivers/dri/r300/compiler/r300_fragprog.h View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2005 Ben Skeggs.
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

/*
* Authors:
* Ben Skeggs <darktama@iinet.net.au>
* Jerome Glisse <j.glisse@gmail.com>
*/
#ifndef __R300_FRAGPROG_H_
#define __R300_FRAGPROG_H_

#include "shader/program.h"
#include "shader/prog_instruction.h"

#include "compiler/radeon_compiler.h"
#include "compiler/radeon_program.h"


extern GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);

extern void r300FragmentProgramDump(struct rX00_fragment_program_code *c);

extern GLboolean r300_transform_TEX(struct radeon_transform_context *t, struct prog_instruction* orig_inst, void* data);

#endif

src/mesa/drivers/dri/r300/r300_fragprog_emit.c → src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c View File

@@ -38,16 +38,17 @@
* \todo FogOption
*/

#include "r300_fragprog.h"
#include "compiler/r300_fragprog.h"

#include "radeon_program_pair.h"
#include "r300_fragprog_swizzle.h"
#include "r300_reg.h"

#include "compiler/radeon_program_pair.h"
#include "compiler/r300_fragprog_swizzle.h"


#define PROG_CODE \
struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)data; \
struct r300_fragment_program_code *code = &c->code->r300
struct r300_fragment_program_code *code = &c->code->code.r300

#define error(fmt, args...) do { \
fprintf(stderr, "%s::%s(): " fmt "\n", \
@@ -201,7 +202,7 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
if (inst->Alpha.DepthWriteMask) {
code->alu.inst[ip].inst3 |= R300_ALU_DSTA_DEPTH;
code->node[code->cur_node].flags |= R300_W_OUT;
c->fp->writes_depth = GL_TRUE;
c->code->writes_depth = GL_TRUE;
}

return GL_TRUE;
@@ -213,7 +214,7 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
*/
static GLboolean finish_node(struct r300_fragment_program_compiler *c)
{
struct r300_fragment_program_code *code = &c->code->r300;
struct r300_fragment_program_code *code = &c->code->code.r300;
struct r300_fragment_program_node *node = &code->node[code->cur_node];

if (node->alu_end < 0) {
@@ -327,13 +328,13 @@ static const struct radeon_pair_handler pair_handler = {
*/
GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
{
struct r300_fragment_program_code *code = &compiler->code->r300;
struct r300_fragment_program_code *code = &compiler->code->code.r300;

_mesa_bzero(code, sizeof(struct r300_fragment_program_code));
code->node[0].alu_end = -1;
code->node[0].tex_end = -1;

if (!radeonPairProgram(compiler->r300->radeon.glCtx, compiler->program, &pair_handler, compiler))
if (!radeonPairProgram(compiler->ctx, compiler->program, &pair_handler, compiler))
return GL_FALSE;

if (!finish_node(compiler))

src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c → src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c View File


src/mesa/drivers/dri/r300/r300_fragprog_swizzle.h → src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.h View File


+ 315
- 0
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c View File

@@ -0,0 +1,315 @@
/*
* Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */

#include "radeon_compiler.h"

#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "shader/prog_statevars.h"

#include "radeon_nqssadce.h"
#include "radeon_program_alu.h"
#include "r300_fragprog.h"
#include "r300_fragprog_swizzle.h"
#include "r500_fragprog.h"


static void nqssadce_init(struct nqssadce_state* s)
{
s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW;
s->Outputs[FRAG_RESULT_DEPTH].Sourced = WRITEMASK_W;
}

/**
* Transform the program to support fragment.position.
*
* Introduce a small fragment at the start of the program that will be
* the only code that directly reads the FRAG_ATTRIB_WPOS input.
* All other code pieces that reference that input will be rewritten
* to read from a newly allocated temporary.
*
*/
static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
{
GLuint InputsRead = compiler->program->InputsRead;

if (!(InputsRead & FRAG_BIT_WPOS)) {
compiler->code->wpos_attr = FRAG_ATTRIB_MAX;
return;
}

static gl_state_index tokens[STATE_LENGTH] = {
STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0
};
struct prog_instruction *fpi;
GLuint window_index;
int i = 0;

for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
{
if (!(InputsRead & (1 << i))) {
InputsRead &= ~(1 << FRAG_ATTRIB_WPOS);
InputsRead |= 1 << i;
compiler->program->InputsRead = InputsRead;
compiler->code->wpos_attr = i;
break;
}
}

GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY);

_mesa_insert_instructions(compiler->program, 0, 3);
fpi = compiler->program->Instructions;
i = 0;

/* perspective divide */
fpi[i].Opcode = OPCODE_RCP;

fpi[i].DstReg.File = PROGRAM_TEMPORARY;
fpi[i].DstReg.Index = tempregi;
fpi[i].DstReg.WriteMask = WRITEMASK_W;
fpi[i].DstReg.CondMask = COND_TR;

fpi[i].SrcReg[0].File = PROGRAM_INPUT;
fpi[i].SrcReg[0].Index = compiler->code->wpos_attr;
fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW;
i++;

fpi[i].Opcode = OPCODE_MUL;

fpi[i].DstReg.File = PROGRAM_TEMPORARY;
fpi[i].DstReg.Index = tempregi;
fpi[i].DstReg.WriteMask = WRITEMASK_XYZ;
fpi[i].DstReg.CondMask = COND_TR;

fpi[i].SrcReg[0].File = PROGRAM_INPUT;
fpi[i].SrcReg[0].Index = compiler->code->wpos_attr;
fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;

fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY;
fpi[i].SrcReg[1].Index = tempregi;
fpi[i].SrcReg[1].Swizzle = SWIZZLE_WWWW;
i++;

/* viewport transformation */
window_index = _mesa_add_state_reference(compiler->program->Parameters, tokens);

fpi[i].Opcode = OPCODE_MAD;

fpi[i].DstReg.File = PROGRAM_TEMPORARY;
fpi[i].DstReg.Index = tempregi;
fpi[i].DstReg.WriteMask = WRITEMASK_XYZ;
fpi[i].DstReg.CondMask = COND_TR;

fpi[i].SrcReg[0].File = PROGRAM_TEMPORARY;
fpi[i].SrcReg[0].Index = tempregi;
fpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);

fpi[i].SrcReg[1].File = PROGRAM_STATE_VAR;
fpi[i].SrcReg[1].Index = window_index;
fpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);

fpi[i].SrcReg[2].File = PROGRAM_STATE_VAR;
fpi[i].SrcReg[2].Index = window_index;
fpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
i++;

for (; i < compiler->program->NumInstructions; ++i) {
int reg;
for (reg = 0; reg < 3; reg++) {
if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT &&
fpi[i].SrcReg[reg].Index == FRAG_ATTRIB_WPOS) {
fpi[i].SrcReg[reg].File = PROGRAM_TEMPORARY;
fpi[i].SrcReg[reg].Index = tempregi;
}
}
}
}


/**
* Rewrite fragment.fogcoord to use a texture coordinate slot.
* Note that fogcoord is forced into an X001 pattern, and this enforcement
* is done here.
*
* See also the counterpart rewriting for vertex programs.
*/
static void rewriteFog(struct r300_fragment_program_compiler *compiler)
{
struct rX00_fragment_program_code *code = compiler->code;
GLuint InputsRead = compiler->program->InputsRead;
int i;

if (!(InputsRead & FRAG_BIT_FOGC)) {
code->fog_attr = FRAG_ATTRIB_MAX;
return;
}

for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
{
if (!(InputsRead & (1 << i))) {
InputsRead &= ~(1 << FRAG_ATTRIB_FOGC);
InputsRead |= 1 << i;
compiler->program->InputsRead = InputsRead;
code->fog_attr = i;
break;
}
}

{
struct prog_instruction *inst;

inst = compiler->program->Instructions;
while (inst->Opcode != OPCODE_END) {
const int src_regs = _mesa_num_inst_src_regs(inst->Opcode);
for (i = 0; i < src_regs; ++i) {
if (inst->SrcReg[i].File == PROGRAM_INPUT && inst->SrcReg[i].Index == FRAG_ATTRIB_FOGC) {
inst->SrcReg[i].Index = code->fog_attr;
inst->SrcReg[i].Swizzle = combine_swizzles(
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE),
inst->SrcReg[i].Swizzle);
}
}
++inst;
}
}
}


static void rewrite_depth_out(struct gl_program *prog)
{
struct prog_instruction *inst;

for (inst = prog->Instructions; inst->Opcode != OPCODE_END; ++inst) {
if (inst->DstReg.File != PROGRAM_OUTPUT || inst->DstReg.Index != FRAG_RESULT_DEPTH)
continue;

if (inst->DstReg.WriteMask & WRITEMASK_Z) {
inst->DstReg.WriteMask = WRITEMASK_W;
} else {
inst->DstReg.WriteMask = 0;
continue;
}

switch (inst->Opcode) {
case OPCODE_FRC:
case OPCODE_MOV:
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
break;
case OPCODE_ADD:
case OPCODE_MAX:
case OPCODE_MIN:
case OPCODE_MUL:
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
break;
case OPCODE_CMP:
case OPCODE_MAD:
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]);
break;
default:
// Scalar instructions needn't be reswizzled
break;
}
}
}

GLboolean r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
{
GLboolean success = GL_FALSE;

if (c->debug) {
fflush(stdout);
_mesa_printf("Fragment Program: Initial program:\n");
_mesa_print_program(c->program);
fflush(stdout);
}

insert_WPOS_trailer(c);

rewriteFog(c);

rewrite_depth_out(c->program);

if (c->is_r500) {
struct radeon_program_transformation transformations[] = {
{ &r500_transform_TEX, c },
{ &radeonTransformALU, 0 },
{ &radeonTransformDeriv, 0 },
{ &radeonTransformTrigScale, 0 }
};
radeonLocalTransform(c->ctx, c->program, 4, transformations);
} else {
struct radeon_program_transformation transformations[] = {
{ &r300_transform_TEX, c },
{ &radeonTransformALU, 0 },
{ &radeonTransformTrigSimple, 0 }
};
radeonLocalTransform(c->ctx, c->program, 3, transformations);
}

if (c->debug) {
_mesa_printf("Fragment Program: After native rewrite:\n");
_mesa_print_program(c->program);
fflush(stdout);
}

if (c->is_r500) {
struct radeon_nqssadce_descr nqssadce = {
.Init = &nqssadce_init,
.IsNativeSwizzle = &r500FPIsNativeSwizzle,
.BuildSwizzle = &r500FPBuildSwizzle
};
radeonNqssaDce(c->ctx, c->program, &nqssadce);
} else {
struct radeon_nqssadce_descr nqssadce = {
.Init = &nqssadce_init,
.IsNativeSwizzle = &r300FPIsNativeSwizzle,
.BuildSwizzle = &r300FPBuildSwizzle
};
radeonNqssaDce(c->ctx, c->program, &nqssadce);
}

if (c->debug) {
_mesa_printf("Compiler: after NqSSA-DCE:\n");
_mesa_print_program(c->program);
fflush(stdout);
}

if (c->is_r500) {
success = r500BuildFragmentProgramHwCode(c);
} else {
success = r300BuildFragmentProgramHwCode(c);
}

if (!success || c->debug) {
if (c->is_r500) {
r500FragmentProgramDump(c->code);
} else {
r300FragmentProgramDump(c->code);
}
}

return success;
}

src/mesa/drivers/dri/r300/r500_fragprog.c → src/mesa/drivers/dri/r300/compiler/r500_fragprog.c View File

@@ -25,7 +25,9 @@
*
*/

#include "r500_fragprog.h"
#include "compiler/r500_fragprog.h"

#include "r300_reg.h"

static void reset_srcreg(struct prog_src_register* reg)
{
@@ -73,7 +75,7 @@ GLboolean r500_transform_TEX(
/* ARB_shadow & EXT_shadow_funcs */
if (inst.Opcode != OPCODE_KIL &&
t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
GLuint comparefunc = GL_NEVER + compiler->state.unit[inst.TexSrcUnit].texture_compare_func;

if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
tgt = radeonAppendInstructions(t->Program, 1);
@@ -119,8 +121,8 @@ GLboolean r500_transform_TEX(

if (inst.Opcode != OPCODE_KIL &&
t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
GLuint depthmode = compiler->fp->state.unit[inst.TexSrcUnit].depth_texture_mode;
GLuint comparefunc = GL_NEVER + compiler->state.unit[inst.TexSrcUnit].texture_compare_func;
GLuint depthmode = compiler->state.unit[inst.TexSrcUnit].depth_texture_mode;
int rcptemp = radeonFindFreeTemporary(t);
int pass, fail;

@@ -375,9 +377,9 @@ static char *to_texop(int val)
return NULL;
}

void r500FragmentProgramDump(union rX00_fragment_program_code *c)
void r500FragmentProgramDump(struct rX00_fragment_program_code *c)
{
struct r500_fragment_program_code *code = &c->r500;
struct r500_fragment_program_code *code = &c->code.r500;
fprintf(stderr, "R500 Fragment Program:\n--------\n");

int n;

src/mesa/drivers/dri/r300/r500_fragprog.h → src/mesa/drivers/dri/r300/compiler/r500_fragprog.h View File

@@ -36,12 +36,12 @@
#include "shader/prog_parameter.h"
#include "shader/prog_instruction.h"

#include "r300_context.h"
#include "radeon_nqssadce.h"
#include "compiler/radeon_compiler.h"
#include "compiler/radeon_nqssadce.h"

extern GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);

extern void r500FragmentProgramDump(union rX00_fragment_program_code *c);
extern void r500FragmentProgramDump(struct rX00_fragment_program_code *c);

extern GLboolean r500FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg);


src/mesa/drivers/dri/r300/r500_fragprog_emit.c → src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c View File

@@ -43,14 +43,16 @@
*
*/

#include "r500_fragprog.h"
#include "compiler/r500_fragprog.h"

#include "radeon_program_pair.h"
#include "r300_reg.h"

#include "compiler/radeon_program_pair.h"


#define PROG_CODE \
struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)data; \
struct r500_fragment_program_code *code = &c->code->r500
struct r500_fragment_program_code *code = &c->code->code.r500

#define error(fmt, args...) do { \
fprintf(stderr, "%s::%s(): " fmt "\n", \
@@ -202,7 +204,7 @@ static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst)
code->inst[ip].inst0 |= (inst->RGB.OutputWriteMask << 15) | (inst->Alpha.OutputWriteMask << 18);
if (inst->Alpha.DepthWriteMask) {
code->inst[ip].inst4 |= R500_ALPHA_W_OMASK;
c->fp->writes_depth = GL_TRUE;
c->code->writes_depth = GL_TRUE;
}

code->inst[ip].inst4 |= R500_ALPHA_ADDRD(inst->Alpha.DestIndex);
@@ -301,14 +303,14 @@ static const struct radeon_pair_handler pair_handler = {

GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
{
struct r500_fragment_program_code *code = &compiler->code->r500;
struct r500_fragment_program_code *code = &compiler->code->code.r500;

_mesa_bzero(code, sizeof(*code));
code->max_temp_idx = 1;
code->inst_offset = 0;
code->inst_end = -1;

if (!radeonPairProgram(compiler->r300->radeon.glCtx, compiler->program, &pair_handler, compiler))
if (!radeonPairProgram(compiler->ctx, compiler->program, &pair_handler, compiler))
return GL_FALSE;

if ((code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) {

+ 162
- 0
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h View File

@@ -0,0 +1,162 @@
/*
* Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */

#ifndef RADEON_COMPILER_H
#define RADEON_COMPILER_H

#include "main/mtypes.h"
#include "shader/prog_instruction.h"

#define R300_PFS_MAX_ALU_INST 64
#define R300_PFS_MAX_TEX_INST 32
#define R300_PFS_MAX_TEX_INDIRECT 4
#define R300_PFS_NUM_TEMP_REGS 32
#define R300_PFS_NUM_CONST_REGS 32

#define R500_PFS_MAX_INST 512
#define R500_PFS_NUM_TEMP_REGS 128
#define R500_PFS_NUM_CONST_REGS 256


#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
#define STATE_R300_TEXRECT_FACTOR (STATE_INTERNAL_DRIVER+1)


/**
* Stores state that influences the compilation of a fragment program.
*/
struct r300_fragment_program_external_state {
struct {
/**
* If the sampler is used as a shadow sampler,
* this field is:
* 0 - GL_LUMINANCE
* 1 - GL_INTENSITY
* 2 - GL_ALPHA
* depending on the depth texture mode.
*/
GLuint depth_texture_mode : 2;

/**
* If the sampler is used as a shadow sampler,
* this field is (texture_compare_func - GL_NEVER).
* [e.g. if compare function is GL_LEQUAL, this field is 3]
*
* Otherwise, this field is 0.
*/
GLuint texture_compare_func : 3;
} unit[16];
};



struct r300_fragment_program_node {
int tex_offset; /**< first tex instruction */
int tex_end; /**< last tex instruction, relative to tex_offset */
int alu_offset; /**< first ALU instruction */
int alu_end; /**< last ALU instruction, relative to alu_offset */
int flags;
};

/**
* Stores an R300 fragment program in its compiled-to-hardware form.
*/
struct r300_fragment_program_code {
struct {
int length; /**< total # of texture instructions used */
GLuint inst[R300_PFS_MAX_TEX_INST];
} tex;

struct {
int length; /**< total # of ALU instructions used */
struct {
GLuint inst0;
GLuint inst1;
GLuint inst2;
GLuint inst3;
} inst[R300_PFS_MAX_ALU_INST];
} alu;

struct r300_fragment_program_node node[4];
int cur_node;
int first_node_has_tex;

/**
* Remember which program register a given hardware constant
* belongs to.
*/
struct prog_src_register constant[R300_PFS_NUM_CONST_REGS];
int const_nr;

int max_temp_idx;
};


struct r500_fragment_program_code {
struct {
GLuint inst0;
GLuint inst1;
GLuint inst2;
GLuint inst3;
GLuint inst4;
GLuint inst5;
} inst[R500_PFS_MAX_INST];

int inst_offset;
int inst_end;

/**
* Remember which program register a given hardware constant
* belongs to.
*/
struct prog_src_register constant[R500_PFS_NUM_CONST_REGS];
int const_nr;

int max_temp_idx;
};

struct rX00_fragment_program_code {
union {
struct r300_fragment_program_code r300;
struct r500_fragment_program_code r500;
} code;

GLboolean writes_depth;

/* attribute that we are sending the WPOS in */
gl_frag_attrib wpos_attr;
/* attribute that we are sending the fog coordinate in */
gl_frag_attrib fog_attr;
};

struct r300_fragment_program_compiler {
GLcontext * ctx;
struct rX00_fragment_program_code *code;
struct gl_program *program;
struct r300_fragment_program_external_state state;
GLboolean is_r500;
GLboolean debug;
};

GLboolean r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c);

#endif /* RADEON_COMPILER_H */

src/mesa/drivers/dri/r300/radeon_nqssadce.c → src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.c View File


src/mesa/drivers/dri/r300/radeon_nqssadce.h → src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.h View File


src/mesa/drivers/dri/r300/radeon_program.c → src/mesa/drivers/dri/r300/compiler/radeon_program.c View File


src/mesa/drivers/dri/r300/radeon_program.h → src/mesa/drivers/dri/r300/compiler/radeon_program.h View File


src/mesa/drivers/dri/r300/radeon_program_alu.c → src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c View File


src/mesa/drivers/dri/r300/radeon_program_alu.h → src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h View File


src/mesa/drivers/dri/r300/radeon_program_pair.c → src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c View File


src/mesa/drivers/dri/r300/radeon_program_pair.h → src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h View File


+ 5
- 131
src/mesa/drivers/dri/r300/r300_context.h View File

@@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "main/mtypes.h"
#include "shader/prog_instruction.h"
#include "compiler/radeon_compiler.h"

struct r300_context;
typedef struct r300_context r300ContextRec;
@@ -396,9 +397,6 @@ struct r300_hw_state {
/* Can be tested with colormat currently. */
#define VSF_MAX_FRAGMENT_TEMPS (14)

#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
#define STATE_R300_TEXRECT_FACTOR (STATE_INTERNAL_DRIVER+1)

#define COLOR_IS_RGBA
#define TAG(x) r300##x
#include "tnl_dd/t_dd_vertex.h"
@@ -413,7 +411,7 @@ struct r300_vertex_program {
GLuint FogAttr;
GLuint WPosAttr;
} key;
struct r300_vertex_shader_hw_code {
int length;
union {
@@ -441,110 +439,6 @@ struct r300_vertex_program_cont {
struct r300_vertex_program *progs;
};

#define R300_PFS_MAX_ALU_INST 64
#define R300_PFS_MAX_TEX_INST 32
#define R300_PFS_MAX_TEX_INDIRECT 4
#define R300_PFS_NUM_TEMP_REGS 32
#define R300_PFS_NUM_CONST_REGS 32

#define R500_PFS_MAX_INST 512
#define R500_PFS_NUM_TEMP_REGS 128
#define R500_PFS_NUM_CONST_REGS 256

struct r300_pfs_compile_state;
struct r500_pfs_compile_state;

/**
* Stores state that influences the compilation of a fragment program.
*/
struct r300_fragment_program_external_state {
struct {
/**
* If the sampler is used as a shadow sampler,
* this field is:
* 0 - GL_LUMINANCE
* 1 - GL_INTENSITY
* 2 - GL_ALPHA
* depending on the depth texture mode.
*/
GLuint depth_texture_mode : 2;

/**
* If the sampler is used as a shadow sampler,
* this field is (texture_compare_func - GL_NEVER).
* [e.g. if compare function is GL_LEQUAL, this field is 3]
*
* Otherwise, this field is 0.
*/
GLuint texture_compare_func : 3;
} unit[16];
};


struct r300_fragment_program_node {
int tex_offset; /**< first tex instruction */
int tex_end; /**< last tex instruction, relative to tex_offset */
int alu_offset; /**< first ALU instruction */
int alu_end; /**< last ALU instruction, relative to alu_offset */
int flags;
};

/**
* Stores an R300 fragment program in its compiled-to-hardware form.
*/
struct r300_fragment_program_code {
struct {
int length; /**< total # of texture instructions used */
GLuint inst[R300_PFS_MAX_TEX_INST];
} tex;

struct {
int length; /**< total # of ALU instructions used */
struct {
GLuint inst0;
GLuint inst1;
GLuint inst2;
GLuint inst3;
} inst[R300_PFS_MAX_ALU_INST];
} alu;

struct r300_fragment_program_node node[4];
int cur_node;
int first_node_has_tex;

/**
* Remember which program register a given hardware constant
* belongs to.
*/
struct prog_src_register constant[R300_PFS_NUM_CONST_REGS];
int const_nr;

int max_temp_idx;
};


struct r500_fragment_program_code {
struct {
GLuint inst0;
GLuint inst1;
GLuint inst2;
GLuint inst3;
GLuint inst4;
GLuint inst5;
} inst[R500_PFS_MAX_INST];

int inst_offset;
int inst_end;

/**
* Remember which program register a given hardware constant
* belongs to.
*/
struct prog_src_register constant[R500_PFS_NUM_CONST_REGS];
int const_nr;

int max_temp_idx;
};

/**
* Store everything about a fragment program that is needed
@@ -555,22 +449,10 @@ struct r300_fragment_program {

GLboolean translated;
GLboolean error;

struct r300_fragment_program_external_state state;
union rX00_fragment_program_code {
struct r300_fragment_program_code r300;
struct r500_fragment_program_code r500;
} code;

GLboolean writes_depth;
GLuint optimization;

struct r300_fragment_program *next;
struct r300_fragment_program_external_state state;

/* attribute that we are sending the WPOS in */
gl_frag_attrib wpos_attr;
/* attribute that we are sending the fog coordinate in */
gl_frag_attrib fog_attr;
struct rX00_fragment_program_code code;
};

struct r300_fragment_program_cont {
@@ -583,12 +465,6 @@ struct r300_fragment_program_cont {
struct r300_fragment_program *progs;
};

struct r300_fragment_program_compiler {
r300ContextPtr r300;
struct r300_fragment_program *fp;
union rX00_fragment_program_code *code;
struct gl_program *program;
};

#define R300_MAX_AOS_ARRAYS 16

@@ -610,8 +486,6 @@ struct r300_swtcl_info {
struct r300_vtable {
void (* SetupRSUnit)(GLcontext *ctx);
void (* SetupFragmentShaderTextures)(GLcontext *ctx, int *tmu_mappings);
GLboolean (* BuildFragmentProgramHwCode)(struct r300_fragment_program_compiler *compiler);
void (* FragmentProgramDump)(union rX00_fragment_program_code *code);
void (* SetupPixelShader)(GLcontext *ctx);
};

@@ -669,7 +543,7 @@ struct r300_context {
uint32_t s3tc_force_disabled:1;
uint32_t stencil_two_side_disabled:1;
} options;
struct r300_swtcl_info swtcl;
struct r300_vertex_buffer vbuf;
struct r300_index_buffer ind_buf;

+ 0
- 111
src/mesa/drivers/dri/r300/r300_fragprog.h View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) 2005 Ben Skeggs.
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

/*
* Authors:
* Ben Skeggs <darktama@iinet.net.au>
* Jerome Glisse <j.glisse@gmail.com>
*/
#ifndef __R300_FRAGPROG_H_
#define __R300_FRAGPROG_H_

#include "shader/program.h"
#include "shader/prog_instruction.h"

#include "r300_context.h"
#include "radeon_program.h"

#define DRI_CONF_FP_OPTIMIZATION_SPEED 0
#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1

#if 1

/**
* Fragment program helper macros
*/

/* Produce unshifted source selectors */
#define FP_TMP(idx) (idx)
#define FP_CONST(idx) ((idx) | (1 << 5))

/* Produce source/dest selector dword */
#define FP_SELC_MASK_NO 0
#define FP_SELC_MASK_X 1
#define FP_SELC_MASK_Y 2
#define FP_SELC_MASK_XY 3
#define FP_SELC_MASK_Z 4
#define FP_SELC_MASK_XZ 5
#define FP_SELC_MASK_YZ 6
#define FP_SELC_MASK_XYZ 7

#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
(((destidx) << R300_ALU_DSTC_SHIFT) | \
(FP_SELC_MASK_##regmask << 23) | \
(FP_SELC_MASK_##outmask << 26) | \
((src0) << R300_ALU_SRC0C_SHIFT) | \
((src1) << R300_ALU_SRC1C_SHIFT) | \
((src2) << R300_ALU_SRC2C_SHIFT))

#define FP_SELA_MASK_NO 0
#define FP_SELA_MASK_W 1

#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
(((destidx) << R300_ALU_DSTA_SHIFT) | \
(FP_SELA_MASK_##regmask << 23) | \
(FP_SELA_MASK_##outmask << 24) | \
((src0) << R300_ALU_SRC0A_SHIFT) | \
((src1) << R300_ALU_SRC1A_SHIFT) | \
((src2) << R300_ALU_SRC2A_SHIFT))

/* Produce unshifted argument selectors */
#define FP_ARGC(source) R300_ALU_ARGC_##source
#define FP_ARGA(source) R300_ALU_ARGA_##source
#define FP_ABS(arg) ((arg) | (1 << 6))
#define FP_NEG(arg) ((arg) ^ (1 << 5))

/* Produce instruction dword */
#define FP_INSTRC(opcode,arg0,arg1,arg2) \
(R300_ALU_OUTC_##opcode | \
((arg0) << R300_ALU_ARG0C_SHIFT) | \
((arg1) << R300_ALU_ARG1C_SHIFT) | \
((arg2) << R300_ALU_ARG2C_SHIFT))

#define FP_INSTRA(opcode,arg0,arg1,arg2) \
(R300_ALU_OUTA_##opcode | \
((arg0) << R300_ALU_ARG0A_SHIFT) | \
((arg1) << R300_ALU_ARG1A_SHIFT) | \
((arg2) << R300_ALU_ARG2A_SHIFT))

#endif

extern GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);

extern void r300FragmentProgramDump(union rX00_fragment_program_code *c);

extern GLboolean r300_transform_TEX(struct radeon_transform_context *t, struct prog_instruction* orig_inst, void* data);

#endif

+ 10
- 270
src/mesa/drivers/dri/r300/r300_fragprog_common.c View File

@@ -43,175 +43,13 @@
#include "shader/prog_print.h"

#include "r300_state.h"
#include "r300_fragprog.h"
#include "r300_fragprog_swizzle.h"
#include "r500_fragprog.h"

#include "radeon_program.h"
#include "radeon_program_alu.h"
#include "compiler/radeon_program.h"
#include "compiler/radeon_program_alu.h"
#include "compiler/r300_fragprog_swizzle.h"
#include "compiler/r300_fragprog.h"
#include "compiler/r500_fragprog.h"

static void nqssadce_init(struct nqssadce_state* s)
{
s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW;
s->Outputs[FRAG_RESULT_DEPTH].Sourced = WRITEMASK_W;
}

/**
* Transform the program to support fragment.position.
*
* Introduce a small fragment at the start of the program that will be
* the only code that directly reads the FRAG_ATTRIB_WPOS input.
* All other code pieces that reference that input will be rewritten
* to read from a newly allocated temporary.
*
*/
static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
{
GLuint InputsRead = compiler->fp->Base->InputsRead;

if (!(InputsRead & FRAG_BIT_WPOS)) {
compiler->fp->wpos_attr = FRAG_ATTRIB_MAX;
return;
}

static gl_state_index tokens[STATE_LENGTH] = {
STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0
};
struct prog_instruction *fpi;
GLuint window_index;
int i = 0;

for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
{
if (!(InputsRead & (1 << i))) {
InputsRead &= ~(1 << FRAG_ATTRIB_WPOS);
InputsRead |= 1 << i;
compiler->fp->Base->InputsRead = InputsRead;
compiler->fp->wpos_attr = i;
break;
}
}

GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY);

_mesa_insert_instructions(compiler->program, 0, 3);
fpi = compiler->program->Instructions;
i = 0;

/* perspective divide */
fpi[i].Opcode = OPCODE_RCP;

fpi[i].DstReg.File = PROGRAM_TEMPORARY;
fpi[i].DstReg.Index = tempregi;
fpi[i].DstReg.WriteMask = WRITEMASK_W;
fpi[i].DstReg.CondMask = COND_TR;

fpi[i].SrcReg[0].File = PROGRAM_INPUT;
fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr;
fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW;
i++;

fpi[i].Opcode = OPCODE_MUL;

fpi[i].DstReg.File = PROGRAM_TEMPORARY;
fpi[i].DstReg.Index = tempregi;
fpi[i].DstReg.WriteMask = WRITEMASK_XYZ;
fpi[i].DstReg.CondMask = COND_TR;

fpi[i].SrcReg[0].File = PROGRAM_INPUT;
fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr;
fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;

fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY;
fpi[i].SrcReg[1].Index = tempregi;
fpi[i].SrcReg[1].Swizzle = SWIZZLE_WWWW;
i++;

/* viewport transformation */
window_index = _mesa_add_state_reference(compiler->program->Parameters, tokens);

fpi[i].Opcode = OPCODE_MAD;

fpi[i].DstReg.File = PROGRAM_TEMPORARY;
fpi[i].DstReg.Index = tempregi;
fpi[i].DstReg.WriteMask = WRITEMASK_XYZ;
fpi[i].DstReg.CondMask = COND_TR;

fpi[i].SrcReg[0].File = PROGRAM_TEMPORARY;
fpi[i].SrcReg[0].Index = tempregi;
fpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);

fpi[i].SrcReg[1].File = PROGRAM_STATE_VAR;
fpi[i].SrcReg[1].Index = window_index;
fpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);

fpi[i].SrcReg[2].File = PROGRAM_STATE_VAR;
fpi[i].SrcReg[2].Index = window_index;
fpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
i++;

for (; i < compiler->program->NumInstructions; ++i) {
int reg;
for (reg = 0; reg < 3; reg++) {
if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT &&
fpi[i].SrcReg[reg].Index == FRAG_ATTRIB_WPOS) {
fpi[i].SrcReg[reg].File = PROGRAM_TEMPORARY;
fpi[i].SrcReg[reg].Index = tempregi;
}
}
}
}


/**
* Rewrite fragment.fogcoord to use a texture coordinate slot.
* Note that fogcoord is forced into an X001 pattern, and this enforcement
* is done here.
*
* See also the counterpart rewriting for vertex programs.
*/
static void rewriteFog(struct r300_fragment_program_compiler *compiler)
{
struct r300_fragment_program *fp = compiler->fp;
GLuint InputsRead;
int i;

InputsRead = fp->Base->InputsRead;

if (!(InputsRead & FRAG_BIT_FOGC)) {
fp->fog_attr = FRAG_ATTRIB_MAX;
return;
}

for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
{
if (!(InputsRead & (1 << i))) {
InputsRead &= ~(1 << FRAG_ATTRIB_FOGC);
InputsRead |= 1 << i;
fp->Base->InputsRead = InputsRead;
fp->fog_attr = i;
break;
}
}

{
struct prog_instruction *inst;

inst = compiler->program->Instructions;
while (inst->Opcode != OPCODE_END) {
const int src_regs = _mesa_num_inst_src_regs(inst->Opcode);
for (i = 0; i < src_regs; ++i) {
if (inst->SrcReg[i].File == PROGRAM_INPUT && inst->SrcReg[i].Index == FRAG_ATTRIB_FOGC) {
inst->SrcReg[i].Index = fp->fog_attr;
inst->SrcReg[i].Swizzle = combine_swizzles(
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE),
inst->SrcReg[i].Swizzle);
}
}
++inst;
}
}
}

static GLuint build_dtm(GLuint depthmode)
{
@@ -251,121 +89,23 @@ static void build_state(
}
}

static void rewrite_depth_out(struct gl_program *prog)
{
struct prog_instruction *inst;

for (inst = prog->Instructions; inst->Opcode != OPCODE_END; ++inst) {
if (inst->DstReg.File != PROGRAM_OUTPUT || inst->DstReg.Index != FRAG_RESULT_DEPTH)
continue;

if (inst->DstReg.WriteMask & WRITEMASK_Z) {
inst->DstReg.WriteMask = WRITEMASK_W;
} else {
inst->DstReg.WriteMask = 0;
continue;
}

switch (inst->Opcode) {
case OPCODE_FRC:
case OPCODE_MOV:
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
break;
case OPCODE_ADD:
case OPCODE_MAX:
case OPCODE_MIN:
case OPCODE_MUL:
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
break;
case OPCODE_CMP:
case OPCODE_MAD:
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]);
break;
default:
// Scalar instructions needn't be reswizzled
break;
}
}
}

void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_fragment_program_compiler compiler;

compiler.r300 = r300;
compiler.fp = fp;
compiler.ctx = ctx;
compiler.code = &fp->code;
compiler.state = fp->state;
compiler.program = fp->Base;
compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE;
compiler.debug = (RADEON_DEBUG & DEBUG_PIXEL) ? GL_TRUE : GL_FALSE;

if (RADEON_DEBUG & DEBUG_PIXEL) {
fflush(stdout);
_mesa_printf("Fragment Program: Initial program:\n");
_mesa_print_program(compiler.program);
fflush(stdout);
}

insert_WPOS_trailer(&compiler);

rewriteFog(&compiler);

rewrite_depth_out(compiler.program);

if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
struct radeon_program_transformation transformations[] = {
{ &r500_transform_TEX, &compiler },
{ &radeonTransformALU, 0 },
{ &radeonTransformDeriv, 0 },
{ &radeonTransformTrigScale, 0 }
};
radeonLocalTransform(ctx, compiler.program, 4, transformations);
} else {
struct radeon_program_transformation transformations[] = {
{ &r300_transform_TEX, &compiler },
{ &radeonTransformALU, 0 },
{ &radeonTransformTrigSimple, 0 }
};
radeonLocalTransform(ctx, compiler.program, 3, transformations);
}

if (RADEON_DEBUG & DEBUG_PIXEL) {
_mesa_printf("Fragment Program: After native rewrite:\n");
_mesa_print_program(compiler.program);
fflush(stdout);
}

if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
struct radeon_nqssadce_descr nqssadce = {
.Init = &nqssadce_init,
.IsNativeSwizzle = &r500FPIsNativeSwizzle,
.BuildSwizzle = &r500FPBuildSwizzle
};
radeonNqssaDce(ctx, compiler.program, &nqssadce);
} else {
struct radeon_nqssadce_descr nqssadce = {
.Init = &nqssadce_init,
.IsNativeSwizzle = &r300FPIsNativeSwizzle,
.BuildSwizzle = &r300FPBuildSwizzle
};
radeonNqssaDce(ctx, compiler.program, &nqssadce);
}

if (RADEON_DEBUG & DEBUG_PIXEL) {
_mesa_printf("Compiler: after NqSSA-DCE:\n");
_mesa_print_program(compiler.program);
fflush(stdout);
}

if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler))
if (!r3xx_compile_fragment_program(&compiler))
fp->error = GL_TRUE;

fp->translated = GL_TRUE;

if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
r300->vtbl.FragmentProgramDump(&fp->code);
}

struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx)

+ 61
- 2
src/mesa/drivers/dri/r300/r300_ioctl.c View File

@@ -55,7 +55,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_vertprog.h"
#include "radeon_reg.h"
#include "r300_emit.h"
#include "r300_fragprog.h"
#include "r300_context.h"

#include "vblank.h"
@@ -66,6 +65,66 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CLEARBUFFER_DEPTH 0x2
#define CLEARBUFFER_STENCIL 0x4

#if 1

/**
* Fragment program helper macros
*/

/* Produce unshifted source selectors */
#define FP_TMP(idx) (idx)
#define FP_CONST(idx) ((idx) | (1 << 5))

/* Produce source/dest selector dword */
#define FP_SELC_MASK_NO 0
#define FP_SELC_MASK_X 1
#define FP_SELC_MASK_Y 2
#define FP_SELC_MASK_XY 3
#define FP_SELC_MASK_Z 4
#define FP_SELC_MASK_XZ 5
#define FP_SELC_MASK_YZ 6
#define FP_SELC_MASK_XYZ 7

#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
(((destidx) << R300_ALU_DSTC_SHIFT) | \
(FP_SELC_MASK_##regmask << 23) | \
(FP_SELC_MASK_##outmask << 26) | \
((src0) << R300_ALU_SRC0C_SHIFT) | \
((src1) << R300_ALU_SRC1C_SHIFT) | \
((src2) << R300_ALU_SRC2C_SHIFT))

#define FP_SELA_MASK_NO 0
#define FP_SELA_MASK_W 1

#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
(((destidx) << R300_ALU_DSTA_SHIFT) | \
(FP_SELA_MASK_##regmask << 23) | \
(FP_SELA_MASK_##outmask << 24) | \
((src0) << R300_ALU_SRC0A_SHIFT) | \
((src1) << R300_ALU_SRC1A_SHIFT) | \
((src2) << R300_ALU_SRC2A_SHIFT))

/* Produce unshifted argument selectors */
#define FP_ARGC(source) R300_ALU_ARGC_##source
#define FP_ARGA(source) R300_ALU_ARGA_##source
#define FP_ABS(arg) ((arg) | (1 << 6))
#define FP_NEG(arg) ((arg) ^ (1 << 5))

/* Produce instruction dword */
#define FP_INSTRC(opcode,arg0,arg1,arg2) \
(R300_ALU_OUTC_##opcode | \
((arg0) << R300_ALU_ARG0C_SHIFT) | \
((arg1) << R300_ALU_ARG1C_SHIFT) | \
((arg2) << R300_ALU_ARG2C_SHIFT))

#define FP_INSTRA(opcode,arg0,arg1,arg2) \
(R300_ALU_OUTA_##opcode | \
((arg0) << R300_ALU_ARG0A_SHIFT) | \
((arg1) << R300_ALU_ARG1A_SHIFT) | \
((arg2) << R300_ALU_ARG2A_SHIFT))

#endif

static void r300EmitClearState(GLcontext * ctx);

static void r300ClearBuffer(r300ContextPtr r300, int flags,
@@ -546,7 +605,7 @@ static int r300KernelClear(GLcontext *ctx, GLuint flags)

/* Make sure it fits there. */
radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
if (flags & BUFFER_BIT_COLOR0) {
rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,

+ 5
- 11
src/mesa/drivers/dri/r300/r300_state.c View File

@@ -62,8 +62,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_emit.h"
#include "r300_tex.h"
#include "r300_fragprog_common.h"
#include "r300_fragprog.h"
#include "r500_fragprog.h"
#include "r300_render.h"
#include "r300_vertprog.h"

@@ -458,7 +456,7 @@ static GLboolean current_fragment_program_writes_depth(GLcontext* ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);

return ctx->FragmentProgram._Current && r300->selected_fp->writes_depth;
return ctx->FragmentProgram._Current && r300->selected_fp->code.writes_depth;
}

static void r300SetEarlyZState(GLcontext * ctx)
@@ -1230,7 +1228,7 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
int i;
struct r300_fragment_program_code *code = &r300->selected_fp->code.r300;
struct r300_fragment_program_code *code = &r300->selected_fp->code.code.r300;

R300_STATECHANGE(r300, fpt);

@@ -1272,7 +1270,7 @@ static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
int i;
struct r500_fragment_program_code *code = &r300->selected_fp->code.r500;
struct r500_fragment_program_code *code = &r300->selected_fp->code.code.r500;

/* find all the texture instructions and relocate the texture units */
for (i = 0; i < code->inst_end + 1; i++) {
@@ -2063,7 +2061,7 @@ static void r300SetupPixelShader(GLcontext *ctx)
struct r300_fragment_program_code *code;
int i, k;

code = &fp->code.r300;
code = &fp->code.code.r300;

R300_STATECHANGE(rmesa, fpi[0]);
R300_STATECHANGE(rmesa, fpi[1]);
@@ -2137,7 +2135,7 @@ static void r500SetupPixelShader(GLcontext *ctx)
((drm_r300_cmd_header_t *) rmesa->hw.r500fp.cmd)->r500fp.count = 0;
((drm_r300_cmd_header_t *) rmesa->hw.r500fp_const.cmd)->r500fp.count = 0;

code = &fp->code.r500;
code = &fp->code.code.r500;

R300_STATECHANGE(rmesa, fp);
rmesa->hw.fp.cmd[R500_FP_PIXSIZE] = code->max_temp_idx;
@@ -2345,13 +2343,9 @@ void r300InitShaderFunctions(r300ContextPtr r300)
r300->vtbl.SetupRSUnit = r500SetupRSUnit;
r300->vtbl.SetupPixelShader = r500SetupPixelShader;
r300->vtbl.SetupFragmentShaderTextures = r500SetupFragmentShaderTextures;
r300->vtbl.BuildFragmentProgramHwCode = r500BuildFragmentProgramHwCode;
r300->vtbl.FragmentProgramDump = r500FragmentProgramDump;
} else {
r300->vtbl.SetupRSUnit = r300SetupRSUnit;
r300->vtbl.SetupPixelShader = r300SetupPixelShader;
r300->vtbl.SetupFragmentShaderTextures = r300SetupFragmentShaderTextures;
r300->vtbl.BuildFragmentProgramHwCode = r300BuildFragmentProgramHwCode;
r300->vtbl.FragmentProgramDump = r300FragmentProgramDump;
}
}

+ 4
- 4
src/mesa/drivers/dri/r300/r300_swtcl.c View File

@@ -150,16 +150,16 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_
ADD_ATTR(VERT_ATTRIB_POINT_SIZE, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_POINT_SIZE, swiz, MASK_X, 0);
}

if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0;
if (rmesa->selected_fp->code.wpos_attr != FRAG_ATTRIB_MAX) {
int tex_id = rmesa->selected_fp->code.wpos_attr - FRAG_ATTRIB_TEX0;

VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
}

if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0;
if (rmesa->selected_fp->code.fog_attr != FRAG_ATTRIB_MAX) {
int tex_id = rmesa->selected_fp->code.fog_attr - FRAG_ATTRIB_TEX0;

VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];

+ 7
- 7
src/mesa/drivers/dri/r300/r300_vertprog.c View File

@@ -40,7 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "shader/prog_statevars.h"
#include "tnl/tnl.h"

#include "radeon_nqssadce.h"
#include "compiler/radeon_nqssadce.h"
#include "r300_context.h"
#include "r300_state.h"

@@ -1558,12 +1558,12 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
_mesa_insert_mvp_code(ctx, vp->Base);
}

if (r300->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
pos_as_texcoord(&vp->Base->Base, r300->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0);
if (r300->selected_fp->code.wpos_attr != FRAG_ATTRIB_MAX) {
pos_as_texcoord(&vp->Base->Base, r300->selected_fp->code.wpos_attr - FRAG_ATTRIB_TEX0);
}

if (r300->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
fog_as_texcoord(&vp->Base->Base, r300->selected_fp->fog_attr - FRAG_ATTRIB_TEX0);
if (r300->selected_fp->code.fog_attr != FRAG_ATTRIB_MAX) {
fog_as_texcoord(&vp->Base->Base, r300->selected_fp->code.fog_attr - FRAG_ATTRIB_TEX0);
}

addArtificialOutputs(ctx, prog);
@@ -1640,8 +1640,8 @@ struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx)

vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
wanted_key.FpReads = r300->selected_fp->Base->InputsRead;
wanted_key.FogAttr = r300->selected_fp->fog_attr;
wanted_key.WPosAttr = r300->selected_fp->wpos_attr;
wanted_key.FogAttr = r300->selected_fp->code.fog_attr;
wanted_key.WPosAttr = r300->selected_fp->code.wpos_attr;

for (vp = vpc->progs; vp; vp = vp->next) {
if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key))

+ 3
- 1
src/mesa/drivers/dri/radeon/radeon_screen.c View File

@@ -57,7 +57,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_tex.h"
#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
#include "r300_context.h"
#include "r300_fragprog.h"
#include "r300_tex.h"
#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
#include "r600_context.h"
@@ -150,6 +149,9 @@ extern const struct dri_extension point_extensions[];

#elif RADEON_COMMON && (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600))

#define DRI_CONF_FP_OPTIMIZATION_SPEED 0
#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1

/* TODO: integrate these into xmlpool.h! */
#define DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(def,min,max) \
DRI_CONF_OPT_BEGIN_V(texture_image_units,int,def, # min ":" # max ) \

Loading…
Cancel
Save