VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-shader.cpp@ 90778

Last change on this file since 90778 was 88803, checked in by vboxsync, 3 years ago

Devices/Graphics: more DX commands; disassemble shaders for debug log. bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 85.9 KB
Line 
1/* $Id: DevVGA-SVGA3d-dx-shader.cpp 88803 2021-04-30 13:23:05Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device - VGPU10+ (DX) shader utilities.
4 */
5
6/*
7 * Copyright (C) 2020-2021 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
23#include <VBox/AssertGuest.h>
24#include <VBox/log.h>
25
26#include <iprt/asm.h>
27#include <iprt/md5.h>
28#include <iprt/mem.h>
29#include <iprt/string.h>
30
31#include "DevVGA-SVGA3d-dx-shader.h"
32
33
34/*
35 *
36 * DXBC shader binary format definitions.
37 *
38 */
39
40/* DXBC container header. */
41typedef struct DXBCHeader
42{
43 uint32_t u32DXBC; /* 0x43425844 = 'D', 'X', 'B', 'C' */
44 uint8_t au8Hash[16]; /* Modified MD5 hash. See dxbcHash. */
45 uint32_t u32Version; /* 1 */
46 uint32_t cbTotal; /* Total size in bytes. Including the header. */
47 uint32_t cBlob; /* Number of entries in aBlobOffset array. */
48 uint32_t aBlobOffset[1]; /* Offsets of blobs from the start of DXBC header. */
49} DXBCHeader;
50
51#define DXBC_MAGIC RT_MAKE_U32_FROM_U8('D', 'X', 'B', 'C')
52
53/* DXBC blob header. */
54typedef struct DXBCBlobHeader
55{
56 uint32_t u32BlobType; /* FourCC code. DXBC_BLOB_TYPE_* */
57 uint32_t cbBlob; /* Size of the blob excluding the blob header. 4 bytes aligned. */
58 /* Followed by the blob's data. */
59} DXBCBlobHeader;
60
61/* DXBC blob types. */
62#define DXBC_BLOB_TYPE_ISGN RT_MAKE_U32_FROM_U8('I', 'S', 'G', 'N')
63#define DXBC_BLOB_TYPE_OSGN RT_MAKE_U32_FROM_U8('O', 'S', 'G', 'N')
64#define DXBC_BLOB_TYPE_SHDR RT_MAKE_U32_FROM_U8('S', 'H', 'D', 'R')
65/** @todo More... */
66
67/* 'SHDR' blob data format. */
68typedef struct DXBCBlobSHDR
69{
70 VGPU10ProgramToken programToken;
71 uint32_t cToken; /* Number of 32 bit tokens including programToken and cToken. */
72 uint32_t au32Token[1]; /* cToken - 2 number of tokens. */
73} DXBCBlobSHDR;
74
75/* Element of an input or output signature. */
76typedef struct DXBCBlobIOSGNElement
77{
78 uint32_t offElementName; /* Offset of the semantic's name relative to the start of the blob data. */
79 uint32_t idxSemantic; /* Semantic index. */
80 uint32_t enmSystemValue; /* SVGA3dDXSignatureSemanticName */
81 uint32_t enmComponentType; /* 1 - unsigned, 2 - integer, 3 - float. */
82 uint32_t idxRegister; /* Shader register index. Elements must be sorted by register index. */
83 uint32_t mask : 8; /* Component mask. Lower 4 bits represent X, Y, Z, W channels. */
84 uint32_t mask2 : 8; /* Which components are used in the shader. */
85 uint32_t pad : 16;
86} DXBCBlobIOSGNElement;
87
88/* 'ISGN' and 'OSGN' blob data format. */
89typedef struct DXBCBlobIOSGN
90{
91 uint32_t cElement; /* Number of signature elements. */
92 uint32_t offElement; /* Offset of the first element from the start of the blob. Equals to 8. */
93 DXBCBlobIOSGNElement aElement[1]; /* Signature elements. Size is cElement. */
94 /* Followed by ASCIIZ semantic names. */
95} DXBCBlobIOSGN;
96
97
98/*
99 * VGPU10 shader parser definitions.
100 */
101
102/* Parsed info about an operand index. */
103typedef struct VGPUOperandIndex
104{
105 uint32_t indexRepresentation; /* VGPU10_OPERAND_INDEX_REPRESENTATION */
106 uint64_t aOperandIndex[2]; /* Needs up to 2 qwords. */
107} VGPUOperandIndex;
108
109/* Parsed info about an operand. */
110typedef struct VGPUOperand
111{
112 uint32_t numComponents : 2; /* VGPU10_OPERAND_NUM_COMPONENTS */
113 uint32_t selectionMode : 2; /* VGPU10_OPERAND_4_COMPONENT_SELECTION_MODE */
114 uint32_t mask : 4; /* 4-bits X, Y, Z, W mask for VGPU10_OPERAND_4_COMPONENT_MASK_MODE. */
115 uint32_t operandType : 8; /* VGPU10_OPERAND_TYPE */
116 uint32_t indexDimension : 2; /* VGPU10_OPERAND_INDEX_DIMENSION */
117 VGPUOperandIndex aOperandIndex[VGPU10_OPERAND_INDEX_3D]; /* Up to 3. */
118 uint32_t aImm[4]; /* Immediate values for VGPU10_OPERAND_TYPE_IMMEDIATE* */
119} VGPUOperand;
120
121/* Parsed info about an opcode. */
122typedef struct VGPUOpcode
123{
124 uint32_t cOpcodeToken; /* Number of tokens for this operation. */
125 uint32_t opcodeType; /* VGPU10_OPCODE_* */
126 uint32_t semanticName; /* SVGA3dDXSignatureSemanticName for system value declarations. */
127 uint32_t cOperand; /* Nunber of operands. */
128 VGPUOperand aOperand[8]; /* 8 should be enough for everyone. */
129} VGPUOpcode;
130
131typedef struct VGPUOpcodeInfo
132{
133 uint32_t cOperand; /* Number of operands for this opcode. */
134} VGPUOpcodeInfo;
135
136static VGPUOpcodeInfo const g_aOpcodeInfo[] =
137{
138 { 3 }, /* VGPU10_OPCODE_ADD */
139 { 3 }, /* VGPU10_OPCODE_AND */
140 { 0 }, /* VGPU10_OPCODE_BREAK */
141 { 1 }, /* VGPU10_OPCODE_BREAKC */
142 { 1 }, /* VGPU10_OPCODE_CALL */
143 { 2 }, /* VGPU10_OPCODE_CALLC */
144 { 1 }, /* VGPU10_OPCODE_CASE */
145 { 0 }, /* VGPU10_OPCODE_CONTINUE */
146 { 1 }, /* VGPU10_OPCODE_CONTINUEC */
147 { 0 }, /* VGPU10_OPCODE_CUT */
148 { 0 }, /* VGPU10_OPCODE_DEFAULT */
149 { 2 }, /* VGPU10_OPCODE_DERIV_RTX */
150 { 2 }, /* VGPU10_OPCODE_DERIV_RTY */
151 { 1 }, /* VGPU10_OPCODE_DISCARD */
152 { 3 }, /* VGPU10_OPCODE_DIV */
153 { 3 }, /* VGPU10_OPCODE_DP2 */
154 { 3 }, /* VGPU10_OPCODE_DP3 */
155 { 3 }, /* VGPU10_OPCODE_DP4 */
156 { 0 }, /* VGPU10_OPCODE_ELSE */
157 { 0 }, /* VGPU10_OPCODE_EMIT */
158 { 0 }, /* VGPU10_OPCODE_EMITTHENCUT */
159 { 0 }, /* VGPU10_OPCODE_ENDIF */
160 { 0 }, /* VGPU10_OPCODE_ENDLOOP */
161 { 0 }, /* VGPU10_OPCODE_ENDSWITCH */
162 { 3 }, /* VGPU10_OPCODE_EQ */
163 { 2 }, /* VGPU10_OPCODE_EXP */
164 { 2 }, /* VGPU10_OPCODE_FRC */
165 { 2 }, /* VGPU10_OPCODE_FTOI */
166 { 2 }, /* VGPU10_OPCODE_FTOU */
167 { 3 }, /* VGPU10_OPCODE_GE */
168 { 3 }, /* VGPU10_OPCODE_IADD */
169 { 1 }, /* VGPU10_OPCODE_IF */
170 { 3 }, /* VGPU10_OPCODE_IEQ */
171 { 3 }, /* VGPU10_OPCODE_IGE */
172 { 3 }, /* VGPU10_OPCODE_ILT */
173 { 4 }, /* VGPU10_OPCODE_IMAD */
174 { 3 }, /* VGPU10_OPCODE_IMAX */
175 { 3 }, /* VGPU10_OPCODE_IMIN */
176 { 4 }, /* VGPU10_OPCODE_IMUL */
177 { 3 }, /* VGPU10_OPCODE_INE */
178 { 2 }, /* VGPU10_OPCODE_INEG */
179 { 3 }, /* VGPU10_OPCODE_ISHL */
180 { 3 }, /* VGPU10_OPCODE_ISHR */
181 { 2 }, /* VGPU10_OPCODE_ITOF */
182 { 1 }, /* VGPU10_OPCODE_LABEL */
183 { 3 }, /* VGPU10_OPCODE_LD */
184 { 4 }, /* VGPU10_OPCODE_LD_MS */
185 { 2 }, /* VGPU10_OPCODE_LOG */
186 { 0 }, /* VGPU10_OPCODE_LOOP */
187 { 3 }, /* VGPU10_OPCODE_LT */
188 { 4 }, /* VGPU10_OPCODE_MAD */
189 { 3 }, /* VGPU10_OPCODE_MIN */
190 { 3 }, /* VGPU10_OPCODE_MAX */
191 { UINT32_MAX }, /* VGPU10_OPCODE_CUSTOMDATA: special opcode */
192 { 2 }, /* VGPU10_OPCODE_MOV */
193 { 4 }, /* VGPU10_OPCODE_MOVC */
194 { 3 }, /* VGPU10_OPCODE_MUL */
195 { 3 }, /* VGPU10_OPCODE_NE */
196 { 0 }, /* VGPU10_OPCODE_NOP */
197 { 2 }, /* VGPU10_OPCODE_NOT */
198 { 3 }, /* VGPU10_OPCODE_OR */
199 { 3 }, /* VGPU10_OPCODE_RESINFO */
200 { 0 }, /* VGPU10_OPCODE_RET */
201 { 1 }, /* VGPU10_OPCODE_RETC */
202 { 2 }, /* VGPU10_OPCODE_ROUND_NE */
203 { 2 }, /* VGPU10_OPCODE_ROUND_NI */
204 { 2 }, /* VGPU10_OPCODE_ROUND_PI */
205 { 2 }, /* VGPU10_OPCODE_ROUND_Z */
206 { 2 }, /* VGPU10_OPCODE_RSQ */
207 { 4 }, /* VGPU10_OPCODE_SAMPLE */
208 { 5 }, /* VGPU10_OPCODE_SAMPLE_C */
209 { 5 }, /* VGPU10_OPCODE_SAMPLE_C_LZ */
210 { 5 }, /* VGPU10_OPCODE_SAMPLE_L */
211 { 6 }, /* VGPU10_OPCODE_SAMPLE_D */
212 { 5 }, /* VGPU10_OPCODE_SAMPLE_B */
213 { 2 }, /* VGPU10_OPCODE_SQRT */
214 { 1 }, /* VGPU10_OPCODE_SWITCH */
215 { 3 }, /* VGPU10_OPCODE_SINCOS */
216 { 4 }, /* VGPU10_OPCODE_UDIV */
217 { 3 }, /* VGPU10_OPCODE_ULT */
218 { 3 }, /* VGPU10_OPCODE_UGE */
219 { 4 }, /* VGPU10_OPCODE_UMUL */
220 { 4 }, /* VGPU10_OPCODE_UMAD */
221 { 3 }, /* VGPU10_OPCODE_UMAX */
222 { 3 }, /* VGPU10_OPCODE_UMIN */
223 { 3 }, /* VGPU10_OPCODE_USHR */
224 { 2 }, /* VGPU10_OPCODE_UTOF */
225 { 3 }, /* VGPU10_OPCODE_XOR */
226 { 1 }, /* VGPU10_OPCODE_DCL_RESOURCE */
227 { 1 }, /* VGPU10_OPCODE_DCL_CONSTANT_BUFFER */
228 { 1 }, /* VGPU10_OPCODE_DCL_SAMPLER */
229 { 1 }, /* VGPU10_OPCODE_DCL_INDEX_RANGE */
230 { 0 }, /* VGPU10_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY */
231 { 0 }, /* VGPU10_OPCODE_DCL_GS_INPUT_PRIMITIVE */
232 { 0 }, /* VGPU10_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT */
233 { 1 }, /* VGPU10_OPCODE_DCL_INPUT */
234 { 1 }, /* VGPU10_OPCODE_DCL_INPUT_SGV */
235 { 1 }, /* VGPU10_OPCODE_DCL_INPUT_SIV */
236 { 1 }, /* VGPU10_OPCODE_DCL_INPUT_PS */
237 { 1 }, /* VGPU10_OPCODE_DCL_INPUT_PS_SGV */
238 { 1 }, /* VGPU10_OPCODE_DCL_INPUT_PS_SIV */
239 { 1 }, /* VGPU10_OPCODE_DCL_OUTPUT */
240 { 1 }, /* VGPU10_OPCODE_DCL_OUTPUT_SGV */
241 { 1 }, /* VGPU10_OPCODE_DCL_OUTPUT_SIV */
242 { 0 }, /* VGPU10_OPCODE_DCL_TEMPS */
243 { 0 }, /* VGPU10_OPCODE_DCL_INDEXABLE_TEMP */
244 { 0 }, /* VGPU10_OPCODE_DCL_GLOBAL_FLAGS */
245 { UINT32_MAX }, /* VGPU10_OPCODE_VMWARE: special opcode */
246 { 4 }, /* VGPU10_OPCODE_LOD */
247 { 4 }, /* VGPU10_OPCODE_GATHER4 */
248 { 3 }, /* VGPU10_OPCODE_SAMPLE_POS */
249 { 2 }, /* VGPU10_OPCODE_SAMPLE_INFO */
250 { UINT32_MAX }, /* VGPU10_OPCODE_RESERVED1: special opcode */
251 { 0 }, /* VGPU10_OPCODE_HS_DECLS */
252 { 0 }, /* VGPU10_OPCODE_HS_CONTROL_POINT_PHASE */
253 { 0 }, /* VGPU10_OPCODE_HS_FORK_PHASE */
254 { 0 }, /* VGPU10_OPCODE_HS_JOIN_PHASE */
255 { 1 }, /* VGPU10_OPCODE_EMIT_STREAM */
256 { 1 }, /* VGPU10_OPCODE_CUT_STREAM */
257 { 1 }, /* VGPU10_OPCODE_EMITTHENCUT_STREAM */
258 { 1 }, /* VGPU10_OPCODE_INTERFACE_CALL */
259 { 2 }, /* VGPU10_OPCODE_BUFINFO */
260 { 2 }, /* VGPU10_OPCODE_DERIV_RTX_COARSE */
261 { 2 }, /* VGPU10_OPCODE_DERIV_RTX_FINE */
262 { 2 }, /* VGPU10_OPCODE_DERIV_RTY_COARSE */
263 { 2 }, /* VGPU10_OPCODE_DERIV_RTY_FINE */
264 { 5 }, /* VGPU10_OPCODE_GATHER4_C */
265 { 5 }, /* VGPU10_OPCODE_GATHER4_PO */
266 { 6 }, /* VGPU10_OPCODE_GATHER4_PO_C */
267 { 2 }, /* VGPU10_OPCODE_RCP */
268 { 2 }, /* VGPU10_OPCODE_F32TOF16 */
269 { 2 }, /* VGPU10_OPCODE_F16TOF32 */
270 { 4 }, /* VGPU10_OPCODE_UADDC */
271 { 4 }, /* VGPU10_OPCODE_USUBB */
272 { 2 }, /* VGPU10_OPCODE_COUNTBITS */
273 { 2 }, /* VGPU10_OPCODE_FIRSTBIT_HI */
274 { 2 }, /* VGPU10_OPCODE_FIRSTBIT_LO */
275 { 2 }, /* VGPU10_OPCODE_FIRSTBIT_SHI */
276 { 4 }, /* VGPU10_OPCODE_UBFE */
277 { 4 }, /* VGPU10_OPCODE_IBFE */
278 { 5 }, /* VGPU10_OPCODE_BFI */
279 { 2 }, /* VGPU10_OPCODE_BFREV */
280 { 5 }, /* VGPU10_OPCODE_SWAPC */
281 { 1 }, /* VGPU10_OPCODE_DCL_STREAM */
282 { 0 }, /* VGPU10_OPCODE_DCL_FUNCTION_BODY */
283 { 0 }, /* VGPU10_OPCODE_DCL_FUNCTION_TABLE */
284 { 0 }, /* VGPU10_OPCODE_DCL_INTERFACE */
285 { 0 }, /* VGPU10_OPCODE_DCL_INPUT_CONTROL_POINT_COUNT */
286 { 0 }, /* VGPU10_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT */
287 { 0 }, /* VGPU10_OPCODE_DCL_TESS_DOMAIN */
288 { 0 }, /* VGPU10_OPCODE_DCL_TESS_PARTITIONING */
289 { 0 }, /* VGPU10_OPCODE_DCL_TESS_OUTPUT_PRIMITIVE */
290 { 0 }, /* VGPU10_OPCODE_DCL_HS_MAX_TESSFACTOR */
291 { 0 }, /* VGPU10_OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT */
292 { 0 }, /* VGPU10_OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT */
293 { 0 }, /* VGPU10_OPCODE_DCL_THREAD_GROUP */
294 { 1 }, /* VGPU10_OPCODE_DCL_UAV_TYPED */
295 { 1 }, /* VGPU10_OPCODE_DCL_UAV_RAW */
296 { 1 }, /* VGPU10_OPCODE_DCL_UAV_STRUCTURED */
297 { 1 }, /* VGPU10_OPCODE_DCL_TGSM_RAW */
298 { 1 }, /* VGPU10_OPCODE_DCL_TGSM_STRUCTURED */
299 { 1 }, /* VGPU10_OPCODE_DCL_RESOURCE_RAW */
300 { 1 }, /* VGPU10_OPCODE_DCL_RESOURCE_STRUCTURED */
301 { 3 }, /* VGPU10_OPCODE_LD_UAV_TYPED */
302 { 3 }, /* VGPU10_OPCODE_STORE_UAV_TYPED */
303 { 3 }, /* VGPU10_OPCODE_LD_RAW */
304 { 3 }, /* VGPU10_OPCODE_STORE_RAW */
305 { 4 }, /* VGPU10_OPCODE_LD_STRUCTURED */
306 { 4 }, /* VGPU10_OPCODE_STORE_STRUCTURED */
307 { 3 }, /* VGPU10_OPCODE_ATOMIC_AND */
308 { 3 }, /* VGPU10_OPCODE_ATOMIC_OR */
309 { 3 }, /* VGPU10_OPCODE_ATOMIC_XOR */
310 { 4 }, /* VGPU10_OPCODE_ATOMIC_CMP_STORE */
311 { 3 }, /* VGPU10_OPCODE_ATOMIC_IADD */
312 { 3 }, /* VGPU10_OPCODE_ATOMIC_IMAX */
313 { 3 }, /* VGPU10_OPCODE_ATOMIC_IMIN */
314 { 3 }, /* VGPU10_OPCODE_ATOMIC_UMAX */
315 { 3 }, /* VGPU10_OPCODE_ATOMIC_UMIN */
316 { 2 }, /* VGPU10_OPCODE_IMM_ATOMIC_ALLOC */
317 { 2 }, /* VGPU10_OPCODE_IMM_ATOMIC_CONSUME */
318 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_IADD */
319 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_AND */
320 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_OR */
321 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_XOR */
322 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_EXCH */
323 { 5 }, /* VGPU10_OPCODE_IMM_ATOMIC_CMP_EXCH */
324 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_IMAX */
325 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_IMIN */
326 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_UMAX */
327 { 4 }, /* VGPU10_OPCODE_IMM_ATOMIC_UMIN */
328 { 0 }, /* VGPU10_OPCODE_SYNC */
329 { 3 }, /* VGPU10_OPCODE_DADD */
330 { 3 }, /* VGPU10_OPCODE_DMAX */
331 { 3 }, /* VGPU10_OPCODE_DMIN */
332 { 3 }, /* VGPU10_OPCODE_DMUL */
333 { 3 }, /* VGPU10_OPCODE_DEQ */
334 { 3 }, /* VGPU10_OPCODE_DGE */
335 { 3 }, /* VGPU10_OPCODE_DLT */
336 { 3 }, /* VGPU10_OPCODE_DNE */
337 { 2 }, /* VGPU10_OPCODE_DMOV */
338 { 4 }, /* VGPU10_OPCODE_DMOVC */
339 { 2 }, /* VGPU10_OPCODE_DTOF */
340 { 2 }, /* VGPU10_OPCODE_FTOD */
341 { 3 }, /* VGPU10_OPCODE_EVAL_SNAPPED */
342 { 3 }, /* VGPU10_OPCODE_EVAL_SAMPLE_INDEX */
343 { 2 }, /* VGPU10_OPCODE_EVAL_CENTROID */
344 { 0 }, /* VGPU10_OPCODE_DCL_GS_INSTANCE_COUNT */
345 { 0 }, /* VGPU10_OPCODE_ABORT */
346 { 0 }, /* VGPU10_OPCODE_DEBUG_BREAK */
347 { 0 }, /* VGPU10_OPCODE_RESERVED0 */
348 { 3 }, /* VGPU10_OPCODE_DDIV */
349 { 4 }, /* VGPU10_OPCODE_DFMA */
350 { 2 }, /* VGPU10_OPCODE_DRCP */
351 { 4 }, /* VGPU10_OPCODE_MSAD */
352 { 2 }, /* VGPU10_OPCODE_DTOI */
353 { 2 }, /* VGPU10_OPCODE_DTOU */
354 { 2 }, /* VGPU10_OPCODE_ITOD */
355 { 2 }, /* VGPU10_OPCODE_UTOD */
356};
357AssertCompile(RT_ELEMENTS(g_aOpcodeInfo) == VGPU10_NUM_OPCODES);
358
359#ifdef LOG_ENABLED
360/*
361 *
362 * Helpers to translate a VGPU10 shader constant to a string.
363 *
364 */
365
366#define SVGA_CASE_ID2STR(idx) case idx: return #idx
367
368static const char *dxbcOpcodeToString(uint32_t opcodeType)
369{
370 VGPU10_OPCODE_TYPE enm = (VGPU10_OPCODE_TYPE)opcodeType;
371 switch (enm)
372 {
373 SVGA_CASE_ID2STR(VGPU10_OPCODE_ADD);
374 SVGA_CASE_ID2STR(VGPU10_OPCODE_AND);
375 SVGA_CASE_ID2STR(VGPU10_OPCODE_BREAK);
376 SVGA_CASE_ID2STR(VGPU10_OPCODE_BREAKC);
377 SVGA_CASE_ID2STR(VGPU10_OPCODE_CALL);
378 SVGA_CASE_ID2STR(VGPU10_OPCODE_CALLC);
379 SVGA_CASE_ID2STR(VGPU10_OPCODE_CASE);
380 SVGA_CASE_ID2STR(VGPU10_OPCODE_CONTINUE);
381 SVGA_CASE_ID2STR(VGPU10_OPCODE_CONTINUEC);
382 SVGA_CASE_ID2STR(VGPU10_OPCODE_CUT);
383 SVGA_CASE_ID2STR(VGPU10_OPCODE_DEFAULT);
384 SVGA_CASE_ID2STR(VGPU10_OPCODE_DERIV_RTX);
385 SVGA_CASE_ID2STR(VGPU10_OPCODE_DERIV_RTY);
386 SVGA_CASE_ID2STR(VGPU10_OPCODE_DISCARD);
387 SVGA_CASE_ID2STR(VGPU10_OPCODE_DIV);
388 SVGA_CASE_ID2STR(VGPU10_OPCODE_DP2);
389 SVGA_CASE_ID2STR(VGPU10_OPCODE_DP3);
390 SVGA_CASE_ID2STR(VGPU10_OPCODE_DP4);
391 SVGA_CASE_ID2STR(VGPU10_OPCODE_ELSE);
392 SVGA_CASE_ID2STR(VGPU10_OPCODE_EMIT);
393 SVGA_CASE_ID2STR(VGPU10_OPCODE_EMITTHENCUT);
394 SVGA_CASE_ID2STR(VGPU10_OPCODE_ENDIF);
395 SVGA_CASE_ID2STR(VGPU10_OPCODE_ENDLOOP);
396 SVGA_CASE_ID2STR(VGPU10_OPCODE_ENDSWITCH);
397 SVGA_CASE_ID2STR(VGPU10_OPCODE_EQ);
398 SVGA_CASE_ID2STR(VGPU10_OPCODE_EXP);
399 SVGA_CASE_ID2STR(VGPU10_OPCODE_FRC);
400 SVGA_CASE_ID2STR(VGPU10_OPCODE_FTOI);
401 SVGA_CASE_ID2STR(VGPU10_OPCODE_FTOU);
402 SVGA_CASE_ID2STR(VGPU10_OPCODE_GE);
403 SVGA_CASE_ID2STR(VGPU10_OPCODE_IADD);
404 SVGA_CASE_ID2STR(VGPU10_OPCODE_IF);
405 SVGA_CASE_ID2STR(VGPU10_OPCODE_IEQ);
406 SVGA_CASE_ID2STR(VGPU10_OPCODE_IGE);
407 SVGA_CASE_ID2STR(VGPU10_OPCODE_ILT);
408 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMAD);
409 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMAX);
410 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMIN);
411 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMUL);
412 SVGA_CASE_ID2STR(VGPU10_OPCODE_INE);
413 SVGA_CASE_ID2STR(VGPU10_OPCODE_INEG);
414 SVGA_CASE_ID2STR(VGPU10_OPCODE_ISHL);
415 SVGA_CASE_ID2STR(VGPU10_OPCODE_ISHR);
416 SVGA_CASE_ID2STR(VGPU10_OPCODE_ITOF);
417 SVGA_CASE_ID2STR(VGPU10_OPCODE_LABEL);
418 SVGA_CASE_ID2STR(VGPU10_OPCODE_LD);
419 SVGA_CASE_ID2STR(VGPU10_OPCODE_LD_MS);
420 SVGA_CASE_ID2STR(VGPU10_OPCODE_LOG);
421 SVGA_CASE_ID2STR(VGPU10_OPCODE_LOOP);
422 SVGA_CASE_ID2STR(VGPU10_OPCODE_LT);
423 SVGA_CASE_ID2STR(VGPU10_OPCODE_MAD);
424 SVGA_CASE_ID2STR(VGPU10_OPCODE_MIN);
425 SVGA_CASE_ID2STR(VGPU10_OPCODE_MAX);
426 SVGA_CASE_ID2STR(VGPU10_OPCODE_CUSTOMDATA);
427 SVGA_CASE_ID2STR(VGPU10_OPCODE_MOV);
428 SVGA_CASE_ID2STR(VGPU10_OPCODE_MOVC);
429 SVGA_CASE_ID2STR(VGPU10_OPCODE_MUL);
430 SVGA_CASE_ID2STR(VGPU10_OPCODE_NE);
431 SVGA_CASE_ID2STR(VGPU10_OPCODE_NOP);
432 SVGA_CASE_ID2STR(VGPU10_OPCODE_NOT);
433 SVGA_CASE_ID2STR(VGPU10_OPCODE_OR);
434 SVGA_CASE_ID2STR(VGPU10_OPCODE_RESINFO);
435 SVGA_CASE_ID2STR(VGPU10_OPCODE_RET);
436 SVGA_CASE_ID2STR(VGPU10_OPCODE_RETC);
437 SVGA_CASE_ID2STR(VGPU10_OPCODE_ROUND_NE);
438 SVGA_CASE_ID2STR(VGPU10_OPCODE_ROUND_NI);
439 SVGA_CASE_ID2STR(VGPU10_OPCODE_ROUND_PI);
440 SVGA_CASE_ID2STR(VGPU10_OPCODE_ROUND_Z);
441 SVGA_CASE_ID2STR(VGPU10_OPCODE_RSQ);
442 SVGA_CASE_ID2STR(VGPU10_OPCODE_SAMPLE);
443 SVGA_CASE_ID2STR(VGPU10_OPCODE_SAMPLE_C);
444 SVGA_CASE_ID2STR(VGPU10_OPCODE_SAMPLE_C_LZ);
445 SVGA_CASE_ID2STR(VGPU10_OPCODE_SAMPLE_L);
446 SVGA_CASE_ID2STR(VGPU10_OPCODE_SAMPLE_D);
447 SVGA_CASE_ID2STR(VGPU10_OPCODE_SAMPLE_B);
448 SVGA_CASE_ID2STR(VGPU10_OPCODE_SQRT);
449 SVGA_CASE_ID2STR(VGPU10_OPCODE_SWITCH);
450 SVGA_CASE_ID2STR(VGPU10_OPCODE_SINCOS);
451 SVGA_CASE_ID2STR(VGPU10_OPCODE_UDIV);
452 SVGA_CASE_ID2STR(VGPU10_OPCODE_ULT);
453 SVGA_CASE_ID2STR(VGPU10_OPCODE_UGE);
454 SVGA_CASE_ID2STR(VGPU10_OPCODE_UMUL);
455 SVGA_CASE_ID2STR(VGPU10_OPCODE_UMAD);
456 SVGA_CASE_ID2STR(VGPU10_OPCODE_UMAX);
457 SVGA_CASE_ID2STR(VGPU10_OPCODE_UMIN);
458 SVGA_CASE_ID2STR(VGPU10_OPCODE_USHR);
459 SVGA_CASE_ID2STR(VGPU10_OPCODE_UTOF);
460 SVGA_CASE_ID2STR(VGPU10_OPCODE_XOR);
461 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_RESOURCE);
462 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_CONSTANT_BUFFER);
463 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_SAMPLER);
464 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INDEX_RANGE);
465 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY);
466 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_GS_INPUT_PRIMITIVE);
467 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT);
468 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INPUT);
469 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INPUT_SGV);
470 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INPUT_SIV);
471 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INPUT_PS);
472 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INPUT_PS_SGV);
473 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INPUT_PS_SIV);
474 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_OUTPUT);
475 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_OUTPUT_SGV);
476 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_OUTPUT_SIV);
477 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_TEMPS);
478 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INDEXABLE_TEMP);
479 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_GLOBAL_FLAGS);
480 SVGA_CASE_ID2STR(VGPU10_OPCODE_VMWARE);
481 SVGA_CASE_ID2STR(VGPU10_OPCODE_LOD);
482 SVGA_CASE_ID2STR(VGPU10_OPCODE_GATHER4);
483 SVGA_CASE_ID2STR(VGPU10_OPCODE_SAMPLE_POS);
484 SVGA_CASE_ID2STR(VGPU10_OPCODE_SAMPLE_INFO);
485 SVGA_CASE_ID2STR(VGPU10_OPCODE_RESERVED1);
486 SVGA_CASE_ID2STR(VGPU10_OPCODE_HS_DECLS);
487 SVGA_CASE_ID2STR(VGPU10_OPCODE_HS_CONTROL_POINT_PHASE);
488 SVGA_CASE_ID2STR(VGPU10_OPCODE_HS_FORK_PHASE);
489 SVGA_CASE_ID2STR(VGPU10_OPCODE_HS_JOIN_PHASE);
490 SVGA_CASE_ID2STR(VGPU10_OPCODE_EMIT_STREAM);
491 SVGA_CASE_ID2STR(VGPU10_OPCODE_CUT_STREAM);
492 SVGA_CASE_ID2STR(VGPU10_OPCODE_EMITTHENCUT_STREAM);
493 SVGA_CASE_ID2STR(VGPU10_OPCODE_INTERFACE_CALL);
494 SVGA_CASE_ID2STR(VGPU10_OPCODE_BUFINFO);
495 SVGA_CASE_ID2STR(VGPU10_OPCODE_DERIV_RTX_COARSE);
496 SVGA_CASE_ID2STR(VGPU10_OPCODE_DERIV_RTX_FINE);
497 SVGA_CASE_ID2STR(VGPU10_OPCODE_DERIV_RTY_COARSE);
498 SVGA_CASE_ID2STR(VGPU10_OPCODE_DERIV_RTY_FINE);
499 SVGA_CASE_ID2STR(VGPU10_OPCODE_GATHER4_C);
500 SVGA_CASE_ID2STR(VGPU10_OPCODE_GATHER4_PO);
501 SVGA_CASE_ID2STR(VGPU10_OPCODE_GATHER4_PO_C);
502 SVGA_CASE_ID2STR(VGPU10_OPCODE_RCP);
503 SVGA_CASE_ID2STR(VGPU10_OPCODE_F32TOF16);
504 SVGA_CASE_ID2STR(VGPU10_OPCODE_F16TOF32);
505 SVGA_CASE_ID2STR(VGPU10_OPCODE_UADDC);
506 SVGA_CASE_ID2STR(VGPU10_OPCODE_USUBB);
507 SVGA_CASE_ID2STR(VGPU10_OPCODE_COUNTBITS);
508 SVGA_CASE_ID2STR(VGPU10_OPCODE_FIRSTBIT_HI);
509 SVGA_CASE_ID2STR(VGPU10_OPCODE_FIRSTBIT_LO);
510 SVGA_CASE_ID2STR(VGPU10_OPCODE_FIRSTBIT_SHI);
511 SVGA_CASE_ID2STR(VGPU10_OPCODE_UBFE);
512 SVGA_CASE_ID2STR(VGPU10_OPCODE_IBFE);
513 SVGA_CASE_ID2STR(VGPU10_OPCODE_BFI);
514 SVGA_CASE_ID2STR(VGPU10_OPCODE_BFREV);
515 SVGA_CASE_ID2STR(VGPU10_OPCODE_SWAPC);
516 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_STREAM);
517 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_FUNCTION_BODY);
518 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_FUNCTION_TABLE);
519 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INTERFACE);
520 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_INPUT_CONTROL_POINT_COUNT);
521 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT);
522 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_TESS_DOMAIN);
523 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_TESS_PARTITIONING);
524 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_TESS_OUTPUT_PRIMITIVE);
525 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_HS_MAX_TESSFACTOR);
526 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT);
527 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT);
528 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_THREAD_GROUP);
529 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_UAV_TYPED);
530 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_UAV_RAW);
531 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_UAV_STRUCTURED);
532 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_TGSM_RAW);
533 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_TGSM_STRUCTURED);
534 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_RESOURCE_RAW);
535 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_RESOURCE_STRUCTURED);
536 SVGA_CASE_ID2STR(VGPU10_OPCODE_LD_UAV_TYPED);
537 SVGA_CASE_ID2STR(VGPU10_OPCODE_STORE_UAV_TYPED);
538 SVGA_CASE_ID2STR(VGPU10_OPCODE_LD_RAW);
539 SVGA_CASE_ID2STR(VGPU10_OPCODE_STORE_RAW);
540 SVGA_CASE_ID2STR(VGPU10_OPCODE_LD_STRUCTURED);
541 SVGA_CASE_ID2STR(VGPU10_OPCODE_STORE_STRUCTURED);
542 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_AND);
543 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_OR);
544 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_XOR);
545 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_CMP_STORE);
546 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_IADD);
547 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_IMAX);
548 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_IMIN);
549 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_UMAX);
550 SVGA_CASE_ID2STR(VGPU10_OPCODE_ATOMIC_UMIN);
551 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_ALLOC);
552 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_CONSUME);
553 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_IADD);
554 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_AND);
555 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_OR);
556 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_XOR);
557 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_EXCH);
558 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_CMP_EXCH);
559 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_IMAX);
560 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_IMIN);
561 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_UMAX);
562 SVGA_CASE_ID2STR(VGPU10_OPCODE_IMM_ATOMIC_UMIN);
563 SVGA_CASE_ID2STR(VGPU10_OPCODE_SYNC);
564 SVGA_CASE_ID2STR(VGPU10_OPCODE_DADD);
565 SVGA_CASE_ID2STR(VGPU10_OPCODE_DMAX);
566 SVGA_CASE_ID2STR(VGPU10_OPCODE_DMIN);
567 SVGA_CASE_ID2STR(VGPU10_OPCODE_DMUL);
568 SVGA_CASE_ID2STR(VGPU10_OPCODE_DEQ);
569 SVGA_CASE_ID2STR(VGPU10_OPCODE_DGE);
570 SVGA_CASE_ID2STR(VGPU10_OPCODE_DLT);
571 SVGA_CASE_ID2STR(VGPU10_OPCODE_DNE);
572 SVGA_CASE_ID2STR(VGPU10_OPCODE_DMOV);
573 SVGA_CASE_ID2STR(VGPU10_OPCODE_DMOVC);
574 SVGA_CASE_ID2STR(VGPU10_OPCODE_DTOF);
575 SVGA_CASE_ID2STR(VGPU10_OPCODE_FTOD);
576 SVGA_CASE_ID2STR(VGPU10_OPCODE_EVAL_SNAPPED);
577 SVGA_CASE_ID2STR(VGPU10_OPCODE_EVAL_SAMPLE_INDEX);
578 SVGA_CASE_ID2STR(VGPU10_OPCODE_EVAL_CENTROID);
579 SVGA_CASE_ID2STR(VGPU10_OPCODE_DCL_GS_INSTANCE_COUNT);
580 SVGA_CASE_ID2STR(VGPU10_OPCODE_ABORT);
581 SVGA_CASE_ID2STR(VGPU10_OPCODE_DEBUG_BREAK);
582 SVGA_CASE_ID2STR(VGPU10_OPCODE_RESERVED0);
583 SVGA_CASE_ID2STR(VGPU10_OPCODE_DDIV);
584 SVGA_CASE_ID2STR(VGPU10_OPCODE_DFMA);
585 SVGA_CASE_ID2STR(VGPU10_OPCODE_DRCP);
586 SVGA_CASE_ID2STR(VGPU10_OPCODE_MSAD);
587 SVGA_CASE_ID2STR(VGPU10_OPCODE_DTOI);
588 SVGA_CASE_ID2STR(VGPU10_OPCODE_DTOU);
589 SVGA_CASE_ID2STR(VGPU10_OPCODE_ITOD);
590 SVGA_CASE_ID2STR(VGPU10_OPCODE_UTOD);
591 SVGA_CASE_ID2STR(VGPU10_NUM_OPCODES);
592 }
593 return NULL;
594}
595
596
597static const char *dxbcShaderTypeToString(uint32_t value)
598{
599 VGPU10_PROGRAM_TYPE enm = (VGPU10_PROGRAM_TYPE)value;
600 switch (enm)
601 {
602 SVGA_CASE_ID2STR(VGPU10_PIXEL_SHADER);
603 SVGA_CASE_ID2STR(VGPU10_VERTEX_SHADER);
604 SVGA_CASE_ID2STR(VGPU10_GEOMETRY_SHADER);
605 SVGA_CASE_ID2STR(VGPU10_HULL_SHADER);
606 SVGA_CASE_ID2STR(VGPU10_DOMAIN_SHADER);
607 SVGA_CASE_ID2STR(VGPU10_COMPUTE_SHADER);
608 }
609 return NULL;
610}
611
612
613static const char *dxbcCustomDataClassToString(uint32_t value)
614{
615 VGPU10_CUSTOMDATA_CLASS enm = (VGPU10_CUSTOMDATA_CLASS)value;
616 switch (enm)
617 {
618 SVGA_CASE_ID2STR(VGPU10_CUSTOMDATA_COMMENT);
619 SVGA_CASE_ID2STR(VGPU10_CUSTOMDATA_DEBUGINFO);
620 SVGA_CASE_ID2STR(VGPU10_CUSTOMDATA_OPAQUE);
621 SVGA_CASE_ID2STR(VGPU10_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER);
622 }
623 return NULL;
624}
625
626
627static const char *dxbcSystemNameToString(uint32_t value)
628{
629 VGPU10_SYSTEM_NAME enm = (VGPU10_SYSTEM_NAME)value;
630 switch (enm)
631 {
632 SVGA_CASE_ID2STR(VGPU10_NAME_UNDEFINED);
633 SVGA_CASE_ID2STR(VGPU10_NAME_POSITION);
634 SVGA_CASE_ID2STR(VGPU10_NAME_CLIP_DISTANCE);
635 SVGA_CASE_ID2STR(VGPU10_NAME_CULL_DISTANCE);
636 SVGA_CASE_ID2STR(VGPU10_NAME_RENDER_TARGET_ARRAY_INDEX);
637 SVGA_CASE_ID2STR(VGPU10_NAME_VIEWPORT_ARRAY_INDEX);
638 SVGA_CASE_ID2STR(VGPU10_NAME_VERTEX_ID);
639 SVGA_CASE_ID2STR(VGPU10_NAME_PRIMITIVE_ID);
640 SVGA_CASE_ID2STR(VGPU10_NAME_INSTANCE_ID);
641 SVGA_CASE_ID2STR(VGPU10_NAME_IS_FRONT_FACE);
642 SVGA_CASE_ID2STR(VGPU10_NAME_SAMPLE_INDEX);
643 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR);
644 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR);
645 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR);
646 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR);
647 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR);
648 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR);
649 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR);
650 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR);
651 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR);
652 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_TRI_INSIDE_TESSFACTOR);
653 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_LINE_DETAIL_TESSFACTOR);
654 SVGA_CASE_ID2STR(VGPU10_NAME_FINAL_LINE_DENSITY_TESSFACTOR);
655 }
656 return NULL;
657}
658
659
660static const char *dxbcOperandTypeToString(uint32_t value)
661{
662 VGPU10_OPERAND_TYPE enm = (VGPU10_OPERAND_TYPE)value;
663 switch (enm)
664 {
665 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_TEMP);
666 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT);
667 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_OUTPUT);
668 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INDEXABLE_TEMP);
669 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_IMMEDIATE32);
670 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_IMMEDIATE64);
671 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_SAMPLER);
672 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_RESOURCE);
673 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_CONSTANT_BUFFER);
674 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER);
675 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_LABEL);
676 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID);
677 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_OUTPUT_DEPTH);
678 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_NULL);
679 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_RASTERIZER);
680 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_OUTPUT_COVERAGE_MASK);
681 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_STREAM);
682 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_FUNCTION_BODY);
683 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_FUNCTION_TABLE);
684 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INTERFACE);
685 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_FUNCTION_INPUT);
686 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_FUNCTION_OUTPUT);
687 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID);
688 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_FORK_INSTANCE_ID);
689 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_JOIN_INSTANCE_ID);
690 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_CONTROL_POINT);
691 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_OUTPUT_CONTROL_POINT);
692 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_PATCH_CONSTANT);
693 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_DOMAIN_POINT);
694 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_THIS_POINTER);
695 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_UAV);
696 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY);
697 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_THREAD_ID);
698 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_THREAD_GROUP_ID);
699 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP);
700 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_COVERAGE_MASK);
701 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED);
702 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_INPUT_GS_INSTANCE_ID);
703 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL);
704 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL);
705 SVGA_CASE_ID2STR(VGPU10_OPERAND_TYPE_CYCLE_COUNTER);
706 SVGA_CASE_ID2STR(VGPU10_NUM_OPERANDS);
707 }
708 return NULL;
709}
710
711
712static const char *dxbcOperandNumComponentsToString(uint32_t value)
713{
714 VGPU10_OPERAND_NUM_COMPONENTS enm = (VGPU10_OPERAND_NUM_COMPONENTS)value;
715 switch (enm)
716 {
717 SVGA_CASE_ID2STR(VGPU10_OPERAND_0_COMPONENT);
718 SVGA_CASE_ID2STR(VGPU10_OPERAND_1_COMPONENT);
719 SVGA_CASE_ID2STR(VGPU10_OPERAND_4_COMPONENT);
720 SVGA_CASE_ID2STR(VGPU10_OPERAND_N_COMPONENT);
721 }
722 return NULL;
723}
724
725
726static const char *dxbcOperandComponentModeToString(uint32_t value)
727{
728 VGPU10_OPERAND_4_COMPONENT_SELECTION_MODE enm = (VGPU10_OPERAND_4_COMPONENT_SELECTION_MODE)value;
729 switch (enm)
730 {
731 SVGA_CASE_ID2STR(VGPU10_OPERAND_4_COMPONENT_MASK_MODE);
732 SVGA_CASE_ID2STR(VGPU10_OPERAND_4_COMPONENT_SWIZZLE_MODE);
733 SVGA_CASE_ID2STR(VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE);
734 }
735 return NULL;
736}
737
738
739static const char *dxbcOperandComponentNameToString(uint32_t value)
740{
741 VGPU10_COMPONENT_NAME enm = (VGPU10_COMPONENT_NAME)value;
742 switch (enm)
743 {
744 SVGA_CASE_ID2STR(VGPU10_COMPONENT_X);
745 SVGA_CASE_ID2STR(VGPU10_COMPONENT_Y);
746 SVGA_CASE_ID2STR(VGPU10_COMPONENT_Z);
747 SVGA_CASE_ID2STR(VGPU10_COMPONENT_W);
748 }
749 return NULL;
750}
751
752
753static const char *dxbcOperandIndexDimensionToString(uint32_t value)
754{
755 VGPU10_OPERAND_INDEX_DIMENSION enm = (VGPU10_OPERAND_INDEX_DIMENSION)value;
756 switch (enm)
757 {
758 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_0D);
759 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_1D);
760 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_2D);
761 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_3D);
762 }
763 return NULL;
764}
765
766
767static const char *dxbcOperandIndexRepresentationToString(uint32_t value)
768{
769 VGPU10_OPERAND_INDEX_REPRESENTATION enm = (VGPU10_OPERAND_INDEX_REPRESENTATION)value;
770 switch (enm)
771 {
772 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_IMMEDIATE32);
773 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_IMMEDIATE64);
774 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_RELATIVE);
775 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE);
776 SVGA_CASE_ID2STR(VGPU10_OPERAND_INDEX_IMMEDIATE64_PLUS_RELATIVE);
777 }
778 return NULL;
779}
780
781
782static const char *dxbcInterpolationModeToString(uint32_t value)
783{
784 VGPU10_INTERPOLATION_MODE enm = (VGPU10_INTERPOLATION_MODE)value;
785 switch (enm)
786 {
787 SVGA_CASE_ID2STR(VGPU10_INTERPOLATION_UNDEFINED);
788 SVGA_CASE_ID2STR(VGPU10_INTERPOLATION_CONSTANT);
789 SVGA_CASE_ID2STR(VGPU10_INTERPOLATION_LINEAR);
790 SVGA_CASE_ID2STR(VGPU10_INTERPOLATION_LINEAR_CENTROID);
791 SVGA_CASE_ID2STR(VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE);
792 SVGA_CASE_ID2STR(VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID);
793 SVGA_CASE_ID2STR(VGPU10_INTERPOLATION_LINEAR_SAMPLE);
794 SVGA_CASE_ID2STR(VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE);
795 }
796 return NULL;
797}
798#endif /* LOG_ENABLED */
799
800/*
801 * MD5 from IPRT (alt-md5.cpp) for DXBC hash calculation.
802 * DXBC hash function uses a different padding for the data, see dxbcHash.
803 * Therefore RTMd5Final is not needed. Two functions have been renamed: dxbcRTMd5Update dxbcRTMd5Init.
804 */
805
806
807/* The four core functions - F1 is optimized somewhat */
808/* #define F1(x, y, z) (x & y | ~x & z) */
809#define F1(x, y, z) (z ^ (x & (y ^ z)))
810#define F2(x, y, z) F1(z, x, y)
811#define F3(x, y, z) (x ^ y ^ z)
812#define F4(x, y, z) (y ^ (x | ~z))
813
814
815/* This is the central step in the MD5 algorithm. */
816#define MD5STEP(f, w, x, y, z, data, s) \
817 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
818
819
820/**
821 * The core of the MD5 algorithm, this alters an existing MD5 hash to reflect
822 * the addition of 16 longwords of new data. RTMd5Update blocks the data and
823 * converts bytes into longwords for this routine.
824 */
825static void rtMd5Transform(uint32_t buf[4], uint32_t const in[16])
826{
827 uint32_t a, b, c, d;
828
829 a = buf[0];
830 b = buf[1];
831 c = buf[2];
832 d = buf[3];
833
834 /* fn, w, x, y, z, data, s) */
835 MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7);
836 MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
837 MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
838 MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
839 MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7);
840 MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
841 MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
842 MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
843 MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7);
844 MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
845 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
846 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
847 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
848 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
849 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
850 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
851
852 MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5);
853 MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9);
854 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
855 MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
856 MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5);
857 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
858 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
859 MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
860 MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5);
861 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
862 MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
863 MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
864 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
865 MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9);
866 MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
867 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
868
869 MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4);
870 MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
871 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
872 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
873 MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4);
874 MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
875 MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
876 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
877 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
878 MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
879 MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
880 MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
881 MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4);
882 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
883 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
884 MD5STEP(F3, b, c, d, a, in[ 2] + 0xc4ac5665, 23);
885
886 MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6);
887 MD5STEP(F4, d, a, b, c, in[ 7] + 0x432aff97, 10);
888 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
889 MD5STEP(F4, b, c, d, a, in[ 5] + 0xfc93a039, 21);
890 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
891 MD5STEP(F4, d, a, b, c, in[ 3] + 0x8f0ccc92, 10);
892 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
893 MD5STEP(F4, b, c, d, a, in[ 1] + 0x85845dd1, 21);
894 MD5STEP(F4, a, b, c, d, in[ 8] + 0x6fa87e4f, 6);
895 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
896 MD5STEP(F4, c, d, a, b, in[ 6] + 0xa3014314, 15);
897 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
898 MD5STEP(F4, a, b, c, d, in[ 4] + 0xf7537e82, 6);
899 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
900 MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15);
901 MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21);
902
903 buf[0] += a;
904 buf[1] += b;
905 buf[2] += c;
906 buf[3] += d;
907}
908
909
910#ifdef RT_BIG_ENDIAN
911/*
912 * Note: this code is harmless on little-endian machines.
913 */
914static void rtMd5ByteReverse(uint32_t *buf, unsigned int longs)
915{
916 uint32_t t;
917 do
918 {
919 t = *buf;
920 t = RT_LE2H_U32(t);
921 *buf = t;
922 buf++;
923 } while (--longs);
924}
925#else /* little endian - do nothing */
926# define rtMd5ByteReverse(buf, len) do { /* Nothing */ } while (0)
927#endif
928
929
930/*
931 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
932 * initialization constants.
933 */
934static void dxbcRTMd5Init(PRTMD5CONTEXT pCtx)
935{
936 pCtx->AltPrivate.buf[0] = 0x67452301;
937 pCtx->AltPrivate.buf[1] = 0xefcdab89;
938 pCtx->AltPrivate.buf[2] = 0x98badcfe;
939 pCtx->AltPrivate.buf[3] = 0x10325476;
940
941 pCtx->AltPrivate.bits[0] = 0;
942 pCtx->AltPrivate.bits[1] = 0;
943}
944
945
946/*
947 * Update context to reflect the concatenation of another buffer full
948 * of bytes.
949 */
950/** @todo Optimize this, because len is always a multiple of 64. */
951static void dxbcRTMd5Update(PRTMD5CONTEXT pCtx, const void *pvBuf, size_t len)
952{
953 const uint8_t *buf = (const uint8_t *)pvBuf;
954 uint32_t t;
955
956 /* Update bitcount */
957 t = pCtx->AltPrivate.bits[0];
958 if ((pCtx->AltPrivate.bits[0] = t + ((uint32_t) len << 3)) < t)
959 pCtx->AltPrivate.bits[1]++; /* Carry from low to high */
960 pCtx->AltPrivate.bits[1] += (uint32_t)(len >> 29);
961
962 t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
963
964 /* Handle any leading odd-sized chunks */
965 if (t)
966 {
967 uint8_t *p = (uint8_t *) pCtx->AltPrivate.in + t;
968
969 t = 64 - t;
970 if (len < t)
971 {
972 memcpy(p, buf, len);
973 return;
974 }
975 memcpy(p, buf, t);
976 rtMd5ByteReverse(pCtx->AltPrivate.in, 16);
977 rtMd5Transform(pCtx->AltPrivate.buf, pCtx->AltPrivate.in);
978 buf += t;
979 len -= t;
980 }
981
982 /* Process data in 64-byte chunks */
983#ifndef RT_BIG_ENDIAN
984 if (!((uintptr_t)buf & 0x3))
985 {
986 while (len >= 64) {
987 rtMd5Transform(pCtx->AltPrivate.buf, (uint32_t const *)buf);
988 buf += 64;
989 len -= 64;
990 }
991 }
992 else
993#endif
994 {
995 while (len >= 64) {
996 memcpy(pCtx->AltPrivate.in, buf, 64);
997 rtMd5ByteReverse(pCtx->AltPrivate.in, 16);
998 rtMd5Transform(pCtx->AltPrivate.buf, pCtx->AltPrivate.in);
999 buf += 64;
1000 len -= 64;
1001 }
1002 }
1003
1004 /* Handle any remaining bytes of data */
1005 memcpy(pCtx->AltPrivate.in, buf, len);
1006}
1007
1008
1009static void dxbcHash(void const *pvData, uint32_t cbData, uint8_t pabDigest[RTMD5HASHSIZE])
1010{
1011 size_t const kBlockSize = 64;
1012 uint8_t au8BlockBuffer[kBlockSize];
1013
1014 static uint8_t const s_au8Padding[kBlockSize] =
1015 {
1016 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1017 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1018 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1019 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020 };
1021
1022 RTMD5CONTEXT Ctx;
1023 PRTMD5CONTEXT const pCtx = &Ctx;
1024 dxbcRTMd5Init(pCtx);
1025
1026 uint8_t const *pu8Data = (uint8_t *)pvData;
1027 size_t cbRemaining = cbData;
1028
1029 size_t const cbCompleteBlocks = cbData & ~ (kBlockSize - 1);
1030 dxbcRTMd5Update(pCtx, pu8Data, cbCompleteBlocks);
1031 pu8Data += cbCompleteBlocks;
1032 cbRemaining -= cbCompleteBlocks;
1033
1034 /* Custom padding. */
1035 if (cbRemaining >= kBlockSize - 2 * sizeof(uint32_t))
1036 {
1037 /* Two additional blocks. */
1038 memcpy(&au8BlockBuffer[0], pu8Data, cbRemaining);
1039 memcpy(&au8BlockBuffer[cbRemaining], s_au8Padding, kBlockSize - cbRemaining);
1040 dxbcRTMd5Update(pCtx, au8BlockBuffer, kBlockSize);
1041
1042 memset(&au8BlockBuffer[sizeof(uint32_t)], 0, kBlockSize - 2 * sizeof(uint32_t));
1043 }
1044 else
1045 {
1046 /* One additional block. */
1047 memcpy(&au8BlockBuffer[sizeof(uint32_t)], pu8Data, cbRemaining);
1048 memcpy(&au8BlockBuffer[sizeof(uint32_t) + cbRemaining], s_au8Padding, kBlockSize - cbRemaining - 2 * sizeof(uint32_t));
1049 }
1050
1051 /* Set the first and last dwords of the last block. */
1052 *(uint32_t *)&au8BlockBuffer[0] = cbData << 3;
1053 *(uint32_t *)&au8BlockBuffer[kBlockSize - sizeof(uint32_t)] = (cbData << 1) | 1;
1054 dxbcRTMd5Update(pCtx, au8BlockBuffer, kBlockSize);
1055
1056 AssertCompile(sizeof(pCtx->AltPrivate.buf) == RTMD5HASHSIZE);
1057 memcpy(pabDigest, pCtx->AltPrivate.buf, RTMD5HASHSIZE);
1058}
1059
1060
1061/*
1062 *
1063 * Shader token reader.
1064 *
1065 */
1066
1067typedef struct DXBCTokenReader
1068{
1069 uint32_t const *pToken; /* Next token to read. */
1070 uint32_t cToken; /* How many tokens total. */
1071 uint32_t cRemainingToken; /* How many tokens remain. */
1072} DXBCTokenReader;
1073
1074
1075DECLINLINE(uint32_t) dxbcTokenReaderByteOffset(DXBCTokenReader *r)
1076{
1077 return (r->cToken - r->cRemainingToken) * 4;
1078}
1079
1080
1081DECLINLINE(uint32_t) dxbcTokenReaderRemaining(DXBCTokenReader *r)
1082{
1083 return r->cRemainingToken;
1084}
1085
1086
1087DECLINLINE(bool) dxbcTokenReaderCanRead(DXBCTokenReader *r, uint32_t cToken)
1088{
1089 return cToken <= r->cRemainingToken;
1090}
1091
1092
1093DECLINLINE(void) dxbcTokenReaderSkip(DXBCTokenReader *r, uint32_t cToken)
1094{
1095 AssertReturnVoid(r->cRemainingToken >= cToken);
1096 r->cRemainingToken -= cToken;
1097 r->pToken += cToken;
1098}
1099
1100
1101DECLINLINE(uint32_t) dxbcTokenReaderRead32(DXBCTokenReader *r)
1102{
1103 AssertReturn(r->cRemainingToken, 0);
1104 --r->cRemainingToken;
1105 return *(r->pToken++);
1106}
1107
1108
1109DECLINLINE(uint64_t) dxbcTokenReaderRead64(DXBCTokenReader *r)
1110{
1111 uint64_t const u64Low = dxbcTokenReaderRead32(r);
1112 uint64_t const u64High = dxbcTokenReaderRead32(r);
1113 return u64Low + (u64High << 32);
1114}
1115
1116
1117/*
1118 *
1119 * Byte writer.
1120 *
1121 */
1122
1123typedef struct DXBCByteWriter
1124{
1125 uint8_t *pu8ByteCodeBegin; /* First byte of the buffer. */
1126 uint8_t *pu8ByteCodePtr; /* Next free byte. */
1127 uint32_t cbAllocated; /* How many bytes allocated in the buffer. */
1128 uint32_t cbRemaining; /* How many bytes remain in the buffer. */
1129} DXBCByteWriter;
1130
1131
1132DECLINLINE(void *) dxbcByteWriterPtr(DXBCByteWriter *w)
1133{
1134 return w->pu8ByteCodePtr;
1135}
1136
1137
1138DECLINLINE(uint32_t) dxbcByteWriterSize(DXBCByteWriter *w)
1139{
1140 return (uint32_t)(w->pu8ByteCodePtr - w->pu8ByteCodeBegin);
1141}
1142
1143
1144DECLINLINE(void) dxbcByteWriterCommit(DXBCByteWriter *w, uint32_t cbCommit)
1145{
1146 Assert(cbCommit < w->cbRemaining);
1147 cbCommit = RT_MIN(cbCommit, w->cbRemaining);
1148 w->pu8ByteCodePtr += cbCommit;
1149 w->cbRemaining -= cbCommit;
1150}
1151
1152
1153DECLINLINE(bool) dxbcByteWriterCanWrite(DXBCByteWriter *w, uint32_t cbMore)
1154{
1155 if (cbMore <= w->cbRemaining)
1156 return true;
1157
1158 /* Do not allow to allocate more than 2 * SVGA3D_MAX_SHADER_MEMORY_BYTES */
1159 uint32_t const cbMax = 2 * SVGA3D_MAX_SHADER_MEMORY_BYTES;
1160 AssertReturn(cbMore < cbMax && RT_ALIGN_32(cbMore, 4096) <= cbMax - w->cbAllocated, false);
1161
1162 uint32_t cbNew = w->cbAllocated + RT_ALIGN_32(cbMore, 4096);
1163 void *pvNew = RTMemAllocZ(cbNew);
1164 if (!pvNew)
1165 return false;
1166
1167 uint32_t const cbCurrent = dxbcByteWriterSize(w);
1168 memcpy(pvNew, w->pu8ByteCodeBegin, cbCurrent);
1169 RTMemFree(w->pu8ByteCodeBegin);
1170
1171 w->pu8ByteCodeBegin = (uint8_t *)pvNew;
1172 w->pu8ByteCodePtr = w->pu8ByteCodeBegin + cbCurrent;
1173 w->cbAllocated = cbNew;
1174 w->cbRemaining = cbNew - cbCurrent;
1175
1176 return true;
1177}
1178
1179
1180DECLINLINE(bool) dxbcByteWriterInit(DXBCByteWriter *w, uint32_t cbInitial)
1181{
1182 RT_ZERO(*w);
1183 return dxbcByteWriterCanWrite(w, cbInitial);
1184}
1185
1186
1187DECLINLINE(void) dxbcByteWriterReset(DXBCByteWriter *w)
1188{
1189 RTMemFree(w->pu8ByteCodeBegin);
1190 RT_ZERO(*w);
1191}
1192
1193
1194DECLINLINE(void) dxbcByteWriterFetchData(DXBCByteWriter *w, void **ppv, uint32_t *pcb)
1195{
1196 *ppv = w->pu8ByteCodeBegin;
1197 *pcb = dxbcByteWriterSize(w);
1198
1199 w->pu8ByteCodeBegin = NULL;
1200 dxbcByteWriterReset(w);
1201}
1202
1203
1204/*
1205 *
1206 * VGPU10 shader parser.
1207 *
1208 */
1209
1210/* Parse an instruction operand. */
1211static int dxbcParseOperand(DXBCTokenReader *r, VGPUOperand *pOperand)
1212{
1213 RT_ZERO(*pOperand);
1214
1215 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1216
1217 VGPU10OperandToken0 operand0;
1218 operand0.value = dxbcTokenReaderRead32(r);
1219
1220 Log6((" %s(%d) %s(%d) %s(%d) %s(%d)\n",
1221 dxbcOperandNumComponentsToString(operand0.numComponents), operand0.numComponents,
1222 dxbcOperandComponentModeToString(operand0.selectionMode), operand0.selectionMode,
1223 dxbcOperandTypeToString(operand0.operandType), operand0.operandType,
1224 dxbcOperandIndexDimensionToString(operand0.indexDimension), operand0.indexDimension));
1225
1226 ASSERT_GUEST_RETURN(operand0.numComponents <= VGPU10_OPERAND_4_COMPONENT, VERR_INVALID_PARAMETER);
1227 if ( operand0.operandType != VGPU10_OPERAND_TYPE_IMMEDIATE32
1228 && operand0.operandType != VGPU10_OPERAND_TYPE_IMMEDIATE64)
1229 {
1230 if (operand0.numComponents == VGPU10_OPERAND_4_COMPONENT)
1231 {
1232 ASSERT_GUEST_RETURN(operand0.selectionMode <= VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE, VERR_INVALID_PARAMETER);
1233 switch (operand0.selectionMode)
1234 {
1235 case VGPU10_OPERAND_4_COMPONENT_MASK_MODE:
1236 Log6((" Mask %#x\n", operand0.mask));
1237 break;
1238 case VGPU10_OPERAND_4_COMPONENT_SWIZZLE_MODE:
1239 Log6((" Swizzle %s(%d) %s(%d) %s(%d) %s(%d)\n",
1240 dxbcOperandComponentNameToString(operand0.swizzleX), operand0.swizzleX,
1241 dxbcOperandComponentNameToString(operand0.swizzleY), operand0.swizzleY,
1242 dxbcOperandComponentNameToString(operand0.swizzleZ), operand0.swizzleZ,
1243 dxbcOperandComponentNameToString(operand0.swizzleW), operand0.swizzleW));
1244 break;
1245 case VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE:
1246 Log6((" Select %s(%d)\n",
1247 dxbcOperandComponentNameToString(operand0.selectMask), operand0.selectMask));
1248 break;
1249 default: /* Never happens. */
1250 break;
1251 }
1252 }
1253 }
1254
1255 if (operand0.extended)
1256 {
1257 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1258
1259 VGPU10OperandToken1 operand1;
1260 operand1.value = dxbcTokenReaderRead32(r);
1261 }
1262
1263 ASSERT_GUEST_RETURN(operand0.indexDimension <= VGPU10_OPERAND_INDEX_3D, VERR_INVALID_PARAMETER);
1264 ASSERT_GUEST_RETURN(operand0.operandType < VGPU10_NUM_OPERANDS, VERR_INVALID_PARAMETER);
1265
1266 if ( operand0.operandType == VGPU10_OPERAND_TYPE_IMMEDIATE32
1267 || operand0.operandType == VGPU10_OPERAND_TYPE_IMMEDIATE64)
1268 {
1269 uint32_t cComponent = 0;
1270 if (operand0.numComponents == VGPU10_OPERAND_4_COMPONENT)
1271 cComponent = 4;
1272 else if (operand0.numComponents == VGPU10_OPERAND_1_COMPONENT)
1273 cComponent = 1;
1274
1275 for (uint32_t i = 0; i < cComponent; ++i)
1276 {
1277 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1278 pOperand->aImm[i] = dxbcTokenReaderRead32(r);
1279 }
1280 }
1281
1282 pOperand->numComponents = operand0.numComponents;
1283 pOperand->selectionMode = operand0.selectionMode;
1284 pOperand->mask = operand0.mask;
1285 pOperand->operandType = operand0.operandType;
1286 pOperand->indexDimension = operand0.indexDimension;
1287
1288 /* 'indexDimension' tells the number of indices. 'i' is the array index, i.e. i = 0 for 1D, etc. */
1289 for (uint32_t i = 0; i < operand0.indexDimension; ++i)
1290 {
1291 if (i == 0) /* VGPU10_OPERAND_INDEX_1D */
1292 pOperand->aOperandIndex[i].indexRepresentation = operand0.index0Representation;
1293 else if (i == 1) /* VGPU10_OPERAND_INDEX_2D */
1294 pOperand->aOperandIndex[i].indexRepresentation = operand0.index1Representation;
1295 else /* VGPU10_OPERAND_INDEX_3D */
1296 continue; /* Skip because it is "rarely if ever used" and is not supported by VGPU10. */
1297
1298 uint32_t const indexRepresentation = pOperand->aOperandIndex[i].indexRepresentation;
1299 switch (indexRepresentation)
1300 {
1301 case VGPU10_OPERAND_INDEX_IMMEDIATE32:
1302 {
1303 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1304 pOperand->aOperandIndex[i].aOperandIndex[0] = dxbcTokenReaderRead32(r);
1305 break;
1306 }
1307 case VGPU10_OPERAND_INDEX_IMMEDIATE64:
1308 {
1309 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 2), VERR_INVALID_PARAMETER);
1310 pOperand->aOperandIndex[i].aOperandIndex[0] = dxbcTokenReaderRead64(r);
1311 break;
1312 }
1313 case VGPU10_OPERAND_INDEX_RELATIVE:
1314 {
1315 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1316 pOperand->aOperandIndex[i].aOperandIndex[0] = dxbcTokenReaderRead32(r);
1317 break;
1318 }
1319 case VGPU10_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE:
1320 {
1321 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 2), VERR_INVALID_PARAMETER);
1322 pOperand->aOperandIndex[i].aOperandIndex[0] = dxbcTokenReaderRead32(r);
1323 pOperand->aOperandIndex[i].aOperandIndex[1] = dxbcTokenReaderRead32(r);
1324 break;
1325 }
1326 case VGPU10_OPERAND_INDEX_IMMEDIATE64_PLUS_RELATIVE:
1327 {
1328 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 3), VERR_INVALID_PARAMETER);
1329 pOperand->aOperandIndex[i].aOperandIndex[0] = dxbcTokenReaderRead64(r);
1330 pOperand->aOperandIndex[i].aOperandIndex[1] = dxbcTokenReaderRead32(r);
1331 break;
1332 }
1333 default:
1334 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER);
1335 }
1336 Log6((" [operand index %d] %s(%d): %#llx, %#llx\n",
1337 i, dxbcOperandIndexRepresentationToString(indexRepresentation), indexRepresentation, pOperand->aOperandIndex[i].aOperandIndex[0], pOperand->aOperandIndex[i].aOperandIndex[1]));
1338 }
1339 return VINF_SUCCESS;
1340}
1341
1342
1343/* Parse an instruction. */
1344static int dxbcParseOpcode(DXBCTokenReader *r, VGPUOpcode *pOpcode)
1345{
1346 RT_ZERO(*pOpcode);
1347 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1348
1349 VGPU10OpcodeToken0 opcode;
1350 opcode.value = dxbcTokenReaderRead32(r);
1351
1352 pOpcode->opcodeType = opcode.opcodeType;
1353 ASSERT_GUEST_RETURN(pOpcode->opcodeType < VGPU10_NUM_OPCODES, VERR_INVALID_PARAMETER);
1354
1355 uint32_t const cOperand = g_aOpcodeInfo[pOpcode->opcodeType].cOperand;
1356 if (cOperand != UINT32_MAX)
1357 {
1358 Log6(("[%#x] %s length %d %s\n",
1359 dxbcTokenReaderByteOffset(r), dxbcOpcodeToString(pOpcode->opcodeType), opcode.instructionLength, dxbcInterpolationModeToString(opcode.interpolationMode)));
1360
1361 ASSERT_GUEST_RETURN(cOperand < RT_ELEMENTS(pOpcode->aOperand), VERR_INVALID_PARAMETER);
1362
1363 pOpcode->cOpcodeToken = opcode.instructionLength;
1364 if (opcode.extended)
1365 {
1366 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1367 if ( pOpcode->opcodeType == VGPU10_OPCODE_DCL_FUNCTION_BODY
1368 || pOpcode->opcodeType == VGPU10_OPCODE_DCL_FUNCTION_TABLE
1369 || pOpcode->opcodeType == VGPU10_OPCODE_DCL_INTERFACE
1370 || pOpcode->opcodeType == VGPU10_OPCODE_INTERFACE_CALL
1371 || pOpcode->opcodeType == VGPU10_OPCODE_DCL_THREAD_GROUP)
1372 {
1373 /* "next DWORD contains ... the actual instruction length in DWORD since it may not fit into 7 bits" */
1374 pOpcode->cOpcodeToken = dxbcTokenReaderRead32(r);
1375 }
1376 else
1377 AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo Anything else special for extended opcodes. */
1378 }
1379
1380 ASSERT_GUEST_RETURN(pOpcode->cOpcodeToken >= 1 && pOpcode->cOpcodeToken < 256, VERR_INVALID_PARAMETER);
1381 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, pOpcode->cOpcodeToken - 1), VERR_INVALID_PARAMETER);
1382
1383 /* Additional tokens before operands. */
1384 switch (pOpcode->opcodeType)
1385 {
1386 case VGPU10_OPCODE_INTERFACE_CALL:
1387 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1388 dxbcTokenReaderSkip(r, 1); /* Function index */
1389 break;
1390
1391 default:
1392 break;
1393 }
1394
1395 /* Operands. */
1396 for (uint32_t iOperand = 0; iOperand < cOperand; ++iOperand)
1397 {
1398 Log6((" [operand %d]\n", iOperand));
1399 int rc = dxbcParseOperand(r, &pOpcode->aOperand[iOperand]);
1400 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), VERR_INVALID_PARAMETER);
1401 }
1402
1403 pOpcode->cOperand = cOperand;
1404
1405 /* Additional tokens after operands. */
1406 switch (pOpcode->opcodeType)
1407 {
1408 case VGPU10_OPCODE_DCL_INPUT_SIV:
1409 case VGPU10_OPCODE_DCL_INPUT_SGV:
1410 case VGPU10_OPCODE_DCL_INPUT_PS_SIV:
1411 case VGPU10_OPCODE_DCL_INPUT_PS_SGV:
1412 case VGPU10_OPCODE_DCL_OUTPUT_SIV:
1413 case VGPU10_OPCODE_DCL_OUTPUT_SGV:
1414 {
1415 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1416
1417 VGPU10NameToken name;
1418 name.value = dxbcTokenReaderRead32(r);
1419 Log6((" %s(%d)\n",
1420 dxbcSystemNameToString(name.name), name.name));
1421 pOpcode->semanticName = name.name;
1422 break;
1423 }
1424 case VGPU10_OPCODE_DCL_RESOURCE:
1425 {
1426 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1427 dxbcTokenReaderSkip(r, 1); /* ResourceReturnTypeToken */
1428 break;
1429 }
1430 case VGPU10_OPCODE_DCL_TEMPS:
1431 {
1432 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1433 dxbcTokenReaderSkip(r, 1); /* number of temps */
1434 break;
1435 }
1436 case VGPU10_OPCODE_DCL_INDEXABLE_TEMP:
1437 {
1438 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 3), VERR_INVALID_PARAMETER);
1439 dxbcTokenReaderSkip(r, 3); /* register index; number of registers; number of components */
1440 break;
1441 }
1442 case VGPU10_OPCODE_DCL_INDEX_RANGE:
1443 {
1444 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1445 dxbcTokenReaderSkip(r, 1); /* count of registers */
1446 break;
1447 }
1448 case VGPU10_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT:
1449 {
1450 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1451 dxbcTokenReaderSkip(r, 1); /* maximum number of primitives */
1452 break;
1453 }
1454 case VGPU10_OPCODE_DCL_GS_INSTANCE_COUNT:
1455 {
1456 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1457 dxbcTokenReaderSkip(r, 1); /* number of instances */
1458 break;
1459 }
1460 case VGPU10_OPCODE_DCL_HS_MAX_TESSFACTOR:
1461 {
1462 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1463 dxbcTokenReaderSkip(r, 1); /* maximum TessFactor */
1464 break;
1465 }
1466 case VGPU10_OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
1467 case VGPU10_OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT:
1468 {
1469 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1470 dxbcTokenReaderSkip(r, 1); /* number of instances of the current fork/join phase program to execute */
1471 break;
1472 }
1473 case VGPU10_OPCODE_DCL_THREAD_GROUP:
1474 {
1475 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 3), VERR_INVALID_PARAMETER);
1476 dxbcTokenReaderSkip(r, 3); /* Thread Group dimensions as UINT32: x, y, z */
1477 break;
1478 }
1479 case VGPU10_OPCODE_DCL_UAV_TYPED:
1480 {
1481 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1482 dxbcTokenReaderSkip(r, 1); /* ResourceReturnTypeToken */
1483 break;
1484 }
1485 case VGPU10_OPCODE_DCL_UAV_STRUCTURED:
1486 {
1487 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1488 dxbcTokenReaderSkip(r, 1); /* byte stride */
1489 break;
1490 }
1491 case VGPU10_OPCODE_DCL_TGSM_RAW:
1492 {
1493 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1494 dxbcTokenReaderSkip(r, 1); /* element count */
1495 break;
1496 }
1497 case VGPU10_OPCODE_DCL_TGSM_STRUCTURED:
1498 {
1499 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 2), VERR_INVALID_PARAMETER);
1500 dxbcTokenReaderSkip(r, 2); /* struct byte stride; struct count */
1501 break;
1502 }
1503 case VGPU10_OPCODE_DCL_RESOURCE_STRUCTURED:
1504 {
1505 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1506 dxbcTokenReaderSkip(r, 1); /* struct byte stride */
1507 break;
1508 }
1509 default:
1510 break;
1511 }
1512 }
1513 else
1514 {
1515 /* Special opcodes. */
1516 if (pOpcode->opcodeType == VGPU10_OPCODE_CUSTOMDATA)
1517 {
1518 Log6(("[%#x] %s %s\n",
1519 dxbcTokenReaderByteOffset(r), dxbcOpcodeToString(pOpcode->opcodeType), dxbcCustomDataClassToString(opcode.customDataClass)));
1520
1521 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1522 pOpcode->cOpcodeToken = dxbcTokenReaderRead32(r);
1523
1524 if (pOpcode->cOpcodeToken < 2)
1525 pOpcode->cOpcodeToken = 2;
1526 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, pOpcode->cOpcodeToken - 2), VERR_INVALID_PARAMETER);
1527
1528 dxbcTokenReaderSkip(r, pOpcode->cOpcodeToken - 2);
1529 }
1530 else if (pOpcode->opcodeType == VGPU10_OPCODE_VMWARE)
1531 {
1532 /** @todo implement */
1533 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER);
1534 }
1535 else
1536 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER);
1537
1538 // pOpcode->cOperand = 0;
1539 }
1540
1541 return VINF_SUCCESS;
1542}
1543
1544
1545/*
1546 * Parse and verify the shader byte code. Extract input and output signatures into pInfo.
1547 */
1548int DXShaderParse(void const *pvShaderCode, uint32_t cbShaderCode, DXShaderInfo *pInfo)
1549{
1550 if (pInfo)
1551 RT_ZERO(*pInfo);
1552
1553 ASSERT_GUEST_RETURN(cbShaderCode <= SVGA3D_MAX_SHADER_MEMORY_BYTES, VERR_INVALID_PARAMETER);
1554 ASSERT_GUEST_RETURN((cbShaderCode & 0x3) == 0, VERR_INVALID_PARAMETER); /* Aligned to the token size. */
1555 ASSERT_GUEST_RETURN(cbShaderCode >= 8, VERR_INVALID_PARAMETER); /* At least program and length tokens. */
1556
1557 uint32_t const *paToken = (uint32_t *)pvShaderCode;
1558
1559 VGPU10ProgramToken const *pProgramToken = (VGPU10ProgramToken *)&paToken[0];
1560 ASSERT_GUEST_RETURN( pProgramToken->majorVersion >= 4
1561 && pProgramToken->programType <= VGPU10_COMPUTE_SHADER, VERR_INVALID_PARAMETER);
1562 if (pInfo)
1563 pInfo->enmProgramType = (VGPU10_PROGRAM_TYPE)pProgramToken->programType;
1564
1565 uint32_t const cToken = paToken[1];
1566 Log6(("Shader version %d.%d type %s(%d) Length %d\n",
1567 pProgramToken->majorVersion, pProgramToken->minorVersion, dxbcShaderTypeToString(pProgramToken->programType), pProgramToken->programType, cToken));
1568 ASSERT_GUEST_RETURN(cbShaderCode / 4 == cToken, VERR_INVALID_PARAMETER); /* Declared length should be equal to the actual. */
1569
1570 DXBCTokenReader parser;
1571 RT_ZERO(parser);
1572
1573 DXBCTokenReader *r = &parser;
1574 r->pToken = &paToken[2];
1575 r->cToken = r->cRemainingToken = cToken - 2;
1576
1577 while (dxbcTokenReaderCanRead(r, 1))
1578 {
1579 VGPUOpcode opcode;
1580 int rc = dxbcParseOpcode(r, &opcode);
1581 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), VERR_INVALID_PARAMETER);
1582
1583 if (pInfo)
1584 {
1585 /* Fetch signatures. */
1586 SVGA3dDXSignatureEntry *pSignatureEntry = NULL;
1587 switch (opcode.opcodeType)
1588 {
1589 case VGPU10_OPCODE_DCL_INPUT:
1590 case VGPU10_OPCODE_DCL_INPUT_PS:
1591 case VGPU10_OPCODE_DCL_INPUT_SIV:
1592 ASSERT_GUEST_RETURN(pInfo->cInputSignature < RT_ELEMENTS(pInfo->aInputSignature), VERR_INVALID_PARAMETER);
1593 pSignatureEntry = &pInfo->aInputSignature[pInfo->cInputSignature++];
1594 break;
1595 case VGPU10_OPCODE_DCL_OUTPUT:
1596 case VGPU10_OPCODE_DCL_OUTPUT_SIV:
1597 ASSERT_GUEST_RETURN(pInfo->cOutputSignature < RT_ELEMENTS(pInfo->aOutputSignature), VERR_INVALID_PARAMETER);
1598 pSignatureEntry = &pInfo->aOutputSignature[pInfo->cOutputSignature++];
1599 break;
1600 default:
1601 break;
1602 }
1603
1604 if (pSignatureEntry)
1605 {
1606 pSignatureEntry->registerIndex = opcode.aOperand[0].aOperandIndex[0].aOperandIndex[0];
1607 pSignatureEntry->semanticName = opcode.semanticName;
1608 pSignatureEntry->mask = opcode.aOperand[0].mask;
1609 pSignatureEntry->componentType = SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN; /// @todo Proper value? Seems that it is not important.
1610 pSignatureEntry->minPrecision = SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT;
1611 }
1612 }
1613 }
1614
1615#ifdef LOG_ENABLED
1616 if (pInfo->cInputSignature)
1617 {
1618 Log6(("Input signatures:\n"));
1619 for (uint32_t i = 0; i < pInfo->cInputSignature; ++i)
1620 Log6((" [%u]: %u %u 0x%X\n", i, pInfo->aInputSignature[i].registerIndex, pInfo->aInputSignature[i].semanticName, pInfo->aInputSignature[i].mask));
1621 }
1622 if (pInfo->cOutputSignature)
1623 {
1624 Log6(("Output signatures:\n"));
1625 for (uint32_t i = 0; i < pInfo->cOutputSignature; ++i)
1626 Log6((" [%u]: %u %u 0x%X\n", i, pInfo->aOutputSignature[i].registerIndex, pInfo->aOutputSignature[i].semanticName, pInfo->aOutputSignature[i].mask));
1627 }
1628 if (pInfo->cPatchConstantSignature)
1629 {
1630 Log6(("Patch constant signatures:\n"));
1631 for (uint32_t i = 0; i < pInfo->cPatchConstantSignature; ++i)
1632 Log6((" [%u]: %u %u 0x%X\n", i, pInfo->aPatchConstantSignature[i].registerIndex, pInfo->aPatchConstantSignature[i].semanticName, pInfo->aPatchConstantSignature[i].mask));
1633 }
1634#endif
1635
1636 return VINF_SUCCESS;
1637}
1638
1639
1640#if 0 // Unused. Replaced with dxbcSemanticInfo.
1641static char const *dxbcSemanticName(SVGA3dDXSignatureSemanticName enmSemanticName)
1642{
1643 /* https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#system-value-semantics */
1644 switch (enmSemanticName)
1645 {
1646 case SVGADX_SIGNATURE_SEMANTIC_NAME_POSITION: return "SV_Position";
1647 case SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE: return "SV_ClipDistance";
1648 case SVGADX_SIGNATURE_SEMANTIC_NAME_CULL_DISTANCE: return "SV_CullDistance";
1649 case SVGADX_SIGNATURE_SEMANTIC_NAME_RENDER_TARGET_ARRAY_INDEX: return "SV_RenderTargetArrayIndex";
1650 case SVGADX_SIGNATURE_SEMANTIC_NAME_VIEWPORT_ARRAY_INDEX: return "SV_ViewportArrayIndex";
1651 case SVGADX_SIGNATURE_SEMANTIC_NAME_VERTEX_ID: return "SV_VertexID";
1652 case SVGADX_SIGNATURE_SEMANTIC_NAME_PRIMITIVE_ID: return "SV_PrimitiveID";
1653 case SVGADX_SIGNATURE_SEMANTIC_NAME_INSTANCE_ID: return "SV_InstanceID";
1654 case SVGADX_SIGNATURE_SEMANTIC_NAME_IS_FRONT_FACE: return "SV_IsFrontFace";
1655 case SVGADX_SIGNATURE_SEMANTIC_NAME_SAMPLE_INDEX: return "SV_SampleIndex";
1656 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR: return "SV_FinalQuadUeq0EdgeTessFactor";
1657 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR: return "SV_FinalQuadVeq0EdgeTessFactor";
1658 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR: return "SV_FinalQuadUeq1EdgeTessFactor";
1659 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR: return "SV_FinalQuadVeq1EdgeTessFactor";
1660 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR: return "SV_FinalQuadUInsideTessFactor";
1661 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR: return "SV_FinalQuadVInsideTessFactor";
1662 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR: return "SV_FinalTriUeq0EdgeTessFactor";
1663 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR: return "SV_FinalTriVeq0EdgeTessFactor";
1664 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR: return "SV_FinalTriWeq0EdgeTessFactor";
1665 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_INSIDE_TESSFACTOR: return "SV_FinalTriInsideTessFactor";
1666 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DETAIL_TESSFACTOR: return "SV_FinalLineDetailTessFactor";
1667 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DENSITY_TESSFACTOR: return "SV_FinalLineDensityTessFactor";
1668 default:
1669 Assert(enmSemanticName == SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED);
1670 break;
1671 }
1672 /* Generic. Arbitrary name. It does not have any meaning. */
1673 return "ATTRIB";
1674}
1675#endif
1676
1677
1678/* https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#system-value-semantics
1679 * Type:
1680 * 0 - undefined
1681 * 1 - unsigned int
1682 * 2 - signed int
1683 * 3 - float
1684 */
1685typedef struct VGPUSemanticInfo
1686{
1687 char const *pszName;
1688 uint32_t u32Type;
1689} VGPUSemanticInfo;
1690
1691static VGPUSemanticInfo const g_aSemanticInfo[SVGADX_SIGNATURE_SEMANTIC_NAME_MAX] =
1692{
1693 { "ATTRIB", 0 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED 0
1694 { "SV_Position", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_POSITION 1
1695 { "SV_ClipDistance", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE 2
1696 { "SV_CullDistance", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_CULL_DISTANCE 3
1697 { "SV_RenderTargetArrayIndex", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_RENDER_TARGET_ARRAY_INDEX 4
1698 { "SV_ViewportArrayIndex", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_VIEWPORT_ARRAY_INDEX 5
1699 { "SV_VertexID", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_VERTEX_ID 6
1700 { "SV_PrimitiveID", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_PRIMITIVE_ID 7
1701 { "SV_InstanceID", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_INSTANCE_ID 8
1702 { "SV_IsFrontFace", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_IS_FRONT_FACE 9
1703 { "SV_SampleIndex", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_SAMPLE_INDEX 10
1704 /** @todo Is this a correct name for all TessFactors? */
1705 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR 11
1706 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR 12
1707 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR 13
1708 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR 14
1709 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR 15
1710 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR 16
1711 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR 17
1712 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR 18
1713 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR 19
1714 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_INSIDE_TESSFACTOR 20
1715 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DETAIL_TESSFACTOR 21
1716 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DENSITY_TESSFACTOR 22
1717};
1718
1719static VGPUSemanticInfo const g_SemanticPSOutput =
1720 { "SV_TARGET", 3 }; // SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED 0
1721
1722
1723static VGPUSemanticInfo const *dxbcSemanticInfo(DXShaderInfo const *pInfo, SVGA3dDXSignatureSemanticName enmSemanticName, uint32_t u32BlobType)
1724{
1725 if (enmSemanticName < RT_ELEMENTS(g_aSemanticInfo))
1726 {
1727 if ( enmSemanticName == 0
1728 && pInfo->enmProgramType == VGPU10_PIXEL_SHADER
1729 && u32BlobType == DXBC_BLOB_TYPE_OSGN)
1730 return &g_SemanticPSOutput;
1731 return &g_aSemanticInfo[enmSemanticName];
1732 }
1733 return &g_aSemanticInfo[0];
1734}
1735
1736
1737static int dxbcCreateIOSGNBlob(DXShaderInfo const *pInfo, DXBCHeader *pHdr, uint32_t u32BlobType,
1738 uint32_t cSignature, SVGA3dDXSignatureEntry const *paSignature, DXBCByteWriter *w)
1739{
1740 /* aIdxSignature contains signature indices. aIdxSignature[0] = signature index for register 0. */
1741 uint32_t aIdxSignature[32];
1742 memset(aIdxSignature, 0xFF, sizeof(aIdxSignature));
1743 AssertReturn(cSignature <= RT_ELEMENTS(aIdxSignature), VERR_INTERNAL_ERROR);
1744 for (uint32_t i = 0; i < cSignature; ++i)
1745 {
1746 SVGA3dDXSignatureEntry const *src = &paSignature[i];
1747 ASSERT_GUEST_RETURN(src->registerIndex < RT_ELEMENTS(aIdxSignature), VERR_INVALID_PARAMETER);
1748 ASSERT_GUEST_RETURN(aIdxSignature[src->registerIndex] == 0xFFFFFFFF, VERR_INVALID_PARAMETER);
1749 aIdxSignature[src->registerIndex] = i;
1750 }
1751
1752 uint32_t cbBlob = RT_UOFFSETOF(DXBCBlobIOSGN, aElement[cSignature])
1753 + cSignature * RT_SIZEOFMEMB(DXBCBlobIOSGN, aElement[0]);
1754 if (!dxbcByteWriterCanWrite(w, sizeof(DXBCBlobHeader) + cbBlob))
1755 return VERR_NO_MEMORY;
1756
1757 DXBCBlobHeader *pHdrBlob = (DXBCBlobHeader *)dxbcByteWriterPtr(w);
1758 pHdrBlob->u32BlobType = u32BlobType;
1759 // pHdrBlob->cbBlob = 0;
1760
1761 DXBCBlobIOSGN *pHdrISGN = (DXBCBlobIOSGN *)&pHdrBlob[1];
1762 pHdrISGN->cElement = cSignature;
1763 pHdrISGN->offElement = RT_UOFFSETOF(DXBCBlobIOSGN, aElement[0]);
1764
1765 uint32_t aSemanticIdx[SVGADX_SIGNATURE_SEMANTIC_NAME_MAX];
1766 RT_ZERO(aSemanticIdx);
1767 uint32_t iSignature = 0;
1768 for (uint32_t iReg = 0; iReg < RT_ELEMENTS(aIdxSignature); ++iReg)
1769 {
1770 if (aIdxSignature[iReg] == 0xFFFFFFFF) /* This register is unused. */
1771 continue;
1772
1773 AssertReturn(iSignature < cSignature, VERR_INTERNAL_ERROR);
1774
1775 SVGA3dDXSignatureEntry const *src = &paSignature[aIdxSignature[iReg]];
1776 DXBCBlobIOSGNElement *dst = &pHdrISGN->aElement[iSignature];
1777
1778 ASSERT_GUEST_RETURN(src->semanticName < SVGADX_SIGNATURE_SEMANTIC_NAME_MAX, VERR_INVALID_PARAMETER);
1779 VGPUSemanticInfo const *pSemanticInfo = dxbcSemanticInfo(pInfo, src->semanticName, u32BlobType);
1780
1781 dst->offElementName = cbBlob; /* Offset of the semantic's name relative to the start of the blob (without hdr). */
1782 dst->idxSemantic = aSemanticIdx[src->semanticName]++;
1783 dst->enmSystemValue = src->semanticName;
1784 dst->enmComponentType = src->componentType ? src->componentType : pSemanticInfo->u32Type;
1785 dst->idxRegister = src->registerIndex;
1786 dst->mask = src->mask;
1787 if (u32BlobType == DXBC_BLOB_TYPE_OSGN)
1788 dst->mask2 = 0;
1789 else
1790 dst->mask2 = src->mask;
1791
1792 /* Figure out the semantic name for this element. */
1793 char const * const pszElementName = pSemanticInfo->pszName;
1794 uint32_t const cbElementName = (uint32_t)strlen(pszElementName) + 1;
1795
1796 if (!dxbcByteWriterCanWrite(w, cbBlob + cbElementName))
1797 return VERR_NO_MEMORY;
1798
1799 char *pszElementNameDst = (char *)pHdrISGN + dst->offElementName;
1800 memcpy(pszElementNameDst, pszElementName, cbElementName);
1801
1802 cbBlob += cbElementName;
1803 ++iSignature;
1804 }
1805
1806 /* Blobs are 4 bytes aligned. Commit the blob data. */
1807 cbBlob = RT_ALIGN_32(cbBlob, 4);
1808 pHdrBlob->cbBlob = cbBlob;
1809 pHdr->cbTotal += cbBlob + sizeof(DXBCBlobHeader);
1810 dxbcByteWriterCommit(w, cbBlob + sizeof(DXBCBlobHeader));
1811 return VINF_SUCCESS;
1812}
1813
1814
1815static int dxbcCreateSHDRBlob(DXBCHeader *pHdr, uint32_t u32BlobType,
1816 void const *pvShader, uint32_t cbShader, DXBCByteWriter *w)
1817{
1818 uint32_t cbBlob = cbShader;
1819 if (!dxbcByteWriterCanWrite(w, sizeof(DXBCBlobHeader) + cbBlob))
1820 return VERR_NO_MEMORY;
1821
1822 DXBCBlobHeader *pHdrBlob = (DXBCBlobHeader *)dxbcByteWriterPtr(w);
1823 pHdrBlob->u32BlobType = u32BlobType;
1824 // pHdrBlob->cbBlob = 0;
1825
1826 memcpy(&pHdrBlob[1], pvShader, cbShader);
1827
1828 /* Blobs are 4 bytes aligned. Commit the blob data. */
1829 cbBlob = RT_ALIGN_32(cbBlob, 4);
1830 pHdrBlob->cbBlob = cbBlob;
1831 pHdr->cbTotal += cbBlob + sizeof(DXBCBlobHeader);
1832 dxbcByteWriterCommit(w, cbBlob + sizeof(DXBCBlobHeader));
1833 return VINF_SUCCESS;
1834}
1835
1836
1837/*
1838 * Create a DXBC container with signature and shader code data blobs.
1839 */
1840static int dxbcCreateFromInfo(DXShaderInfo const *pInfo, void const *pvShader, uint32_t cbShader, DXBCByteWriter *w)
1841{
1842 int rc;
1843
1844 /* Create a DXBC container with ISGN, OSGN and SHDR blobs. */
1845 uint32_t const cBlob = 3;
1846 uint32_t const cbHdr = RT_UOFFSETOF(DXBCHeader, aBlobOffset[cBlob]); /* Header with blob offsets. */
1847 if (!dxbcByteWriterCanWrite(w, cbHdr))
1848 return VERR_NO_MEMORY;
1849
1850 /* Container header. */
1851 DXBCHeader *pHdr = (DXBCHeader *)dxbcByteWriterPtr(w);
1852 pHdr->u32DXBC = DXBC_MAGIC;
1853 // RT_ZERO(pHdr->au8Hash);
1854 pHdr->u32Version = 1;
1855 pHdr->cbTotal = cbHdr;
1856 pHdr->cBlob = cBlob;
1857 //RT_ZERO(pHdr->aBlobOffset);
1858 dxbcByteWriterCommit(w, cbHdr);
1859
1860 /* Blobs. */
1861 uint32_t iBlob = 0;
1862
1863 pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
1864 rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_ISGN, pInfo->cInputSignature, &pInfo->aInputSignature[0], w);
1865 AssertRCReturn(rc, rc);
1866
1867 pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
1868 rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_OSGN, pInfo->cOutputSignature, &pInfo->aOutputSignature[0], w);
1869 AssertRCReturn(rc, rc);
1870
1871 pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
1872 rc = dxbcCreateSHDRBlob(pHdr, DXBC_BLOB_TYPE_SHDR, pvShader, cbShader, w);
1873 AssertRCReturn(rc, rc);
1874
1875 AssertCompile(RT_UOFFSETOF(DXBCHeader, u32Version) == 0x14);
1876 dxbcHash(&pHdr->u32Version, pHdr->cbTotal - RT_UOFFSETOF(DXBCHeader, u32Version), pHdr->au8Hash);
1877
1878 return VINF_SUCCESS;
1879}
1880
1881
1882int DXShaderCreateDXBC(DXShaderInfo const *pInfo, void const *pvShaderCode, uint32_t cbShaderCode, void **ppvDXBC, uint32_t *pcbDXBC)
1883{
1884 /* Build DXBC container. */
1885 int rc;
1886 DXBCByteWriter dxbcByteWriter;
1887 DXBCByteWriter *w = &dxbcByteWriter;
1888 if (dxbcByteWriterInit(w, 4096 + cbShaderCode))
1889 {
1890 rc = dxbcCreateFromInfo(pInfo, pvShaderCode, cbShaderCode, w);
1891 if (RT_SUCCESS(rc))
1892 dxbcByteWriterFetchData(w, ppvDXBC, pcbDXBC);
1893 }
1894 else
1895 rc = VERR_NO_MEMORY;
1896 return rc;
1897}
1898
1899
1900#ifdef DXBC_STANDALONE_TEST
1901static int dxbcCreateFromBytecode(void const *pvShaderCode, uint32_t cbShaderCode, void **ppvDXBC, uint32_t *pcbDXBC)
1902{
1903 /* Parse the shader bytecode and create DXBC container with resource, signature and shader bytecode blobs. */
1904 DXShaderInfo info;
1905 RT_ZERO(info);
1906 int rc = DXShaderParse(pvShaderCode, cbShaderCode, &info);
1907 if (RT_SUCCESS(rc))
1908 rc = DXShaderCreateDXBC(&info, pvShaderCode, cbShaderCode, ppvDXBC, pcbDXBC);
1909 return rc;
1910}
1911
1912static int parseShaderVM(void const *pvShaderCode, uint32_t cbShaderCode)
1913{
1914 void *pv = NULL;
1915 uint32_t cb = 0;
1916 int rc = dxbcCreateFromBytecode(pvShaderCode, cbShaderCode, &pv, &cb);
1917 if (RT_SUCCESS(rc))
1918 {
1919 /* Hexdump DXBC */
1920 printf("{\n");
1921 uint8_t *pu8 = (uint8_t *)pv;
1922 for (uint32_t i = 0; i < cb; ++i)
1923 {
1924 if ((i % 16) == 0)
1925 {
1926 if (i > 0)
1927 printf(",\n");
1928
1929 printf(" 0x%02x", pu8[i]);
1930 }
1931 else
1932 {
1933 printf(", 0x%02x", pu8[i]);
1934 }
1935 }
1936 printf("\n");
1937 printf("};\n");
1938
1939 RTMemFree(pv);
1940 }
1941
1942 return rc;
1943}
1944
1945static DXBCBlobHeader *dxbcFindBlob(DXBCHeader *pDXBCHeader, uint32_t u32BlobType)
1946{
1947 uint8_t const *pu8DXBCBegin = (uint8_t *)pDXBCHeader;
1948 for (uint32_t i = 0; i < pDXBCHeader->cBlob; ++i)
1949 {
1950 DXBCBlobHeader *pCurrentBlob = (DXBCBlobHeader *)&pu8DXBCBegin[pDXBCHeader->aBlobOffset[i]];
1951 if (pCurrentBlob->u32BlobType == u32BlobType)
1952 return pCurrentBlob;
1953 }
1954 return NULL;
1955}
1956
1957static int dxbcExtractShaderCode(DXBCHeader *pDXBCHeader, void **ppvCode, uint32_t *pcbCode)
1958{
1959 DXBCBlobHeader *pBlob = dxbcFindBlob(pDXBCHeader, DXBC_BLOB_TYPE_SHDR);
1960 AssertReturn(pBlob, VERR_NOT_IMPLEMENTED);
1961
1962 DXBCBlobSHDR *pSHDR = (DXBCBlobSHDR *)&pBlob[1];
1963 *pcbCode = pSHDR->cToken * 4;
1964 *ppvCode = RTMemAlloc(*pcbCode);
1965 AssertReturn(*ppvCode, VERR_NO_MEMORY);
1966
1967 memcpy(*ppvCode, pSHDR, *pcbCode);
1968 return VINF_SUCCESS;
1969}
1970
1971static int parseShaderDXBC(void const *pvDXBC)
1972{
1973 DXBCHeader *pDXBCHeader = (DXBCHeader *)pvDXBC;
1974 void *pvShaderCode = NULL;
1975 uint32_t cbShaderCode = 0;
1976 int rc = dxbcExtractShaderCode(pDXBCHeader, &pvShaderCode, &cbShaderCode);
1977 if (RT_SUCCESS(rc))
1978 {
1979 rc = parseShaderVM(pvShaderCode, cbShaderCode);
1980 RTMemFree(pvShaderCode);
1981 }
1982 return rc;
1983}
1984#endif /* DXBC_STANDALONE_TEST */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use