VirtualBox

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

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

Devices/Graphics: shader management: bugref:9830

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