Started back-porting Dxbx pixel shaders

This commit is contained in:
PatrickvL 2017-09-13 20:57:33 +01:00
parent 8b11cce5b6
commit 8ff5c497e7
1 changed files with 237 additions and 5 deletions

View File

@ -1,8 +1,8 @@
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * ,;;;"````" `;;;, .,;; ;;;"";;" `;;;, .,;;
// * [[[ "[[,,[[" [[[__[[\. "[[,,[["
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
@ -34,6 +34,8 @@
#ifndef PIXELSHADER_H
#define PIXELSHADER_H
#pragma once
#include "Cxbx.h"
/*---------------------------------------------------------------------------*/
@ -413,10 +415,240 @@ enum PS_GLOBALFLAGS
// change PS_TEXTUREMODES_PROJECT3D to PS_TEXTUREMODES_PROJECT2D
// change PS_TEXTUREMODES_CUBEMAP to PS_TEXTUREMODES_PROJECT2D
PS_GLOBALFLAGS_NO_TEXMODE_ADJUST= 0x0000L, // don't adjust texture modes
PS_GLOBALFLAGS_NO_TEXMODE_ADJUST= 0x0000L, // don"t adjust texture modes
PS_GLOBALFLAGS_TEXMODE_ADJUST= 0x0001L, // adjust texture modes according to set texture
};
#if 0 // Dxbx translation
enum PSH_OPCODE
{
PO_COMMENT,
PO_PS,
PO_DEF,
#ifdef CXBX_USE_PS_2_0
PO_DCL,
#endif
PO_TEX,
PO_TEXBEM,
PO_TEXBEML,
PO_TEXBRDF, // Xbox ext.
PO_TEXCOORD,
PO_TEXKILL,
PO_TEXDP3, // Note : ps.1.3 only
PO_TEXDP3TEX, // Note : ps.1.3 only
PO_TEXM3X2TEX,
PO_TEXM3X2DEPTH, // Note : requires ps.1.3 and a preceding texm3x2pad
PO_TEXM3X3DIFF, // Xbox ext.
PO_TEXM3X3VSPEC,
PO_TEXM3X3TEX, // Note : Uses a cube texture
PO_TEXREG2AR,
PO_TEXREG2GB,
PO_TEXM3X2PAD, // Note : Must be combined with texm3x2tex or texm3x2depth
PO_TEXM3X3PAD,
PO_TEXM3X3SPEC, // NOTE : NEEDS 3 ARGUMENTS!
// Direct3D8 arithmetic instructions :
PO_ADD,
PO_CMP,
PO_CND,
PO_DP3, // dp3 d, s1,s2 : d=s0 dot s1 (replicated to all channels, .rgb=color only, .a=color+alpha)
PO_DP4, // dp3 d, s1,s2 : d.r=d.g=d.b=d.a=(s1.r*s2.r)+(s1.g*s2.g)+(s1.b*s2.b)+(s1.a*s2.a)
PO_LRP,
PO_MAD,
PO_MOV,
PO_MUL,
PO_NOP,
PO_SUB,
// Xbox1 opcodes :
PO_XMMA,
PO_XMMC,
PO_XDM,
PO_XDD,
PO_XFC
};
const struct { char *mn; int _Out; int _In; char *note; } PSH_OPCODE_DEFS[/*PSH_OPCODE*/] = {
// Pixel shader header opcodes (must be specified in this order) :
{/* PO_COMMENT */ /*mn:*/";", /*_Out: */ 0, /*_In: */ 0, /*note:*/""}, //
{/* PO_PS */ /*mn:*/"ps", /*_Out: */ 0, /*_In: */ 0, /*note:*/""}, // Must occur once, Xbox needs an x prefix {xps}, Native needs a 1.3 suffix {ps.1.3}
{/* PO_DEF */ /*mn:*/"def", /*_Out: */ 1, /*_In: */ 4, /*note:*/""}, // Output must be a PARAM_C, arguments must be 4 floats [0.00f .. 1.00f]
#ifdef CXBX_USE_PS_2_0
{/* PO_DCL */ /*mn:*/"dcl", /*_Out: */ 1, /*_In: */ 0, /*note:*/""},
#endif
{/* PO_TEX */ /*mn:*/"tex", /*_Out: */ 1, /*_In: */ 0, /*note:*/""},
{/* PO_TEXBEM */ /*mn:*/"texbem", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXBEML */ /*mn:*/"texbeml", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXBRDF */ /*mn:*/"texbrdf", /*_Out: */ 1, /*_In: */ 1, /*note:*/""}, // /*note: */ Not supported by Direct3D8 ?
{/* PO_TEXCOORD */ /*mn:*/"texcoord", /*_Out: */ 1, /*_In: */ 0, /*note:*/""},
{/* PO_TEXKILL */ /*mn:*/"texkill", /*_Out: */ 1, /*_In: */ 0, /*note:*/""},
{/* PO_TEXDP3 */ /*mn:*/"texdp3", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXDP3TEX */ /*mn:*/"texdp3tex", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXM3X2TEX */ /*mn:*/"texm3x2tex", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXM3X2DEPTH */ /*mn:*/"texm3x2depth", /*_Out: */ 1, /*_In: */ 1, /*note:*/""}, // /*note: */ requires ps.1.3 and a preceding texm3x2pad
{/* PO_TEXM3X3DIFF */ /*mn:*/"texm3x3diff", /*_Out: */ 1, /*_In: */ 1, /*note:*/""}, // /*note: */ Not supported by Direct3D8 ?
{/* PO_TEXM3X3VSPEC */ /*mn:*/"texm3x3vspec", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXM3X3TEX */ /*mn:*/"texm3x3tex", /*_Out: */ 1, /*_In: */ 1, /*note:*/""}, // /*note: */ Uses a cube texture
{/* PO_TEXREG2AR */ /*mn:*/"texreg2ar", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXREG2GB */ /*mn:*/"texreg2gb", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXM3X2PAD */ /*mn:*/"texm3x2pad", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXM3X3PAD */ /*mn:*/"texm3x3pad", /*_Out: */ 1, /*_In: */ 1, /*note:*/""},
{/* PO_TEXM3X3SPEC */ /*mn:*/"texm3x3spec", /*_Out: */ 1, /*_In: */ 2, /*note:*/""},
// Arithmetic opcodes :
{/* PO_ADD */ /*mn:*/"add", /*_Out: */ 1, /*_In: */ 2, /*note:*/"d0=s0+s1"},
{/* PO_CMP */ /*mn:*/"cmp", /*_Out: */ 1, /*_In: */ 3, /*note:*/"d0={s0>=0?s1:s2}"},
{/* PO_CND */ /*mn:*/"cnd", /*_Out: */ 1, /*_In: */ 3, /*note:*/"d1={s0.a>0.5?s1:s2}"}, // 1st input must be "r0.a"
{/* PO_DP3 */ /*mn:*/"dp3", /*_Out: */ 1, /*_In: */ 2, /*note:*/"d0=s0 dot3 s1"},
{/* PO_DP4 */ /*mn:*/"dp4", /*_Out: */ 1, /*_In: */ 2, /*note:*/"d0=s0 dot4 s1"},
{/* PO_LRP */ /*mn:*/"lrp", /*_Out: */ 1, /*_In: */ 3, /*note:*/"d0=s0*s1+{1-s0}*s2=s0*{s1-s2}+s2"},
{/* PO_MAD */ /*mn:*/"mad", /*_Out: */ 1, /*_In: */ 3, /*note:*/"d0=s0*s1+s2"},
{/* PO_MOV */ /*mn:*/"mov", /*_Out: */ 1, /*_In: */ 1, /*note:*/"d0=s0"},
{/* PO_MUL */ /*mn:*/"mul", /*_Out: */ 1, /*_In: */ 2, /*note:*/"d0=s0*s1"},
{/* PO_NOP */ /*mn:*/"nop", /*_Out: */ 0, /*_In: */ 0, /*note:*/""},
{/* PO_SUB */ /*mn:*/"sub", /*_Out: */ 1, /*_In: */ 2, /*note:*/"d0=s0-s1"},
// Xbox-only {NV2A} opcodes :
{/* PO_XMMA */ /*mn:*/"xmma", /*_Out: */ 3, /*_In: */ 4, /*note:*/"d0=s0*s1, d1=s2*s3, d2={s0*s1}+{s2*s3}"},
{/* PO_XMMC */ /*mn:*/"xmmc", /*_Out: */ 3, /*_In: */ 4, /*note:*/"d0=s0*s1, d1=s2*s3, d2={r0.a>0.5}?{s0*s1}:{s2*s3}"},
{/* PO_XDM */ /*mn:*/"xdm", /*_Out: */ 2, /*_In: */ 4, /*note:*/"d0=s0 dot s1, d1=s2*s3"},
{/* PO_XDD */ /*mn:*/"xdd", /*_Out: */ 2, /*_In: */ 4, /*note:*/"d0=s0 dot s1, d1=s2 dot s3"},
{/* PO_XFC */ /*mn:*/"xfc", /*_Out: */ 0, /*_In: */ 7, /*note:*/"r0.rgb=s0*s1+{1-s0}*s2+s3, r0.a=s6.a, prod=s4*s5, sum=r0+v1"}
};
enum PSH_ARGUMENT_TYPE
{
PARAM_VALUE, // Xbox only; Numberic constants used in Xbox-only opcodes
PARAM_DISCARD, // Xbox only;
PARAM_FOG, // Final combiner only; Read-only register fog register
PARAM_V1R0_SUM, // Final combiner only; Read-only register that contains the result of V1+R0
PARAM_EF_PROD, // Final combiner only; Read-only register that contains the result of final combiner parameters E * F
PARAM_R, // Temporary registers (unassigned except r0.a, which on NV2A is initially set to t0.a)
PARAM_T, // Textures
PARAM_V, // Vertex colors
PARAM_C // Constant registers, set by def opcodes or SetPixelShaderConstant
};
const char *PSH_ARGUMENT_TYPE_Str[/*PSH_ARGUMENT_TYPE*/] = {
// Prefix # r/w Input? Output? Note
"", // * r No No Used for numeric constants like -1, 0, 1
"discard", // * w No Yes Only for xbox opcodes (native opcodes have single output - discards must be removed)
"fog", // 1 r Yes No Only for final combiner parameter
"sum", // 1 r Yes No Only for final combiner parameter
"prod", // 1 r Yes No Only for final combiner parameter
"r", // 2 r/w Yes Yes We fake a few extra registers and resolve them in FixupPixelShader
"t", // 4 r/w Yes Yes D3D9 cannot write to these!
"v", // 2 r Yes Yes
"c" // 16 r Yes No Xbox has 8*c0,c1=16, while PC D3D8 has only 8, we try to reduce that in FixupPixelShader
};
const
int FakeRegNr_Sum = 2;
int FakeRegNr_Prod = 3;
int FakeRegNr_Xmm1 = 4;
int FakeRegNr_Xmm2 = 5;
// TODO : Translate From Dxbx :
//const
//int XFC_COMBINERSTAGENR = X_PSH_COMBINECOUNT; // Always call XFC "stage 9", 1 after the 8th combiner
int PSH_XBOX_MAX_C_REGISTER_COUNT = 16;
int PSH_XBOX_MAX_R_REGISTER_COUNT = 2;
int PSH_XBOX_MAX_T_REGISTER_COUNT = 4;
int PSH_XBOX_MAX_V_REGISTER_COUNT = 2;
// Extra constants to support features not present in Native D3D :
int PSH_XBOX_CONSTANT_FOG = PSH_XBOX_MAX_C_REGISTER_COUNT; // = 16
int PSH_XBOX_CONSTANT_FC0 = PSH_XBOX_CONSTANT_FOG + 1; // = 17
int PSH_XBOX_CONSTANT_FC1 = PSH_XBOX_CONSTANT_FC0 + 1; // = 18
int PSH_XBOX_CONSTANT_MAX = PSH_XBOX_CONSTANT_FC1 + 1; // = 19
#ifdef CXBX_USE_PS_3_0
int PSH_PC_MAX_C_REGISTER_COUNT = 224; // ps 3.0
int PSH_PC_MAX_R_REGISTER_COUNT = 32; // ps 3.0
int PSH_PC_MAX_S_REGISTER_COUNT = 16; // ps 3.0
int PSH_PC_MAX_V_REGISTER_COUNT = 10; // ps 3.0
int PSH_PC_MAX_REGISTER_COUNT = 224;
#else
#ifdef CXBX_USE_PS_2_0
int PSH_PC_MAX_C_REGISTER_COUNT = 32; // ps 2.0
int PSH_PC_MAX_R_REGISTER_COUNT = 12; // ps 2.0
int PSH_PC_MAX_S_REGISTER_COUNT = 16; // ps 2.0
int PSH_PC_MAX_T_REGISTER_COUNT = 8; // ps 2.0
int PSH_PC_MAX_V_REGISTER_COUNT = 2; // ps 2.0
int PSH_PC_MAX_REGISTER_COUNT = 32;
#else // CXBX_USE_PS_1_3
int PSH_PC_MAX_C_REGISTER_COUNT = 8; // ps 1.3
int PSH_PC_MAX_R_REGISTER_COUNT = 2; // ps 1.3
int PSH_PC_MAX_T_REGISTER_COUNT = 4; // ps 1.3
int PSH_PC_MAX_V_REGISTER_COUNT = 2; // ps 1.3
int PSH_PC_MAX_REGISTER_COUNT = 8;
#endif
#endif
enum PSH_INST_MODIFIER {
INSMOD_NONE, // y = x
INSMOD_BIAS, // y = x - 0.5 // Xbox only : TODO : Fixup occurrances!
INSMOD_X2, // y = x * 2
INSMOD_BX2, // y = (x - 0.5) * 2 // Xbox only : TODO : Fixup occurrances!
INSMOD_X4, // y = x * 4
INSMOD_D2, // y = x * 0.5
INSMOD_SAT // Xbox doesn"t support this, but has ARGMOD_SATURATE instead
};
const char *PSH_INST_MODIFIER_Str[/*PSH_INST_MODIFIER*/] = {
"",
"_bias",
"_x2",
"_bx2",
"_x4",
"_d2",
"_sat"
};
// Four argument modifiers (applied in this order) :
// 1: Inversion (invert or negate : "1-" or "-")
// 2: Apply bias ("_bias")
// 3: Apply scale ("_x2", "_bx2", "_x4", or "_d2")
// 4: Apply clamp ("_sat")
enum PSH_ARG_MODIFIER {
ARGMOD_IDENTITY, // y = x
ARGMOD_INVERT, // y = 1-x -> 0..1 > 1..0
ARGMOD_NEGATE, // y = -x -> 0..1 > 0..-1
ARGMOD_BIAS, // y = x-0.5 -> 0..1 > -0.5..0.5
ARGMOD_SCALE_X2, // y = x*2 -> 0..1 > 0..2
ARGMOD_SCALE_BX2, // y = (x*2)-1 -> 0..1 > -1..1
ARGMOD_SCALE_X4, // y = x*4 -> 0..1 > 0..4
ARGMOD_SCALE_D2, // y = x/2 -> 0..1 > 0..0.5
ARGMOD_SATURATE, // Xbox - not available in PS1.3 (can be done on output instead)
ARGMOD_ALPHA_REPLICATE,
ARGMOD_BLUE_REPLICATE // PS1.1-PS1.3 only allow this if destination writemask = .a
};
// TODO : Translate From Dxbx :
// PSH_ARG_MODIFIERs = set of PSH_ARG_MODIFIER;
const char *PSH_ARG_MODIFIER_Str[/*PSH_ARG_MODIFIER*/] = {
"%s",
"1-%s",
"-%s",
"%s_bias",
"%s_x2",
"%s_bx2",
"%s_x4",
"%s_d2",
"%s_sat",
"%s", // .a is added via Mask
"%s" // .b idem
};
#endif // 0 Dxbx translation
// dump pixel shader definition to file
void DumpPixelShaderDefToFile( X_D3DPIXELSHADERDEF* pPSDef, const char* pszCode );
// print relevant contents to the debug console
@ -425,7 +657,7 @@ void PrintPixelShaderDefContents( X_D3DPIXELSHADERDEF* pDSDef );
HRESULT EmuRecompilePshDef( X_D3DPIXELSHADERDEF* pPSDef, LPD3DXBUFFER* ppRecompiled );
/*
* Kingofc's pixel shader functions
* Kingofc"s pixel shader functions
*/
// Pixel Shader Stuff
HRESULT CreatePixelShaderFunction(X_D3DPIXELSHADERDEF *pPSD, LPD3DXBUFFER* ppRecompiled);
@ -441,4 +673,4 @@ inline void null_func_psh(...) { }
#define DbgPshPrintf XTL::null_func_psh
#endif
#endif
#endif // PIXELSHADER_H