VirtualBox

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

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

Devices/Graphics: Build fix: bugref:9830

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette