VirtualBox

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

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

Devices/Graphics: implemented some DXQuery commands; fixed various issues found by piglit: bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 103.7 KB
Line 
1/* $Id: DevVGA-SVGA3d-dx-shader.cpp 94264 2022-03-16 05:57:21Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device - VGPU10+ (DX) shader utilities.
4 */
5
6/*
7 * Copyright (C) 2020-2022 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 {
1524 VGPU10OpcodeToken1 opcode1;
1525 opcode1.value = dxbcTokenReaderRead32(r);
1526 ASSERT_GUEST(opcode1.opcodeType == VGPU10_EXTENDED_OPCODE_SAMPLE_CONTROLS);
1527 }
1528 }
1529
1530 ASSERT_GUEST_RETURN(pOpcode->cOpcodeToken >= 1 && pOpcode->cOpcodeToken < 256, VERR_INVALID_PARAMETER);
1531 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, pOpcode->cOpcodeToken - 1), VERR_INVALID_PARAMETER);
1532
1533#ifdef LOG_ENABLED
1534 Log6((" %08X", opcode.value));
1535 for (uint32_t i = 1; i < pOpcode->cOpcodeToken; ++i)
1536 Log6((" %08X", r->pToken[i - 1]));
1537 Log6(("\n"));
1538
1539 if (pOpcode->opcodeType == VGPU10_OPCODE_DCL_RESOURCE)
1540 Log6((" %s\n",
1541 dxbcResourceDimensionToString(opcode.resourceDimension)));
1542 else
1543 Log6((" %s\n",
1544 dxbcInterpolationModeToString(opcode.interpolationMode)));
1545#endif
1546 /* Additional tokens before operands. */
1547 switch (pOpcode->opcodeType)
1548 {
1549 case VGPU10_OPCODE_INTERFACE_CALL:
1550 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1551 dxbcTokenReaderSkip(r, 1); /* Function index */
1552 break;
1553
1554 default:
1555 break;
1556 }
1557
1558 /* Operands. */
1559 uint32_t cOperandRemain = RT_ELEMENTS(pOpcode->aValOperand);
1560 for (uint32_t i = 0; i < cOperand; ++i)
1561 {
1562 Log6((" [operand %d]\n", i));
1563 uint32_t const idxOperand = RT_ELEMENTS(pOpcode->aValOperand) - cOperandRemain;
1564 pOpcode->aIdxOperand[i] = idxOperand;
1565 int rc = dxbcParseOperand(r, &pOpcode->aValOperand[idxOperand], &cOperandRemain);
1566 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), VERR_INVALID_PARAMETER);
1567 }
1568
1569 pOpcode->cOperand = cOperand;
1570
1571 /* Additional tokens after operands. */
1572 switch (pOpcode->opcodeType)
1573 {
1574 case VGPU10_OPCODE_DCL_INPUT_SIV:
1575 case VGPU10_OPCODE_DCL_INPUT_SGV:
1576 case VGPU10_OPCODE_DCL_INPUT_PS_SIV:
1577 case VGPU10_OPCODE_DCL_INPUT_PS_SGV:
1578 case VGPU10_OPCODE_DCL_OUTPUT_SIV:
1579 case VGPU10_OPCODE_DCL_OUTPUT_SGV:
1580 {
1581 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1582
1583 VGPU10NameToken name;
1584 name.value = dxbcTokenReaderRead32(r);
1585 Log6((" %s(%d)\n",
1586 dxbcSystemNameToString(name.name), name.name));
1587 pOpcode->semanticName = name.name;
1588 break;
1589 }
1590 case VGPU10_OPCODE_DCL_RESOURCE:
1591 {
1592 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1593 dxbcTokenReaderSkip(r, 1); /* ResourceReturnTypeToken */
1594 break;
1595 }
1596 case VGPU10_OPCODE_DCL_TEMPS:
1597 {
1598 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1599 dxbcTokenReaderSkip(r, 1); /* number of temps */
1600 break;
1601 }
1602 case VGPU10_OPCODE_DCL_INDEXABLE_TEMP:
1603 {
1604 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 3), VERR_INVALID_PARAMETER);
1605 dxbcTokenReaderSkip(r, 3); /* register index; number of registers; number of components */
1606 break;
1607 }
1608 case VGPU10_OPCODE_DCL_INDEX_RANGE:
1609 {
1610 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1611 dxbcTokenReaderSkip(r, 1); /* count of registers */
1612 break;
1613 }
1614 case VGPU10_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT:
1615 {
1616 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1617 dxbcTokenReaderSkip(r, 1); /* maximum number of primitives */
1618 break;
1619 }
1620 case VGPU10_OPCODE_DCL_GS_INSTANCE_COUNT:
1621 {
1622 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1623 dxbcTokenReaderSkip(r, 1); /* number of instances */
1624 break;
1625 }
1626 case VGPU10_OPCODE_DCL_HS_MAX_TESSFACTOR:
1627 {
1628 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1629 dxbcTokenReaderSkip(r, 1); /* maximum TessFactor */
1630 break;
1631 }
1632 case VGPU10_OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
1633 case VGPU10_OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT:
1634 {
1635 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1636 dxbcTokenReaderSkip(r, 1); /* number of instances of the current fork/join phase program to execute */
1637 break;
1638 }
1639 case VGPU10_OPCODE_DCL_THREAD_GROUP:
1640 {
1641 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 3), VERR_INVALID_PARAMETER);
1642 dxbcTokenReaderSkip(r, 3); /* Thread Group dimensions as UINT32: x, y, z */
1643 break;
1644 }
1645 case VGPU10_OPCODE_DCL_UAV_TYPED:
1646 {
1647 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1648 dxbcTokenReaderSkip(r, 1); /* ResourceReturnTypeToken */
1649 break;
1650 }
1651 case VGPU10_OPCODE_DCL_UAV_STRUCTURED:
1652 {
1653 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1654 dxbcTokenReaderSkip(r, 1); /* byte stride */
1655 break;
1656 }
1657 case VGPU10_OPCODE_DCL_TGSM_RAW:
1658 {
1659 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1660 dxbcTokenReaderSkip(r, 1); /* element count */
1661 break;
1662 }
1663 case VGPU10_OPCODE_DCL_TGSM_STRUCTURED:
1664 {
1665 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 2), VERR_INVALID_PARAMETER);
1666 dxbcTokenReaderSkip(r, 2); /* struct byte stride; struct count */
1667 break;
1668 }
1669 case VGPU10_OPCODE_DCL_RESOURCE_STRUCTURED:
1670 {
1671 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1672 dxbcTokenReaderSkip(r, 1); /* struct byte stride */
1673 break;
1674 }
1675 default:
1676 break;
1677 }
1678 }
1679 else
1680 {
1681 /* Special opcodes. */
1682 if (pOpcode->opcodeType == VGPU10_OPCODE_CUSTOMDATA)
1683 {
1684 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
1685 pOpcode->cOpcodeToken = dxbcTokenReaderRead32(r);
1686
1687 if (pOpcode->cOpcodeToken < 2)
1688 pOpcode->cOpcodeToken = 2;
1689 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, pOpcode->cOpcodeToken - 2), VERR_INVALID_PARAMETER);
1690
1691#ifdef LOG_ENABLED
1692 Log6((" %08X", opcode.value));
1693 for (uint32_t i = 1; i < pOpcode->cOpcodeToken; ++i)
1694 Log6((" %08X", r->pToken[i - 1]));
1695 Log6(("\n"));
1696
1697 Log6((" %s\n",
1698 dxbcCustomDataClassToString(opcode.customDataClass)));
1699#endif
1700 dxbcTokenReaderSkip(r, pOpcode->cOpcodeToken - 2);
1701 }
1702 else if (pOpcode->opcodeType == VGPU10_OPCODE_VMWARE)
1703 {
1704 pOpcode->cOpcodeToken = opcode.instructionLength;
1705 pOpcode->opcodeSubtype = opcode.vmwareOpcodeType;
1706
1707#ifdef LOG_ENABLED
1708 Log6((" %08X", opcode.value));
1709 for (uint32_t i = 1; i < pOpcode->cOpcodeToken; ++i)
1710 Log6((" %08X", r->pToken[i - 1]));
1711 Log6(("\n"));
1712
1713 Log6((" %s(%d)\n",
1714 dxbcVmwareOpcodeTypeToString(opcode.vmwareOpcodeType), opcode.vmwareOpcodeType));
1715#endif
1716
1717 if (opcode.vmwareOpcodeType == VGPU10_VMWARE_OPCODE_IDIV)
1718 {
1719 /* Integer divide. */
1720 pOpcode->cOperand = 4; /* dstQuit, dstRem, src0, src1. */
1721
1722 /* Operands. */
1723 uint32_t cOperandRemain = RT_ELEMENTS(pOpcode->aValOperand);
1724 for (uint32_t i = 0; i < pOpcode->cOperand; ++i)
1725 {
1726 Log6((" [operand %d]\n", i));
1727 uint32_t const idxOperand = RT_ELEMENTS(pOpcode->aValOperand) - cOperandRemain;
1728 pOpcode->aIdxOperand[i] = idxOperand;
1729 int rc = dxbcParseOperand(r, &pOpcode->aValOperand[idxOperand], &cOperandRemain);
1730 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), VERR_INVALID_PARAMETER);
1731 }
1732 }
1733 //else if (opcode.vmwareOpcodeType == VGPU10_VMWARE_OPCODE_DFRC)
1734 //else if (opcode.vmwareOpcodeType == VGPU10_VMWARE_OPCODE_DRSQ)
1735 else
1736 {
1737 /** @todo implement */
1738 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER);
1739 }
1740 }
1741 else
1742 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER);
1743
1744 // pOpcode->cOperand = 0;
1745 }
1746
1747 return VINF_SUCCESS;
1748}
1749
1750
1751typedef struct DXBCOUTPUTCTX
1752{
1753 VGPU10ProgramToken programToken;
1754 uint32_t cToken; /* Number of tokens in the original shader code. */
1755
1756 uint32_t offSubroutine; /* Current offset where to write subroutines. */
1757} DXBCOUTPUTCTX;
1758
1759
1760static void dxbcOutputInit(DXBCOUTPUTCTX *pOutctx, VGPU10ProgramToken const *pProgramToken, uint32_t cToken)
1761{
1762 RT_ZERO(*pOutctx);
1763 pOutctx->programToken = *pProgramToken;
1764 pOutctx->cToken = cToken;
1765
1766 pOutctx->offSubroutine = cToken * 4;
1767}
1768
1769
1770static int dxbcEmitVmwareIDIV(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w, VGPUOpcode *pOpcode)
1771{
1772 /* Insert a call and append a subroutne. */
1773 VGPU10OpcodeToken0 opcode;
1774 VGPU10OperandToken0 operand;
1775
1776 uint32_t const label = (pOutctx->offSubroutine - dxbcByteWriterSize(w)) / 4;
1777
1778 /*
1779 * Call
1780 */
1781 opcode.value = 0;
1782 opcode.opcodeType = VGPU10_OPCODE_CALL;
1783 opcode.instructionLength = 3;
1784 dxbcByteWriterAddTokens(w, &opcode.value, 1);
1785
1786 operand.value = 0;
1787 operand.numComponents = VGPU10_OPERAND_1_COMPONENT;
1788 operand.operandType = VGPU10_OPERAND_TYPE_LABEL;
1789 operand.indexDimension = VGPU10_OPERAND_INDEX_1D;
1790 operand.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
1791 dxbcByteWriterAddTokens(w, &operand.value, 1);
1792
1793 dxbcByteWriterAddTokens(w, &label, 1);
1794
1795 opcode.value = 0;
1796 opcode.opcodeType = VGPU10_OPCODE_NOP;
1797 opcode.instructionLength = 1;
1798 for (int i = 0; i < 8 - 3; ++i)
1799 dxbcByteWriterAddTokens(w, &opcode.value, 1);
1800
1801 /*
1802 * Subroutine.
1803 */
1804 DXBCByteWriterState savedWriterState;
1805 if (!dxbcByteWriterSetOffset(w, pOutctx->offSubroutine, &savedWriterState))
1806 return w->rc;
1807
1808 /* label */
1809 opcode.value = 0;
1810 opcode.opcodeType = VGPU10_OPCODE_LABEL;
1811 opcode.instructionLength = 3;
1812 dxbcByteWriterAddTokens(w, &opcode.value, 1);
1813
1814 operand.value = 0;
1815 operand.numComponents = VGPU10_OPERAND_1_COMPONENT;
1816 operand.operandType = VGPU10_OPERAND_TYPE_LABEL;
1817 operand.indexDimension = VGPU10_OPERAND_INDEX_1D;
1818 operand.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
1819 dxbcByteWriterAddTokens(w, &operand.value, 1);
1820 dxbcByteWriterAddTokens(w, &label, 1);
1821
1822 /* Just output UDIV for now. */
1823 opcode.value = 0;
1824 opcode.opcodeType = VGPU10_OPCODE_UDIV;
1825 opcode.instructionLength = pOpcode->cOpcodeToken;
1826 dxbcByteWriterAddTokens(w, &opcode.value, 1);
1827 dxbcByteWriterAddTokens(w, &pOpcode->paOpcodeToken[1], pOpcode->cOpcodeToken - 1);
1828
1829 /* ret */
1830 opcode.value = 0;
1831 opcode.opcodeType = VGPU10_OPCODE_RET;
1832 opcode.instructionLength = 1;
1833 dxbcByteWriterAddTokens(w, &opcode.value, 1);
1834
1835 pOutctx->offSubroutine = dxbcByteWriterSize(w);
1836 dxbcByteWriterRestore(w, &savedWriterState);
1837
1838 return w->rc;
1839}
1840
1841
1842static int dxbcOutputOpcode(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w, VGPUOpcode *pOpcode)
1843{
1844#ifdef DEBUG
1845 void *pvBegin = dxbcByteWriterPtr(w);
1846#endif
1847
1848 if ( pOutctx->programToken.programType == VGPU10_PIXEL_SHADER
1849 && pOpcode->opcodeType == VGPU10_OPCODE_DCL_RESOURCE)
1850 {
1851 /** @todo This is a workaround. */
1852 /* Sometimes the guest (Mesa) created a shader with uninitialized resource dimension.
1853 * Use texture 2d because it is what a pixel shader normally uses.
1854 */
1855 ASSERT_GUEST_RETURN(pOpcode->cOpcodeToken == 4, VERR_INVALID_PARAMETER);
1856
1857 VGPU10OpcodeToken0 opcode;
1858 opcode.value = pOpcode->paOpcodeToken[0];
1859 if (opcode.resourceDimension == VGPU10_RESOURCE_DIMENSION_BUFFER)
1860 {
1861 opcode.resourceDimension = VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
1862 dxbcByteWriterAddTokens(w, &opcode.value, 1);
1863 dxbcByteWriterAddTokens(w, &pOpcode->paOpcodeToken[1], 2);
1864 uint32_t const returnType = 0x5555; /* float */
1865 dxbcByteWriterAddTokens(w, &returnType, 1);
1866 return VINF_SUCCESS;
1867 }
1868 }
1869 else if (pOpcode->opcodeType == VGPU10_OPCODE_VMWARE)
1870 {
1871 if (pOpcode->opcodeSubtype == VGPU10_VMWARE_OPCODE_IDIV)
1872 {
1873 return dxbcEmitVmwareIDIV(pOutctx, w, pOpcode);
1874 }
1875
1876 ASSERT_GUEST_FAILED_RETURN(VERR_NOT_SUPPORTED);
1877 }
1878
1879#ifdef DEBUG
1880 /* The code above must emit either nothing or everything. */
1881 Assert((uintptr_t)pvBegin == (uintptr_t)dxbcByteWriterPtr(w));
1882#endif
1883
1884 /* Just emit the unmodified instruction. */
1885 dxbcByteWriterAddTokens(w, pOpcode->paOpcodeToken, pOpcode->cOpcodeToken);
1886 return VINF_SUCCESS;
1887}
1888
1889
1890static int dxbcOutputFinalize(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w)
1891{
1892 RT_NOREF(pOutctx, w);
1893 return VINF_SUCCESS;
1894}
1895
1896
1897/*
1898 * Parse and verify the shader byte code. Extract input and output signatures into pInfo.
1899 */
1900int DXShaderParse(void const *pvShaderCode, uint32_t cbShaderCode, DXShaderInfo *pInfo)
1901{
1902 if (pInfo)
1903 RT_ZERO(*pInfo);
1904
1905 ASSERT_GUEST_RETURN(cbShaderCode <= SVGA3D_MAX_SHADER_MEMORY_BYTES, VERR_INVALID_PARAMETER);
1906 ASSERT_GUEST_RETURN((cbShaderCode & 0x3) == 0, VERR_INVALID_PARAMETER); /* Aligned to the token size. */
1907 ASSERT_GUEST_RETURN(cbShaderCode >= 8, VERR_INVALID_PARAMETER); /* At least program and length tokens. */
1908
1909 uint32_t const *paToken = (uint32_t *)pvShaderCode;
1910
1911 VGPU10ProgramToken const *pProgramToken = (VGPU10ProgramToken *)&paToken[0];
1912 ASSERT_GUEST_RETURN( pProgramToken->majorVersion >= 4
1913 && pProgramToken->programType <= VGPU10_COMPUTE_SHADER, VERR_INVALID_PARAMETER);
1914 if (pInfo)
1915 pInfo->enmProgramType = (VGPU10_PROGRAM_TYPE)pProgramToken->programType;
1916
1917 uint32_t const cToken = paToken[1];
1918 Log6(("Shader version %d.%d type %s(%d) Length %d\n",
1919 pProgramToken->majorVersion, pProgramToken->minorVersion, dxbcShaderTypeToString(pProgramToken->programType), pProgramToken->programType, cToken));
1920 ASSERT_GUEST_RETURN(cbShaderCode / 4 == cToken, VERR_INVALID_PARAMETER); /* Declared length should be equal to the actual. */
1921
1922 /* Write the parsed (and possibly modified) shader to a memory buffer. */
1923 DXBCByteWriter dxbcByteWriter;
1924 DXBCByteWriter *w = &dxbcByteWriter;
1925 if (!dxbcByteWriterInit(w, 4096 + cbShaderCode))
1926 return VERR_NO_MEMORY;
1927
1928 dxbcByteWriterAddTokens(w, paToken, 2);
1929
1930 DXBCTokenReader parser;
1931 RT_ZERO(parser);
1932
1933 DXBCTokenReader *r = &parser;
1934 r->pToken = &paToken[2];
1935 r->cToken = r->cRemainingToken = cToken - 2;
1936
1937 DXBCOUTPUTCTX outctx;
1938 dxbcOutputInit(&outctx, pProgramToken, cToken);
1939
1940 int rc = VINF_SUCCESS;
1941 while (dxbcTokenReaderCanRead(r, 1))
1942 {
1943 uint32_t const offOpcode = dxbcByteWriterSize(w);
1944
1945 VGPUOpcode opcode;
1946 rc = dxbcParseOpcode(r, &opcode);
1947 ASSERT_GUEST_STMT_BREAK(RT_SUCCESS(rc), rc = VERR_INVALID_PARAMETER);
1948
1949 rc = dxbcOutputOpcode(&outctx, w, &opcode);
1950 AssertRCBreak(rc);
1951
1952 if (pInfo)
1953 {
1954 /* Remember offsets of DCL_RESOURCE instructions. */
1955 if ( outctx.programToken.programType == VGPU10_PIXEL_SHADER
1956 && opcode.opcodeType == VGPU10_OPCODE_DCL_RESOURCE)
1957 {
1958 ASSERT_GUEST_STMT_BREAK(pInfo->cDclResource <= SVGA3D_DX_MAX_SRVIEWS,
1959 rc = VERR_NOT_SUPPORTED);
1960
1961 pInfo->aOffDclResource[pInfo->cDclResource++] = offOpcode;
1962 }
1963
1964 /* Fetch signatures. */
1965 SVGA3dDXSignatureEntry *pSignatureEntry = NULL;
1966 switch (opcode.opcodeType)
1967 {
1968 case VGPU10_OPCODE_DCL_INPUT:
1969 case VGPU10_OPCODE_DCL_INPUT_PS:
1970 case VGPU10_OPCODE_DCL_INPUT_SIV:
1971 ASSERT_GUEST_STMT_BREAK(pInfo->cInputSignature < RT_ELEMENTS(pInfo->aInputSignature), rc = VERR_INVALID_PARAMETER);
1972 pSignatureEntry = &pInfo->aInputSignature[pInfo->cInputSignature++];
1973 break;
1974 case VGPU10_OPCODE_DCL_OUTPUT:
1975 case VGPU10_OPCODE_DCL_OUTPUT_SIV:
1976 case VGPU10_OPCODE_DCL_OUTPUT_SGV:
1977 ASSERT_GUEST_STMT_BREAK(pInfo->cOutputSignature < RT_ELEMENTS(pInfo->aOutputSignature), rc = VERR_INVALID_PARAMETER);
1978 pSignatureEntry = &pInfo->aOutputSignature[pInfo->cOutputSignature++];
1979 break;
1980 default:
1981 break;
1982 }
1983
1984 if (RT_FAILURE(rc))
1985 break;
1986
1987 if (pSignatureEntry)
1988 {
1989 ASSERT_GUEST_STMT_BREAK( opcode.aValOperand[0].aOperandIndex[0].indexRepresentation == VGPU10_OPERAND_INDEX_IMMEDIATE32
1990 || opcode.aValOperand[0].aOperandIndex[0].indexRepresentation == VGPU10_OPERAND_INDEX_IMMEDIATE64,
1991 rc = VERR_NOT_SUPPORTED);
1992
1993 uint32_t const indexDimension = opcode.aValOperand[0].indexDimension;
1994 if (indexDimension == VGPU10_OPERAND_INDEX_0D)
1995 {
1996 if (opcode.aValOperand[0].operandType == VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID)
1997 {
1998 pSignatureEntry->registerIndex = 0;
1999 pSignatureEntry->semanticName = SVGADX_SIGNATURE_SEMANTIC_NAME_PRIMITIVE_ID;
2000 }
2001 else if (opcode.aValOperand[0].operandType == VGPU10_OPERAND_TYPE_OUTPUT_DEPTH)
2002 {
2003 /* oDepth is always last in the signature. Register index is equal to 0xFFFFFFFF. */
2004 pSignatureEntry->registerIndex = 0xFFFFFFFF;
2005 pSignatureEntry->semanticName = SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED;
2006 }
2007 else
2008 ASSERT_GUEST_FAILED_STMT_BREAK(rc = VERR_NOT_SUPPORTED);
2009 }
2010 else
2011 {
2012 ASSERT_GUEST_STMT_BREAK( indexDimension == VGPU10_OPERAND_INDEX_1D
2013 || indexDimension == VGPU10_OPERAND_INDEX_2D
2014 || indexDimension == VGPU10_OPERAND_INDEX_3D,
2015 rc = VERR_NOT_SUPPORTED);
2016 /* The register index seems to be in the highest dimension. */
2017 pSignatureEntry->registerIndex = opcode.aValOperand[0].aOperandIndex[indexDimension - VGPU10_OPERAND_INDEX_1D].iOperandImmediate;
2018 pSignatureEntry->semanticName = opcode.semanticName;
2019 }
2020 pSignatureEntry->mask = opcode.aValOperand[0].mask;
2021 pSignatureEntry->componentType = SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN; /// @todo Proper value? Seems that it is not important.
2022 pSignatureEntry->minPrecision = SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT;
2023 }
2024 }
2025 }
2026
2027 if (RT_FAILURE(rc))
2028 {
2029 return rc;
2030 }
2031
2032 rc = dxbcOutputFinalize(&outctx, w);
2033 if (RT_FAILURE(rc))
2034 {
2035 return rc;
2036 }
2037
2038 dxbcByteWriterFetchData(w, &pInfo->pvBytecode, &pInfo->cbBytecode);
2039 uint32_t *pcOutputToken = (uint32_t *)pInfo->pvBytecode + 1;
2040 *pcOutputToken = pInfo->cbBytecode / 4;
2041
2042#ifdef LOG_ENABLED
2043 if (pInfo->cInputSignature)
2044 {
2045 Log6(("Input signatures:\n"));
2046 for (uint32_t i = 0; i < pInfo->cInputSignature; ++i)
2047 Log6((" [%u]: %u %u 0x%X\n", i, pInfo->aInputSignature[i].registerIndex, pInfo->aInputSignature[i].semanticName, pInfo->aInputSignature[i].mask));
2048 }
2049 if (pInfo->cOutputSignature)
2050 {
2051 Log6(("Output signatures:\n"));
2052 for (uint32_t i = 0; i < pInfo->cOutputSignature; ++i)
2053 Log6((" [%u]: %u %u 0x%X\n", i, pInfo->aOutputSignature[i].registerIndex, pInfo->aOutputSignature[i].semanticName, pInfo->aOutputSignature[i].mask));
2054 }
2055 if (pInfo->cPatchConstantSignature)
2056 {
2057 Log6(("Patch constant signatures:\n"));
2058 for (uint32_t i = 0; i < pInfo->cPatchConstantSignature; ++i)
2059 Log6((" [%u]: %u %u 0x%X\n", i, pInfo->aPatchConstantSignature[i].registerIndex, pInfo->aPatchConstantSignature[i].semanticName, pInfo->aPatchConstantSignature[i].mask));
2060 }
2061#endif
2062
2063 return VINF_SUCCESS;
2064}
2065
2066
2067void DXShaderFree(DXShaderInfo *pInfo)
2068{
2069 RTMemFree(pInfo->pvBytecode);
2070 RT_ZERO(*pInfo);
2071}
2072
2073
2074#if 0 // Unused. Replaced with dxbcSemanticInfo.
2075static char const *dxbcSemanticName(SVGA3dDXSignatureSemanticName enmSemanticName)
2076{
2077 /* https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#system-value-semantics */
2078 switch (enmSemanticName)
2079 {
2080 case SVGADX_SIGNATURE_SEMANTIC_NAME_POSITION: return "SV_Position";
2081 case SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE: return "SV_ClipDistance";
2082 case SVGADX_SIGNATURE_SEMANTIC_NAME_CULL_DISTANCE: return "SV_CullDistance";
2083 case SVGADX_SIGNATURE_SEMANTIC_NAME_RENDER_TARGET_ARRAY_INDEX: return "SV_RenderTargetArrayIndex";
2084 case SVGADX_SIGNATURE_SEMANTIC_NAME_VIEWPORT_ARRAY_INDEX: return "SV_ViewportArrayIndex";
2085 case SVGADX_SIGNATURE_SEMANTIC_NAME_VERTEX_ID: return "SV_VertexID";
2086 case SVGADX_SIGNATURE_SEMANTIC_NAME_PRIMITIVE_ID: return "SV_PrimitiveID";
2087 case SVGADX_SIGNATURE_SEMANTIC_NAME_INSTANCE_ID: return "SV_InstanceID";
2088 case SVGADX_SIGNATURE_SEMANTIC_NAME_IS_FRONT_FACE: return "SV_IsFrontFace";
2089 case SVGADX_SIGNATURE_SEMANTIC_NAME_SAMPLE_INDEX: return "SV_SampleIndex";
2090 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR: return "SV_FinalQuadUeq0EdgeTessFactor";
2091 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR: return "SV_FinalQuadVeq0EdgeTessFactor";
2092 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR: return "SV_FinalQuadUeq1EdgeTessFactor";
2093 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR: return "SV_FinalQuadVeq1EdgeTessFactor";
2094 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR: return "SV_FinalQuadUInsideTessFactor";
2095 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR: return "SV_FinalQuadVInsideTessFactor";
2096 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR: return "SV_FinalTriUeq0EdgeTessFactor";
2097 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR: return "SV_FinalTriVeq0EdgeTessFactor";
2098 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR: return "SV_FinalTriWeq0EdgeTessFactor";
2099 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_INSIDE_TESSFACTOR: return "SV_FinalTriInsideTessFactor";
2100 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DETAIL_TESSFACTOR: return "SV_FinalLineDetailTessFactor";
2101 case SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DENSITY_TESSFACTOR: return "SV_FinalLineDensityTessFactor";
2102 default:
2103 Assert(enmSemanticName == SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED);
2104 break;
2105 }
2106 /* Generic. Arbitrary name. It does not have any meaning. */
2107 return "ATTRIB";
2108}
2109#endif
2110
2111
2112/* https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#system-value-semantics
2113 * Type:
2114 * 0 - undefined
2115 * 1 - unsigned int
2116 * 2 - signed int
2117 * 3 - float
2118 */
2119typedef struct VGPUSemanticInfo
2120{
2121 char const *pszName;
2122 uint32_t u32Type;
2123} VGPUSemanticInfo;
2124
2125static VGPUSemanticInfo const g_aSemanticInfo[SVGADX_SIGNATURE_SEMANTIC_NAME_MAX] =
2126{
2127 { "ATTRIB", 0 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED 0
2128 { "SV_Position", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_POSITION 1
2129 { "SV_ClipDistance", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE 2
2130 { "SV_CullDistance", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_CULL_DISTANCE 3
2131 { "SV_RenderTargetArrayIndex", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_RENDER_TARGET_ARRAY_INDEX 4
2132 { "SV_ViewportArrayIndex", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_VIEWPORT_ARRAY_INDEX 5
2133 { "SV_VertexID", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_VERTEX_ID 6
2134 { "SV_PrimitiveID", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_PRIMITIVE_ID 7
2135 { "SV_InstanceID", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_INSTANCE_ID 8
2136 { "SV_IsFrontFace", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_IS_FRONT_FACE 9
2137 { "SV_SampleIndex", 1 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_SAMPLE_INDEX 10
2138 /** @todo Is this a correct name for all TessFactors? */
2139 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR 11
2140 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR 12
2141 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR 13
2142 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR 14
2143 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR 15
2144 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR 16
2145 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR 17
2146 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR 18
2147 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR 19
2148 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_INSIDE_TESSFACTOR 20
2149 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DETAIL_TESSFACTOR 21
2150 { "SV_TessFactor", 3 }, // SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DENSITY_TESSFACTOR 22
2151};
2152
2153static VGPUSemanticInfo const g_SemanticPSOutput =
2154 { "SV_TARGET", 3 }; // SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED 0
2155
2156
2157static VGPUSemanticInfo const *dxbcSemanticInfo(DXShaderInfo const *pInfo, SVGA3dDXSignatureSemanticName enmSemanticName, uint32_t u32BlobType)
2158{
2159 if (enmSemanticName < RT_ELEMENTS(g_aSemanticInfo))
2160 {
2161 if ( enmSemanticName == 0
2162 && pInfo->enmProgramType == VGPU10_PIXEL_SHADER
2163 && u32BlobType == DXBC_BLOB_TYPE_OSGN)
2164 return &g_SemanticPSOutput;
2165 return &g_aSemanticInfo[enmSemanticName];
2166 }
2167 return &g_aSemanticInfo[0];
2168}
2169
2170
2171static int dxbcCreateIOSGNBlob(DXShaderInfo const *pInfo, DXBCHeader *pHdr, uint32_t u32BlobType,
2172 uint32_t cSignature, SVGA3dDXSignatureEntry const *paSignature, DXBCByteWriter *w)
2173{
2174 /* aIdxSignature contains signature indices. aIdxSignature[0] = signature index for register 0. */
2175 uint32_t aIdxSignature[32];
2176 memset(aIdxSignature, 0xFF, sizeof(aIdxSignature));
2177 AssertReturn(cSignature <= RT_ELEMENTS(aIdxSignature), VERR_INTERNAL_ERROR);
2178 for (uint32_t i = 0; i < cSignature; ++i)
2179 {
2180 SVGA3dDXSignatureEntry const *src = &paSignature[i];
2181 if (src->registerIndex == 0xFFFFFFFF)
2182 {
2183 /* oDepth for PS output. */
2184 ASSERT_GUEST_RETURN(pInfo->enmProgramType == VGPU10_PIXEL_SHADER, VERR_INVALID_PARAMETER);
2185
2186 /* Must be placed last in the signature. */
2187 ASSERT_GUEST_RETURN(aIdxSignature[cSignature - 1] == 0xFFFFFFFF, VERR_INVALID_PARAMETER);
2188 aIdxSignature[cSignature - 1] = i;
2189 continue;
2190 }
2191
2192 ASSERT_GUEST_RETURN(src->registerIndex < RT_ELEMENTS(aIdxSignature), VERR_INVALID_PARAMETER);
2193 ASSERT_GUEST_RETURN(aIdxSignature[src->registerIndex] == 0xFFFFFFFF, VERR_INVALID_PARAMETER);
2194 aIdxSignature[src->registerIndex] = i;
2195 }
2196
2197 uint32_t cbBlob = RT_UOFFSETOF_DYN(DXBCBlobIOSGN, aElement[cSignature])
2198 + cSignature * RT_SIZEOFMEMB(DXBCBlobIOSGN, aElement[0]);
2199 if (!dxbcByteWriterCanWrite(w, sizeof(DXBCBlobHeader) + cbBlob))
2200 return VERR_NO_MEMORY;
2201
2202 DXBCBlobHeader *pHdrBlob = (DXBCBlobHeader *)dxbcByteWriterPtr(w);
2203 pHdrBlob->u32BlobType = u32BlobType;
2204 // pHdrBlob->cbBlob = 0;
2205
2206 DXBCBlobIOSGN *pHdrISGN = (DXBCBlobIOSGN *)&pHdrBlob[1];
2207 pHdrISGN->cElement = cSignature;
2208 pHdrISGN->offElement = RT_UOFFSETOF(DXBCBlobIOSGN, aElement[0]);
2209
2210 uint32_t aSemanticIdx[SVGADX_SIGNATURE_SEMANTIC_NAME_MAX];
2211 RT_ZERO(aSemanticIdx);
2212 uint32_t iSignature = 0;
2213 for (uint32_t iReg = 0; iReg < RT_ELEMENTS(aIdxSignature); ++iReg)
2214 {
2215 if (aIdxSignature[iReg] == 0xFFFFFFFF) /* This register is unused. */
2216 continue;
2217
2218 AssertReturn(iSignature < cSignature, VERR_INTERNAL_ERROR);
2219
2220 SVGA3dDXSignatureEntry const *src = &paSignature[aIdxSignature[iReg]];
2221 DXBCBlobIOSGNElement *dst = &pHdrISGN->aElement[iSignature];
2222
2223 ASSERT_GUEST_RETURN(src->semanticName < SVGADX_SIGNATURE_SEMANTIC_NAME_MAX, VERR_INVALID_PARAMETER);
2224 VGPUSemanticInfo const *pSemanticInfo = dxbcSemanticInfo(pInfo, src->semanticName, u32BlobType);
2225
2226 dst->offElementName = cbBlob; /* Offset of the semantic's name relative to the start of the blob (without hdr). */
2227 /* Use the register index as the semantic index for generic attributes in order to
2228 * produce compatible semantic names between shaders.
2229 */
2230 dst->idxSemantic = src->semanticName == SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED
2231 ? src->registerIndex
2232 : aSemanticIdx[src->semanticName]++;
2233 dst->enmSystemValue = src->semanticName;
2234 dst->enmComponentType = src->componentType ? src->componentType : pSemanticInfo->u32Type;
2235 dst->idxRegister = src->registerIndex;
2236 dst->mask = src->mask;
2237 if (u32BlobType == DXBC_BLOB_TYPE_OSGN)
2238 dst->mask2 = 0;
2239 else
2240 dst->mask2 = src->mask;
2241
2242 /* Figure out the semantic name for this element. */
2243 char const * const pszElementName = pSemanticInfo->pszName;
2244 uint32_t const cbElementName = (uint32_t)strlen(pszElementName) + 1;
2245
2246 if (!dxbcByteWriterCanWrite(w, cbBlob + cbElementName))
2247 return VERR_NO_MEMORY;
2248
2249 char *pszElementNameDst = (char *)pHdrISGN + dst->offElementName;
2250 memcpy(pszElementNameDst, pszElementName, cbElementName);
2251
2252 cbBlob += cbElementName;
2253 ++iSignature;
2254 }
2255
2256 /* Blobs are 4 bytes aligned. Commit the blob data. */
2257 cbBlob = RT_ALIGN_32(cbBlob, 4);
2258 pHdrBlob->cbBlob = cbBlob;
2259 pHdr->cbTotal += cbBlob + sizeof(DXBCBlobHeader);
2260 dxbcByteWriterCommit(w, cbBlob + sizeof(DXBCBlobHeader));
2261 return VINF_SUCCESS;
2262}
2263
2264
2265static int dxbcCreateSHDRBlob(DXBCHeader *pHdr, uint32_t u32BlobType,
2266 void const *pvShader, uint32_t cbShader, DXBCByteWriter *w)
2267{
2268 uint32_t cbBlob = cbShader;
2269 if (!dxbcByteWriterCanWrite(w, sizeof(DXBCBlobHeader) + cbBlob))
2270 return VERR_NO_MEMORY;
2271
2272 DXBCBlobHeader *pHdrBlob = (DXBCBlobHeader *)dxbcByteWriterPtr(w);
2273 pHdrBlob->u32BlobType = u32BlobType;
2274 // pHdrBlob->cbBlob = 0;
2275
2276 memcpy(&pHdrBlob[1], pvShader, cbShader);
2277
2278 /* Blobs are 4 bytes aligned. Commit the blob data. */
2279 cbBlob = RT_ALIGN_32(cbBlob, 4);
2280 pHdrBlob->cbBlob = cbBlob;
2281 pHdr->cbTotal += cbBlob + sizeof(DXBCBlobHeader);
2282 dxbcByteWriterCommit(w, cbBlob + sizeof(DXBCBlobHeader));
2283 return VINF_SUCCESS;
2284}
2285
2286
2287/*
2288 * Create a DXBC container with signature and shader code data blobs.
2289 */
2290static int dxbcCreateFromInfo(DXShaderInfo const *pInfo, void const *pvShader, uint32_t cbShader, DXBCByteWriter *w)
2291{
2292 int rc;
2293
2294 /* Create a DXBC container with ISGN, OSGN and SHDR blobs. */
2295 uint32_t const cBlob = 3;
2296 uint32_t const cbHdr = RT_UOFFSETOF(DXBCHeader, aBlobOffset[cBlob]); /* Header with blob offsets. */
2297 if (!dxbcByteWriterCanWrite(w, cbHdr))
2298 return VERR_NO_MEMORY;
2299
2300 /* Container header. */
2301 DXBCHeader *pHdr = (DXBCHeader *)dxbcByteWriterPtr(w);
2302 pHdr->u32DXBC = DXBC_MAGIC;
2303 // RT_ZERO(pHdr->au8Hash);
2304 pHdr->u32Version = 1;
2305 pHdr->cbTotal = cbHdr;
2306 pHdr->cBlob = cBlob;
2307 //RT_ZERO(pHdr->aBlobOffset);
2308 dxbcByteWriterCommit(w, cbHdr);
2309
2310 /* Blobs. */
2311 uint32_t iBlob = 0;
2312
2313 pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
2314 rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_ISGN, pInfo->cInputSignature, &pInfo->aInputSignature[0], w);
2315 AssertRCReturn(rc, rc);
2316
2317 pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
2318 rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_OSGN, pInfo->cOutputSignature, &pInfo->aOutputSignature[0], w);
2319 AssertRCReturn(rc, rc);
2320
2321 pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
2322 rc = dxbcCreateSHDRBlob(pHdr, DXBC_BLOB_TYPE_SHDR, pvShader, cbShader, w);
2323 AssertRCReturn(rc, rc);
2324
2325 AssertCompile(RT_UOFFSETOF(DXBCHeader, u32Version) == 0x14);
2326 dxbcHash(&pHdr->u32Version, pHdr->cbTotal - RT_UOFFSETOF(DXBCHeader, u32Version), pHdr->au8Hash);
2327
2328 return VINF_SUCCESS;
2329}
2330
2331
2332int DXShaderCreateDXBC(DXShaderInfo const *pInfo, void **ppvDXBC, uint32_t *pcbDXBC)
2333{
2334 /* Build DXBC container. */
2335 int rc;
2336 DXBCByteWriter dxbcByteWriter;
2337 DXBCByteWriter *w = &dxbcByteWriter;
2338 if (dxbcByteWriterInit(w, 4096 + pInfo->cbBytecode))
2339 {
2340 rc = dxbcCreateFromInfo(pInfo, pInfo->pvBytecode, pInfo->cbBytecode, w);
2341 if (RT_SUCCESS(rc))
2342 dxbcByteWriterFetchData(w, ppvDXBC, pcbDXBC);
2343 }
2344 else
2345 rc = VERR_NO_MEMORY;
2346 return rc;
2347}
2348
2349
2350static char const *dxbcGetOutputSemanticName(DXShaderInfo const *pInfo, uint32_t idxRegister, uint32_t u32BlobType,
2351 uint32_t cSignature, SVGA3dDXSignatureEntry const *paSignature)
2352{
2353 for (uint32_t i = 0; i < cSignature; ++i)
2354 {
2355 SVGA3dDXSignatureEntry const *p = &paSignature[i];
2356 if (p->registerIndex == idxRegister)
2357 {
2358 AssertReturn(p->semanticName < SVGADX_SIGNATURE_SEMANTIC_NAME_MAX, NULL);
2359 VGPUSemanticInfo const *pSemanticInfo = dxbcSemanticInfo(pInfo, p->semanticName, u32BlobType);
2360 return pSemanticInfo->pszName;
2361 }
2362 }
2363 return NULL;
2364}
2365
2366char const *DXShaderGetOutputSemanticName(DXShaderInfo const *pInfo, uint32_t idxRegister)
2367{
2368 return dxbcGetOutputSemanticName(pInfo, idxRegister, DXBC_BLOB_TYPE_OSGN, pInfo->cOutputSignature, &pInfo->aOutputSignature[0]);
2369}
2370
2371int DXShaderUpdateResourceTypes(DXShaderInfo const *pInfo, VGPU10_RESOURCE_DIMENSION *paResourceType, uint32_t cResourceType)
2372{
2373 for (uint32_t i = 0; i < pInfo->cDclResource; ++i)
2374 {
2375 VGPU10_RESOURCE_DIMENSION const resourceType = i < cResourceType ? paResourceType[i] : VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
2376 AssertContinue(resourceType <= VGPU10_RESOURCE_DIMENSION_TEXTURECUBEARRAY);
2377
2378 uint32_t const offToken = pInfo->aOffDclResource[i];
2379 AssertContinue(offToken < pInfo->cbBytecode);
2380 uint32_t *paToken = (uint32_t *)((uintptr_t)pInfo->pvBytecode + offToken);
2381
2382 VGPU10OpcodeToken0 *pOpcode = (VGPU10OpcodeToken0 *)&paToken[0];
2383 pOpcode->resourceDimension = resourceType;
2384 // paToken[1] unmodified
2385 // paToken[2] unmodified
2386 paToken[3] = 0x5555; /** @todo VGPU10ResourceReturnTypeToken float */
2387 }
2388
2389 return VINF_SUCCESS;
2390}
2391
2392#ifdef DXBC_STANDALONE_TEST
2393static int dxbcCreateFromBytecode(void const *pvShaderCode, uint32_t cbShaderCode, void **ppvDXBC, uint32_t *pcbDXBC)
2394{
2395 /* Parse the shader bytecode and create DXBC container with resource, signature and shader bytecode blobs. */
2396 DXShaderInfo info;
2397 RT_ZERO(info);
2398 int rc = DXShaderParse(pvShaderCode, cbShaderCode, &info);
2399 if (RT_SUCCESS(rc))
2400 rc = DXShaderCreateDXBC(&info, ppvDXBC, pcbDXBC);
2401 return rc;
2402}
2403
2404static int parseShaderVM(void const *pvShaderCode, uint32_t cbShaderCode)
2405{
2406 void *pv = NULL;
2407 uint32_t cb = 0;
2408 int rc = dxbcCreateFromBytecode(pvShaderCode, cbShaderCode, &pv, &cb);
2409 if (RT_SUCCESS(rc))
2410 {
2411 /* Hexdump DXBC */
2412 printf("{\n");
2413 uint8_t *pu8 = (uint8_t *)pv;
2414 for (uint32_t i = 0; i < cb; ++i)
2415 {
2416 if ((i % 16) == 0)
2417 {
2418 if (i > 0)
2419 printf(",\n");
2420
2421 printf(" 0x%02x", pu8[i]);
2422 }
2423 else
2424 {
2425 printf(", 0x%02x", pu8[i]);
2426 }
2427 }
2428 printf("\n");
2429 printf("};\n");
2430
2431 RTMemFree(pv);
2432 }
2433
2434 return rc;
2435}
2436
2437static DXBCBlobHeader *dxbcFindBlob(DXBCHeader *pDXBCHeader, uint32_t u32BlobType)
2438{
2439 uint8_t const *pu8DXBCBegin = (uint8_t *)pDXBCHeader;
2440 for (uint32_t i = 0; i < pDXBCHeader->cBlob; ++i)
2441 {
2442 DXBCBlobHeader *pCurrentBlob = (DXBCBlobHeader *)&pu8DXBCBegin[pDXBCHeader->aBlobOffset[i]];
2443 if (pCurrentBlob->u32BlobType == u32BlobType)
2444 return pCurrentBlob;
2445 }
2446 return NULL;
2447}
2448
2449static int dxbcExtractShaderCode(DXBCHeader *pDXBCHeader, void **ppvCode, uint32_t *pcbCode)
2450{
2451 DXBCBlobHeader *pBlob = dxbcFindBlob(pDXBCHeader, DXBC_BLOB_TYPE_SHDR);
2452 AssertReturn(pBlob, VERR_NOT_IMPLEMENTED);
2453
2454 DXBCBlobSHDR *pSHDR = (DXBCBlobSHDR *)&pBlob[1];
2455 *pcbCode = pSHDR->cToken * 4;
2456 *ppvCode = RTMemAlloc(*pcbCode);
2457 AssertReturn(*ppvCode, VERR_NO_MEMORY);
2458
2459 memcpy(*ppvCode, pSHDR, *pcbCode);
2460 return VINF_SUCCESS;
2461}
2462
2463static int parseShaderDXBC(void const *pvDXBC)
2464{
2465 DXBCHeader *pDXBCHeader = (DXBCHeader *)pvDXBC;
2466 void *pvShaderCode = NULL;
2467 uint32_t cbShaderCode = 0;
2468 int rc = dxbcExtractShaderCode(pDXBCHeader, &pvShaderCode, &cbShaderCode);
2469 if (RT_SUCCESS(rc))
2470 {
2471 rc = parseShaderVM(pvShaderCode, cbShaderCode);
2472 RTMemFree(pvShaderCode);
2473 }
2474 return rc;
2475}
2476#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