forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

FP/VP assembler project

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PS3 Development
View previous topic :: View next topic  
Author Message
cnlohr



Joined: 05 Feb 2006
Posts: 24

PostPosted: Thu Nov 22, 2007 3:06 am    Post subject: FP/VP assembler project Reply with quote

Ok, it looks like the next imperative step is to write the assembler for the shading programs. Since I'm new at this, it's a critical step, I've become much more busy, and it would take me much longer than the other devs, I'll recind my request to do this project.

So far it appears there are two really important parts of the headers that are necessary. 1) The definitions and 2) the bit-packed structures. Nouveau has both, but I can only seem to find #1 right now, I'll post #2 as soon as I find it.

*EDIT* NOTE: This list is incomplete for all hardware. It was only the basic stuff out of nouveau_shader.h, we should include nv20_shader.h nv30_shader.h, etc. info as well. Differences are clear in the Vertex shading part. This mostly just deals with the fragment shading part.

So, without further ado, below is the general header for defining the many commands and the different command classes (jump, inst, etc.).

The header:
Code:
#ifndef _SRECOMP_H
#define _SRECOMP_H

//This file contains tons of structures and stuff that
//has been ripped from Nouveau.

struct _nvs_command_set;

typedef enum {
   NVS_FILE_NONE,
   NVS_FILE_TEMP,
   NVS_FILE_ATTRIB,
   NVS_FILE_CONST,
   NVS_FILE_RESULT,
   NVS_FILE_ADDRESS,
   NVS_FILE_UNKNOWN
} nvsRegFile;

typedef enum {
   NVS_SWZ_X = 0,
   NVS_SWZ_Y = 1,
   NVS_SWZ_Z = 2,
   NVS_SWZ_W = 3
} nvsSwzComp;

typedef struct {
   nvsRegFile   file;
   unsigned int      index;

   unsigned int      indexed;
   unsigned int      addr_reg;
   nvsSwzComp      addr_comp;

   nvsSwzComp      swizzle[4];
   int         negate;
   int         abs;
} nvsRegister;

typedef enum {
   NVS_OP_UNKNOWN = 0,
   NVS_OP_NOP,
   NVS_OP_ABS, NVS_OP_ADD, NVS_OP_ARA, NVS_OP_ARL, NVS_OP_ARR,
   NVS_OP_BRA, NVS_OP_BRK,
   NVS_OP_CAL, NVS_OP_CMP, NVS_OP_COS,
   NVS_OP_DDX, NVS_OP_DDY, NVS_OP_DIV, NVS_OP_DP2, NVS_OP_DP2A, NVS_OP_DP3,
   NVS_OP_DP4, NVS_OP_DPH, NVS_OP_DST,
   NVS_OP_EX2, NVS_OP_EXP,
   NVS_OP_FLR, NVS_OP_FRC,
   NVS_OP_IF,
   NVS_OP_KIL,
   NVS_OP_LG2, NVS_OP_LIT, NVS_OP_LOG, NVS_OP_LOOP, NVS_OP_LRP,
   NVS_OP_MAD, NVS_OP_MAX, NVS_OP_MIN, NVS_OP_MOV, NVS_OP_MUL,
   NVS_OP_NRM,
   NVS_OP_PK2H, NVS_OP_PK2US, NVS_OP_PK4B, NVS_OP_PK4UB, NVS_OP_POW,
   NVS_OP_POPA, NVS_OP_PUSHA,
   NVS_OP_RCC, NVS_OP_RCP, NVS_OP_REP, NVS_OP_RET, NVS_OP_RFL, NVS_OP_RSQ,
   NVS_OP_SCS, NVS_OP_SEQ, NVS_OP_SFL, NVS_OP_SGE, NVS_OP_SGT, NVS_OP_SIN,
   NVS_OP_SLE, NVS_OP_SLT, NVS_OP_SNE, NVS_OP_SSG, NVS_OP_STR, NVS_OP_SUB,
   NVS_OP_SWZ,
   NVS_OP_TEX, NVS_OP_TXB, NVS_OP_TXD, NVS_OP_TXL, NVS_OP_TXP,
   NVS_OP_UP2H, NVS_OP_UP2US, NVS_OP_UP4B, NVS_OP_UP4UB,
   NVS_OP_X2D, NVS_OP_XPD,
   NVS_OP_EMUL
} nvsOpcode;

typedef enum {
   NVS_PREC_FLOAT32,
   NVS_PREC_FLOAT16,
   NVS_PREC_FIXED12,
   NVS_PREC_UNKNOWN
} nvsPrecision;

typedef enum {
   NVS_FR_POSITION   = 0,
   NVS_FR_WEIGHT   = 1,
   NVS_FR_NORMAL   = 2,
   NVS_FR_COL0      = 3,
   NVS_FR_COL1      = 4,
   NVS_FR_FOGCOORD   = 5,
   NVS_FR_TEXCOORD0   = 8,
   NVS_FR_TEXCOORD1   = 9,
   NVS_FR_TEXCOORD2   = 10,
   NVS_FR_TEXCOORD3   = 11,
   NVS_FR_TEXCOORD4   = 12,
   NVS_FR_TEXCOORD5   = 13,
   NVS_FR_TEXCOORD6   = 14,
   NVS_FR_TEXCOORD7   = 15,
   NVS_FR_BFC0      = 16,
   NVS_FR_BFC1      = 17,
   NVS_FR_POINTSZ   = 18,
   NVS_FR_FRAGDATA0   = 19,
   NVS_FR_FRAGDATA1   = 20,
   NVS_FR_FRAGDATA2   = 21,
   NVS_FR_FRAGDATA3   = 22,
   NVS_FR_CLIP0      = 23,
   NVS_FR_CLIP1      = 24,
   NVS_FR_CLIP2      = 25,
   NVS_FR_CLIP3      = 26,
   NVS_FR_CLIP4      = 27,
   NVS_FR_CLIP5      = 28,
   NVS_FR_CLIP6      = 29,
   NVS_FR_FACING   = 30,
   NVS_FR_UNKNOWN
} nvsFixedReg;

typedef enum {
   NVS_COND_FL, NVS_COND_LT, NVS_COND_EQ, NVS_COND_LE, NVS_COND_GT,
   NVS_COND_NE, NVS_COND_GE, NVS_COND_TR, NVS_COND_UN,
   NVS_COND_UNKNOWN
} nvsCond;


typedef enum {
   NVS_TEX_TARGET_1D,
   NVS_TEX_TARGET_2D,
   NVS_TEX_TARGET_3D,
   NVS_TEX_TARGET_CUBE,
   NVS_TEX_TARGET_RECT,
   NVS_TEX_TARGET_UNKNOWN = 0
} nvsTexTarget;

typedef enum {
   NVS_SCALE_1X    = 0,
   NVS_SCALE_2X    = 1,
   NVS_SCALE_4X    = 2,
   NVS_SCALE_8X    = 3,
   NVS_SCALE_INV_2X = 5,
   NVS_SCALE_INV_4X = 6,
   NVS_SCALE_INV_8X = 7,
} nvsScale;

/* Arith/TEX instructions */
typedef struct nvs_instruction {
   struct _nvs_command_set * header;

   nvsOpcode   op;
   unsigned int saturate;

   nvsRegister   dest;
   unsigned int   mask;
   nvsScale   dest_scale;

   nvsRegister   src[3];

   unsigned int tex_unit;
   nvsTexTarget tex_target;

   nvsCond   cond;
   nvsSwzComp   cond_swizzle[4];
   int      cond_reg;
   int      cond_test;
   int      cond_update;
} nvsInstruction;


/* BRA, CAL, IF */
typedef struct nvs_branch {
   struct _nvs_command_set *  header;

   nvsOpcode   op;

   nvsCond      cond;
   nvsSwzComp   cond_swizzle[4];
   int      cond_test;

   struct _nvs_command_set *target_head;
   struct _nvs_command_set *target_tail;
   struct _nvs_command_set *else_head;
   struct _nvs_command_set *else_tail;
} nvsBranch;

/* LOOP+ENDLOOP */
typedef struct {
   struct _nvs_command_set *  header;

   int                count;
   int                initial;
   int                increment;

   struct _nvs_command_set *insn_head;
   struct _nvs_command_set *insn_tail;
} nvsLoop;

/* label+following instructions */
typedef struct nvs_subroutine {
   struct _nvs_command_set *  header;

   char *             label;
   struct _nvs_command_set *insn_head;
   struct _nvs_command_set *insn_tail;
} nvsSubroutine;


typedef struct _nvs_command_set
{
   struct _nvs_command_set * parent;
   struct _nvs_command_set * prev;
   struct _nvs_command_set * next;
   enum {
      NVS_INSTRUCTION,
      NVS_BRANCH,
      NVS_LOOP,
      NVS_SUBROUTINE
   } type;
   union {
      nvsInstruction I;
      nvsBranch B;
      nvsLoop L;
      nvsSubroutine S;
   } data;
} nvsCommandSet;



//Now we get to the good stuff
//Compile an arbfp10 program
nvsCommandSet * AssembleShader( const char * shader );




#endif

/*
 * Copyright (C) 2006 Ben Skeggs
 * Copyright (C) 2007 Charles Lohr (mostly reformatting, no new content)
 *
 * 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>
 */


The .c file.
Code:
#include "srecomp.h"


struct _opcode_info
{
   const char *name;
   int numsrc;
   int flags;
};

#define CHECK_RANGE(idx, arr) ((idx)<sizeof(_##arr)/sizeof(const char *)) \
   ? _##arr[(idx)] : #arr"_OOB"

#define NODS      (1<<0)
#define BRANCH_TR (1<<1)
#define BRANCH_EL (1<<2)
#define BRANCH_EN (1<<3)
#define BRANCH_RE (1<<4)
#define BRANCH_ALL (BRANCH_TR|BRANCH_EL|BRANCH_EN)
#define COUNT_INC (1<<4)
#define COUNT_IND (1<<5)
#define COUNT_NUM (1<<6)
#define COUNT_ALL (COUNT_INC|COUNT_IND|COUNT_NUM)
#define TI_UNIT   (1<<7)

static struct _opcode_info ops[] = {
   [NVS_OP_ABS] = {"ABS", 1, 0},
   [NVS_OP_ADD] = {"ADD", 2, 0},
   [NVS_OP_ARA] = {"ARA", 1, 0},
   [NVS_OP_ARL] = {"ARL", 1, 0},
   [NVS_OP_ARR] = {"ARR", 1, 0},
   [NVS_OP_BRA] = {"BRA", 0, NODS | BRANCH_TR},
   [NVS_OP_BRK] = {"BRK", 0, NODS},
   [NVS_OP_CAL] = {"CAL", 0, NODS | BRANCH_TR},
   [NVS_OP_CMP] = {"CMP", 2, 0},
   [NVS_OP_COS] = {"COS", 1, 0},
   [NVS_OP_DIV] = {"DIV", 2, 0},
   [NVS_OP_DDX] = {"DDX", 1, 0},
   [NVS_OP_DDY] = {"DDY", 1, 0},
   [NVS_OP_DP2] = {"DP2", 2, 0},
   [NVS_OP_DP2A] = {"DP2A", 3, 0},
   [NVS_OP_DP3] = {"DP3", 2, 0},
   [NVS_OP_DP4] = {"DP4", 2, 0},
   [NVS_OP_DPH] = {"DPH", 2, 0},
   [NVS_OP_DST] = {"DST", 2, 0},
   [NVS_OP_EX2] = {"EX2", 1, 0},
   [NVS_OP_EXP] = {"EXP", 1, 0},
   [NVS_OP_FLR] = {"FLR", 1, 0},
   [NVS_OP_FRC] = {"FRC", 1, 0},
   [NVS_OP_IF] = {"IF", 0, NODS | BRANCH_EL | BRANCH_EN},
   [NVS_OP_KIL] = {"KIL", 1, 0},
   [NVS_OP_LG2] = {"LG2", 1, 0},
   [NVS_OP_LIT] = {"LIT", 1, 0},
   [NVS_OP_LOG] = {"LOG", 1, 0},
   [NVS_OP_LOOP] = {"LOOP", 0, NODS | COUNT_ALL | BRANCH_EN},
   [NVS_OP_LRP] = {"LRP", 3, 0},
   [NVS_OP_MAD] = {"MAD", 3, 0},
   [NVS_OP_MAX] = {"MAX", 2, 0},
   [NVS_OP_MIN] = {"MIN", 2, 0},
   [NVS_OP_MOV] = {"MOV", 1, 0},
   [NVS_OP_MUL] = {"MUL", 2, 0},
   [NVS_OP_NRM] = {"NRM", 1, 0},
   [NVS_OP_PK2H] = {"PK2H", 1, 0},
   [NVS_OP_PK2US] = {"PK2US", 1, 0},
   [NVS_OP_PK4B] = {"PK4B", 1, 0},
   [NVS_OP_PK4UB] = {"PK4UB", 1, 0},
   [NVS_OP_POW] = {"POW", 2, 0},
   [NVS_OP_POPA] = {"POPA", 0, 0},
   [NVS_OP_PUSHA] = {"PUSHA", 1, NODS},
   [NVS_OP_RCC] = {"RCC", 1, 0},
   [NVS_OP_RCP] = {"RCP", 1, 0},
   [NVS_OP_REP] = {"REP", 0, NODS | BRANCH_EN | COUNT_NUM},
   [NVS_OP_RET] = {"RET", 0, NODS},
   [NVS_OP_RFL] = {"RFL", 1, 0},
   [NVS_OP_RSQ] = {"RSQ", 1, 0},
   [NVS_OP_SCS] = {"SCS", 1, 0},
   [NVS_OP_SEQ] = {"SEQ", 2, 0},
   [NVS_OP_SFL] = {"SFL", 2, 0},
   [NVS_OP_SGE] = {"SGE", 2, 0},
   [NVS_OP_SGT] = {"SGT", 2, 0},
   [NVS_OP_SIN] = {"SIN", 1, 0},
   [NVS_OP_SLE] = {"SLE", 2, 0},
   [NVS_OP_SLT] = {"SLT", 2, 0},
   [NVS_OP_SNE] = {"SNE", 2, 0},
   [NVS_OP_SSG] = {"SSG", 1, 0},
   [NVS_OP_STR] = {"STR", 2, 0},
   [NVS_OP_SUB] = {"SUB", 2, 0},
   [NVS_OP_TEX] = {"TEX", 1, TI_UNIT},
   [NVS_OP_TXB] = {"TXB", 1, TI_UNIT},
   [NVS_OP_TXD] = {"TXD", 3, TI_UNIT},
   [NVS_OP_TXL] = {"TXL", 1, TI_UNIT},
   [NVS_OP_TXP] = {"TXP", 1, TI_UNIT},
   [NVS_OP_UP2H] = {"UP2H", 1, 0},
   [NVS_OP_UP2US] = {"UP2US", 1, 0},
   [NVS_OP_UP4B] = {"UP4B", 1, 0},
   [NVS_OP_UP4UB] = {"UP4UB", 1, 0},
   [NVS_OP_X2D] = {"X2D", 3, 0},
   [NVS_OP_XPD] = {"XPD", 2, 0},
   [NVS_OP_NOP] = {"NOP", 0, NODS},
};

static struct _opcode_info *
_get_op_info(int op)
{
   if (op >= (sizeof(ops) / sizeof(struct _opcode_info)))
      return 0;
   if (ops[op].name == 0)
      return 0;
   return &ops[op];
}

static const char *_SFR_STRING[] = {
   [NVS_FR_POSITION] = "position",
   [NVS_FR_WEIGHT] = "weight",
   [NVS_FR_NORMAL] = "normal",
   [NVS_FR_COL0] = "color",
   [NVS_FR_COL1] = "color.secondary",
   [NVS_FR_BFC0] = "bfc",
   [NVS_FR_BFC1] = "bfc.secondary",
   [NVS_FR_FOGCOORD] = "fogcoord",
   [NVS_FR_POINTSZ] = "pointsize",
   [NVS_FR_TEXCOORD0] = "texcoord[0]",
   [NVS_FR_TEXCOORD1] = "texcoord[1]",
   [NVS_FR_TEXCOORD2] = "texcoord[2]",
   [NVS_FR_TEXCOORD3] = "texcoord[3]",
   [NVS_FR_TEXCOORD4] = "texcoord[4]",
   [NVS_FR_TEXCOORD5] = "texcoord[5]",
   [NVS_FR_TEXCOORD6] = "texcoord[6]",
   [NVS_FR_TEXCOORD7] = "texcoord[7]",
   [NVS_FR_FRAGDATA0] = "data[0]",
   [NVS_FR_FRAGDATA1] = "data[1]",
   [NVS_FR_FRAGDATA2] = "data[2]",
   [NVS_FR_FRAGDATA3] = "data[3]",
   [NVS_FR_CLIP0] = "clip_plane[0]",
   [NVS_FR_CLIP1] = "clip_plane[1]",
   [NVS_FR_CLIP2] = "clip_plane[2]",
   [NVS_FR_CLIP3] = "clip_plane[3]",
   [NVS_FR_CLIP4] = "clip_plane[4]",
   [NVS_FR_CLIP5] = "clip_plane[5]",
   [NVS_FR_CLIP6] = "clip_plane[6]",
   [NVS_FR_FACING] = "facing",
};

#define SFR_STRING(idx) CHECK_RANGE((idx), SFR_STRING)

static const char *_SWZ_STRING[] = {
   [NVS_SWZ_X] = "x",
   [NVS_SWZ_Y] = "y",
   [NVS_SWZ_Z] = "z",
   [NVS_SWZ_W] = "w"
};

#define SWZ_STRING(idx) CHECK_RANGE((idx), SWZ_STRING)

static const char *_NVS_PREC_STRING[] = {
   [NVS_PREC_FLOAT32] = "R",
   [NVS_PREC_FLOAT16] = "H",
   [NVS_PREC_FIXED12] = "X",
   [NVS_PREC_UNKNOWN] = "?"
};

#define NVS_PREC_STRING(idx) CHECK_RANGE((idx), NVS_PREC_STRING)

static const char *_NVS_COND_STRING[] = {
   [NVS_COND_FL] = "FL",
   [NVS_COND_LT] = "LT",
   [NVS_COND_EQ] = "EQ",
   [NVS_COND_LE] = "LE",
   [NVS_COND_GT] = "GT",
   [NVS_COND_NE] = "NE",
   [NVS_COND_GE] = "GE",
   [NVS_COND_TR] = "TR",
   [NVS_COND_UNKNOWN] = "??"
};

nvsCommandSet * AssembleShader( const char * shader )
{

}



/*
 * Copyright (C) 2006 Ben Skeggs
 * Copyright (C) 2007 Charles Lohr (mostly just reformatting)
 *
 * 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>
 */




EDIT: I guess I must be going crazy. I can't seem to find the bitwise structure. I'm starting to think I may have gotten confused when I was reading the mesa stuff and may be thinking of the brw_structs for the intel cards.

Additionally, the code that this was ripped from was http://gitweb.freedesktop.org/?p=mesa/mesa.git;a=tree;h=8a824f979d658ef779b5aa513fb6c92e0bdc4282;hb=578641941f45c56deb382317a7ff7cad496679cf;f=src/mesa/drivers/dri/nouveau
And it contains all the goodies for the end opcodes for the cards (take a look at nv40_shader.h)

Sorry all I've been able to do yet was research.
Back to top
View user's profile Send private message AIM Address
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Thu Nov 22, 2007 5:55 am    Post subject: Reply with quote

it is binary microcode layout for NV40.

http://gitweb.freedesktop.org/?p=mesa/mesa.git;a=blob;h=584f4c23e0838e6fd36016e929b946b0d3107a65;hb=578641941f45c56deb382317a7ff7cad496679cf;f=src/mesa/drivers/dri/nouveau/nv40_shader.h

Basic stuff:

http://nouveau.cvs.sourceforge.net/nouveau/nv40_demo/nv30_fpinst.h?revision=1.2&view=markup
Back to top
View user's profile Send private message Send e-mail Visit poster's website
ps2devman



Joined: 09 Oct 2006
Posts: 265

PostPosted: Mon Nov 26, 2007 4:17 am    Post subject: VP40 assembler grammar study Reply with quote

- Get cgc.exe from NVidia SDK 9.5 (free)

- Create vs_texture.cg (theoretical source of nv_shader.h content) :

Code:


struct myVertexInput{
   float4 position : POSITION;
   float4 texcoord0 : TEXCOORD0;
   float4 texcoord1 : TEXCOORD1;
};

struct myVertexOutput{
   float4 pos : POSITION;
   float4 tex0 : TEXCOORD0;
   float4 tex1 : TEXCOORD1;
};

myVertexOutput main(myVertexInput I)
{
   myVertexOutput result;
   
   result.pos = I.position;
   result.tex0 = I.texcoord0;
   result.tex1 = I.texcoord1;

   return result;
}



- Cgc.exe -profile vp40 -o vs_texture.vsh vs_texture.cg

- You obtain vs_texture.vsh :

Quote:


!!ARBvp1.0
OPTION NV_vertex_program3;
# cgc version 1.3.0001, build date Jan 7 2005 14:01:35
# command line args: -profile vp40
# source file: vs_texture.cg
#vendor NVIDIA Corporation
#version 1.0.02
#profile vp40
#program main
#var float4 I.position : $vin.ATTR0 : ATTR0 : 0 : 1
#var float4 I.texcoord0 : $vin.ATTR8 : ATTR8 : 0 : 1
#var float4 I.texcoord1 : $vin.ATTR9 : ATTR9 : 0 : 1
#var float4 main.pos : $vout.HPOS : HPOS : -1 : 1
#var float4 main.tex0 : $vout.TEX0 : TEX0 : -1 : 1
#var float4 main.tex1 : $vout.TEX1 : TEX1 : -1 : 1
PARAM c[1] = { program.local[0] };
TEMP CC;
BB1:
MOV result.position, vertex.attrib[0];
MOV result.texcoord[0], vertex.attrib[8];
MOV result.texcoord[1], vertex.attrib[9];
END
# 3 instructions, 0 R-regs




- You can notice the line "OPTION NV_vertex_program3;"

- A quick search on internet gives 3 official grammar description files :

http://www.nvidia.com/dev_content/nvopenglspecs/GL_NV_vertex_program.txt
http://www.nvidia.com/dev_content/nvopenglspecs/GL_NV_vertex_program2.txt
http://www.nvidia.com/dev_content/nvopenglspecs/GL_NV_vertex_program3.txt
Back to top
View user's profile Send private message
ps2devman



Joined: 09 Oct 2006
Posts: 265

PostPosted: Mon Nov 26, 2007 7:19 am    Post subject: FP30 assembler study Reply with quote

- You write ps_texture.cg (theoretical source of nv_shader.h content):

Code:



struct myVertexOutput {
   float2 texture_coords : TEXCOORD0;
};

float4 main(myVertexOutput I, uniform sampler2D colorMap):COLOR
{
   return tex2D(colorMap, I.texture_coords.xy);
}




- Cgc.exe -profile fp30 -o ps_texture.psh ps_texture.cg
(possible option for fp30: -profileopts NumInstructionSlots=<val>)

or
- Cgc.exe -profile fp30unlimited -o ps_texture.psh ps_texture.cg
(no option)

- You obtain ps_texture.psh (1st case) :

Code:


!!FP1.0
# cgc version 1.3.0001, build date Jan  7 2005 14:01:35
# command line args: -profile fp30
# source file: ps_texture.cg
#vendor NVIDIA Corporation
#version 1.0.02
#profile fp30
#program main
#semantic main.colorMap
#var float2 I.texture_coords : $vin.TEX0 : TEX0 : 0 : 1
#var sampler2D colorMap :  : texunit 0 : 1 : 1
#var float4 main : $vout.COL : COL : -1 : 1
TEX   o[COLR], f[TEX0], TEX0, 2D;
END
# 1 instructions, 0 R-regs, 0 H-regs



- Specs

http://www.nvidia.com/dev_content/nvopenglspecs/GL_NV_fragment_program.txt
http://www.nvidia.com/dev_content/nvopenglspecs/GL_NV_fragment_program2.txt
Back to top
View user's profile Send private message
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Sat Dec 01, 2007 5:15 am    Post subject: Reply with quote

Hi, I commited basic vertex shader compiler into libps3rsx. It is able to compile test example:

Code:

!!VP1.0
DP4 o[HPOS].x,  v[OPOS], c[0];
DP4 o[HPOS].y,  v[OPOS], c[1];
DP4 o[HPOS].z,  v[OPOS], c[2];
DP4 o[HPOS].w,  v[OPOS], c[3];
MOV o[TEX0],    v[TEX0];
END


Just few hours with yacc. It is relative full nv_vertex_program compiler ( only without address register stuff ). It is pretty nice if somebody is able to extend it into nv_vertex_program2 compiler.

I want to make offline tool for shader compilation. And runtime code for loading under libps3rsx. In day or two.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
ps2devman



Joined: 09 Oct 2006
Posts: 265

PostPosted: Sat Dec 01, 2007 5:28 am    Post subject: Reply with quote

Great! You rule!
Back to top
View user's profile Send private message
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Sat Dec 01, 2007 6:37 am    Post subject: Reply with quote

yacc rulzz.

I coded loading shaders from memory. Shader compiler generates binary shader on the hard disk, I'm loading this microcode.

Code:

int load_vertex_shader(  uint32_t *fifo )
{
   int fd, size;
   void *file = map_file( "../../data/mvp.vertex", &fd, &size );

   if( size && file )
   {
      vertex_shader_desc_t *desc = file;
      int res = set_vertex_shader( desc, (uint32_t *)( (uint8 *)file + sizeof( *desc ) ), fifo, Nv3D );
      unmap_file( file, fd, size );
      return res;
   }

   return 0;
}
Back to top
View user's profile Send private message Send e-mail Visit poster's website
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Sat Dec 01, 2007 6:44 am    Post subject: Reply with quote

You can play with vertex shader compiler, loading of broken microcode does not hang up GPU. I think, there are bugs in compiler.

If somebody want he can write fragment shader compiler. It is easy with yacc. I'll wait for few days.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Sun Dec 02, 2007 12:59 am    Post subject: Reply with quote

Hi, does somebody want to implement fragment shader assembler? By analogy with vertex one. cnlohr :)?

If noreply in 12 hours - I'll implement it :).
Back to top
View user's profile Send private message Send e-mail Visit poster's website
ps2devman



Joined: 09 Oct 2006
Posts: 265

PostPosted: Sun Dec 02, 2007 1:43 am    Post subject: Reply with quote

I'm lacking free time (end of fiscal year, insane work to do, even on weekends). Today I've just managed to keep some free time for trying to apply the 1080i patch to marcus other_os demo 1.1. I'm trying that at the moment.

Hehe... You are too fast for us, you know...
Back to top
View user's profile Send private message
mc



Joined: 12 Jan 2005
Posts: 212
Location: Linköping

PostPosted: Sun Dec 02, 2007 1:49 am    Post subject: Reply with quote

ps2devman: Triple buffering in 1080i will use more DDR-ram, so you'll
need to increase "BB" to at least 24. This also means you'll need to map
more DDR-ram to the CPU for texture upload to work.
_________________
Flying at a high speed
Having the courage
Getting over crisis
I rescue the people
Back to top
View user's profile Send private message
ps2devman



Joined: 09 Oct 2006
Posts: 265

PostPosted: Sun Dec 02, 2007 2:00 am    Post subject: Reply with quote

Thx for the hint. That will help me.
Hanging in HD mode hurts since you have to reinitialize bios and play with cables each time to see something again in LD... But it's ok, I'm over motivated (but I don't have much time to succeed, I cross fingers) !

EDIT: Strange, the reset didn't make my PS3 lose the HD settings... Maybe it depends on how bad it hangs...
Back to top
View user's profile Send private message
ps2devman



Joined: 09 Oct 2006
Posts: 265

PostPosted: Sun Dec 02, 2007 2:56 am    Post subject: Reply with quote

I failed. I applied same change to av.c and proto.h as usual (see post "otheros demo 1080i patch").

In demo.c I've tried BB=2 (I was probably wrong to assume it was the number of buffers like in otheros demo 1.0), but I've tried also BB=24 like you said with DDR_SIZE=48Mb in fb.c, but it hangs right at startup.

I'm not good enough (yet) to debug this... I will retry in January.
Back to top
View user's profile Send private message
mc



Joined: 12 Jan 2005
Posts: 212
Location: Linköping

PostPosted: Sun Dec 02, 2007 6:10 am    Post subject: Reply with quote

Yes, BB is not number of buffers, but number of megabytes up in DDR
ram where stuff like textures and z-buffer is placed. (This comes from
IronPeter's samples.) Trying to map as much as 48M might overflow the
MMU htab. The easiest way to get it working is probably to leave BB and
DDR_SIZE as they are, and instead modify the code to put the framebuffers
_after_ the Z buffer. Since the CPU doesn't need to access the framebuffers
(all rendering is done by the RSX), they can be after the end of the
MMU mapped region without any problems. Just change the computation
of "offset" in the main loop to add 64MB or something to the offset. Then

there should be plenty of space for large framebuffers.

(Sorry about the off-topicness of these posts...)
_________________
Flying at a high speed
Having the courage
Getting over crisis
I rescue the people
Back to top
View user's profile Send private message
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Mon Dec 03, 2007 5:27 am    Post subject: Reply with quote

hi, I implemented fp assembler. Buggy as hell. I need few days to clean up.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
mc



Joined: 12 Jan 2005
Posts: 212
Location: Linköping

PostPosted: Mon Dec 03, 2007 7:28 am    Post subject: Reply with quote

Sweet. Now all I need to do is learn fp language, and I'll modify my demo
to compute the fractals on the fly using fragment programs. :-)
(Any links to a good reference and/or tutorial?)
_________________
Flying at a high speed
Having the courage
Getting over crisis
I rescue the people
Back to top
View user's profile Send private message
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Mon Dec 03, 2007 6:23 pm    Post subject: Reply with quote

nice idea, good testcase.

it is mandelbrot shader from Humus http://www.humus.ca/index.php?page=3D&start=48

http://www.everfall.com/paste/id.php?09yzovsck729

It is written in arbfp, not nvfp asm. Probably I'll be able to support both semantics, probably only nvfp one.

Good testcase.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Tue Dec 04, 2007 4:53 am    Post subject: fp asm Reply with quote

I commited it.

It is able to compile

!!FP1.0

TEXX H0, f[TEX0], TEX0, 2D;

MULX H0, H0, {0.3, 0.6, 1.0, 1.0};

END

Feel free to post bugs :).
Back to top
View user's profile Send private message Send e-mail Visit poster's website
ArtVandelae



Joined: 08 Nov 2007
Posts: 3

PostPosted: Tue Dec 04, 2007 6:44 am    Post subject: Reply with quote

Nice work. I've been able to successfully compile several shaders by using your assembler after using the Nvidia Cg compiler to go from GLSL to asm code. There seem to be a few issues when compiling more complex shaders, however.

In particular, the assembler errors when the code wants to use the "HC" temporary register as in the line:

MULXC HC.x, H0, H0.w;

It also seems to error when the code attempts to use a condition code such as the following:

MOVR R3.xy(EQ.x), {-0.0009765625, 0.0009765625};

The entire shader is listed below. For the record, it is a fragment program implementation of the 2xSaI filter hard-coded for reading from a 1024x1024 texture. The original GLSL code was written by Guest(r) and can be found here. It was compiled from GLSL by using Cg with the following command line:

cgc.exe -oglsl -profile fp30 -entry main -o 2xSaI.fp 2xSaI.glsl

Code:
!!FP1.0
MULR  R0.xy, f[TEX0], {1024}.x;
FRCR  R0.zw, R0.xyxy;
FLRR  R0.xy, R0;
MULR  R3.zw, R0.xyxy, {0.0009765625}.x;
MOVR  R3.xy, {0.0009765625, -0.0009765625};
SLTR  H0.zw, R0, {0.5}.x;
SGER  H0.xy, R0.zwzw, {0.5}.x;
MULXC HC.x, H0, H0.w;
MULX  H0.x, H0, H0.y;
MOVR  R3.xy(EQ.x), {-0.0009765625, 0.0009765625};
MADR  R0.xy, R3, {0.5}.x, R3.zwzw;
ADDR  R4.xy, R0, {-0.00048828125}.x;
ADDR  R2.xy, R4, -R3;
ADDR  R4.zw, R2.xyxy, {0.0009765625}.x;
TEX   R1, R4.zwzw, TEX0, 2D;
ADDR  R0.xy, R3.zwzw, -R3;
TEX   R0, R0, TEX0, 2D;
DP3R  R1.w, R1, {65536, 256, 1};
DP3R  R5.z, R0, {65536, 256, 1};
ADDR  R5.xy, R3.zwzw, {0.0009765625}.x;
ADDR  R0.xy, R5, -R3;
TEX   R0, R0, TEX0, 2D;
DP3R  R2.w, R0, {65536, 256, 1};
ADDR  R0.x, R1.w, -R2.w;
ADDR  R2.z, R1.w, -R5;
SLTR  H1.y, |R0.x|, -|R2.z|;
SGTR  H1.x, |R0|, -|R2.z|;
TEX   R0, R3.zwzw, TEX0, 2D;
DP3R  R0.w, R0, {65536, 256, 1};
SEQR  H1.w, R0, R1;
MOVR  o[COLR].xyz, R0;
ADDR  R2.z, H1.x, -H1.y;
ADDR  R7.xy, R4, {0.0009765625}.x;
MULX  H0.y, H0.z, H0.w;
ADDR  R5.w, R0, -R5.z;
ADDR  R2.w, R0, -R2;
SLTR  H1.y, |R2.w|, -|R5.w|;
SGTR  H1.x, |R2.w|, -|R5.w|;
ADDR  R2.w, H1.x, -H1.y;
ADDR  R6.x, R2.z, -R2.w;
TEX   R2, R2, TEX0, 2D;
DP3R  R6.y, R2, {65536, 256, 1};
TEX   R2, R4, TEX0, 2D;
DP3R  R5.w, R2, {65536, 256, 1};
ADDR  R6.z, R1.w, -R6.y;
ADDR  R2.x, R1.w, -R5.w;
SLTR  H1.y, |R2.x|, -|R6.z|;
SGTR  H1.x, |R2|, -|R6.z|;
ADDR  R2.z, R0.w, -R6.y;
ADDR  R2.x, H1, -H1.y;
ADDR  R2.y, R0.w, -R5.w;
SLTR  H1.y, |R2|, -|R2.z|;
SGTR  H1.x, |R2.y|, -|R2.z|;
ADDR  R2.y, H1.x, -H1;
ADDR  R2.x, R2.y, -R2;
ADDR  R6.x, R2, -R6;
ADDR  R2.xy, R5, R3;
TEX   R2, R2, TEX0, 2D;
DP3R  R6.y, R2, {65536, 256, 1};
ADDR  R2.xy, R3.zwzw, R3;
TEX   R2, R2, TEX0, 2D;
DP3R  R6.w, R2, {65536, 256, 1};
SEQR  H0.z, R0.w, R6.w;
ADDR  R6.z, R1.w, -R6.y;
ADDR  R2.x, R1.w, -R6.w;
SLTR  H1.y, |R2.x|, -|R6.z|;
SGTR  H1.x, |R2|, -|R6.z|;
ADDR  R2.z, R0.w, -R6.y;
ADDR  R2.x, H1, -H1.y;
ADDR  R2.y, R0.w, -R6.w;
SLTR  H1.y, |R2|, -|R2.z|;
SGTR  H1.x, |R2.y|, -|R2.z|;
ADDR  R2.y, H1.x, -H1;
ADDR  R2.x, R2, -R2.y;
ADDR  R6.x, R6, -R2;
ADDR  R2.xy, R4.zwzw, {0.0009765625}.x;
TEX   R2, R2, TEX0, 2D;
DP3R  R4.z, R2, {65536, 256, 1};
ADDR  R2.xy, R7, {0.0009765625}.x;
TEX   R2, R2, TEX0, 2D;
DP3R  R7.z, R2, {65536, 256, 1};
ADDR  R4.w, R1, -R4.z;
ADDR  R2.x, R1.w, -R7.z;
SLTR  H1.y, |R4.w|, -|R2.x|;
SGTR  H1.x, |R4.w|, -|R2|;
ADDR  R2.y, R0.w, -R4.z;
TEX   R4, R5, TEX0, 2D;
ADDR  R2.x, H1, -H1.y;
ADDR  R2.z, R0.w, -R7;
SLTR  H1.y, |R2|, -|R2.z|;
SGTR  H1.x, |R2.y|, -|R2.z|;
ADDR  R2.y, H1.x, -H1;
ADDR  R6.y, R2, -R2.x;
TEX   R2, R7, TEX0, 2D;
DP3R  R2.w, R2, {65536, 256, 1};
SGTR  H1.x, R6, -R6.y;
SNER  H2.y, R1.w, R2.w;
DP3R  R4.w, R4, {65536, 256, 1};
SEQX  H1.y, H1.x, {0}.x;
SEQR  H1.x, R0.w, R4.w;
SEQX  H2.x, H2.y, {0};
MULX  H2.z, H1.x, H2.x;
SEQX  H1.z, H1.w, {0}.x;
MULX  H2.w, H2.z, H1.z;
SLTR  H1.z, R6.x, -R6.y;
MULX  H1.y, H2.w, H1;
MULXC HC.x, H1.y, H1.z;
ADDR  R6.xyz, R0, R1;
ADDR  R6.xyz, R2, R6;
ADDR  R4.xyz, R4, R6;
MOVR  o[COLR].xyz(NE.x), R1;
SEQX  H1.z, H1, {0}.x;
MULXC HC.x, H1.y, H1.z;
MULR  R4.xyz, R4, {0.25}.x;
SEQX  H1.y, H1.x, {0}.x;
SEQR  H1.z, R1.w, R2.w;
MULX  H2.x, H1.y, H1.z;
MOVR  o[COLR].xyz(NE.x), R4;
MOVXC RC.x, H2;
MOVR  o[COLR].xyz(NE.x), R1;
SEQX  H1.z, H1, {0}.x;
MULX  H1.y, H1, H1.z;
MOVXC RC.x, H1.y;
MOVR  o[COLR].xyz(NE.x), R4;
SEQX  H0.x, H0, {0};
MULXC HC.x, H0, H0.y;
ADDR  R1.xy, R3, R7;
TEX   R1, R1, TEX0, 2D;
MOVR  R4.xyz, R0;
MOVR  o[COLR].xyz(NE.x), R0;
SNER  H0.w, R5, R2;
MULX  H0.z, H1.w, H0;
MULX  H0.z, H0, H0.w;
DP3R  R1.x, R1, {65536, 256, 1};
SEQR  H0.w, R2, R1.x;
MULX  H0.z, H0, H0.w;
ADDR  R1.xyz, R0, R2;
MULR  R6.xyz, R1, {0.5}.x;
ADDR  R1.xy, R3.zwzw, {-0.0009765625}.x;
TEX   R1, R1, TEX0, 2D;
SEQR  H1.z, R2.w, R7;
SEQR  H0.w, R0, R5;
MADX_SAT H0.w, H0, H1.z, H0.z;
SEQX  H0.w, H0, {0}.x;
MULX  H1.x, H1, H2.y;
MULXC HC.x, H1, H0.w;
MOVR  R4.xyz(NE.x), R6;
MULXC HC.x, H1.w, H2.z;
MOVR  R4.xyz(NE.x), R0;
MOVXC RC.x, H2.w;
MOVR  R4.xyz(NE.x), R6;
SEQR  H1.x, R2.w, R4.w;
SEQR  H0.w, R2, R5;
MULX  H0.w, H0, H1.x;
SNER  H1.x, R0.w, R6.w;
MULX  H0.w, H0, H1.x;
DP3R  R1.x, R1, {65536, 256, 1};
SEQR  H1.x, R0.w, R1;
MULX  H0.w, H0, H1.x;
SEQR  H1.x, R2.w, R6.w;
SEQR  H1.z, R0.w, R5;
MADX_SAT H1.x, H1, H1.z, H0.w;
MULXC HC.x, H2, H1;
MOVR  R4.xyz(NE.x), R2;
SEQX  H1.x, H1, {0};
MULXC HC.x, H2, H1;
MOVR  R4.xyz(NE.x), R6;
MULXC HC.x, H1.y, H0.z;
SEQX  H0.z, H0, {0}.x;
MOVR  R4.xyz(NE.x), R0;
MULX  H0.z, H1.y, H0;
MULXC HC.x, H0.z, H0.w;
MOVR  R4.xyz(NE.x), R2;
SEQX  H0.w, H0, {0}.x;
MULXC HC.x, H0.z, H0.w;
MOVR  R4.xyz(NE.x), R6;
SEQX  H0.y, H0, {0}.x;
MULXC HC.x, H0, H0.y;
MOVR  o[COLR].xyz(NE.x), R4;
END
Back to top
View user's profile Send private message
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Tue Dec 04, 2007 5:38 pm    Post subject: Reply with quote

Ok, thanks for your test. Conditional ops are supported, it is probably small bug in semantic.

Situation with HC, RC is worser. I do not want to use "real" register. Does write mask affect conditional mask, is it possible to use "real" register like H0, R0 with zero write mask?

Also there are problems with RSQ operation. It must be implemented as exp ( 0.5 * lg x ).

The main problem now is fp constants. The code for constants setting is not yet written :).
Back to top
View user's profile Send private message Send e-mail Visit poster's website
hermes



Joined: 30 Mar 2004
Posts: 25
Location: Spain

PostPosted: Sun Dec 16, 2007 3:32 am    Post subject: Reply with quote

Hi.
I have done some modification to the IronPeter shader compilers.
If you use an output file .h it work in different form and the output is a .h C header with an array of datas and some defines based in the same name of the file.

for example:

shader.vp
Code:

!!VP1.0
MOV o[HPOS], v[OPOS];
MOV o[COL0], v[OCOL0];
MOV o[TEX0],    v[TEX0];
END


./vp myvp.h < shader.vp
(note vp program is a.out renamed from /toolshaderv)

The output:
myvp.h
Code:

// Vertex Program - Output by Hermes / www.elotrolado.net

#define myvp_vp_in 0x109

#define myvp_vp_out 0x4001

#define myvp_vp_len  12

unsigned int myvp_vp[myvp_vp_len]={
    0x401f9c6c, 0x40000d, 0x8106c083, 0x6041ff80,
    0x401f9c6c, 0x40030d, 0x8106c083, 0x6041ff84,
    0x401f9c6c, 0x40080d, 0x8106c083, 0x6041ff9d};

// End


In the same way the fragment program output:

shader_tex_color.fp
Code:

!!FP1.0

TEX   H0, f[TEX0], TEX0, 2D;
MULT H0,H0,f[COL0];
END


./fp fp_tex_color.h < shader_tex_color.fp
(note fp program is a.out renamed from /toolshaderf)

The Output:
fp_tex_color.h
Code:

// Fragment Program - Output by Hermes / www.elotrolado.net

#define fp_tex_color_fp_regs 2

#define fp_tex_color_fp_len  8

unsigned int fp_tex_color_fp[fp_tex_color_fp_len]={
    0x17009e80, 0x1c9dc801, 0x0, 0x0,
    0x2003e81, 0x1c9dc900, 0x1c901, 0x0};

// End


You can donwload the modified source and the binary code from this link:

http://mods.elotrolado.net/~hermes/ps3/tools_shaders.tar.gz

My little example code

Well, as you can see, i am using a light component to modulate the texture color.

I have done two fragment programs to draw triangles with and without texture. If you want to draw triangles without textures, you can use this Fragment Program:

shader_color.fp
Code:

!!FP1.0
MOV H0,f[COL0];
END


./fp fp_color.h < shader_color.fp

The Output:
fp_color.h
Code:

// Fragment Program - Output by Hermes / www.elotrolado.net

#define fp_color_fp_regs 2

#define fp_color_fp_len  4

unsigned int fp_color_fp[fp_color_fp_len]={
    0x1003e81, 0x1c9dc801, 0x0, 0x0};
// End



To load the vertex program, you can use this modifieds functions:

Code:

int NV40_LoadVtxProg2( uint32_t *fifo, uint32_t vp_in_reg, uint32_t vp_out_reg, uint32_t *shader, int shader_size)
{
  volatile uint32_t *ptr = fifo;
  uint32_t i;

  BEGIN_RING(Nv3D, NV40TCL_VP_UPLOAD_FROM_ID, 1);
  OUT_RING  ( 0 );
  for (i=0; i<shader_size; i+=4)
  {
    BEGIN_RING(Nv3D, NV40TCL_VP_UPLOAD_INST(0), 4);
    OUT_RING  (shader[i + 0]);
    OUT_RING  (shader[i + 1]);
    OUT_RING  (shader[i + 2]);
    OUT_RING  (shader[i + 3]);

  }

  BEGIN_RING(Nv3D, NV40TCL_VP_START_FROM_ID, 1);
  OUT_RING  (0);

  BEGIN_RING(Nv3D, NV40TCL_VP_ATTRIB_EN, 2);
  OUT_RING  (vp_in_reg);
  OUT_RING  (vp_out_reg);

  BEGIN_RING( Nv3D, 0x1478, 1 );
  OUT_RING  (0);

  return ptr - fifo;
}

int NV40_LoadFragProg2( uint32_t *fifo, uint32_t *fbmem, uint32_t *shader_hw_id, uint32_t *shader, int shader_size, int shader_regs)
{
  uint32_t i;
  uint32_t offset = fp_offset / 4;
  uint32_t *ptr = fifo;
  static int next_hw_id_offset = 0;
  unsigned int hw_id=0;

if(shader_hw_id) hw_id=*shader_hw_id;

  if (!hw_id)
  {

    for( i = 0; i < shader_size; ++i )
    {
      fbmem[ offset + next_hw_id_offset + i] = endian_fp( shader[i] );
    }


    hw_id  = offset;
    hw_id += next_hw_id_offset;
    hw_id *= 4;

    next_hw_id_offset += shader_size;
    next_hw_id_offset = (next_hw_id_offset + 63) & ~63;
  }
if(shader_hw_id) *shader_hw_id=hw_id;

  //printf( "frag prog 0x%x \n", shader->hw_id );
  BEGIN_RING(Nv3D, NV40TCL_FP_ADDRESS, 1);
  OUT_RING  (hw_id | NV40TCL_FP_ADDRESS_DMA0);
  BEGIN_RING(Nv3D, NV40TCL_FP_CONTROL, 1);
  OUT_RING  ( ( shader_regs << NV40TCL_FP_CONTROL_TEMP_COUNT_SHIFT ) );

  return ptr - fifo;
}


To use it:

Code:

#include "myvp.h"
#include "fp_color.h"
#include "fp_tex_color.h"

uint32_t fp_color=0; //  to 0 the first time
uint32_t fp_tex_color=0; //  to 0 the first time
.....
.....

int bind3d(....)
{
....
....

ptr += NV40_LoadVtxProg2( ptr, myvp_vp_in,myvp_vp_out,myvp_vp, myvp_vp_len );

  ptr += NV40_LoadFragProg2( ptr, fbmem, &fp_color, fp_color_fp, fp_color_fp_len, fp_color_fp_regs);

  ptr += NV40_LoadFragProg2( ptr, fbmem, &fp_tex_color, fp_tex_color_fp, fp_tex_color_fp_len, fp_tex_color_fp_regs);


With this code i load the Vertex Program and the two Fragment Programs the first time.

I can use the variables fp_color and fp_tex_color to select the FP to use the next times.

To buid the vertex you can use this macros:
Code:

#define CV_COLOR(r,g,b,a) BEGIN_RING(Nv3D, NV40TCL_VTX_ATTR_4F_X(3), 4);\
           OUT_RINGf ((r)); OUT_RINGf ((g));\
                     OUT_RINGf ((b)); OUT_RINGf ((a));\

#define CV_VERT(sx,sy,sz) BEGIN_RING(Nv3D, NV40TCL_VTX_ATTR_4F_X(0), 4);\
           OUT_RINGf ((sx)); OUT_RINGf ((sy));\
                     OUT_RINGf ((sz)); OUT_RINGf ((1.0f));\

#define CV_TEXT(tx,ty) BEGIN_RING(Nv3D, NV40TCL_VTX_ATTR_2F_X(8), 2);\
           OUT_RINGf ((tx)); OUT_RINGf ((ty));\



#define CV_OUT1(r,g,b,a, sx,sy, sz, tx, ty) do {                                                     \
   CV_COLOR(r,g,b,a)\
   CV_VERT(sx,sy,sz)\
   CV_TEXT(tx,ty)\
} while(0)


And example code to use triangles with and without textures, using NV40TCL_SHADE_MODEL_SMOOTH (gouraud) and vertex color:

Code:

int NV40_EmitGeometry( uint32_t *fifo, uint32_t *fbmem )
{
 volatile uint32_t *ptr = fifo;
 uint32_t i;
 static float A=0.0f,B=1.0f;
 float Y=(float) (height/2);


 // TEXTURED
 ptr += NV40_LoadFragProg2( ptr, fbmem, &fp_tex_color, fp_tex_color_fp, fp_tex_color_fp_len, fp_tex_color_fp_regs);

  BEGIN_RING(Nv3D, 0x1718, 1);
  OUT_RING  (0);
  BEGIN_RING(Nv3D, 0x1718, 1);
  OUT_RING  (0);
  BEGIN_RING(Nv3D, 0x1718, 1);
  OUT_RING  (0);

 
  BEGIN_RING(Nv3D, NV40TCL_BEGIN_END, 1);
  OUT_RING  (NV40TCL_BEGIN_END_TRIANGLES);

  float pi = atan( 1.0f ) * 1.0f;

  for( i = 0; i < 12; ++i )
  {
   float si = sin( -(X/256.0f)+i * pi / 1.5f );
    float co = cos(-(X/256.0f)+ i * pi / 1.5f );
 si=si*A/128.0f;
 co=co*A/128.0f;
    float x1 = 200.0f, y1 = 80.0f;
    float x2 = -200.0f, y2 = 10.0f;
    float x3 = -200.0f, y3 = 150.0f;

    CV_OUT1(1.0f,1.0f,1.0f,1.0f, width-X + x1 * co + y1 * si, Y - x1 * si + y1 * co, 1.0f, 0.5f, 0.0f  );
    CV_OUT1(1.0f,0.0f,1.0f,1.0f, width-X + x2 * co + y2 * si, Y - x2 * si + y2 * co, 0.5f, 0.0f, 1.0f  );
    CV_OUT1(0.0f,1.0f,0.0f,0.0f, width-X + x3 * co + y3 * si, Y - x3 * si + y3 * co, 0.5f, 1.0f, 1.0f  );

 }
  BEGIN_RING(Nv3D, NV40TCL_BEGIN_END, 1);
 OUT_RING  (NV40TCL_BEGIN_END_STOP);

// NONTEXTURED
ptr += NV40_LoadFragProg2( ptr, fbmem, &fp_color, fp_color_fp, fp_color_fp_len, fp_color_fp_regs);


 BEGIN_RING(Nv3D, NV40TCL_BEGIN_END, 1);
  OUT_RING  (NV40TCL_BEGIN_END_TRIANGLES);

  for( i = 0; i < 12; ++i )
  {
    float si = sin( (X/256.0f)+i * pi / 1.5f );
    float co = cos((X/256.0f)+ i * pi / 1.5f );
 si=si*A/128.0f;
 co=co*A/128.0f;
    float x1 = 200.0f, y1 = 80.0f;
    float x2 = -200.0f, y2 = 10.0f;
    float x3 = -200.0f, y3 = 150.0f;

    if(i & 1)
   {
    CV_OUT1(1.0f,1.0f,0.0f,1.0f, X + x1 * co + y1 * si, Y - x1 * si + y1 * co, 0.5f, 0.5f, 0.0f  );
       CV_OUT1(1.0f,1.0f,0.0f,1.0f, X + x2 * co + y2 * si, Y - x2 * si + y2 * co, 0.0f, 0.0f, 1.0f  );
       CV_OUT1(1.0f,1.0f,0.0f,1.0f, X + x3 * co + y3 * si, Y - x3 * si + y3 * co, 0.0f, 1.0f, 1.0f  );
   }
else
{
    CV_OUT1(1.0f,0.0f,0.0f,1.0f, X + x1 * co + y1 * si, Y - x1 * si + y1 * co, 0.5f, 0.5f, 0.0f  );
    CV_OUT1(1.0f,0.0f,0.0f,1.0f, X + x2 * co + y2 * si, Y - x2 * si + y2 * co, 0.0f, 0.0f, 1.0f  );
    CV_OUT1(1.0f,0.0f,0.0f,1.0f, X + x3 * co + y3 * si, Y - x3 * si + y3 * co, 0.0f, 1.0f, 1.0f  );
}
  }
 
  A+=B;

if(A>256.0f) B=-1.0f;
if(A<=0.0f) B=1.0f;

 

  BEGIN_RING(Nv3D, NV40TCL_BEGIN_END, 1);
  OUT_RING  (NV40TCL_BEGIN_END_STOP);

  return ptr - fifo;
}


I hope you understand my example code... it is the same example from my Yellow Dog Linux 5.01 3D patch released on the PS3 Linux forum, but modified to use the news shaders and the vertex color.

Maybe i release all the source code more later, when it can work using /dev/fb0, /dev/fb1 and /dev/ps3gpu_* methods .

I am thinking to port my PS2 Game named "Guitar Fun" to the PS3 (Guitar Hero clone) under GPL license and i think it can be done using this littles shaders :) (it is not easy to do, but it is possible). To many thanks to IronPeter and others for you work.

Sorry for my bad english ;)
Back to top
View user's profile Send private message
IronPeter



Joined: 06 Aug 2007
Posts: 207

PostPosted: Sun Dec 16, 2007 7:20 am    Post subject: Reply with quote

You can look at fragment.h and vertex.h files. These files contain clean refactored interface to shader stuff. look simple_dxt for example of usage.

If you want to generate .h and .c files with shaders - please, keep common ( with fragment.h and vertex.h ) interface for shader setup.

If you extend compiler with .h and .cpp output - please, keep it as alernative cmd line option.

I can commit your work in repo in that case.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
hermes



Joined: 30 Mar 2004
Posts: 25
Location: Spain

PostPosted: Sun Dec 16, 2007 7:56 am    Post subject: Reply with quote

IronPeter wrote:

If you extend compiler with .h and .cpp output - please, keep it as alernative cmd line option.

I can commit your work in repo in that case.


.h output is alternative cmd option line: Only if you use .h it use this output. If you use for example, ./vp myshader.bin < shader it use your output method


For the others question, i must see the news changes in detail;)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PS3 Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group