1 // Copyright 2008 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #pragma once
6 
7 #include "Common/CommonTypes.h"
8 #include "VideoCommon/LightingShaderGen.h"
9 #include "VideoCommon/ShaderGenCommon.h"
10 
11 enum class APIType;
12 
13 #pragma pack(1)
14 struct pixel_shader_uid_data
15 {
16   // TODO: Optimize field order for easy access!
17 
18   u32 num_values;  // TODO: Shouldn't be a u32
NumValuespixel_shader_uid_data19   u32 NumValues() const { return num_values; }
20   u32 components : 2;
21   u32 pad0 : 2;
22   u32 useDstAlpha : 1;
23   u32 Pretest : 2;
24   u32 nIndirectStagesUsed : 4;
25   u32 genMode_numtexgens : 4;
26   u32 genMode_numtevstages : 4;
27   u32 genMode_numindstages : 3;
28   u32 alpha_test_comp0 : 3;
29   u32 alpha_test_comp1 : 3;
30   u32 alpha_test_logic : 2;
31   u32 alpha_test_use_zcomploc_hack : 1;
32   u32 fog_proj : 1;
33 
34   u32 fog_fsel : 3;
35   u32 fog_RangeBaseEnabled : 1;
36   u32 ztex_op : 2;
37   u32 per_pixel_depth : 1;
38   u32 forced_early_z : 1;
39   u32 early_ztest : 1;
40   u32 late_ztest : 1;
41   u32 bounding_box : 1;
42   u32 zfreeze : 1;
43   u32 numColorChans : 2;
44   u32 rgba6_format : 1;
45   u32 dither : 1;
46   u32 uint_output : 1;
47   u32 blend_enable : 1;            // Only used with shader_framebuffer_fetch blend
48   u32 blend_src_factor : 3;        // Only used with shader_framebuffer_fetch blend
49   u32 blend_src_factor_alpha : 3;  // Only used with shader_framebuffer_fetch blend
50   u32 blend_dst_factor : 3;        // Only used with shader_framebuffer_fetch blend
51   u32 blend_dst_factor_alpha : 3;  // Only used with shader_framebuffer_fetch blend
52   u32 blend_subtract : 1;          // Only used with shader_framebuffer_fetch blend
53   u32 blend_subtract_alpha : 1;    // Only used with shader_framebuffer_fetch blend
54 
55   u32 texMtxInfo_n_projection : 8;  // 8x1 bit
56   u32 tevindref_bi0 : 3;
57   u32 tevindref_bc0 : 3;
58   u32 tevindref_bi1 : 3;
59   u32 tevindref_bc1 : 3;
60   u32 tevindref_bi2 : 3;
61   u32 tevindref_bc3 : 3;
62   u32 tevindref_bi4 : 3;
63   u32 tevindref_bc4 : 3;
64 
SetTevindrefValuespixel_shader_uid_data65   void SetTevindrefValues(int index, u32 texcoord, u32 texmap)
66   {
67     if (index == 0)
68     {
69       tevindref_bc0 = texcoord;
70       tevindref_bi0 = texmap;
71     }
72     else if (index == 1)
73     {
74       tevindref_bc1 = texcoord;
75       tevindref_bi1 = texmap;
76     }
77     else if (index == 2)
78     {
79       tevindref_bc3 = texcoord;
80       tevindref_bi2 = texmap;
81     }
82     else if (index == 3)
83     {
84       tevindref_bc4 = texcoord;
85       tevindref_bi4 = texmap;
86     }
87   }
88 
GetTevindirefCoordpixel_shader_uid_data89   u32 GetTevindirefCoord(int index) const
90   {
91     if (index == 0)
92     {
93       return tevindref_bc0;
94     }
95     else if (index == 1)
96     {
97       return tevindref_bc1;
98     }
99     else if (index == 2)
100     {
101       return tevindref_bc3;
102     }
103     else if (index == 3)
104     {
105       return tevindref_bc4;
106     }
107     return 0;
108   }
109 
GetTevindirefMappixel_shader_uid_data110   u32 GetTevindirefMap(int index) const
111   {
112     if (index == 0)
113     {
114       return tevindref_bi0;
115     }
116     else if (index == 1)
117     {
118       return tevindref_bi1;
119     }
120     else if (index == 2)
121     {
122       return tevindref_bi2;
123     }
124     else if (index == 3)
125     {
126       return tevindref_bi4;
127     }
128     return 0;
129   }
130 
131   struct
132   {
133     // TODO: Can save a lot space by removing the padding bits
134     u32 cc : 24;
135     u32 ac : 24;  // tswap and rswap are left blank (encoded into the tevksel fields below)
136 
137     u32 tevorders_texmap : 3;
138     u32 tevorders_texcoord : 3;
139     u32 tevorders_enable : 1;
140     u32 tevorders_colorchan : 3;
141     u32 pad1 : 6;
142 
143     // TODO: Clean up the swapXY mess
144     u32 hasindstage : 1;
145     u32 tevind : 21;
146     u32 tevksel_swap1a : 2;
147     u32 tevksel_swap2a : 2;
148     u32 tevksel_swap1b : 2;
149     u32 tevksel_swap2b : 2;
150     u32 pad2 : 2;
151 
152     u32 tevksel_swap1c : 2;
153     u32 tevksel_swap2c : 2;
154     u32 tevksel_swap1d : 2;
155     u32 tevksel_swap2d : 2;
156     u32 tevksel_kc : 5;
157     u32 tevksel_ka : 5;
158     u32 pad3 : 14;
159   } stagehash[16];
160 
161   LightingUidData lighting;
162 };
163 #pragma pack()
164 
165 using PixelShaderUid = ShaderUid<pixel_shader_uid_data>;
166 
167 ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
168                                    const pixel_shader_uid_data* uid_data);
169 void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens,
170                                   const ShaderHostConfig& host_config, bool bounding_box);
171 void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config,
172                                    PixelShaderUid* uid);
173 PixelShaderUid GetPixelShaderUid();
174