VirtualBox

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

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

Devices/Graphics: parser improvements; logging: bugref:9830

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