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#ifndef DXBC_H_
28#define DXBC_H_
29
30#include <stdint.h>
31#include <vector>
32#include <map>
33#include <iostream>
34#include "le32.h"
35
36#define FOURCC(a, b, c, d) ((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24 ))
37#define FOURCC_DXBC FOURCC('D', 'X', 'B', 'C')
38#define FOURCC_RDEF FOURCC('R', 'D', 'E', 'F')
39#define FOURCC_ISGN FOURCC('I', 'S', 'G', 'N')
40#define FOURCC_OSGN FOURCC('O', 'S', 'G', 'N')
41#define FOURCC_SHDR FOURCC('S', 'H', 'D', 'R')
42#define FOURCC_SHEX FOURCC('S', 'H', 'E', 'X')
43#define FOURCC_STAT FOURCC('S', 'T', 'A', 'T')
44#define FOURCC_PCSG FOURCC('P', 'C', 'S', 'G')
45
46/* this is always little-endian! */
47struct dxbc_chunk_header
48{
49	unsigned fourcc;
50	unsigned size;
51};
52
53/* this is always little-endian! */
54struct dxbc_chunk_signature : public dxbc_chunk_header
55{
56	uint32_t count;
57	uint32_t unk;
58	struct
59	{
60		uint32_t name_offset;
61		uint32_t semantic_index;
62		uint32_t system_value_type;
63		uint32_t component_type;
64		uint32_t register_num;
65		uint8_t mask;
66		uint8_t read_write_mask;
67		uint8_t stream; /* TODO: guess! */
68		uint8_t unused;
69	} elements[];
70};
71
72struct dxbc_container
73{
74	const void* data;
75	std::vector<dxbc_chunk_header*> chunks;
76	std::map<unsigned, unsigned> chunk_map;
77};
78
79struct dxbc_container_header
80{
81	unsigned fourcc;
82	uint32_t unk[4];
83	uint32_t one;
84	uint32_t total_size;
85	uint32_t chunk_count;
86};
87
88dxbc_container* dxbc_parse(const void* data, int size);
89std::ostream& operator <<(std::ostream& out, const dxbc_container& container);
90
91dxbc_chunk_header* dxbc_find_chunk(const void* data, int size, unsigned fourcc);
92
93static inline dxbc_chunk_header* dxbc_find_shader_bytecode(const void* data, int size)
94{
95	dxbc_chunk_header* chunk;
96	chunk = dxbc_find_chunk(data, size, FOURCC_SHDR);
97	if(!chunk)
98		chunk = dxbc_find_chunk(data, size, FOURCC_SHEX);
99	return chunk;
100}
101
102#define DXBC_FIND_INPUT_SIGNATURE    0
103#define DXBC_FIND_OUTPUT_SIGNATURE   1
104#define DXBC_FIND_PATCH_SIGNATURE    2
105
106static inline dxbc_chunk_signature* dxbc_find_signature(const void* data, int size, unsigned kind)
107{
108	unsigned fourcc;
109	switch(kind) {
110	case DXBC_FIND_INPUT_SIGNATURE:  fourcc = FOURCC_ISGN; break;
111	case DXBC_FIND_OUTPUT_SIGNATURE: fourcc = FOURCC_OSGN; break;
112	case DXBC_FIND_PATCH_SIGNATURE:  fourcc = FOURCC_PCSG; break;
113	default:
114		return NULL;
115	}
116	return (dxbc_chunk_signature*)dxbc_find_chunk(data, size, fourcc);
117}
118
119struct _D3D11_SIGNATURE_PARAMETER_DESC;
120typedef struct _D3D11_SIGNATURE_PARAMETER_DESC D3D11_SIGNATURE_PARAMETER_DESC;
121int dxbc_parse_signature(dxbc_chunk_signature* sig, D3D11_SIGNATURE_PARAMETER_DESC** params);
122
123std::pair<void*, size_t> dxbc_assemble(struct dxbc_chunk_header** chunks, unsigned num_chunks);
124
125#endif /* DXBC_H_ */
126