VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-hlp.cpp@ 86009

Last change on this file since 86009 was 86009, checked in by vboxsync, 4 years ago

Devices/Graphics: Use current VMSVGA headers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1/* $Id: DevVGA-SVGA3d-hlp.cpp 86009 2020-09-02 23:01:09Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device helpers
4 */
5
6/*
7 * Copyright (C) 2020 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#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
19#include <VBox/AssertGuest.h>
20#include <VBox/log.h>
21
22#include <iprt/cdefs.h>
23#include <iprt/errcore.h>
24#include <iprt/types.h>
25
26#include "DevVGA-SVGA.h"
27
28typedef struct VMSVGA3DSHADERPARSECONTEXT
29{
30 uint32_t type;
31} VMSVGA3DSHADERPARSECONTEXT;
32
33static int vmsvga3dShaderParseRegOffset(VMSVGA3DSHADERPARSECONTEXT *pCtx,
34 bool fIsSrc,
35 SVGA3dShaderRegType regType,
36 uint32_t off)
37{
38 RT_NOREF(pCtx, fIsSrc);
39
40 switch (regType)
41 {
42 case SVGA3DREG_TEMP:
43 break;
44 case SVGA3DREG_INPUT:
45 break;
46 case SVGA3DREG_CONST:
47 break;
48 case SVGA3DREG_ADDR /* also SVGA3DREG_TEXTURE */:
49 break;
50 case SVGA3DREG_RASTOUT:
51 break;
52 case SVGA3DREG_ATTROUT:
53 break;
54 case SVGA3DREG_TEXCRDOUT /* also SVGA3DREG_OUTPUT */:
55 break;
56 case SVGA3DREG_CONSTINT:
57 break;
58 case SVGA3DREG_COLOROUT:
59 break;
60 case SVGA3DREG_DEPTHOUT:
61 break;
62 case SVGA3DREG_SAMPLER:
63 break;
64 case SVGA3DREG_CONST2:
65 break;
66 case SVGA3DREG_CONST3:
67 break;
68 case SVGA3DREG_CONST4:
69 break;
70 case SVGA3DREG_CONSTBOOL:
71 break;
72 case SVGA3DREG_LOOP:
73 break;
74 case SVGA3DREG_TEMPFLOAT16:
75 break;
76 case SVGA3DREG_MISCTYPE:
77 ASSERT_GUEST_RETURN( off == SVGA3DMISCREG_POSITION
78 || off == SVGA3DMISCREG_FACE, VERR_PARSE_ERROR);
79 break;
80 case SVGA3DREG_LABEL:
81 break;
82 case SVGA3DREG_PREDICATE:
83 break;
84 default:
85 ASSERT_GUEST_FAILED_RETURN(VERR_PARSE_ERROR);
86 }
87
88 return VINF_SUCCESS;
89}
90
91#if 0
92static int vmsvga3dShaderParseSrcToken(VMSVGA3DSHADERPARSECONTEXT *pCtx, uint32_t const *pToken)
93{
94 RT_NOREF(pCtx);
95
96 SVGA3dShaderSrcToken src;
97 src.value = *pToken;
98
99 SVGA3dShaderRegType const regType = (SVGA3dShaderRegType)(src.type_upper << 3 | src.type_lower);
100 Log3(("Src: type %d, r0 %d, srcMod %d, swizzle 0x%x, r1 %d, relAddr %d, num %d\n",
101 regType, src.reserved0, src.srcMod, src.swizzle, src.reserved1, src.relAddr, src.num));
102
103 return vmsvga3dShaderParseRegOffset(pCtx, true, regType, src.num);
104}
105#endif
106
107static int vmsvga3dShaderParseDestToken(VMSVGA3DSHADERPARSECONTEXT *pCtx, uint32_t const *pToken)
108{
109 RT_NOREF(pCtx);
110
111 SVGA3dShaderDestToken dest;
112 dest.value = *pToken;
113
114 SVGA3dShaderRegType const regType = (SVGA3dShaderRegType)(dest.type_upper << 3 | dest.type_lower);
115 Log3(("Dest: type %d, r0 %d, shfScale %d, dstMod %d, mask 0x%x, r1 %d, relAddr %d, num %d\n",
116 regType, dest.reserved0, dest.shfScale, dest.dstMod, dest.mask, dest.reserved1, dest.relAddr, dest.num));
117
118 return vmsvga3dShaderParseRegOffset(pCtx, false, regType, dest.num);
119}
120
121static int vmsvga3dShaderParseDclArgs(VMSVGA3DSHADERPARSECONTEXT *pCtx, uint32_t const *pToken)
122{
123 SVGA3DOpDclArgs a;
124 a.values[0] = pToken[0]; // declaration
125 a.values[1] = pToken[1]; // dst
126
127 return vmsvga3dShaderParseDestToken(pCtx, (uint32_t *)&a.dst);
128}
129
130/* Parse the shader code
131 * https://docs.microsoft.com/en-us/windows-hardware/drivers/display/shader-code-format
132 */
133int vmsvga3dShaderParse(uint32_t cbShaderData, uint32_t const *pShaderData)
134{
135 uint32_t const *paTokensStart = (uint32_t *)pShaderData;
136 uint32_t const cTokens = cbShaderData / sizeof(uint32_t);
137
138 /* 48KB is an arbitrary limit. */
139 ASSERT_GUEST_RETURN(cTokens >= 2 && cTokens < (48 * _1K) / sizeof(paTokensStart[0]), VERR_INVALID_PARAMETER);
140
141#ifdef LOG_ENABLED
142 Log3(("Shader code:\n"));
143 const uint32_t cTokensPerLine = 8;
144 for (uint32_t iToken = 0; iToken < cTokens; ++iToken)
145 {
146 if ((iToken % cTokensPerLine) == 0)
147 {
148 if (iToken == 0)
149 Log3(("0x%08X,", paTokensStart[iToken]));
150 else
151 Log3(("\n0x%08X,", paTokensStart[iToken]));
152 }
153 else
154 Log3((" 0x%08X,", paTokensStart[iToken]));
155 }
156 Log3(("\n"));
157#endif
158
159 /* "The first token must be a version token." */
160 SVGA3dShaderVersion const *pVersion = (SVGA3dShaderVersion const *)paTokensStart;
161 ASSERT_GUEST_RETURN( pVersion->type == SVGA3D_VS_TYPE
162 || pVersion->type == SVGA3D_PS_TYPE, VERR_PARSE_ERROR);
163
164 VMSVGA3DSHADERPARSECONTEXT ctx;
165 ctx.type = pVersion->type;
166
167 /* Scan the tokens. Immediately return an error code on any unexpected data. */
168 const uint32_t *paTokensEnd = &paTokensStart[cTokens];
169 const uint32_t *pToken = &paTokensStart[1];
170 while (pToken < paTokensEnd)
171 {
172 SVGA3dShaderInstToken const token = *(SVGA3dShaderInstToken *)pToken;
173
174 /* Figure out the instruction length, which is how many tokens follow the instruction token. */
175 uint32_t cInstLen;
176 if (token.op == SVGA3DOP_COMMENT)
177 cInstLen = token.comment_size;
178 else
179 cInstLen = token.size;
180
181 Log3(("op %d, cInstLen %d\n", token.op, cInstLen));
182
183 ASSERT_GUEST_RETURN(cInstLen < paTokensEnd - pToken, VERR_PARSE_ERROR);
184
185 if (token.op == SVGA3DOP_END)
186 {
187 ASSERT_GUEST_RETURN(token.value == 0x0000FFFF, VERR_PARSE_ERROR);
188 break;
189 }
190
191 int rc;
192 switch (token.op)
193 {
194 case SVGA3DOP_DCL:
195 ASSERT_GUEST_RETURN(cInstLen == 2, VERR_PARSE_ERROR);
196 rc = vmsvga3dShaderParseDclArgs(&ctx, &pToken[1]);
197 if (RT_FAILURE(rc))
198 return rc;
199 break;
200 case SVGA3DOP_NOP:
201 case SVGA3DOP_MOV:
202 case SVGA3DOP_ADD:
203 case SVGA3DOP_SUB:
204 case SVGA3DOP_MAD:
205 case SVGA3DOP_MUL:
206 case SVGA3DOP_RCP:
207 case SVGA3DOP_RSQ:
208 case SVGA3DOP_DP3:
209 case SVGA3DOP_DP4:
210 case SVGA3DOP_MIN:
211 case SVGA3DOP_MAX:
212 case SVGA3DOP_SLT:
213 case SVGA3DOP_SGE:
214 case SVGA3DOP_EXP:
215 case SVGA3DOP_LOG:
216 case SVGA3DOP_LIT:
217 case SVGA3DOP_DST:
218 case SVGA3DOP_LRP:
219 case SVGA3DOP_FRC:
220 case SVGA3DOP_M4x4:
221 case SVGA3DOP_M4x3:
222 case SVGA3DOP_M3x4:
223 case SVGA3DOP_M3x3:
224 case SVGA3DOP_M3x2:
225 case SVGA3DOP_CALL:
226 case SVGA3DOP_CALLNZ:
227 case SVGA3DOP_LOOP:
228 case SVGA3DOP_RET:
229 case SVGA3DOP_ENDLOOP:
230 case SVGA3DOP_LABEL:
231 case SVGA3DOP_POW:
232 case SVGA3DOP_CRS:
233 case SVGA3DOP_SGN:
234 case SVGA3DOP_ABS:
235 case SVGA3DOP_NRM:
236 case SVGA3DOP_SINCOS:
237 case SVGA3DOP_REP:
238 case SVGA3DOP_ENDREP:
239 case SVGA3DOP_IF:
240 case SVGA3DOP_IFC:
241 case SVGA3DOP_ELSE:
242 case SVGA3DOP_ENDIF:
243 case SVGA3DOP_BREAK:
244 case SVGA3DOP_BREAKC:
245 case SVGA3DOP_MOVA:
246 case SVGA3DOP_DEFB:
247 case SVGA3DOP_DEFI:
248 case SVGA3DOP_TEXCOORD:
249 case SVGA3DOP_TEXKILL:
250 case SVGA3DOP_TEX:
251 case SVGA3DOP_TEXBEM:
252 case SVGA3DOP_TEXBEML:
253 case SVGA3DOP_TEXREG2AR:
254 case SVGA3DOP_TEXREG2GB:
255 case SVGA3DOP_TEXM3x2PAD:
256 case SVGA3DOP_TEXM3x2TEX:
257 case SVGA3DOP_TEXM3x3PAD:
258 case SVGA3DOP_TEXM3x3TEX:
259 case SVGA3DOP_RESERVED0:
260 case SVGA3DOP_TEXM3x3SPEC:
261 case SVGA3DOP_TEXM3x3VSPEC:
262 case SVGA3DOP_EXPP:
263 case SVGA3DOP_LOGP:
264 case SVGA3DOP_CND:
265 case SVGA3DOP_DEF:
266 case SVGA3DOP_TEXREG2RGB:
267 case SVGA3DOP_TEXDP3TEX:
268 case SVGA3DOP_TEXM3x2DEPTH:
269 case SVGA3DOP_TEXDP3:
270 case SVGA3DOP_TEXM3x3:
271 case SVGA3DOP_TEXDEPTH:
272 case SVGA3DOP_CMP:
273 case SVGA3DOP_BEM:
274 case SVGA3DOP_DP2ADD:
275 case SVGA3DOP_DSX:
276 case SVGA3DOP_DSY:
277 case SVGA3DOP_TEXLDD:
278 case SVGA3DOP_SETP:
279 case SVGA3DOP_TEXLDL:
280 case SVGA3DOP_BREAKP:
281 case SVGA3DOP_PHASE:
282 case SVGA3DOP_COMMENT:
283 break;
284
285 default:
286 ASSERT_GUEST_FAILED_RETURN(VERR_PARSE_ERROR);
287 }
288
289 /* Next token. */
290 pToken += cInstLen + 1;
291 }
292
293 return VINF_SUCCESS;
294}
295
296void vmsvga3dShaderLogRel(char const *pszMsg, SVGA3dShaderType type, uint32_t cbShaderData, uint32_t const *pShaderData)
297{
298 /* Dump the shader code. */
299 static int scLogged = 0;
300 if (scLogged < 8)
301 {
302 ++scLogged;
303
304 LogRel(("VMSVGA: %s shader: %s:\n", (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", pszMsg));
305 const uint32_t cTokensPerLine = 8;
306 const uint32_t *paTokens = (uint32_t *)pShaderData;
307 const uint32_t cTokens = cbShaderData / sizeof(uint32_t);
308 for (uint32_t iToken = 0; iToken < cTokens; ++iToken)
309 {
310 if ((iToken % cTokensPerLine) == 0)
311 {
312 if (iToken == 0)
313 LogRel(("0x%08X,", paTokens[iToken]));
314 else
315 LogRel(("\n0x%08X,", paTokens[iToken]));
316 }
317 else
318 LogRel((" 0x%08X,", paTokens[iToken]));
319 }
320 LogRel(("\n"));
321 }
322}
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