Home | History | Annotate | Download | only in include
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 Luca Barbieri
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial
     15  * portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  **************************************************************************/
     26 
     27 /* Header for Shader Model 4.0, 4.1 and 5.0 */
     28 
     29 #ifndef SM4_H_
     30 #define SM4_H_
     31 
     32 #include <stdint.h>
     33 #include <string.h>
     34 #include <stdlib.h>
     35 #include <memory>
     36 #include <vector>
     37 #include <map>
     38 #include <iostream>
     39 #include "le32.h"
     40 
     41 #include "sm4_defs.h"
     42 
     43 extern const char* sm4_opcode_names[];
     44 extern const char* sm4_file_names[];
     45 extern const char* sm4_shortfile_names[];
     46 extern const char* sm4_target_names[];
     47 extern const char* sm4_interpolation_names[];
     48 extern const char* sm4_sv_names[];
     49 
     50 struct sm4_token_version
     51 {
     52 	unsigned minor : 4;
     53 	unsigned major : 4;
     54 	unsigned format : 8;
     55 	unsigned type : 16;
     56 };
     57 
     58 struct sm4_token_instruction
     59 {
     60 	// we don't make it an union directly because unions can't be inherited from
     61 	union
     62 	{
     63 		// length and extended are always present, but they are only here to reduce duplication
     64 		struct
     65 		{
     66 			unsigned opcode : 11;
     67 			unsigned _11_23 : 13;
     68 			unsigned length : 7;
     69 			unsigned extended : 1;
     70 		};
     71 		struct
     72 		{
     73 			unsigned opcode : 11;
     74 			unsigned resinfo_return_type : 2;
     75 			unsigned sat : 1;
     76 			unsigned _14_17 : 4;
     77 			unsigned test_nz : 1; // bit 18
     78 			unsigned precise_mask : 4;
     79 			unsigned _23 : 1;
     80 			unsigned length : 7;
     81 			unsigned extended : 1;
     82 		} insn;
     83 		struct
     84 		{
     85 			unsigned opcode : 11;
     86 			unsigned threads_in_group : 1;
     87 			unsigned shared_memory : 1;
     88 			unsigned uav_group : 1;
     89 			unsigned uav_global : 1;
     90 			unsigned _15_17 : 3;
     91 		} sync;
     92 		struct
     93 		{
     94 			unsigned opcode : 11;
     95 			unsigned allow_refactoring : 1;
     96 			unsigned fp64 : 1;
     97 			unsigned early_depth_stencil : 1;
     98 			unsigned enable_raw_and_structured_in_non_cs : 1;
     99 		} dcl_global_flags;
    100 		struct
    101 		{
    102 			unsigned opcode : 11;
    103 			unsigned target : 5;
    104 			unsigned nr_samples : 7;
    105 		} dcl_resource;
    106 		struct
    107 		{
    108 			unsigned opcode : 11;
    109 			unsigned shadow : 1;
    110 			unsigned mono : 1;
    111 		} dcl_sampler;
    112 		struct
    113 		{
    114 			unsigned opcode : 11;
    115 			unsigned interpolation : 5;
    116 		} dcl_input_ps;
    117 		struct
    118 		{
    119 			unsigned opcode : 11;
    120 			unsigned dynamic : 1;
    121 		} dcl_constant_buffer;
    122 		struct
    123 		{
    124 			unsigned opcode : 11;
    125 			unsigned primitive : 6;
    126 		} dcl_gs_input_primitive;
    127 		struct
    128 		{
    129 			unsigned opcode : 11;
    130 			unsigned primitive_topology : 7;
    131 		} dcl_gs_output_primitive_topology;
    132 		struct
    133 		{
    134 			unsigned opcode : 11;
    135 			unsigned control_points : 6;
    136 		} dcl_input_control_point_count;
    137 		struct
    138 		{
    139 			unsigned opcode : 11;
    140 			unsigned control_points : 6;
    141 		} dcl_output_control_point_count;
    142 		struct
    143 		{
    144 			unsigned opcode : 11;
    145 			unsigned domain : 3; /* D3D_TESSELLATOR_DOMAIN */
    146 		} dcl_tess_domain;
    147 		struct
    148 		{
    149 			unsigned opcode : 11;
    150 			unsigned partitioning : 3; /* D3D_TESSELLATOR_PARTITIONING */
    151 		} dcl_tess_partitioning;
    152 		struct
    153 		{
    154 			unsigned opcode : 11;
    155 			unsigned primitive : 3; /* D3D_TESSELLATOR_OUTPUT_PRIMITIVE */
    156 		} dcl_tess_output_primitive;
    157 	};
    158 };
    159 
    160 union sm4_token_instruction_extended
    161 {
    162 	struct
    163 	{
    164 		unsigned type : 6;
    165 		unsigned _6_30 : 25;
    166 		unsigned extended :1;
    167 	};
    168 	struct
    169 	{
    170 		unsigned type : 6;
    171 		unsigned _6_8 : 3;
    172 		int offset_u : 4;
    173 		int offset_v : 4;
    174 		int offset_w : 4;
    175 	} sample_controls;
    176 	struct
    177 	{
    178 		unsigned type : 6;
    179 		unsigned target : 5;
    180 	} resource_target;
    181 	struct
    182 	{
    183 		unsigned type : 6;
    184 		unsigned x : 4;
    185 		unsigned y : 4;
    186 		unsigned z : 4;
    187 		unsigned w : 4;
    188 	} resource_return_type;
    189 };
    190 
    191 struct sm4_token_resource_return_type
    192 {
    193 	unsigned x : 4;
    194 	unsigned y : 4;
    195 	unsigned z : 4;
    196 	unsigned w : 4;
    197 };
    198 
    199 struct sm4_token_operand
    200 {
    201 	unsigned comps_enum : 2; /* sm4_operands_comps */
    202 	unsigned mode : 2; /* sm4_operand_mode */
    203 	unsigned sel : 8;
    204 	unsigned file : 8; /* sm4_file */
    205 	unsigned num_indices : 2;
    206 	unsigned index0_repr : 3; /* sm4_operand_index_repr */
    207 	unsigned index1_repr : 3; /* sm4_operand_index_repr */
    208 	unsigned index2_repr : 3; /* sm4_operand_index_repr */
    209 	unsigned extended : 1;
    210 };
    211 
    212 #define SM4_OPERAND_SEL_MASK(sel) ((sel) & 0xf)
    213 #define SM4_OPERAND_SEL_SWZ(sel, i) (((sel) >> ((i) * 2)) & 3)
    214 #define SM4_OPERAND_SEL_SCALAR(sel) ((sel) & 3)
    215 
    216 struct sm4_token_operand_extended
    217 {
    218 	unsigned type : 6;
    219 	unsigned neg : 1;
    220 	unsigned abs : 1;
    221 };
    222 
    223 union sm4_any
    224 {
    225 	double f64;
    226 	float f32;
    227 	int64_t i64;
    228 	int32_t i32;
    229 	uint64_t u64;
    230 	int64_t u32;
    231 };
    232 
    233 struct sm4_op;
    234 struct sm4_insn;
    235 struct sm4_dcl;
    236 struct sm4_program;
    237 std::ostream& operator <<(std::ostream& out, const sm4_op& op);
    238 std::ostream& operator <<(std::ostream& out, const sm4_insn& op);
    239 std::ostream& operator <<(std::ostream& out, const sm4_dcl& op);
    240 std::ostream& operator <<(std::ostream& out, const sm4_program& op);
    241 
    242 struct sm4_op
    243 {
    244 	uint8_t mode;
    245 	uint8_t comps;
    246 	uint8_t mask;
    247 	uint8_t num_indices;
    248 	uint8_t swizzle[4];
    249 	sm4_file file;
    250 	sm4_any imm_values[4];
    251 	bool neg;
    252 	bool abs;
    253 	struct
    254 	{
    255 		int64_t disp;
    256 		std::auto_ptr<sm4_op> reg;
    257 	} indices[3];
    258 
    259 	bool is_index_simple(unsigned i) const
    260 	{
    261 		 return !indices[i].reg.get() && indices[i].disp >= 0 && (int64_t)(int32_t)indices[i].disp == indices[i].disp;
    262 	}
    263 
    264 	bool has_simple_index() const
    265 	{
    266 		return num_indices == 1 && is_index_simple(0);
    267 	}
    268 
    269 	sm4_op()
    270 	{
    271 		memset(this, 0, sizeof(*this));
    272 	}
    273 
    274 	void dump();
    275 
    276 private:
    277 	sm4_op(const sm4_op& op)
    278 	{}
    279 };
    280 
    281 /* for sample_d */
    282 #define SM4_MAX_OPS 6
    283 
    284 struct sm4_insn : public sm4_token_instruction
    285 {
    286 	int8_t sample_offset[3];
    287 	uint8_t resource_target;
    288 	uint8_t resource_return_type[4];
    289 
    290 	unsigned num;
    291 	unsigned num_ops;
    292 	std::auto_ptr<sm4_op> ops[SM4_MAX_OPS];
    293 
    294 	sm4_insn()
    295 	{
    296 		memset(this, 0, sizeof(*this));
    297 	}
    298 
    299 	void dump();
    300 
    301 private:
    302 	sm4_insn(const sm4_insn& op)
    303 	{}
    304 };
    305 
    306 struct sm4_dcl : public sm4_token_instruction
    307 {
    308 	std::auto_ptr<sm4_op> op;
    309 	union
    310 	{
    311 		unsigned num;
    312 		float f32;
    313 		sm4_sv sv;
    314 		struct
    315 		{
    316 			unsigned id;
    317 			unsigned expected_function_table_length;
    318 			unsigned table_length;
    319 			unsigned array_length;
    320 		} intf;
    321 		unsigned thread_group_size[3];
    322 		sm4_token_resource_return_type rrt;
    323 		struct
    324 		{
    325 			unsigned num;
    326 			unsigned comps;
    327 		} indexable_temp;
    328 		struct
    329 		{
    330 			unsigned stride;
    331 			unsigned count;
    332 		} structured;
    333 	};
    334 
    335 	void* data;
    336 
    337 	sm4_dcl()
    338 	{
    339 		memset(this, 0, sizeof(*this));
    340 	}
    341 
    342 	~sm4_dcl()
    343 	{
    344 		free(data);
    345 	}
    346 
    347 	void dump();
    348 
    349 private:
    350 	sm4_dcl(const sm4_dcl& op)
    351 	{}
    352 };
    353 
    354 struct _D3D11_SIGNATURE_PARAMETER_DESC;
    355 
    356 struct sm4_program
    357 {
    358 	sm4_token_version version;
    359 	std::vector<sm4_dcl*> dcls;
    360 	std::vector<sm4_insn*> insns;
    361 
    362 	_D3D11_SIGNATURE_PARAMETER_DESC* params_in;
    363 	_D3D11_SIGNATURE_PARAMETER_DESC* params_out;
    364 	_D3D11_SIGNATURE_PARAMETER_DESC* params_patch;
    365 	unsigned num_params_in;
    366 	unsigned num_params_out;
    367 	unsigned num_params_patch;
    368 
    369 	/* for ifs, the insn number of the else or endif if there is no else
    370 	 * for elses, the insn number of the endif
    371 	 * for endifs, the insn number of the if
    372 	 * for loops, the insn number of the endloop
    373 	 * for endloops, the insn number of the loop
    374 	 * for all others, -1
    375 	 */
    376 	std::vector<int> cf_insn_linked;
    377 
    378 	bool labels_found;
    379 	std::vector<int> label_to_insn_num;
    380 
    381 	sm4_program()
    382 	{
    383 		memset(&version, 0, sizeof(version));
    384 		labels_found = false;
    385 		num_params_in = num_params_out = num_params_patch = 0;
    386 	}
    387 
    388 	~sm4_program()
    389 	{
    390 		for(std::vector<sm4_dcl*>::iterator i = dcls.begin(), e = dcls.end(); i != e; ++i)
    391 			delete *i;
    392 		for(std::vector<sm4_insn*>::iterator i = insns.begin(), e = insns.end(); i != e; ++i)
    393 			delete *i;
    394 
    395 		if(num_params_in)
    396 			free(params_in);
    397 		if(num_params_out)
    398 			free(params_out);
    399 		if(num_params_patch)
    400 			free(params_patch);
    401 	}
    402 
    403 	void dump();
    404 
    405 private:
    406 	sm4_program(const sm4_dcl& op)
    407 	{}
    408 };
    409 
    410 sm4_program* sm4_parse(void* tokens, int size);
    411 
    412 bool sm4_link_cf_insns(sm4_program& program);
    413 bool sm4_find_labels(sm4_program& program);
    414 
    415 #endif /* SM4_H_ */
    416 
    417