VirtualBox

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

Last change on this file since 95782 was 95782, checked in by vboxsync, 2 years ago

Devices/Graphics: retry D3D device creation in debug build. bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 404.8 KB
Line 
1/* $Id: DevVGA-SVGA3d-win-dx.cpp 95782 2022-07-21 19:27:58Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device
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#include <VBox/vmm/pdmdev.h>
26#include <VBox/vmm/pgm.h>
27
28#include <iprt/assert.h>
29#include <iprt/avl.h>
30#include <iprt/errcore.h>
31#include <iprt/mem.h>
32
33#include <VBoxVideo.h> /* required by DevVGA.h */
34#include <VBoxVideo3D.h>
35
36/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
37#include "DevVGA.h"
38
39#include "DevVGA-SVGA.h"
40#include "DevVGA-SVGA3d.h"
41#include "DevVGA-SVGA3d-internal.h"
42#include "DevVGA-SVGA3d-dx-shader.h"
43
44/* d3d11_1.h has a structure field named 'Status' but Status is defined as int on Linux host */
45#if defined(Status)
46#undef Status
47#endif
48#include <d3d11_1.h>
49
50
51#ifdef RT_OS_WINDOWS
52# define VBOX_D3D11_LIBRARY_NAME "d3d11"
53#else
54# define VBOX_D3D11_LIBRARY_NAME "VBoxDxVk"
55#endif
56
57#define DX_FORCE_SINGLE_DEVICE
58
59/* This is not available on non Windows hosts. */
60#ifndef D3D_RELEASE
61# define D3D_RELEASE(a_Ptr) do { if ((a_Ptr)) (a_Ptr)->Release(); (a_Ptr) = NULL; } while (0)
62#endif
63
64/** Fake ID for the backend DX context. The context creates all shared textures. */
65#define DX_CID_BACKEND UINT32_C(0xfffffffe)
66
67#define D3D_RELEASE_ARRAY(a_Count, a_papArray) do { \
68 for (uint32_t i = 0; i < (a_Count); ++i) \
69 D3D_RELEASE((a_papArray)[i]); \
70} while (0)
71
72typedef struct D3D11BLITTER
73{
74 ID3D11Device *pDevice;
75 ID3D11DeviceContext *pImmediateContext;
76
77 ID3D11VertexShader *pVertexShader;
78 ID3D11PixelShader *pPixelShader;
79 ID3D11SamplerState *pSamplerState;
80 ID3D11RasterizerState *pRasterizerState;
81 ID3D11BlendState *pBlendState;
82} D3D11BLITTER;
83
84typedef struct DXDEVICE
85{
86 ID3D11Device1 *pDevice; /* Device. */
87 ID3D11DeviceContext1 *pImmediateContext; /* Corresponding context. */
88 IDXGIFactory *pDxgiFactory; /* DXGI Factory. */
89 D3D_FEATURE_LEVEL FeatureLevel;
90
91 /* Staging buffer for transfer to surface buffers. */
92 ID3D11Buffer *pStagingBuffer; /* The staging buffer resource. */
93 uint32_t cbStagingBuffer; /* Current size of the staging buffer resource. */
94
95 D3D11BLITTER Blitter; /* Blits one texture to another. */
96} DXDEVICE;
97
98/* Kind of a texture view. */
99typedef enum VMSVGA3DBACKVIEWTYPE
100{
101 VMSVGA3D_VIEWTYPE_NONE = 0,
102 VMSVGA3D_VIEWTYPE_RENDERTARGET = 1,
103 VMSVGA3D_VIEWTYPE_DEPTHSTENCIL = 2,
104 VMSVGA3D_VIEWTYPE_SHADERRESOURCE = 3,
105 VMSVGA3D_VIEWTYPE_UNORDEREDACCESS = 4
106} VMSVGA3DBACKVIEWTYPE;
107
108/* Information about a texture view to track all created views:.
109 * when a surface is invalidated, then all views must deleted;
110 * when a view is deleted, then the view must be unlinked from the surface.
111 */
112typedef struct DXVIEWINFO
113{
114 uint32_t sid; /* Surface which the view was created for. */
115 uint32_t cid; /* DX context which created the view. */
116 uint32_t viewId; /* View id assigned by the guest. */
117 VMSVGA3DBACKVIEWTYPE enmViewType;
118} DXVIEWINFO;
119
120/* Context Object Table element for a texture view. */
121typedef struct DXVIEW
122{
123 uint32_t cid; /* DX context which created the view. */
124 uint32_t sid; /* Surface which the view was created for. */
125 uint32_t viewId; /* View id assigned by the guest. */
126 VMSVGA3DBACKVIEWTYPE enmViewType;
127
128 union
129 {
130 ID3D11View *pView; /* The view object. */
131 ID3D11RenderTargetView *pRenderTargetView;
132 ID3D11DepthStencilView *pDepthStencilView;
133 ID3D11ShaderResourceView *pShaderResourceView;
134 ID3D11UnorderedAccessView *pUnorderedAccessView;
135 } u;
136
137 RTLISTNODE nodeSurfaceView; /* Views are linked to the surface. */
138} DXVIEW;
139
140/* What kind of resource has been created for the VMSVGA3D surface. */
141typedef enum VMSVGA3DBACKRESTYPE
142{
143 VMSVGA3D_RESTYPE_NONE = 0,
144 VMSVGA3D_RESTYPE_SCREEN_TARGET = 1,
145 VMSVGA3D_RESTYPE_TEXTURE_1D = 2,
146 VMSVGA3D_RESTYPE_TEXTURE_2D = 3,
147 VMSVGA3D_RESTYPE_TEXTURE_CUBE = 4,
148 VMSVGA3D_RESTYPE_TEXTURE_3D = 5,
149 VMSVGA3D_RESTYPE_BUFFER = 6,
150} VMSVGA3DBACKRESTYPE;
151
152typedef struct VMSVGA3DBACKENDSURFACE
153{
154 VMSVGA3DBACKRESTYPE enmResType;
155 DXGI_FORMAT enmDxgiFormat;
156 union
157 {
158 ID3D11Resource *pResource;
159 ID3D11Texture1D *pTexture1D;
160 ID3D11Texture2D *pTexture2D;
161 ID3D11Texture3D *pTexture3D;
162 ID3D11Buffer *pBuffer;
163 } u;
164
165 /* For updates from memory. */
166 union /** @todo One per format. */
167 {
168 ID3D11Resource *pResource;
169 ID3D11Texture1D *pTexture1D;
170 ID3D11Texture2D *pTexture2D;
171 ID3D11Texture3D *pTexture3D;
172 } dynamic;
173
174 /* For reading the texture content. */
175 union /** @todo One per format. */
176 {
177 ID3D11Resource *pResource;
178 ID3D11Texture1D *pTexture1D;
179 ID3D11Texture2D *pTexture2D;
180 ID3D11Texture3D *pTexture3D;
181 } staging;
182
183 /* Screen targets are created as shared surfaces. */
184 HANDLE SharedHandle; /* The shared handle of this structure. */
185
186 /* DX context which last rendered to the texture.
187 * This is only for render targets and screen targets, which can be shared between contexts.
188 * The backend context (cid == DX_CID_BACKEND) can also be a drawing context.
189 */
190 uint32_t cidDrawing;
191
192 /** AVL tree containing DXSHAREDTEXTURE structures. */
193 AVLU32TREE SharedTextureTree;
194
195 /* Render target views, depth stencil views and shader resource views created for this texture or buffer. */
196 RTLISTANCHOR listView; /* DXVIEW */
197
198} VMSVGA3DBACKENDSURFACE;
199
200/* "The only resources that can be shared are 2D non-mipmapped textures." */
201typedef struct DXSHAREDTEXTURE
202{
203 AVLU32NODECORE Core; /* Key is context id which opened this texture. */
204 ID3D11Texture2D *pTexture; /* The opened shared texture. */
205 uint32_t sid; /* Surface id. */
206} DXSHAREDTEXTURE;
207
208
209typedef struct VMSVGAHWSCREEN
210{
211 ID3D11Texture2D *pTexture; /* Shared texture for the screen content. Only used as CopyResource target. */
212 IDXGIResource *pDxgiResource; /* Interface of the texture. */
213 IDXGIKeyedMutex *pDXGIKeyedMutex; /* Synchronization interface for the render device. */
214 HANDLE SharedHandle; /* The shared handle of this structure. */
215 uint32_t sidScreenTarget; /* The source surface for this screen. */
216} VMSVGAHWSCREEN;
217
218
219typedef struct DXELEMENTLAYOUT
220{
221 ID3D11InputLayout *pElementLayout;
222 uint32_t cElementDesc;
223 D3D11_INPUT_ELEMENT_DESC aElementDesc[32];
224} DXELEMENTLAYOUT;
225
226typedef struct DXSHADER
227{
228 SVGA3dShaderType enmShaderType;
229 union
230 {
231 ID3D11DeviceChild *pShader; /* All. */
232 ID3D11VertexShader *pVertexShader; /* SVGA3D_SHADERTYPE_VS */
233 ID3D11PixelShader *pPixelShader; /* SVGA3D_SHADERTYPE_PS */
234 ID3D11GeometryShader *pGeometryShader; /* SVGA3D_SHADERTYPE_GS */
235 ID3D11HullShader *pHullShader; /* SVGA3D_SHADERTYPE_HS */
236 ID3D11DomainShader *pDomainShader; /* SVGA3D_SHADERTYPE_DS */
237 ID3D11ComputeShader *pComputeShader; /* SVGA3D_SHADERTYPE_CS */
238 };
239 void *pvDXBC;
240 uint32_t cbDXBC;
241
242 uint32_t soid; /* Stream output declarations for geometry shaders. */
243
244 DXShaderInfo shaderInfo;
245} DXSHADER;
246
247typedef struct DXQUERY
248{
249 union
250 {
251 ID3D11Query *pQuery;
252 ID3D11Predicate *pPredicate;
253 };
254} DXQUERY;
255
256typedef struct DXSTREAMOUTPUT
257{
258 UINT cDeclarationEntry;
259 D3D11_SO_DECLARATION_ENTRY aDeclarationEntry[SVGA3D_MAX_STREAMOUT_DECLS];
260} DXSTREAMOUTPUT;
261
262typedef struct DXBOUNDVERTEXBUFFER
263{
264 ID3D11Buffer *pBuffer;
265 uint32_t stride;
266 uint32_t offset;
267} DXBOUNDVERTEXBUFFER;
268
269typedef struct DXBOUNDINDEXBUFFER
270{
271 ID3D11Buffer *pBuffer;
272 DXGI_FORMAT indexBufferFormat;
273 uint32_t indexBufferOffset;
274} DXBOUNDINDEXBUFFER;
275
276typedef struct DXBOUNDRESOURCES /* Currently bound resources. Mirror SVGADXContextMobFormat structure. */
277{
278 struct
279 {
280 DXBOUNDVERTEXBUFFER vertexBuffers[SVGA3D_DX_MAX_VERTEXBUFFERS];
281 DXBOUNDINDEXBUFFER indexBuffer;
282 } inputAssembly;
283 struct
284 {
285 ID3D11Buffer *constantBuffers[SVGA3D_DX_MAX_CONSTBUFFERS];
286 } shaderState[SVGA3D_NUM_SHADERTYPE];
287} DXBOUNDRESOURCES;
288
289
290typedef struct VMSVGA3DBACKENDDXCONTEXT
291{
292 DXDEVICE dxDevice; /* DX device interfaces for this context operations. */
293
294 /* Arrays for Context-Object Tables. Number of entries depends on COTable size. */
295 uint32_t cBlendState; /* Number of entries in the papBlendState array. */
296 uint32_t cDepthStencilState; /* papDepthStencilState */
297 uint32_t cSamplerState; /* papSamplerState */
298 uint32_t cRasterizerState; /* papRasterizerState */
299 uint32_t cElementLayout; /* paElementLayout */
300 uint32_t cRenderTargetView; /* paRenderTargetView */
301 uint32_t cDepthStencilView; /* paDepthStencilView */
302 uint32_t cShaderResourceView; /* paShaderResourceView */
303 uint32_t cQuery; /* paQuery */
304 uint32_t cShader; /* paShader */
305 uint32_t cStreamOutput; /* paStreamOutput */
306 uint32_t cUnorderedAccessView; /* paUnorderedAccessView */
307 ID3D11BlendState **papBlendState;
308 ID3D11DepthStencilState **papDepthStencilState;
309 ID3D11SamplerState **papSamplerState;
310 ID3D11RasterizerState **papRasterizerState;
311 DXELEMENTLAYOUT *paElementLayout;
312 DXVIEW *paRenderTargetView;
313 DXVIEW *paDepthStencilView;
314 DXVIEW *paShaderResourceView;
315 DXQUERY *paQuery;
316 DXSHADER *paShader;
317 DXSTREAMOUTPUT *paStreamOutput;
318 DXVIEW *paUnorderedAccessView;
319
320 uint32_t cSOTarget; /* How many SO targets are currently set (SetSOTargets) */
321
322 DXBOUNDRESOURCES resources;
323} VMSVGA3DBACKENDDXCONTEXT;
324
325/* Shader disassembler function. Optional. */
326typedef HRESULT FN_D3D_DISASSEMBLE(LPCVOID pSrcData, SIZE_T SrcDataSize, UINT Flags, LPCSTR szComments, ID3D10Blob **ppDisassembly);
327typedef FN_D3D_DISASSEMBLE *PFN_D3D_DISASSEMBLE;
328
329typedef struct VMSVGA3DBACKEND
330{
331 RTLDRMOD hD3D11;
332 PFN_D3D11_CREATE_DEVICE pfnD3D11CreateDevice;
333
334 RTLDRMOD hD3DCompiler;
335 PFN_D3D_DISASSEMBLE pfnD3DDisassemble;
336
337 DXDEVICE dxDevice; /* Device for the VMSVGA3D context independent operation. */
338
339 DXBOUNDRESOURCES resources; /* What is currently applied to the pipeline. */
340
341 bool fSingleDevice; /* Whether to use one DX device for all guest contexts. */
342
343 /** @todo Here a set of functions which do different job in single and multiple device modes. */
344} VMSVGA3DBACKEND;
345
346
347/* Static function prototypes. */
348static int dxDeviceFlush(DXDEVICE *pDevice);
349static int dxDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry);
350static int dxDefineUnorderedAccessView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dUAViewId uaViewId, SVGACOTableDXUAViewEntry const *pEntry);
351static int dxDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry);
352static int dxDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry);
353static int dxSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext);
354static int dxSetCSUnorderedAccessViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext);
355static DECLCALLBACK(void) vmsvga3dBackSurfaceDestroy(PVGASTATECC pThisCC, bool fClearCOTableEntry, PVMSVGA3DSURFACE pSurface);
356static int dxDestroyShader(DXSHADER *pDXShader);
357static int dxDestroyQuery(DXQUERY *pDXQuery);
358
359static HRESULT BlitInit(D3D11BLITTER *pBlitter, ID3D11Device *pDevice, ID3D11DeviceContext *pImmediateContext);
360static void BlitRelease(D3D11BLITTER *pBlitter);
361
362
363/* This is not available with the DXVK headers for some reason. */
364#ifndef RT_OS_WINDOWS
365typedef enum D3D11_TEXTURECUBE_FACE {
366 D3D11_TEXTURECUBE_FACE_POSITIVE_X,
367 D3D11_TEXTURECUBE_FACE_NEGATIVE_X,
368 D3D11_TEXTURECUBE_FACE_POSITIVE_Y,
369 D3D11_TEXTURECUBE_FACE_NEGATIVE_Y,
370 D3D11_TEXTURECUBE_FACE_POSITIVE_Z,
371 D3D11_TEXTURECUBE_FACE_NEGATIVE_Z
372} D3D11_TEXTURECUBE_FACE;
373#endif
374
375
376DECLINLINE(D3D11_TEXTURECUBE_FACE) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
377{
378 D3D11_TEXTURECUBE_FACE Face;
379 switch (iFace)
380 {
381 case 0: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_X; break;
382 case 1: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_X; break;
383 case 2: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Y; break;
384 case 3: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Y; break;
385 case 4: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Z; break;
386 default:
387 case 5: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Z; break;
388 }
389 return Face;
390}
391
392/* This is to workaround issues with X8 formats, because they can't be used in some operations. */
393#define DX_REPLACE_X8_WITH_A8
394static DXGI_FORMAT vmsvgaDXSurfaceFormat2Dxgi(SVGA3dSurfaceFormat format)
395{
396 /* Ensure that correct headers are used.
397 * SVGA3D_AYUV was equal to 45, then replaced with SVGA3D_FORMAT_DEAD2 = 45, and redefined as SVGA3D_AYUV = 152.
398 */
399 AssertCompile(SVGA3D_AYUV == 152);
400
401#define DXGI_FORMAT_ DXGI_FORMAT_UNKNOWN
402 /** @todo More formats. */
403 switch (format)
404 {
405#ifdef DX_REPLACE_X8_WITH_A8
406 case SVGA3D_X8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
407#else
408 case SVGA3D_X8R8G8B8: return DXGI_FORMAT_B8G8R8X8_UNORM;
409#endif
410 case SVGA3D_A8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
411 case SVGA3D_R5G6B5: return DXGI_FORMAT_B5G6R5_UNORM;
412 case SVGA3D_X1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM;
413 case SVGA3D_A1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM;
414 case SVGA3D_A4R4G4B4: break; // 11.1 return DXGI_FORMAT_B4G4R4A4_UNORM;
415 case SVGA3D_Z_D32: break;
416 case SVGA3D_Z_D16: return DXGI_FORMAT_D16_UNORM;
417 case SVGA3D_Z_D24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
418 case SVGA3D_Z_D15S1: break;
419 case SVGA3D_LUMINANCE8: return DXGI_FORMAT_;
420 case SVGA3D_LUMINANCE4_ALPHA4: return DXGI_FORMAT_;
421 case SVGA3D_LUMINANCE16: return DXGI_FORMAT_;
422 case SVGA3D_LUMINANCE8_ALPHA8: return DXGI_FORMAT_;
423 case SVGA3D_DXT1: return DXGI_FORMAT_;
424 case SVGA3D_DXT2: return DXGI_FORMAT_;
425 case SVGA3D_DXT3: return DXGI_FORMAT_;
426 case SVGA3D_DXT4: return DXGI_FORMAT_;
427 case SVGA3D_DXT5: return DXGI_FORMAT_;
428 case SVGA3D_BUMPU8V8: return DXGI_FORMAT_;
429 case SVGA3D_BUMPL6V5U5: return DXGI_FORMAT_;
430 case SVGA3D_BUMPX8L8V8U8: return DXGI_FORMAT_;
431 case SVGA3D_FORMAT_DEAD1: break;
432 case SVGA3D_ARGB_S10E5: return DXGI_FORMAT_;
433 case SVGA3D_ARGB_S23E8: return DXGI_FORMAT_;
434 case SVGA3D_A2R10G10B10: return DXGI_FORMAT_;
435 case SVGA3D_V8U8: return DXGI_FORMAT_;
436 case SVGA3D_Q8W8V8U8: return DXGI_FORMAT_;
437 case SVGA3D_CxV8U8: return DXGI_FORMAT_;
438 case SVGA3D_X8L8V8U8: return DXGI_FORMAT_;
439 case SVGA3D_A2W10V10U10: return DXGI_FORMAT_;
440 case SVGA3D_ALPHA8: return DXGI_FORMAT_;
441 case SVGA3D_R_S10E5: return DXGI_FORMAT_;
442 case SVGA3D_R_S23E8: return DXGI_FORMAT_;
443 case SVGA3D_RG_S10E5: return DXGI_FORMAT_;
444 case SVGA3D_RG_S23E8: return DXGI_FORMAT_;
445 case SVGA3D_BUFFER: return DXGI_FORMAT_;
446 case SVGA3D_Z_D24X8: return DXGI_FORMAT_;
447 case SVGA3D_V16U16: return DXGI_FORMAT_;
448 case SVGA3D_G16R16: return DXGI_FORMAT_;
449 case SVGA3D_A16B16G16R16: return DXGI_FORMAT_;
450 case SVGA3D_UYVY: return DXGI_FORMAT_;
451 case SVGA3D_YUY2: return DXGI_FORMAT_;
452 case SVGA3D_NV12: return DXGI_FORMAT_;
453 case SVGA3D_FORMAT_DEAD2: break; /* Old SVGA3D_AYUV */
454 case SVGA3D_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_TYPELESS;
455 case SVGA3D_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_UINT;
456 case SVGA3D_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_SINT;
457 case SVGA3D_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_TYPELESS;
458 case SVGA3D_R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT;
459 case SVGA3D_R32G32B32_UINT: return DXGI_FORMAT_R32G32B32_UINT;
460 case SVGA3D_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_SINT;
461 case SVGA3D_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_TYPELESS;
462 case SVGA3D_R16G16B16A16_UINT: return DXGI_FORMAT_R16G16B16A16_UINT;
463 case SVGA3D_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM;
464 case SVGA3D_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_SINT;
465 case SVGA3D_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_TYPELESS;
466 case SVGA3D_R32G32_UINT: return DXGI_FORMAT_R32G32_UINT;
467 case SVGA3D_R32G32_SINT: return DXGI_FORMAT_R32G32_SINT;
468 case SVGA3D_R32G8X24_TYPELESS: return DXGI_FORMAT_R32G8X24_TYPELESS;
469 case SVGA3D_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
470 case SVGA3D_R32_FLOAT_X8X24: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
471 case SVGA3D_X32_G8X24_UINT: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
472 case SVGA3D_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_TYPELESS;
473 case SVGA3D_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_UINT;
474 case SVGA3D_R11G11B10_FLOAT: return DXGI_FORMAT_R11G11B10_FLOAT;
475 case SVGA3D_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_TYPELESS;
476 case SVGA3D_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
477 case SVGA3D_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
478 case SVGA3D_R8G8B8A8_UINT: return DXGI_FORMAT_R8G8B8A8_UINT;
479 case SVGA3D_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_SINT;
480 case SVGA3D_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_TYPELESS;
481 case SVGA3D_R16G16_UINT: return DXGI_FORMAT_R16G16_UINT;
482 case SVGA3D_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT;
483 case SVGA3D_R32_TYPELESS: return DXGI_FORMAT_R32_TYPELESS;
484 case SVGA3D_D32_FLOAT: return DXGI_FORMAT_D32_FLOAT;
485 case SVGA3D_R32_UINT: return DXGI_FORMAT_R32_UINT;
486 case SVGA3D_R32_SINT: return DXGI_FORMAT_R32_SINT;
487 case SVGA3D_R24G8_TYPELESS: return DXGI_FORMAT_R24G8_TYPELESS;
488 case SVGA3D_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT;
489 case SVGA3D_R24_UNORM_X8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
490 case SVGA3D_X24_G8_UINT: return DXGI_FORMAT_X24_TYPELESS_G8_UINT;
491 case SVGA3D_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_TYPELESS;
492 case SVGA3D_R8G8_UNORM: return DXGI_FORMAT_R8G8_UNORM;
493 case SVGA3D_R8G8_UINT: return DXGI_FORMAT_R8G8_UINT;
494 case SVGA3D_R8G8_SINT: return DXGI_FORMAT_R8G8_SINT;
495 case SVGA3D_R16_TYPELESS: return DXGI_FORMAT_R16_TYPELESS;
496 case SVGA3D_R16_UNORM: return DXGI_FORMAT_R16_UNORM;
497 case SVGA3D_R16_UINT: return DXGI_FORMAT_R16_UINT;
498 case SVGA3D_R16_SNORM: return DXGI_FORMAT_R16_SNORM;
499 case SVGA3D_R16_SINT: return DXGI_FORMAT_R16_SINT;
500 case SVGA3D_R8_TYPELESS: return DXGI_FORMAT_R8_TYPELESS;
501 case SVGA3D_R8_UNORM: return DXGI_FORMAT_R8_UNORM;
502 case SVGA3D_R8_UINT: return DXGI_FORMAT_R8_UINT;
503 case SVGA3D_R8_SNORM: return DXGI_FORMAT_R8_SNORM;
504 case SVGA3D_R8_SINT: return DXGI_FORMAT_R8_SINT;
505 case SVGA3D_P8: break;
506 case SVGA3D_R9G9B9E5_SHAREDEXP: return DXGI_FORMAT_R9G9B9E5_SHAREDEXP;
507 case SVGA3D_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM;
508 case SVGA3D_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM;
509 case SVGA3D_BC1_TYPELESS: return DXGI_FORMAT_BC1_TYPELESS;
510 case SVGA3D_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM_SRGB;
511 case SVGA3D_BC2_TYPELESS: return DXGI_FORMAT_BC2_TYPELESS;
512 case SVGA3D_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM_SRGB;
513 case SVGA3D_BC3_TYPELESS: return DXGI_FORMAT_BC3_TYPELESS;
514 case SVGA3D_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM_SRGB;
515 case SVGA3D_BC4_TYPELESS: return DXGI_FORMAT_BC4_TYPELESS;
516 case SVGA3D_ATI1: break;
517 case SVGA3D_BC4_SNORM: return DXGI_FORMAT_BC4_SNORM;
518 case SVGA3D_BC5_TYPELESS: return DXGI_FORMAT_BC5_TYPELESS;
519 case SVGA3D_ATI2: break;
520 case SVGA3D_BC5_SNORM: return DXGI_FORMAT_BC5_SNORM;
521 case SVGA3D_R10G10B10_XR_BIAS_A2_UNORM: return DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM;
522 case SVGA3D_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_TYPELESS;
523 case SVGA3D_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
524#ifdef DX_REPLACE_X8_WITH_A8
525 case SVGA3D_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_TYPELESS;
526 case SVGA3D_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
527#else
528 case SVGA3D_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_TYPELESS;
529 case SVGA3D_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
530#endif
531 case SVGA3D_Z_DF16: break;
532 case SVGA3D_Z_DF24: break;
533 case SVGA3D_Z_D24S8_INT: return DXGI_FORMAT_D24_UNORM_S8_UINT;
534 case SVGA3D_YV12: break;
535 case SVGA3D_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT;
536 case SVGA3D_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT;
537 case SVGA3D_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM;
538 case SVGA3D_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT;
539 case SVGA3D_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM;
540 case SVGA3D_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM;
541 case SVGA3D_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT;
542 case SVGA3D_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM;
543 case SVGA3D_R16G16_SNORM: return DXGI_FORMAT_R16G16_SNORM;
544 case SVGA3D_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT;
545 case SVGA3D_R8G8_SNORM: return DXGI_FORMAT_R8G8_SNORM;
546 case SVGA3D_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT;
547 case SVGA3D_D16_UNORM: return DXGI_FORMAT_D16_UNORM;
548 case SVGA3D_A8_UNORM: return DXGI_FORMAT_A8_UNORM;
549 case SVGA3D_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM;
550 case SVGA3D_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM;
551 case SVGA3D_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM;
552 case SVGA3D_B5G6R5_UNORM: return DXGI_FORMAT_B5G6R5_UNORM;
553 case SVGA3D_B5G5R5A1_UNORM: return DXGI_FORMAT_B5G5R5A1_UNORM;
554 case SVGA3D_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
555#ifdef DX_REPLACE_X8_WITH_A8
556 case SVGA3D_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
557#else
558 case SVGA3D_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM;
559#endif
560 case SVGA3D_BC4_UNORM: return DXGI_FORMAT_BC4_UNORM;
561 case SVGA3D_BC5_UNORM: return DXGI_FORMAT_BC5_UNORM;
562
563 case SVGA3D_B4G4R4A4_UNORM: return DXGI_FORMAT_;
564 case SVGA3D_BC6H_TYPELESS: return DXGI_FORMAT_BC6H_TYPELESS;
565 case SVGA3D_BC6H_UF16: return DXGI_FORMAT_BC6H_UF16;
566 case SVGA3D_BC6H_SF16: return DXGI_FORMAT_BC6H_SF16;
567 case SVGA3D_BC7_TYPELESS: return DXGI_FORMAT_BC7_TYPELESS;
568 case SVGA3D_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM;
569 case SVGA3D_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM_SRGB;
570 case SVGA3D_AYUV: return DXGI_FORMAT_;
571
572 case SVGA3D_FORMAT_INVALID:
573 case SVGA3D_FORMAT_MAX: break;
574 }
575 // AssertFailed();
576 return DXGI_FORMAT_UNKNOWN;
577#undef DXGI_FORMAT_
578}
579
580
581static SVGA3dSurfaceFormat vmsvgaDXDevCapSurfaceFmt2Format(SVGA3dDevCapIndex enmDevCap)
582{
583 switch (enmDevCap)
584 {
585 case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8: return SVGA3D_X8R8G8B8;
586 case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8: return SVGA3D_A8R8G8B8;
587 case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10: return SVGA3D_A2R10G10B10;
588 case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5: return SVGA3D_X1R5G5B5;
589 case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5: return SVGA3D_A1R5G5B5;
590 case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4: return SVGA3D_A4R4G4B4;
591 case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5: return SVGA3D_R5G6B5;
592 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16: return SVGA3D_LUMINANCE16;
593 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8: return SVGA3D_LUMINANCE8_ALPHA8;
594 case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8: return SVGA3D_ALPHA8;
595 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8: return SVGA3D_LUMINANCE8;
596 case SVGA3D_DEVCAP_SURFACEFMT_Z_D16: return SVGA3D_Z_D16;
597 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8: return SVGA3D_Z_D24S8;
598 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8: return SVGA3D_Z_D24X8;
599 case SVGA3D_DEVCAP_SURFACEFMT_DXT1: return SVGA3D_DXT1;
600 case SVGA3D_DEVCAP_SURFACEFMT_DXT2: return SVGA3D_DXT2;
601 case SVGA3D_DEVCAP_SURFACEFMT_DXT3: return SVGA3D_DXT3;
602 case SVGA3D_DEVCAP_SURFACEFMT_DXT4: return SVGA3D_DXT4;
603 case SVGA3D_DEVCAP_SURFACEFMT_DXT5: return SVGA3D_DXT5;
604 case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8: return SVGA3D_BUMPX8L8V8U8;
605 case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10: return SVGA3D_A2W10V10U10;
606 case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8: return SVGA3D_BUMPU8V8;
607 case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8: return SVGA3D_Q8W8V8U8;
608 case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8: return SVGA3D_CxV8U8;
609 case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5: return SVGA3D_R_S10E5;
610 case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8: return SVGA3D_R_S23E8;
611 case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5: return SVGA3D_RG_S10E5;
612 case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8: return SVGA3D_RG_S23E8;
613 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5: return SVGA3D_ARGB_S10E5;
614 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8: return SVGA3D_ARGB_S23E8;
615 case SVGA3D_DEVCAP_SURFACEFMT_V16U16: return SVGA3D_V16U16;
616 case SVGA3D_DEVCAP_SURFACEFMT_G16R16: return SVGA3D_G16R16;
617 case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16: return SVGA3D_A16B16G16R16;
618 case SVGA3D_DEVCAP_SURFACEFMT_UYVY: return SVGA3D_UYVY;
619 case SVGA3D_DEVCAP_SURFACEFMT_YUY2: return SVGA3D_YUY2;
620 case SVGA3D_DEVCAP_SURFACEFMT_NV12: return SVGA3D_NV12;
621 case SVGA3D_DEVCAP_DEAD10: return SVGA3D_FORMAT_DEAD2; /* SVGA3D_DEVCAP_SURFACEFMT_AYUV -> SVGA3D_AYUV */
622 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16: return SVGA3D_Z_DF16;
623 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24: return SVGA3D_Z_DF24;
624 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT: return SVGA3D_Z_D24S8_INT;
625 case SVGA3D_DEVCAP_SURFACEFMT_ATI1: return SVGA3D_ATI1;
626 case SVGA3D_DEVCAP_SURFACEFMT_ATI2: return SVGA3D_ATI2;
627 case SVGA3D_DEVCAP_SURFACEFMT_YV12: return SVGA3D_YV12;
628 default:
629 AssertFailed();
630 break;
631 }
632 return SVGA3D_FORMAT_INVALID;
633}
634
635
636static SVGA3dSurfaceFormat vmsvgaDXDevCapDxfmt2Format(SVGA3dDevCapIndex enmDevCap)
637{
638 switch (enmDevCap)
639 {
640 case SVGA3D_DEVCAP_DXFMT_X8R8G8B8: return SVGA3D_X8R8G8B8;
641 case SVGA3D_DEVCAP_DXFMT_A8R8G8B8: return SVGA3D_A8R8G8B8;
642 case SVGA3D_DEVCAP_DXFMT_R5G6B5: return SVGA3D_R5G6B5;
643 case SVGA3D_DEVCAP_DXFMT_X1R5G5B5: return SVGA3D_X1R5G5B5;
644 case SVGA3D_DEVCAP_DXFMT_A1R5G5B5: return SVGA3D_A1R5G5B5;
645 case SVGA3D_DEVCAP_DXFMT_A4R4G4B4: return SVGA3D_A4R4G4B4;
646 case SVGA3D_DEVCAP_DXFMT_Z_D32: return SVGA3D_Z_D32;
647 case SVGA3D_DEVCAP_DXFMT_Z_D16: return SVGA3D_Z_D16;
648 case SVGA3D_DEVCAP_DXFMT_Z_D24S8: return SVGA3D_Z_D24S8;
649 case SVGA3D_DEVCAP_DXFMT_Z_D15S1: return SVGA3D_Z_D15S1;
650 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8: return SVGA3D_LUMINANCE8;
651 case SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4: return SVGA3D_LUMINANCE4_ALPHA4;
652 case SVGA3D_DEVCAP_DXFMT_LUMINANCE16: return SVGA3D_LUMINANCE16;
653 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8: return SVGA3D_LUMINANCE8_ALPHA8;
654 case SVGA3D_DEVCAP_DXFMT_DXT1: return SVGA3D_DXT1;
655 case SVGA3D_DEVCAP_DXFMT_DXT2: return SVGA3D_DXT2;
656 case SVGA3D_DEVCAP_DXFMT_DXT3: return SVGA3D_DXT3;
657 case SVGA3D_DEVCAP_DXFMT_DXT4: return SVGA3D_DXT4;
658 case SVGA3D_DEVCAP_DXFMT_DXT5: return SVGA3D_DXT5;
659 case SVGA3D_DEVCAP_DXFMT_BUMPU8V8: return SVGA3D_BUMPU8V8;
660 case SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5: return SVGA3D_BUMPL6V5U5;
661 case SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8: return SVGA3D_BUMPX8L8V8U8;
662 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1: return SVGA3D_FORMAT_DEAD1;
663 case SVGA3D_DEVCAP_DXFMT_ARGB_S10E5: return SVGA3D_ARGB_S10E5;
664 case SVGA3D_DEVCAP_DXFMT_ARGB_S23E8: return SVGA3D_ARGB_S23E8;
665 case SVGA3D_DEVCAP_DXFMT_A2R10G10B10: return SVGA3D_A2R10G10B10;
666 case SVGA3D_DEVCAP_DXFMT_V8U8: return SVGA3D_V8U8;
667 case SVGA3D_DEVCAP_DXFMT_Q8W8V8U8: return SVGA3D_Q8W8V8U8;
668 case SVGA3D_DEVCAP_DXFMT_CxV8U8: return SVGA3D_CxV8U8;
669 case SVGA3D_DEVCAP_DXFMT_X8L8V8U8: return SVGA3D_X8L8V8U8;
670 case SVGA3D_DEVCAP_DXFMT_A2W10V10U10: return SVGA3D_A2W10V10U10;
671 case SVGA3D_DEVCAP_DXFMT_ALPHA8: return SVGA3D_ALPHA8;
672 case SVGA3D_DEVCAP_DXFMT_R_S10E5: return SVGA3D_R_S10E5;
673 case SVGA3D_DEVCAP_DXFMT_R_S23E8: return SVGA3D_R_S23E8;
674 case SVGA3D_DEVCAP_DXFMT_RG_S10E5: return SVGA3D_RG_S10E5;
675 case SVGA3D_DEVCAP_DXFMT_RG_S23E8: return SVGA3D_RG_S23E8;
676 case SVGA3D_DEVCAP_DXFMT_BUFFER: return SVGA3D_BUFFER;
677 case SVGA3D_DEVCAP_DXFMT_Z_D24X8: return SVGA3D_Z_D24X8;
678 case SVGA3D_DEVCAP_DXFMT_V16U16: return SVGA3D_V16U16;
679 case SVGA3D_DEVCAP_DXFMT_G16R16: return SVGA3D_G16R16;
680 case SVGA3D_DEVCAP_DXFMT_A16B16G16R16: return SVGA3D_A16B16G16R16;
681 case SVGA3D_DEVCAP_DXFMT_UYVY: return SVGA3D_UYVY;
682 case SVGA3D_DEVCAP_DXFMT_YUY2: return SVGA3D_YUY2;
683 case SVGA3D_DEVCAP_DXFMT_NV12: return SVGA3D_NV12;
684 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2: return SVGA3D_FORMAT_DEAD2; /* SVGA3D_DEVCAP_DXFMT_AYUV -> SVGA3D_AYUV */
685 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS: return SVGA3D_R32G32B32A32_TYPELESS;
686 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT: return SVGA3D_R32G32B32A32_UINT;
687 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT: return SVGA3D_R32G32B32A32_SINT;
688 case SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS: return SVGA3D_R32G32B32_TYPELESS;
689 case SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT: return SVGA3D_R32G32B32_FLOAT;
690 case SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT: return SVGA3D_R32G32B32_UINT;
691 case SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT: return SVGA3D_R32G32B32_SINT;
692 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS: return SVGA3D_R16G16B16A16_TYPELESS;
693 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT: return SVGA3D_R16G16B16A16_UINT;
694 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM: return SVGA3D_R16G16B16A16_SNORM;
695 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT: return SVGA3D_R16G16B16A16_SINT;
696 case SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS: return SVGA3D_R32G32_TYPELESS;
697 case SVGA3D_DEVCAP_DXFMT_R32G32_UINT: return SVGA3D_R32G32_UINT;
698 case SVGA3D_DEVCAP_DXFMT_R32G32_SINT: return SVGA3D_R32G32_SINT;
699 case SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS: return SVGA3D_R32G8X24_TYPELESS;
700 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT: return SVGA3D_D32_FLOAT_S8X24_UINT;
701 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24: return SVGA3D_R32_FLOAT_X8X24;
702 case SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT: return SVGA3D_X32_G8X24_UINT;
703 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS: return SVGA3D_R10G10B10A2_TYPELESS;
704 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT: return SVGA3D_R10G10B10A2_UINT;
705 case SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT: return SVGA3D_R11G11B10_FLOAT;
706 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS: return SVGA3D_R8G8B8A8_TYPELESS;
707 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM: return SVGA3D_R8G8B8A8_UNORM;
708 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB: return SVGA3D_R8G8B8A8_UNORM_SRGB;
709 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT: return SVGA3D_R8G8B8A8_UINT;
710 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT: return SVGA3D_R8G8B8A8_SINT;
711 case SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS: return SVGA3D_R16G16_TYPELESS;
712 case SVGA3D_DEVCAP_DXFMT_R16G16_UINT: return SVGA3D_R16G16_UINT;
713 case SVGA3D_DEVCAP_DXFMT_R16G16_SINT: return SVGA3D_R16G16_SINT;
714 case SVGA3D_DEVCAP_DXFMT_R32_TYPELESS: return SVGA3D_R32_TYPELESS;
715 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT: return SVGA3D_D32_FLOAT;
716 case SVGA3D_DEVCAP_DXFMT_R32_UINT: return SVGA3D_R32_UINT;
717 case SVGA3D_DEVCAP_DXFMT_R32_SINT: return SVGA3D_R32_SINT;
718 case SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS: return SVGA3D_R24G8_TYPELESS;
719 case SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT: return SVGA3D_D24_UNORM_S8_UINT;
720 case SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8: return SVGA3D_R24_UNORM_X8;
721 case SVGA3D_DEVCAP_DXFMT_X24_G8_UINT: return SVGA3D_X24_G8_UINT;
722 case SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS: return SVGA3D_R8G8_TYPELESS;
723 case SVGA3D_DEVCAP_DXFMT_R8G8_UNORM: return SVGA3D_R8G8_UNORM;
724 case SVGA3D_DEVCAP_DXFMT_R8G8_UINT: return SVGA3D_R8G8_UINT;
725 case SVGA3D_DEVCAP_DXFMT_R8G8_SINT: return SVGA3D_R8G8_SINT;
726 case SVGA3D_DEVCAP_DXFMT_R16_TYPELESS: return SVGA3D_R16_TYPELESS;
727 case SVGA3D_DEVCAP_DXFMT_R16_UNORM: return SVGA3D_R16_UNORM;
728 case SVGA3D_DEVCAP_DXFMT_R16_UINT: return SVGA3D_R16_UINT;
729 case SVGA3D_DEVCAP_DXFMT_R16_SNORM: return SVGA3D_R16_SNORM;
730 case SVGA3D_DEVCAP_DXFMT_R16_SINT: return SVGA3D_R16_SINT;
731 case SVGA3D_DEVCAP_DXFMT_R8_TYPELESS: return SVGA3D_R8_TYPELESS;
732 case SVGA3D_DEVCAP_DXFMT_R8_UNORM: return SVGA3D_R8_UNORM;
733 case SVGA3D_DEVCAP_DXFMT_R8_UINT: return SVGA3D_R8_UINT;
734 case SVGA3D_DEVCAP_DXFMT_R8_SNORM: return SVGA3D_R8_SNORM;
735 case SVGA3D_DEVCAP_DXFMT_R8_SINT: return SVGA3D_R8_SINT;
736 case SVGA3D_DEVCAP_DXFMT_P8: return SVGA3D_P8;
737 case SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP: return SVGA3D_R9G9B9E5_SHAREDEXP;
738 case SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM: return SVGA3D_R8G8_B8G8_UNORM;
739 case SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM: return SVGA3D_G8R8_G8B8_UNORM;
740 case SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS: return SVGA3D_BC1_TYPELESS;
741 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB: return SVGA3D_BC1_UNORM_SRGB;
742 case SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS: return SVGA3D_BC2_TYPELESS;
743 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB: return SVGA3D_BC2_UNORM_SRGB;
744 case SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS: return SVGA3D_BC3_TYPELESS;
745 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB: return SVGA3D_BC3_UNORM_SRGB;
746 case SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS: return SVGA3D_BC4_TYPELESS;
747 case SVGA3D_DEVCAP_DXFMT_ATI1: return SVGA3D_ATI1;
748 case SVGA3D_DEVCAP_DXFMT_BC4_SNORM: return SVGA3D_BC4_SNORM;
749 case SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS: return SVGA3D_BC5_TYPELESS;
750 case SVGA3D_DEVCAP_DXFMT_ATI2: return SVGA3D_ATI2;
751 case SVGA3D_DEVCAP_DXFMT_BC5_SNORM: return SVGA3D_BC5_SNORM;
752 case SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM: return SVGA3D_R10G10B10_XR_BIAS_A2_UNORM;
753 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS: return SVGA3D_B8G8R8A8_TYPELESS;
754 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB: return SVGA3D_B8G8R8A8_UNORM_SRGB;
755 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS: return SVGA3D_B8G8R8X8_TYPELESS;
756 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB: return SVGA3D_B8G8R8X8_UNORM_SRGB;
757 case SVGA3D_DEVCAP_DXFMT_Z_DF16: return SVGA3D_Z_DF16;
758 case SVGA3D_DEVCAP_DXFMT_Z_DF24: return SVGA3D_Z_DF24;
759 case SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT: return SVGA3D_Z_D24S8_INT;
760 case SVGA3D_DEVCAP_DXFMT_YV12: return SVGA3D_YV12;
761 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT: return SVGA3D_R32G32B32A32_FLOAT;
762 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT: return SVGA3D_R16G16B16A16_FLOAT;
763 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM: return SVGA3D_R16G16B16A16_UNORM;
764 case SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT: return SVGA3D_R32G32_FLOAT;
765 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM: return SVGA3D_R10G10B10A2_UNORM;
766 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM: return SVGA3D_R8G8B8A8_SNORM;
767 case SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT: return SVGA3D_R16G16_FLOAT;
768 case SVGA3D_DEVCAP_DXFMT_R16G16_UNORM: return SVGA3D_R16G16_UNORM;
769 case SVGA3D_DEVCAP_DXFMT_R16G16_SNORM: return SVGA3D_R16G16_SNORM;
770 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT: return SVGA3D_R32_FLOAT;
771 case SVGA3D_DEVCAP_DXFMT_R8G8_SNORM: return SVGA3D_R8G8_SNORM;
772 case SVGA3D_DEVCAP_DXFMT_R16_FLOAT: return SVGA3D_R16_FLOAT;
773 case SVGA3D_DEVCAP_DXFMT_D16_UNORM: return SVGA3D_D16_UNORM;
774 case SVGA3D_DEVCAP_DXFMT_A8_UNORM: return SVGA3D_A8_UNORM;
775 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM: return SVGA3D_BC1_UNORM;
776 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM: return SVGA3D_BC2_UNORM;
777 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM: return SVGA3D_BC3_UNORM;
778 case SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM: return SVGA3D_B5G6R5_UNORM;
779 case SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM: return SVGA3D_B5G5R5A1_UNORM;
780 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM: return SVGA3D_B8G8R8A8_UNORM;
781 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM: return SVGA3D_B8G8R8X8_UNORM;
782 case SVGA3D_DEVCAP_DXFMT_BC4_UNORM: return SVGA3D_BC4_UNORM;
783 case SVGA3D_DEVCAP_DXFMT_BC5_UNORM: return SVGA3D_BC5_UNORM;
784 case SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS: return SVGA3D_BC6H_TYPELESS;
785 case SVGA3D_DEVCAP_DXFMT_BC6H_UF16: return SVGA3D_BC6H_UF16;
786 case SVGA3D_DEVCAP_DXFMT_BC6H_SF16: return SVGA3D_BC6H_SF16;
787 case SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS: return SVGA3D_BC7_TYPELESS;
788 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM: return SVGA3D_BC7_UNORM;
789 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB: return SVGA3D_BC7_UNORM_SRGB;
790 default:
791 AssertFailed();
792 break;
793 }
794 return SVGA3D_FORMAT_INVALID;
795}
796
797
798static int vmsvgaDXCheckFormatSupportPreDX(PVMSVGA3DSTATE pState, SVGA3dSurfaceFormat enmFormat, uint32_t *pu32DevCap)
799{
800 int rc = VINF_SUCCESS;
801
802 *pu32DevCap = 0;
803
804 DXGI_FORMAT const dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(enmFormat);
805 if (dxgiFormat != DXGI_FORMAT_UNKNOWN)
806 {
807 RT_NOREF(pState);
808 /** @todo Implement */
809 }
810 else
811 rc = VERR_NOT_SUPPORTED;
812 return rc;
813}
814
815static int vmsvgaDXCheckFormatSupport(PVMSVGA3DSTATE pState, SVGA3dSurfaceFormat enmFormat, uint32_t *pu32DevCap)
816{
817 int rc = VINF_SUCCESS;
818
819 *pu32DevCap = 0;
820
821 DXGI_FORMAT const dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(enmFormat);
822 if (dxgiFormat != DXGI_FORMAT_UNKNOWN)
823 {
824 ID3D11Device *pDevice = pState->pBackend->dxDevice.pDevice;
825 UINT FormatSupport = 0;
826 HRESULT hr = pDevice->CheckFormatSupport(dxgiFormat, &FormatSupport);
827 if (SUCCEEDED(hr))
828 {
829 *pu32DevCap |= SVGA3D_DXFMT_SUPPORTED;
830
831 if (FormatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)
832 *pu32DevCap |= SVGA3D_DXFMT_SHADER_SAMPLE;
833
834 if (FormatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)
835 *pu32DevCap |= SVGA3D_DXFMT_COLOR_RENDERTARGET;
836
837 if (FormatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)
838 *pu32DevCap |= SVGA3D_DXFMT_DEPTH_RENDERTARGET;
839
840 if (FormatSupport & D3D11_FORMAT_SUPPORT_BLENDABLE)
841 *pu32DevCap |= SVGA3D_DXFMT_BLENDABLE;
842
843 if (FormatSupport & D3D11_FORMAT_SUPPORT_MIP)
844 *pu32DevCap |= SVGA3D_DXFMT_MIPS;
845
846 if (FormatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE)
847 *pu32DevCap |= SVGA3D_DXFMT_ARRAY;
848
849 if (FormatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D)
850 *pu32DevCap |= SVGA3D_DXFMT_VOLUME;
851
852 if (FormatSupport & D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER)
853 *pu32DevCap |= SVGA3D_DXFMT_DX_VERTEX_BUFFER;
854
855 UINT NumQualityLevels;
856 hr = pDevice->CheckMultisampleQualityLevels(dxgiFormat, 2, &NumQualityLevels);
857 if (SUCCEEDED(hr) && NumQualityLevels != 0)
858 *pu32DevCap |= SVGA3D_DXFMT_MULTISAMPLE;
859 }
860 else
861 {
862 LogFunc(("CheckFormatSupport failed for 0x%08x, hr = 0x%08x\n", dxgiFormat, hr));
863 rc = VERR_NOT_SUPPORTED;
864 }
865 }
866 else
867 rc = VERR_NOT_SUPPORTED;
868 return rc;
869}
870
871
872static int dxDeviceCreate(PVMSVGA3DBACKEND pBackend, DXDEVICE *pDXDevice)
873{
874 int rc = VINF_SUCCESS;
875
876 if (pBackend->fSingleDevice && pBackend->dxDevice.pDevice)
877 {
878 pDXDevice->pDevice = pBackend->dxDevice.pDevice;
879 pDXDevice->pDevice->AddRef();
880
881 pDXDevice->pImmediateContext = pBackend->dxDevice.pImmediateContext;
882 pDXDevice->pImmediateContext->AddRef();
883
884 pDXDevice->pDxgiFactory = pBackend->dxDevice.pDxgiFactory;
885 pDXDevice->pDxgiFactory->AddRef();
886
887 pDXDevice->FeatureLevel = pBackend->dxDevice.FeatureLevel;
888
889 pDXDevice->pStagingBuffer = 0;
890 pDXDevice->cbStagingBuffer = 0;
891
892 BlitInit(&pDXDevice->Blitter, pDXDevice->pDevice, pDXDevice->pImmediateContext);
893 return rc;
894 }
895
896 IDXGIAdapter *pAdapter = NULL; /* Default adapter. */
897 static D3D_FEATURE_LEVEL const s_aFeatureLevels[] =
898 {
899 D3D_FEATURE_LEVEL_11_1,
900 D3D_FEATURE_LEVEL_11_0
901 };
902 UINT Flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
903#ifdef DEBUG
904 Flags |= D3D11_CREATE_DEVICE_DEBUG;
905#endif
906
907 ID3D11Device *pDevice = 0;
908 ID3D11DeviceContext *pImmediateContext = 0;
909 HRESULT hr = pBackend->pfnD3D11CreateDevice(pAdapter,
910 D3D_DRIVER_TYPE_HARDWARE,
911 NULL,
912 Flags,
913 s_aFeatureLevels,
914 RT_ELEMENTS(s_aFeatureLevels),
915 D3D11_SDK_VERSION,
916 &pDevice,
917 &pDXDevice->FeatureLevel,
918 &pImmediateContext);
919#ifdef DEBUG
920 if (FAILED(hr))
921 {
922 /* Device creation may fail because _DEBUG flag requires "D3D11 SDK Layers for Windows 10" ("Graphics Tools"):
923 * Settings/System/Apps/Optional features/Add a feature/Graphics Tools
924 * Retry without the flag.
925 */
926 Flags &= ~D3D11_CREATE_DEVICE_DEBUG;
927 hr = pBackend->pfnD3D11CreateDevice(pAdapter,
928 D3D_DRIVER_TYPE_HARDWARE,
929 NULL,
930 Flags,
931 s_aFeatureLevels,
932 RT_ELEMENTS(s_aFeatureLevels),
933 D3D11_SDK_VERSION,
934 &pDevice,
935 &pDXDevice->FeatureLevel,
936 &pImmediateContext);
937 }
938#endif
939
940 if (SUCCEEDED(hr))
941 {
942 LogRel(("VMSVGA: Feature level %#x\n", pDXDevice->FeatureLevel));
943
944 hr = pDevice->QueryInterface(__uuidof(ID3D11Device1), (void**)&pDXDevice->pDevice);
945 AssertReturnStmt(SUCCEEDED(hr),
946 D3D_RELEASE(pImmediateContext); D3D_RELEASE(pDevice),
947 VERR_NOT_SUPPORTED);
948
949 hr = pImmediateContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void**)&pDXDevice->pImmediateContext);
950 AssertReturnStmt(SUCCEEDED(hr),
951 D3D_RELEASE(pImmediateContext); D3D_RELEASE(pDXDevice->pDevice); D3D_RELEASE(pDevice),
952 VERR_NOT_SUPPORTED);
953
954#ifdef DEBUG
955 /* Break into debugger when DX runtime detects anything unusual. */
956 HRESULT hr2;
957 ID3D11Debug *pDebug = 0;
958 hr2 = pDXDevice->pDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pDebug);
959 if (SUCCEEDED(hr2))
960 {
961 ID3D11InfoQueue *pInfoQueue = 0;
962 hr2 = pDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&pInfoQueue);
963 if (SUCCEEDED(hr2))
964 {
965 pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
966// pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
967// pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
968
969 /* No breakpoints for the following messages. */
970 D3D11_MESSAGE_ID saIgnoredMessageIds[] =
971 {
972 /* Message ID: Caused by: */
973 D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH, /* Autogenerated input signatures. */
974 D3D11_MESSAGE_ID_LIVE_DEVICE, /* Live object report. Does not seem to prevent a breakpoint. */
975 (D3D11_MESSAGE_ID)3146081 /*DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET*/, /* U. */
976 D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET, /* U. */
977 D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH, /* U. */
978 D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT, /* P. */
979 D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK, /* S. */
980 };
981
982 D3D11_INFO_QUEUE_FILTER filter;
983 RT_ZERO(filter);
984 filter.DenyList.NumIDs = RT_ELEMENTS(saIgnoredMessageIds);
985 filter.DenyList.pIDList = saIgnoredMessageIds;
986 pInfoQueue->AddStorageFilterEntries(&filter);
987
988 D3D_RELEASE(pInfoQueue);
989 }
990 D3D_RELEASE(pDebug);
991 }
992#endif
993
994 IDXGIDevice *pDxgiDevice = 0;
995 hr = pDXDevice->pDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDxgiDevice);
996 if (SUCCEEDED(hr))
997 {
998 IDXGIAdapter *pDxgiAdapter = 0;
999 hr = pDxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&pDxgiAdapter);
1000 if (SUCCEEDED(hr))
1001 {
1002 hr = pDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&pDXDevice->pDxgiFactory);
1003 D3D_RELEASE(pDxgiAdapter);
1004 }
1005
1006 D3D_RELEASE(pDxgiDevice);
1007 }
1008 }
1009
1010 if (SUCCEEDED(hr))
1011 BlitInit(&pDXDevice->Blitter, pDXDevice->pDevice, pDXDevice->pImmediateContext);
1012 else
1013 rc = VERR_NOT_SUPPORTED;
1014
1015 return rc;
1016}
1017
1018
1019static void dxDeviceDestroy(PVMSVGA3DBACKEND pBackend, DXDEVICE *pDevice)
1020{
1021 RT_NOREF(pBackend);
1022
1023 BlitRelease(&pDevice->Blitter);
1024
1025 D3D_RELEASE(pDevice->pStagingBuffer);
1026
1027 D3D_RELEASE(pDevice->pDxgiFactory);
1028 D3D_RELEASE(pDevice->pImmediateContext);
1029
1030#ifdef DEBUG
1031 HRESULT hr2;
1032 ID3D11Debug *pDebug = 0;
1033 hr2 = pDevice->pDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pDebug);
1034 if (SUCCEEDED(hr2))
1035 {
1036 /// @todo Use this to see whether all resources have been properly released.
1037 //DEBUG_BREAKPOINT_TEST();
1038 //pDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL | (D3D11_RLDO_FLAGS)0x4 /*D3D11_RLDO_IGNORE_INTERNAL*/);
1039 D3D_RELEASE(pDebug);
1040 }
1041#endif
1042
1043 D3D_RELEASE(pDevice->pDevice);
1044 RT_ZERO(*pDevice);
1045}
1046
1047
1048static void dxViewAddToList(PVGASTATECC pThisCC, DXVIEW *pDXView)
1049{
1050 LogFunc(("cid = %u, sid = %u, viewId = %u, type = %u\n",
1051 pDXView->cid, pDXView->sid, pDXView->viewId, pDXView->enmViewType));
1052
1053 Assert(pDXView->u.pView); /* Only already created views should be added. Guard against mis-use by callers. */
1054
1055 PVMSVGA3DSURFACE pSurface;
1056 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pDXView->sid, &pSurface);
1057 AssertRCReturnVoid(rc);
1058
1059 RTListAppend(&pSurface->pBackendSurface->listView, &pDXView->nodeSurfaceView);
1060}
1061
1062
1063static void dxViewRemoveFromList(DXVIEW *pDXView)
1064{
1065 LogFunc(("cid = %u, sid = %u, viewId = %u, type = %u\n",
1066 pDXView->cid, pDXView->sid, pDXView->viewId, pDXView->enmViewType));
1067 /* pView can be NULL, if COT entry is already empty. */
1068 if (pDXView->u.pView)
1069 {
1070 Assert(pDXView->nodeSurfaceView.pNext && pDXView->nodeSurfaceView.pPrev);
1071 RTListNodeRemove(&pDXView->nodeSurfaceView);
1072 }
1073}
1074
1075
1076static int dxViewDestroy(DXVIEW *pDXView)
1077{
1078 LogFunc(("cid = %u, sid = %u, viewId = %u, type = %u\n",
1079 pDXView->cid, pDXView->sid, pDXView->viewId, pDXView->enmViewType));
1080 if (pDXView->u.pView)
1081 {
1082 D3D_RELEASE(pDXView->u.pView);
1083 RTListNodeRemove(&pDXView->nodeSurfaceView);
1084 RT_ZERO(*pDXView);
1085 }
1086
1087 return VINF_SUCCESS;
1088}
1089
1090
1091static int dxViewInit(DXVIEW *pDXView, PVMSVGA3DSURFACE pSurface, VMSVGA3DDXCONTEXT *pDXContext, uint32_t viewId, VMSVGA3DBACKVIEWTYPE enmViewType, ID3D11View *pView)
1092{
1093 pDXView->cid = pDXContext->cid;
1094 pDXView->sid = pSurface->id;
1095 pDXView->viewId = viewId;
1096 pDXView->enmViewType = enmViewType;
1097 pDXView->u.pView = pView;
1098 RTListAppend(&pSurface->pBackendSurface->listView, &pDXView->nodeSurfaceView);
1099
1100 LogFunc(("cid = %u, sid = %u, viewId = %u, type = %u\n",
1101 pDXView->cid, pDXView->sid, pDXView->viewId, pDXView->enmViewType));
1102
1103DXVIEW *pIter, *pNext;
1104RTListForEachSafe(&pSurface->pBackendSurface->listView, pIter, pNext, DXVIEW, nodeSurfaceView)
1105{
1106 AssertPtr(pNext);
1107 LogFunc(("pIter=%p, pNext=%p\n", pIter, pNext));
1108}
1109
1110 return VINF_SUCCESS;
1111}
1112
1113
1114DECLINLINE(bool) dxIsSurfaceShareable(PVMSVGA3DSURFACE pSurface)
1115{
1116 /* It is not expected that volume textures will be shared between contexts. */
1117 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_VOLUME)
1118 return false;
1119
1120 return (pSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET)
1121 || (pSurface->f.surfaceFlags & SVGA3D_SURFACE_BIND_RENDER_TARGET);
1122}
1123
1124
1125static DXDEVICE *dxDeviceFromCid(uint32_t cid, PVMSVGA3DSTATE pState)
1126{
1127 if (cid != DX_CID_BACKEND)
1128 {
1129 if (pState->pBackend->fSingleDevice)
1130 return &pState->pBackend->dxDevice;
1131
1132 VMSVGA3DDXCONTEXT *pDXContext;
1133 int rc = vmsvga3dDXContextFromCid(pState, cid, &pDXContext);
1134 if (RT_SUCCESS(rc))
1135 return &pDXContext->pBackendDXContext->dxDevice;
1136 }
1137 else
1138 return &pState->pBackend->dxDevice;
1139
1140 AssertFailed();
1141 return NULL;
1142}
1143
1144
1145static DXDEVICE *dxDeviceFromContext(PVMSVGA3DSTATE p3dState, VMSVGA3DDXCONTEXT *pDXContext)
1146{
1147 if (pDXContext && !p3dState->pBackend->fSingleDevice)
1148 return &pDXContext->pBackendDXContext->dxDevice;
1149
1150 return &p3dState->pBackend->dxDevice;
1151}
1152
1153
1154static int dxDeviceFlush(DXDEVICE *pDevice)
1155{
1156 /** @todo Should the flush follow the query submission? */
1157 pDevice->pImmediateContext->Flush();
1158
1159 ID3D11Query *pQuery = 0;
1160 D3D11_QUERY_DESC qd;
1161 RT_ZERO(qd);
1162 qd.Query = D3D11_QUERY_EVENT;
1163
1164 HRESULT hr = pDevice->pDevice->CreateQuery(&qd, &pQuery);
1165 Assert(hr == S_OK); RT_NOREF(hr);
1166 pDevice->pImmediateContext->End(pQuery);
1167
1168 BOOL queryData;
1169 while (pDevice->pImmediateContext->GetData(pQuery, &queryData, sizeof(queryData), 0) != S_OK)
1170 RTThreadYield();
1171
1172 D3D_RELEASE(pQuery);
1173
1174 return VINF_SUCCESS;
1175}
1176
1177
1178static int dxContextWait(uint32_t cidDrawing, PVMSVGA3DSTATE pState)
1179{
1180 if (pState->pBackend->fSingleDevice)
1181 return VINF_SUCCESS;
1182
1183 /* Flush cidDrawing context and issue a query. */
1184 DXDEVICE *pDXDevice = dxDeviceFromCid(cidDrawing, pState);
1185 if (pDXDevice)
1186 return dxDeviceFlush(pDXDevice);
1187 /* cidDrawing does not exist anymore. */
1188 return VINF_SUCCESS;
1189}
1190
1191
1192static int dxSurfaceWait(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface, uint32_t cidRequesting)
1193{
1194 if (pState->pBackend->fSingleDevice)
1195 return VINF_SUCCESS;
1196
1197 VMSVGA3DBACKENDSURFACE *pBackendSurface = pSurface->pBackendSurface;
1198 if (!pBackendSurface)
1199 AssertFailedReturn(VERR_INVALID_STATE);
1200
1201 int rc = VINF_SUCCESS;
1202 if (pBackendSurface->cidDrawing != SVGA_ID_INVALID)
1203 {
1204 if (pBackendSurface->cidDrawing != cidRequesting)
1205 {
1206 LogFunc(("sid = %u, assoc cid = %u, drawing cid = %u, req cid = %u\n",
1207 pSurface->id, pSurface->idAssociatedContext, pBackendSurface->cidDrawing, cidRequesting));
1208 Assert(dxIsSurfaceShareable(pSurface));
1209 rc = dxContextWait(pBackendSurface->cidDrawing, pState);
1210 pBackendSurface->cidDrawing = SVGA_ID_INVALID;
1211 }
1212 }
1213 return rc;
1214}
1215
1216
1217static ID3D11Resource *dxResource(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface, VMSVGA3DDXCONTEXT *pDXContext)
1218{
1219 VMSVGA3DBACKENDSURFACE *pBackendSurface = pSurface->pBackendSurface;
1220 if (!pBackendSurface)
1221 AssertFailedReturn(NULL);
1222
1223 ID3D11Resource *pResource;
1224
1225 uint32_t const cidRequesting = pDXContext ? pDXContext->cid : DX_CID_BACKEND;
1226 if (cidRequesting == pSurface->idAssociatedContext || pState->pBackend->fSingleDevice)
1227 pResource = pBackendSurface->u.pResource;
1228 else
1229 {
1230 /*
1231 * Context, which as not created the surface, is requesting.
1232 */
1233 AssertReturn(pDXContext, NULL);
1234
1235 Assert(dxIsSurfaceShareable(pSurface));
1236 Assert(pSurface->idAssociatedContext == DX_CID_BACKEND);
1237
1238 DXSHAREDTEXTURE *pSharedTexture = (DXSHAREDTEXTURE *)RTAvlU32Get(&pBackendSurface->SharedTextureTree, pDXContext->cid);
1239 if (!pSharedTexture)
1240 {
1241 DXDEVICE *pDevice = dxDeviceFromContext(pState, pDXContext);
1242 AssertReturn(pDevice->pDevice, NULL);
1243
1244 AssertReturn(pBackendSurface->SharedHandle, NULL);
1245
1246 /* This context has not yet opened the texture. */
1247 pSharedTexture = (DXSHAREDTEXTURE *)RTMemAllocZ(sizeof(DXSHAREDTEXTURE));
1248 AssertReturn(pSharedTexture, NULL);
1249
1250 pSharedTexture->Core.Key = pDXContext->cid;
1251 bool const fSuccess = RTAvlU32Insert(&pBackendSurface->SharedTextureTree, &pSharedTexture->Core);
1252 AssertReturn(fSuccess, NULL);
1253
1254 HRESULT hr = pDevice->pDevice->OpenSharedResource(pBackendSurface->SharedHandle, __uuidof(ID3D11Texture2D), (void**)&pSharedTexture->pTexture);
1255 Assert(SUCCEEDED(hr));
1256 if (SUCCEEDED(hr))
1257 pSharedTexture->sid = pSurface->id;
1258 else
1259 {
1260 RTAvlU32Remove(&pBackendSurface->SharedTextureTree, pDXContext->cid);
1261 RTMemFree(pSharedTexture);
1262 return NULL;
1263 }
1264 }
1265
1266 pResource = pSharedTexture->pTexture;
1267 }
1268
1269 /* Wait for drawing to finish. */
1270 dxSurfaceWait(pState, pSurface, cidRequesting);
1271
1272 return pResource;
1273}
1274
1275
1276static uint32_t dxGetRenderTargetViewSid(PVMSVGA3DDXCONTEXT pDXContext, uint32_t renderTargetViewId)
1277{
1278 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->cot.cRTView, SVGA_ID_INVALID);
1279
1280 SVGACOTableDXRTViewEntry const *pRTViewEntry = &pDXContext->cot.paRTView[renderTargetViewId];
1281 return pRTViewEntry->sid;
1282}
1283
1284
1285static SVGACOTableDXSRViewEntry const *dxGetShaderResourceViewEntry(PVMSVGA3DDXCONTEXT pDXContext, uint32_t shaderResourceViewId)
1286{
1287 ASSERT_GUEST_RETURN(shaderResourceViewId < pDXContext->cot.cSRView, NULL);
1288
1289 SVGACOTableDXSRViewEntry const *pSRViewEntry = &pDXContext->cot.paSRView[shaderResourceViewId];
1290 return pSRViewEntry;
1291}
1292
1293
1294static SVGACOTableDXUAViewEntry const *dxGetUnorderedAccessViewEntry(PVMSVGA3DDXCONTEXT pDXContext, uint32_t uaViewId)
1295{
1296 ASSERT_GUEST_RETURN(uaViewId < pDXContext->cot.cUAView, NULL);
1297
1298 SVGACOTableDXUAViewEntry const *pUAViewEntry = &pDXContext->cot.paUAView[uaViewId];
1299 return pUAViewEntry;
1300}
1301
1302
1303static SVGACOTableDXDSViewEntry const *dxGetDepthStencilViewEntry(PVMSVGA3DDXCONTEXT pDXContext, uint32_t depthStencilViewId)
1304{
1305 ASSERT_GUEST_RETURN(depthStencilViewId < pDXContext->cot.cDSView, NULL);
1306
1307 SVGACOTableDXDSViewEntry const *pDSViewEntry = &pDXContext->cot.paDSView[depthStencilViewId];
1308 return pDSViewEntry;
1309}
1310
1311
1312static SVGACOTableDXRTViewEntry const *dxGetRenderTargetViewEntry(PVMSVGA3DDXCONTEXT pDXContext, uint32_t renderTargetViewId)
1313{
1314 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->cot.cRTView, NULL);
1315
1316 SVGACOTableDXRTViewEntry const *pRTViewEntry = &pDXContext->cot.paRTView[renderTargetViewId];
1317 return pRTViewEntry;
1318}
1319
1320
1321static int dxTrackRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
1322{
1323 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1324 AssertReturn(pState, VERR_INVALID_STATE);
1325
1326 for (unsigned long i = 0; i < RT_ELEMENTS(pDXContext->svgaDXContext.renderState.renderTargetViewIds); ++i)
1327 {
1328 uint32_t const renderTargetViewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
1329 if (renderTargetViewId == SVGA_ID_INVALID)
1330 continue;
1331
1332 uint32_t const sid = dxGetRenderTargetViewSid(pDXContext, renderTargetViewId);
1333 LogFunc(("[%u] sid = %u, drawing cid = %u\n", i, sid, pDXContext->cid));
1334
1335 PVMSVGA3DSURFACE pSurface;
1336 int rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
1337 if (RT_SUCCESS(rc))
1338 {
1339 AssertContinue(pSurface->pBackendSurface);
1340 pSurface->pBackendSurface->cidDrawing = pDXContext->cid;
1341 }
1342 }
1343 return VINF_SUCCESS;
1344}
1345
1346
1347static int dxDefineStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid, SVGACOTableDXStreamOutputEntry const *pEntry, DXSHADER *pDXShader)
1348{
1349 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1350 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
1351
1352 /* Make D3D11_SO_DECLARATION_ENTRY array from SVGA3dStreamOutputDeclarationEntry. */
1353 SVGA3dStreamOutputDeclarationEntry const *paDecls;
1354 PVMSVGAMOB pMob = NULL;
1355 if (pEntry->usesMob)
1356 {
1357 pMob = vmsvgaR3MobGet(pSvgaR3State, pEntry->mobid);
1358 ASSERT_GUEST_RETURN(pMob, VERR_INVALID_PARAMETER);
1359
1360 /* Create a memory pointer for the MOB, which is accessible by host. */
1361 int rc = vmsvgaR3MobBackingStoreCreate(pSvgaR3State, pMob, vmsvgaR3MobSize(pMob));
1362 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
1363
1364 /* Get pointer to the shader bytecode. This will also verify the offset. */
1365 paDecls = (SVGA3dStreamOutputDeclarationEntry const *)vmsvgaR3MobBackingStorePtr(pMob, pEntry->offsetInBytes);
1366 AssertReturnStmt(paDecls, vmsvgaR3MobBackingStoreDelete(pSvgaR3State, pMob), VERR_INTERNAL_ERROR);
1367 }
1368 else
1369 paDecls = &pEntry->decl[0];
1370
1371 pDXStreamOutput->cDeclarationEntry = pEntry->numOutputStreamEntries;
1372 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1373 {
1374 D3D11_SO_DECLARATION_ENTRY *pDst = &pDXStreamOutput->aDeclarationEntry[i];
1375 SVGA3dStreamOutputDeclarationEntry const *pSrc = &paDecls[i];
1376
1377 uint32_t const registerMask = pSrc->registerMask & 0xF;
1378 unsigned const iFirstBit = ASMBitFirstSetU32(registerMask);
1379 unsigned const iLastBit = ASMBitLastSetU32(registerMask);
1380
1381 pDst->Stream = pSrc->stream;
1382 pDst->SemanticName = NULL; /* Semantic name and index will be taken from the shader output declaration. */
1383 pDst->SemanticIndex = 0;
1384 pDst->StartComponent = iFirstBit > 0 ? iFirstBit - 1 : 0;
1385 pDst->ComponentCount = iFirstBit > 0 ? iLastBit - (iFirstBit - 1) : 0;
1386 pDst->OutputSlot = pSrc->outputSlot;
1387 }
1388
1389 uint32_t MaxSemanticIndex = 0;
1390 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1391 {
1392 D3D11_SO_DECLARATION_ENTRY *pDeclarationEntry = &pDXStreamOutput->aDeclarationEntry[i];
1393 SVGA3dStreamOutputDeclarationEntry const *decl = &paDecls[i];
1394
1395 /* Find the corresponding register and mask in the GS shader output. */
1396 int idxFound = -1;
1397 for (uint32_t iOutputEntry = 0; iOutputEntry < pDXShader->shaderInfo.cOutputSignature; ++iOutputEntry)
1398 {
1399 SVGA3dDXSignatureEntry const *pOutputEntry = &pDXShader->shaderInfo.aOutputSignature[iOutputEntry];
1400 if ( pOutputEntry->registerIndex == decl->registerIndex
1401 && (decl->registerMask & ~pOutputEntry->mask) == 0) /* SO decl mask is a subset of shader output mask. */
1402 {
1403 idxFound = iOutputEntry;
1404 break;
1405 }
1406 }
1407
1408 if (idxFound >= 0)
1409 {
1410 DXShaderAttributeSemantic const *pOutputSemantic = &pDXShader->shaderInfo.aOutputSemantic[idxFound];
1411 pDeclarationEntry->SemanticName = pOutputSemantic->pcszSemanticName;
1412 pDeclarationEntry->SemanticIndex = pOutputSemantic->SemanticIndex;
1413 MaxSemanticIndex = RT_MAX(MaxSemanticIndex, pOutputSemantic->SemanticIndex);
1414 }
1415 else
1416 AssertFailed();
1417 }
1418
1419 /* A geometry shader may return components of the same register as different attributes:
1420 *
1421 * Output signature
1422 * Name Index Mask Register
1423 * ATTRIB 2 xy 2
1424 * ATTRIB 3 z 2
1425 *
1426 * For ATTRIB 3 the stream output declaration expects StartComponent = 0 and ComponentCount = 1
1427 * (not StartComponent = 2 and ComponentCount = 1):
1428 *
1429 * Stream output declaration
1430 * SemanticName SemanticIndex StartComponent ComponentCount
1431 * ATTRIB 2 0 2
1432 * ATTRIB 3 0 1
1433 *
1434 * Stream output declaration can have multiple entries for the same attribute.
1435 * In this case StartComponent is the offset within the attribute.
1436 *
1437 * Output signature
1438 * Name Index Mask Register
1439 * ATTRIB 0 xyzw 0
1440 *
1441 * Stream output declaration
1442 * SemanticName SemanticIndex StartComponent ComponentCount
1443 * ATTRIB 0 0 1
1444 * ATTRIB 0 1 1
1445 *
1446 * StartComponent has been computed as the component offset in a register:
1447 * 'StartComponent = iFirstBit > 0 ? iFirstBit - 1 : 0;'.
1448 *
1449 * StartComponent must be the offset in an attribute.
1450 */
1451 for (uint32_t SemanticIndex = 0; SemanticIndex <= MaxSemanticIndex; ++SemanticIndex)
1452 {
1453 /* Find minimum StartComponent value for this attribute. */
1454 uint32_t MinStartComponent = UINT32_MAX;
1455 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1456 {
1457 D3D11_SO_DECLARATION_ENTRY *pDeclarationEntry = &pDXStreamOutput->aDeclarationEntry[i];
1458 if (pDeclarationEntry->SemanticIndex == SemanticIndex)
1459 MinStartComponent = RT_MIN(MinStartComponent, pDeclarationEntry->StartComponent);
1460 }
1461
1462 AssertContinue(MinStartComponent != UINT32_MAX);
1463
1464 /* Adjust the StartComponent to start from 0 for this attribute. */
1465 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1466 {
1467 D3D11_SO_DECLARATION_ENTRY *pDeclarationEntry = &pDXStreamOutput->aDeclarationEntry[i];
1468 if (pDeclarationEntry->SemanticIndex == SemanticIndex)
1469 pDeclarationEntry->StartComponent -= MinStartComponent;
1470 }
1471 }
1472
1473 if (pMob)
1474 vmsvgaR3MobBackingStoreDelete(pSvgaR3State, pMob);
1475
1476 return VINF_SUCCESS;
1477}
1478
1479static void dxDestroyStreamOutput(DXSTREAMOUTPUT *pDXStreamOutput)
1480{
1481 RT_ZERO(*pDXStreamOutput);
1482}
1483
1484static D3D11_BLEND dxBlendFactorAlpha(uint8_t svgaBlend)
1485{
1486 /* "Blend options that end in _COLOR are not allowed." but the guest sometimes sends them. */
1487 switch (svgaBlend)
1488 {
1489 case SVGA3D_BLENDOP_ZERO: return D3D11_BLEND_ZERO;
1490 case SVGA3D_BLENDOP_ONE: return D3D11_BLEND_ONE;
1491 case SVGA3D_BLENDOP_SRCCOLOR: return D3D11_BLEND_SRC_ALPHA;
1492 case SVGA3D_BLENDOP_INVSRCCOLOR: return D3D11_BLEND_INV_SRC_ALPHA;
1493 case SVGA3D_BLENDOP_SRCALPHA: return D3D11_BLEND_SRC_ALPHA;
1494 case SVGA3D_BLENDOP_INVSRCALPHA: return D3D11_BLEND_INV_SRC_ALPHA;
1495 case SVGA3D_BLENDOP_DESTALPHA: return D3D11_BLEND_DEST_ALPHA;
1496 case SVGA3D_BLENDOP_INVDESTALPHA: return D3D11_BLEND_INV_DEST_ALPHA;
1497 case SVGA3D_BLENDOP_DESTCOLOR: return D3D11_BLEND_DEST_ALPHA;
1498 case SVGA3D_BLENDOP_INVDESTCOLOR: return D3D11_BLEND_INV_DEST_ALPHA;
1499 case SVGA3D_BLENDOP_SRCALPHASAT: return D3D11_BLEND_SRC_ALPHA_SAT;
1500 case SVGA3D_BLENDOP_BLENDFACTOR: return D3D11_BLEND_BLEND_FACTOR;
1501 case SVGA3D_BLENDOP_INVBLENDFACTOR: return D3D11_BLEND_INV_BLEND_FACTOR;
1502 case SVGA3D_BLENDOP_SRC1COLOR: return D3D11_BLEND_SRC1_ALPHA;
1503 case SVGA3D_BLENDOP_INVSRC1COLOR: return D3D11_BLEND_INV_SRC1_ALPHA;
1504 case SVGA3D_BLENDOP_SRC1ALPHA: return D3D11_BLEND_SRC1_ALPHA;
1505 case SVGA3D_BLENDOP_INVSRC1ALPHA: return D3D11_BLEND_INV_SRC1_ALPHA;
1506 case SVGA3D_BLENDOP_BLENDFACTORALPHA: return D3D11_BLEND_BLEND_FACTOR;
1507 case SVGA3D_BLENDOP_INVBLENDFACTORALPHA: return D3D11_BLEND_INV_BLEND_FACTOR;
1508 default:
1509 break;
1510 }
1511 return D3D11_BLEND_ZERO;
1512}
1513
1514
1515static D3D11_BLEND dxBlendFactorColor(uint8_t svgaBlend)
1516{
1517 switch (svgaBlend)
1518 {
1519 case SVGA3D_BLENDOP_ZERO: return D3D11_BLEND_ZERO;
1520 case SVGA3D_BLENDOP_ONE: return D3D11_BLEND_ONE;
1521 case SVGA3D_BLENDOP_SRCCOLOR: return D3D11_BLEND_SRC_COLOR;
1522 case SVGA3D_BLENDOP_INVSRCCOLOR: return D3D11_BLEND_INV_SRC_COLOR;
1523 case SVGA3D_BLENDOP_SRCALPHA: return D3D11_BLEND_SRC_ALPHA;
1524 case SVGA3D_BLENDOP_INVSRCALPHA: return D3D11_BLEND_INV_SRC_ALPHA;
1525 case SVGA3D_BLENDOP_DESTALPHA: return D3D11_BLEND_DEST_ALPHA;
1526 case SVGA3D_BLENDOP_INVDESTALPHA: return D3D11_BLEND_INV_DEST_ALPHA;
1527 case SVGA3D_BLENDOP_DESTCOLOR: return D3D11_BLEND_DEST_COLOR;
1528 case SVGA3D_BLENDOP_INVDESTCOLOR: return D3D11_BLEND_INV_DEST_COLOR;
1529 case SVGA3D_BLENDOP_SRCALPHASAT: return D3D11_BLEND_SRC_ALPHA_SAT;
1530 case SVGA3D_BLENDOP_BLENDFACTOR: return D3D11_BLEND_BLEND_FACTOR;
1531 case SVGA3D_BLENDOP_INVBLENDFACTOR: return D3D11_BLEND_INV_BLEND_FACTOR;
1532 case SVGA3D_BLENDOP_SRC1COLOR: return D3D11_BLEND_SRC1_COLOR;
1533 case SVGA3D_BLENDOP_INVSRC1COLOR: return D3D11_BLEND_INV_SRC1_COLOR;
1534 case SVGA3D_BLENDOP_SRC1ALPHA: return D3D11_BLEND_SRC1_ALPHA;
1535 case SVGA3D_BLENDOP_INVSRC1ALPHA: return D3D11_BLEND_INV_SRC1_ALPHA;
1536 case SVGA3D_BLENDOP_BLENDFACTORALPHA: return D3D11_BLEND_BLEND_FACTOR;
1537 case SVGA3D_BLENDOP_INVBLENDFACTORALPHA: return D3D11_BLEND_INV_BLEND_FACTOR;
1538 default:
1539 break;
1540 }
1541 return D3D11_BLEND_ZERO;
1542}
1543
1544
1545static D3D11_BLEND_OP dxBlendOp(uint8_t svgaBlendEq)
1546{
1547 return (D3D11_BLEND_OP)svgaBlendEq;
1548}
1549
1550
1551/** @todo AssertCompile for types like D3D11_COMPARISON_FUNC and SVGA3dComparisonFunc */
1552static HRESULT dxBlendStateCreate(DXDEVICE *pDevice, SVGACOTableDXBlendStateEntry const *pEntry, ID3D11BlendState **pp)
1553{
1554 D3D11_BLEND_DESC BlendDesc;
1555 BlendDesc.AlphaToCoverageEnable = RT_BOOL(pEntry->alphaToCoverageEnable);
1556 BlendDesc.IndependentBlendEnable = RT_BOOL(pEntry->independentBlendEnable);
1557 for (int i = 0; i < SVGA3D_MAX_RENDER_TARGETS; ++i)
1558 {
1559 BlendDesc.RenderTarget[i].BlendEnable = RT_BOOL(pEntry->perRT[i].blendEnable);
1560 BlendDesc.RenderTarget[i].SrcBlend = dxBlendFactorColor(pEntry->perRT[i].srcBlend);
1561 BlendDesc.RenderTarget[i].DestBlend = dxBlendFactorColor(pEntry->perRT[i].destBlend);
1562 BlendDesc.RenderTarget[i].BlendOp = dxBlendOp (pEntry->perRT[i].blendOp);
1563 BlendDesc.RenderTarget[i].SrcBlendAlpha = dxBlendFactorAlpha(pEntry->perRT[i].srcBlendAlpha);
1564 BlendDesc.RenderTarget[i].DestBlendAlpha = dxBlendFactorAlpha(pEntry->perRT[i].destBlendAlpha);
1565 BlendDesc.RenderTarget[i].BlendOpAlpha = dxBlendOp (pEntry->perRT[i].blendOpAlpha);
1566 BlendDesc.RenderTarget[i].RenderTargetWriteMask = pEntry->perRT[i].renderTargetWriteMask;
1567 /** @todo logicOpEnable and logicOp */
1568 }
1569
1570 HRESULT hr = pDevice->pDevice->CreateBlendState(&BlendDesc, pp);
1571 Assert(SUCCEEDED(hr));
1572 return hr;
1573}
1574
1575
1576static HRESULT dxDepthStencilStateCreate(DXDEVICE *pDevice, SVGACOTableDXDepthStencilEntry const *pEntry, ID3D11DepthStencilState **pp)
1577{
1578 D3D11_DEPTH_STENCIL_DESC desc;
1579 desc.DepthEnable = pEntry->depthEnable;
1580 desc.DepthWriteMask = (D3D11_DEPTH_WRITE_MASK)pEntry->depthWriteMask;
1581 desc.DepthFunc = (D3D11_COMPARISON_FUNC)pEntry->depthFunc;
1582 desc.StencilEnable = pEntry->stencilEnable;
1583 desc.StencilReadMask = pEntry->stencilReadMask;
1584 desc.StencilWriteMask = pEntry->stencilWriteMask;
1585 desc.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)pEntry->frontStencilFailOp;
1586 desc.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)pEntry->frontStencilDepthFailOp;
1587 desc.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)pEntry->frontStencilPassOp;
1588 desc.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)pEntry->frontStencilFunc;
1589 desc.BackFace.StencilFailOp = (D3D11_STENCIL_OP)pEntry->backStencilFailOp;
1590 desc.BackFace.StencilDepthFailOp = (D3D11_STENCIL_OP)pEntry->backStencilDepthFailOp;
1591 desc.BackFace.StencilPassOp = (D3D11_STENCIL_OP)pEntry->backStencilPassOp;
1592 desc.BackFace.StencilFunc = (D3D11_COMPARISON_FUNC)pEntry->backStencilFunc;
1593 /** @todo frontEnable, backEnable */
1594
1595 HRESULT hr = pDevice->pDevice->CreateDepthStencilState(&desc, pp);
1596 Assert(SUCCEEDED(hr));
1597 return hr;
1598}
1599
1600
1601static HRESULT dxSamplerStateCreate(DXDEVICE *pDevice, SVGACOTableDXSamplerEntry const *pEntry, ID3D11SamplerState **pp)
1602{
1603 D3D11_SAMPLER_DESC desc;
1604 /* Guest sometimes sends inconsistent (from D3D11 point of view) set of filter flags. */
1605 if (pEntry->filter & SVGA3D_FILTER_ANISOTROPIC)
1606 desc.Filter = (pEntry->filter & SVGA3D_FILTER_COMPARE)
1607 ? D3D11_FILTER_COMPARISON_ANISOTROPIC
1608 : D3D11_FILTER_ANISOTROPIC;
1609 else
1610 desc.Filter = (D3D11_FILTER)pEntry->filter;
1611 desc.AddressU = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressU;
1612 desc.AddressV = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressV;
1613 desc.AddressW = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressW;
1614 desc.MipLODBias = pEntry->mipLODBias;
1615 desc.MaxAnisotropy = RT_CLAMP(pEntry->maxAnisotropy, 1, 16); /* "Valid values are between 1 and 16" */
1616 desc.ComparisonFunc = (D3D11_COMPARISON_FUNC)pEntry->comparisonFunc;
1617 desc.BorderColor[0] = pEntry->borderColor.value[0];
1618 desc.BorderColor[1] = pEntry->borderColor.value[1];
1619 desc.BorderColor[2] = pEntry->borderColor.value[2];
1620 desc.BorderColor[3] = pEntry->borderColor.value[3];
1621 desc.MinLOD = pEntry->minLOD;
1622 desc.MaxLOD = pEntry->maxLOD;
1623
1624 HRESULT hr = pDevice->pDevice->CreateSamplerState(&desc, pp);
1625 Assert(SUCCEEDED(hr));
1626 return hr;
1627}
1628
1629
1630static D3D11_FILL_MODE dxFillMode(uint8_t svgaFillMode)
1631{
1632 if (svgaFillMode == SVGA3D_FILLMODE_POINT)
1633 return D3D11_FILL_WIREFRAME;
1634 return (D3D11_FILL_MODE)svgaFillMode;
1635}
1636
1637
1638static HRESULT dxRasterizerStateCreate(DXDEVICE *pDevice, SVGACOTableDXRasterizerStateEntry const *pEntry, ID3D11RasterizerState **pp)
1639{
1640 D3D11_RASTERIZER_DESC desc;
1641 desc.FillMode = dxFillMode(pEntry->fillMode);
1642 desc.CullMode = (D3D11_CULL_MODE)pEntry->cullMode;
1643 desc.FrontCounterClockwise = pEntry->frontCounterClockwise;
1644 /** @todo provokingVertexLast */
1645 desc.DepthBias = pEntry->depthBias;
1646 desc.DepthBiasClamp = pEntry->depthBiasClamp;
1647 desc.SlopeScaledDepthBias = pEntry->slopeScaledDepthBias;
1648 desc.DepthClipEnable = pEntry->depthClipEnable;
1649 desc.ScissorEnable = pEntry->scissorEnable;
1650 desc.MultisampleEnable = pEntry->multisampleEnable;
1651 desc.AntialiasedLineEnable = pEntry->antialiasedLineEnable;
1652 /** @todo lineWidth lineStippleEnable lineStippleFactor lineStipplePattern forcedSampleCount */
1653
1654 HRESULT hr = pDevice->pDevice->CreateRasterizerState(&desc, pp);
1655 Assert(SUCCEEDED(hr));
1656 return hr;
1657}
1658
1659
1660static HRESULT dxRenderTargetViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXRTViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11RenderTargetView **pp)
1661{
1662 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
1663
1664 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
1665
1666 D3D11_RENDER_TARGET_VIEW_DESC desc;
1667 RT_ZERO(desc);
1668 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
1669 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN || pEntry->format == SVGA3D_BUFFER, E_FAIL);
1670 switch (pEntry->resourceDimension)
1671 {
1672 case SVGA3D_RESOURCE_BUFFER:
1673 desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER;
1674 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
1675 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
1676 break;
1677 case SVGA3D_RESOURCE_TEXTURE1D:
1678 if (pSurface->surfaceDesc.numArrayElements <= 1)
1679 {
1680 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
1681 desc.Texture1D.MipSlice = pEntry->desc.tex.mipSlice;
1682 }
1683 else
1684 {
1685 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
1686 desc.Texture1DArray.MipSlice = pEntry->desc.tex.mipSlice;
1687 desc.Texture1DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1688 desc.Texture1DArray.ArraySize = pEntry->desc.tex.arraySize;
1689 }
1690 break;
1691 case SVGA3D_RESOURCE_TEXTURE2D:
1692 if (pSurface->surfaceDesc.numArrayElements <= 1)
1693 {
1694 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1695 desc.Texture2D.MipSlice = pEntry->desc.tex.mipSlice;
1696 }
1697 else
1698 {
1699 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1700 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
1701 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1702 desc.Texture2DArray.ArraySize = pEntry->desc.tex.arraySize;
1703 }
1704 break;
1705 case SVGA3D_RESOURCE_TEXTURE3D:
1706 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1707 desc.Texture3D.MipSlice = pEntry->desc.tex3D.mipSlice;
1708 desc.Texture3D.FirstWSlice = pEntry->desc.tex3D.firstW;
1709 desc.Texture3D.WSize = pEntry->desc.tex3D.wSize;
1710 break;
1711 case SVGA3D_RESOURCE_TEXTURECUBE:
1712 AssertFailed(); /** @todo test. Probably not applicable to a render target view. */
1713 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1714 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
1715 desc.Texture2DArray.FirstArraySlice = 0;
1716 desc.Texture2DArray.ArraySize = 6;
1717 break;
1718 case SVGA3D_RESOURCE_BUFFEREX:
1719 AssertFailed(); /** @todo test. Probably not applicable to a render target view. */
1720 desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER;
1721 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
1722 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
1723 break;
1724 default:
1725 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1726 }
1727
1728 HRESULT hr = pDevice->pDevice->CreateRenderTargetView(pResource, &desc, pp);
1729 Assert(SUCCEEDED(hr));
1730 return hr;
1731}
1732
1733
1734static HRESULT dxShaderResourceViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXSRViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11ShaderResourceView **pp)
1735{
1736 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
1737
1738 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
1739
1740 D3D11_SHADER_RESOURCE_VIEW_DESC desc;
1741 RT_ZERO(desc);
1742 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
1743 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN || pEntry->format == SVGA3D_BUFFER, E_FAIL);
1744
1745 switch (pEntry->resourceDimension)
1746 {
1747 case SVGA3D_RESOURCE_BUFFER:
1748 desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
1749 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
1750 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
1751 break;
1752 case SVGA3D_RESOURCE_TEXTURE1D:
1753 if (pSurface->surfaceDesc.numArrayElements <= 1)
1754 {
1755 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
1756 desc.Texture1D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1757 desc.Texture1D.MipLevels = pEntry->desc.tex.mipLevels;
1758 }
1759 else
1760 {
1761 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
1762 desc.Texture1DArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1763 desc.Texture1DArray.MipLevels = pEntry->desc.tex.mipLevels;
1764 desc.Texture1DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1765 desc.Texture1DArray.ArraySize = pEntry->desc.tex.arraySize;
1766 }
1767 break;
1768 case SVGA3D_RESOURCE_TEXTURE2D:
1769 if (pSurface->surfaceDesc.numArrayElements <= 1)
1770 {
1771 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
1772 desc.Texture2D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1773 desc.Texture2D.MipLevels = pEntry->desc.tex.mipLevels;
1774 }
1775 else
1776 {
1777 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1778 desc.Texture2DArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1779 desc.Texture2DArray.MipLevels = pEntry->desc.tex.mipLevels;
1780 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1781 desc.Texture2DArray.ArraySize = pEntry->desc.tex.arraySize;
1782 }
1783 break;
1784 case SVGA3D_RESOURCE_TEXTURE3D:
1785 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
1786 desc.Texture3D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1787 desc.Texture3D.MipLevels = pEntry->desc.tex.mipLevels;
1788 break;
1789 case SVGA3D_RESOURCE_TEXTURECUBE:
1790 if (pSurface->surfaceDesc.numArrayElements <= 6)
1791 {
1792 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
1793 desc.TextureCube.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1794 desc.TextureCube.MipLevels = pEntry->desc.tex.mipLevels;
1795 }
1796 else
1797 {
1798 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
1799 desc.TextureCubeArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1800 desc.TextureCubeArray.MipLevels = pEntry->desc.tex.mipLevels;
1801 desc.TextureCubeArray.First2DArrayFace = pEntry->desc.tex.firstArraySlice;
1802 desc.TextureCubeArray.NumCubes = pEntry->desc.tex.arraySize / 6;
1803 }
1804 break;
1805 case SVGA3D_RESOURCE_BUFFEREX:
1806 AssertFailed(); /** @todo test. */
1807 desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
1808 desc.BufferEx.FirstElement = pEntry->desc.bufferex.firstElement;
1809 desc.BufferEx.NumElements = pEntry->desc.bufferex.numElements;
1810 desc.BufferEx.Flags = pEntry->desc.bufferex.flags;
1811 break;
1812 default:
1813 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1814 }
1815
1816 HRESULT hr = pDevice->pDevice->CreateShaderResourceView(pResource, &desc, pp);
1817 Assert(SUCCEEDED(hr));
1818 return hr;
1819}
1820
1821
1822static HRESULT dxUnorderedAccessViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXUAViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11UnorderedAccessView **pp)
1823{
1824 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
1825
1826 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
1827
1828 D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
1829 RT_ZERO(desc);
1830 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
1831 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN || pEntry->format == SVGA3D_BUFFER, E_FAIL);
1832
1833 switch (pEntry->resourceDimension)
1834 {
1835 case SVGA3D_RESOURCE_BUFFER:
1836 desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
1837 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
1838 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
1839 desc.Buffer.Flags = pEntry->desc.buffer.flags;
1840 break;
1841 case SVGA3D_RESOURCE_TEXTURE1D:
1842 if (pSurface->surfaceDesc.numArrayElements <= 1)
1843 {
1844 desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D;
1845 desc.Texture1D.MipSlice = pEntry->desc.tex.mipSlice;
1846 }
1847 else
1848 {
1849 desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY;
1850 desc.Texture1DArray.MipSlice = pEntry->desc.tex.mipSlice;
1851 desc.Texture1DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1852 desc.Texture1DArray.ArraySize = pEntry->desc.tex.arraySize;
1853 }
1854 break;
1855 case SVGA3D_RESOURCE_TEXTURE2D:
1856 if (pSurface->surfaceDesc.numArrayElements <= 1)
1857 {
1858 desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
1859 desc.Texture2D.MipSlice = pEntry->desc.tex.mipSlice;
1860 }
1861 else
1862 {
1863 desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
1864 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
1865 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1866 desc.Texture2DArray.ArraySize = pEntry->desc.tex.arraySize;
1867 }
1868 break;
1869 case SVGA3D_RESOURCE_TEXTURE3D:
1870 desc.Texture3D.MipSlice = pEntry->desc.tex3D.mipSlice;
1871 desc.Texture3D.FirstWSlice = pEntry->desc.tex3D.firstW;
1872 desc.Texture3D.WSize = pEntry->desc.tex3D.wSize;
1873 break;
1874 default:
1875 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1876 }
1877
1878 HRESULT hr = pDevice->pDevice->CreateUnorderedAccessView(pResource, &desc, pp);
1879 Assert(SUCCEEDED(hr));
1880 return hr;
1881}
1882
1883
1884static HRESULT dxDepthStencilViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXDSViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11DepthStencilView **pp)
1885{
1886 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
1887
1888 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
1889
1890 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
1891 RT_ZERO(desc);
1892 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
1893 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN || pEntry->format == SVGA3D_BUFFER, E_FAIL);
1894 desc.Flags = pEntry->flags;
1895 switch (pEntry->resourceDimension)
1896 {
1897 case SVGA3D_RESOURCE_TEXTURE1D:
1898 if (pSurface->surfaceDesc.numArrayElements <= 1)
1899 {
1900 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
1901 desc.Texture1D.MipSlice = pEntry->mipSlice;
1902 }
1903 else
1904 {
1905 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY;
1906 desc.Texture1DArray.MipSlice = pEntry->mipSlice;
1907 desc.Texture1DArray.FirstArraySlice = pEntry->firstArraySlice;
1908 desc.Texture1DArray.ArraySize = pEntry->arraySize;
1909 }
1910 break;
1911 case SVGA3D_RESOURCE_TEXTURE2D:
1912 if (pSurface->surfaceDesc.numArrayElements <= 1)
1913 {
1914 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
1915 desc.Texture2D.MipSlice = pEntry->mipSlice;
1916 }
1917 else
1918 {
1919 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
1920 desc.Texture2DArray.MipSlice = pEntry->mipSlice;
1921 desc.Texture2DArray.FirstArraySlice = pEntry->firstArraySlice;
1922 desc.Texture2DArray.ArraySize = pEntry->arraySize;
1923 }
1924 break;
1925 default:
1926 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1927 }
1928
1929 HRESULT hr = pDevice->pDevice->CreateDepthStencilView(pResource, &desc, pp);
1930 Assert(SUCCEEDED(hr));
1931 return hr;
1932}
1933
1934
1935static HRESULT dxShaderCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, DXSHADER *pDXShader)
1936{
1937 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
1938
1939 HRESULT hr = S_OK;
1940
1941 switch (pDXShader->enmShaderType)
1942 {
1943 case SVGA3D_SHADERTYPE_VS:
1944 hr = pDevice->pDevice->CreateVertexShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pVertexShader);
1945 Assert(SUCCEEDED(hr));
1946 break;
1947 case SVGA3D_SHADERTYPE_PS:
1948 hr = pDevice->pDevice->CreatePixelShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pPixelShader);
1949 Assert(SUCCEEDED(hr));
1950 break;
1951 case SVGA3D_SHADERTYPE_GS:
1952 {
1953 SVGA3dStreamOutputId const soid = pDXContext->svgaDXContext.streamOut.soid;
1954 if (soid == SVGA_ID_INVALID)
1955 {
1956 hr = pDevice->pDevice->CreateGeometryShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pGeometryShader);
1957 Assert(SUCCEEDED(hr));
1958 }
1959 else
1960 {
1961 ASSERT_GUEST_RETURN(soid < pDXContext->pBackendDXContext->cStreamOutput, E_INVALIDARG);
1962
1963 SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[soid];
1964 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
1965
1966 hr = pDevice->pDevice->CreateGeometryShaderWithStreamOutput(pDXShader->pvDXBC, pDXShader->cbDXBC,
1967 pDXStreamOutput->aDeclarationEntry, pDXStreamOutput->cDeclarationEntry,
1968 pEntry->numOutputStreamStrides ? pEntry->streamOutputStrideInBytes : NULL, pEntry->numOutputStreamStrides,
1969 pEntry->rasterizedStream,
1970 /*pClassLinkage=*/ NULL, &pDXShader->pGeometryShader);
1971 AssertBreak(SUCCEEDED(hr));
1972
1973 pDXShader->soid = soid;
1974 }
1975 break;
1976 }
1977 case SVGA3D_SHADERTYPE_HS:
1978 hr = pDevice->pDevice->CreateHullShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pHullShader);
1979 Assert(SUCCEEDED(hr));
1980 break;
1981 case SVGA3D_SHADERTYPE_DS:
1982 hr = pDevice->pDevice->CreateDomainShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pDomainShader);
1983 Assert(SUCCEEDED(hr));
1984 break;
1985 case SVGA3D_SHADERTYPE_CS:
1986 hr = pDevice->pDevice->CreateComputeShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pComputeShader);
1987 Assert(SUCCEEDED(hr));
1988 break;
1989 default:
1990 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1991 }
1992
1993 return hr;
1994}
1995
1996
1997static void dxShaderSet(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderType type, DXSHADER *pDXShader)
1998{
1999 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2000
2001 switch (type)
2002 {
2003 case SVGA3D_SHADERTYPE_VS:
2004 pDevice->pImmediateContext->VSSetShader(pDXShader ? pDXShader->pVertexShader : NULL, NULL, 0);
2005 break;
2006 case SVGA3D_SHADERTYPE_PS:
2007 pDevice->pImmediateContext->PSSetShader(pDXShader ? pDXShader->pPixelShader : NULL, NULL, 0);
2008 break;
2009 case SVGA3D_SHADERTYPE_GS:
2010 {
2011 Assert(!pDXShader || (pDXShader->soid == pDXContext->svgaDXContext.streamOut.soid));
2012 pDevice->pImmediateContext->GSSetShader(pDXShader ? pDXShader->pGeometryShader : NULL, NULL, 0);
2013 } break;
2014 case SVGA3D_SHADERTYPE_HS:
2015 pDevice->pImmediateContext->HSSetShader(pDXShader ? pDXShader->pHullShader : NULL, NULL, 0);
2016 break;
2017 case SVGA3D_SHADERTYPE_DS:
2018 pDevice->pImmediateContext->DSSetShader(pDXShader ? pDXShader->pDomainShader : NULL, NULL, 0);
2019 break;
2020 case SVGA3D_SHADERTYPE_CS:
2021 pDevice->pImmediateContext->CSSetShader(pDXShader ? pDXShader->pComputeShader : NULL, NULL, 0);
2022 break;
2023 default:
2024 ASSERT_GUEST_FAILED_RETURN_VOID();
2025 }
2026}
2027
2028
2029static void dxConstantBufferSet(DXDEVICE *pDevice, uint32_t slot, SVGA3dShaderType type, ID3D11Buffer *pConstantBuffer)
2030{
2031 switch (type)
2032 {
2033 case SVGA3D_SHADERTYPE_VS:
2034 pDevice->pImmediateContext->VSSetConstantBuffers(slot, 1, &pConstantBuffer);
2035 break;
2036 case SVGA3D_SHADERTYPE_PS:
2037 pDevice->pImmediateContext->PSSetConstantBuffers(slot, 1, &pConstantBuffer);
2038 break;
2039 case SVGA3D_SHADERTYPE_GS:
2040 pDevice->pImmediateContext->GSSetConstantBuffers(slot, 1, &pConstantBuffer);
2041 break;
2042 case SVGA3D_SHADERTYPE_HS:
2043 pDevice->pImmediateContext->HSSetConstantBuffers(slot, 1, &pConstantBuffer);
2044 break;
2045 case SVGA3D_SHADERTYPE_DS:
2046 pDevice->pImmediateContext->DSSetConstantBuffers(slot, 1, &pConstantBuffer);
2047 break;
2048 case SVGA3D_SHADERTYPE_CS:
2049 pDevice->pImmediateContext->CSSetConstantBuffers(slot, 1, &pConstantBuffer);
2050 break;
2051 default:
2052 ASSERT_GUEST_FAILED_RETURN_VOID();
2053 }
2054}
2055
2056
2057static void dxSamplerSet(DXDEVICE *pDevice, SVGA3dShaderType type, uint32_t startSampler, uint32_t cSampler, ID3D11SamplerState * const *papSampler)
2058{
2059 switch (type)
2060 {
2061 case SVGA3D_SHADERTYPE_VS:
2062 pDevice->pImmediateContext->VSSetSamplers(startSampler, cSampler, papSampler);
2063 break;
2064 case SVGA3D_SHADERTYPE_PS:
2065 pDevice->pImmediateContext->PSSetSamplers(startSampler, cSampler, papSampler);
2066 break;
2067 case SVGA3D_SHADERTYPE_GS:
2068 pDevice->pImmediateContext->GSSetSamplers(startSampler, cSampler, papSampler);
2069 break;
2070 case SVGA3D_SHADERTYPE_HS:
2071 pDevice->pImmediateContext->HSSetSamplers(startSampler, cSampler, papSampler);
2072 break;
2073 case SVGA3D_SHADERTYPE_DS:
2074 pDevice->pImmediateContext->DSSetSamplers(startSampler, cSampler, papSampler);
2075 break;
2076 case SVGA3D_SHADERTYPE_CS:
2077 pDevice->pImmediateContext->CSSetSamplers(startSampler, cSampler, papSampler);
2078 break;
2079 default:
2080 ASSERT_GUEST_FAILED_RETURN_VOID();
2081 }
2082}
2083
2084
2085static void dxShaderResourceViewSet(DXDEVICE *pDevice, SVGA3dShaderType type, uint32_t startView, uint32_t cShaderResourceView, ID3D11ShaderResourceView * const *papShaderResourceView)
2086{
2087 switch (type)
2088 {
2089 case SVGA3D_SHADERTYPE_VS:
2090 pDevice->pImmediateContext->VSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2091 break;
2092 case SVGA3D_SHADERTYPE_PS:
2093 pDevice->pImmediateContext->PSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2094 break;
2095 case SVGA3D_SHADERTYPE_GS:
2096 pDevice->pImmediateContext->GSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2097 break;
2098 case SVGA3D_SHADERTYPE_HS:
2099 pDevice->pImmediateContext->HSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2100 break;
2101 case SVGA3D_SHADERTYPE_DS:
2102 pDevice->pImmediateContext->DSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2103 break;
2104 case SVGA3D_SHADERTYPE_CS:
2105 pDevice->pImmediateContext->CSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2106 break;
2107 default:
2108 ASSERT_GUEST_FAILED_RETURN_VOID();
2109 }
2110}
2111
2112
2113static void dxCSUnorderedAccessViewSet(DXDEVICE *pDevice, uint32_t startView, uint32_t cView, ID3D11UnorderedAccessView * const *papUnorderedAccessView, UINT *pUAVInitialCounts)
2114{
2115 pDevice->pImmediateContext->CSSetUnorderedAccessViews(startView, cView, papUnorderedAccessView, pUAVInitialCounts);
2116}
2117
2118
2119static int dxBackendSurfaceAlloc(PVMSVGA3DBACKENDSURFACE *ppBackendSurface)
2120{
2121 PVMSVGA3DBACKENDSURFACE pBackendSurface = (PVMSVGA3DBACKENDSURFACE)RTMemAllocZ(sizeof(VMSVGA3DBACKENDSURFACE));
2122 AssertPtrReturn(pBackendSurface, VERR_NO_MEMORY);
2123 pBackendSurface->cidDrawing = SVGA_ID_INVALID;
2124 RTListInit(&pBackendSurface->listView);
2125 *ppBackendSurface = pBackendSurface;
2126 return VINF_SUCCESS;
2127}
2128
2129
2130static HRESULT dxInitSharedHandle(PVMSVGA3DBACKEND pBackend, PVMSVGA3DBACKENDSURFACE pBackendSurface)
2131{
2132 if (pBackend->fSingleDevice)
2133 return S_OK;
2134
2135 /* Get the shared handle. */
2136 IDXGIResource *pDxgiResource = NULL;
2137 HRESULT hr = pBackendSurface->u.pResource->QueryInterface(__uuidof(IDXGIResource), (void**)&pDxgiResource);
2138 Assert(SUCCEEDED(hr));
2139 if (SUCCEEDED(hr))
2140 {
2141 hr = pDxgiResource->GetSharedHandle(&pBackendSurface->SharedHandle);
2142 Assert(SUCCEEDED(hr));
2143 D3D_RELEASE(pDxgiResource);
2144 }
2145
2146 return hr;
2147}
2148
2149
2150static int vmsvga3dBackSurfaceCreateScreenTarget(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
2151{
2152 PVMSVGA3DSTATE p3dState = pThisCC->svga.p3dState;
2153 AssertReturn(p3dState, VERR_INVALID_STATE);
2154
2155 PVMSVGA3DBACKEND pBackend = p3dState->pBackend;
2156 AssertReturn(pBackend, VERR_INVALID_STATE);
2157
2158 DXDEVICE *pDXDevice = &pBackend->dxDevice;
2159 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
2160
2161 /* Surface must have SCREEN_TARGET flag. */
2162 ASSERT_GUEST_RETURN(RT_BOOL(pSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET), VERR_INVALID_PARAMETER);
2163
2164 if (VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
2165 {
2166 AssertFailed(); /* Should the function not be used like that? */
2167 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
2168 }
2169
2170 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2171 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2172 AssertRCReturn(rc, rc);
2173
2174 D3D11_TEXTURE2D_DESC td;
2175 RT_ZERO(td);
2176 td.Width = pSurface->paMipmapLevels[0].mipmapSize.width;
2177 td.Height = pSurface->paMipmapLevels[0].mipmapSize.height;
2178 Assert(pSurface->cLevels == 1);
2179 td.MipLevels = 1;
2180 td.ArraySize = 1;
2181 td.Format = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
2182 td.SampleDesc.Count = 1;
2183 td.SampleDesc.Quality = 0;
2184 td.Usage = D3D11_USAGE_DEFAULT;
2185 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
2186 td.CPUAccessFlags = 0;
2187 td.MiscFlags = pBackend->fSingleDevice ? 0 : D3D11_RESOURCE_MISC_SHARED;
2188
2189 HRESULT hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->u.pTexture2D);
2190 Assert(SUCCEEDED(hr));
2191 if (SUCCEEDED(hr))
2192 {
2193 /* Map-able texture. */
2194 td.Usage = D3D11_USAGE_DYNAMIC;
2195 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2196 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2197 td.MiscFlags = 0;
2198 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->dynamic.pTexture2D);
2199 Assert(SUCCEEDED(hr));
2200 }
2201
2202 if (SUCCEEDED(hr))
2203 {
2204 /* Staging texture. */
2205 td.Usage = D3D11_USAGE_STAGING;
2206 td.BindFlags = 0; /* No flags allowed. */
2207 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2208 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->staging.pTexture2D);
2209 Assert(SUCCEEDED(hr));
2210 }
2211
2212 if (SUCCEEDED(hr))
2213 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2214
2215 if (SUCCEEDED(hr))
2216 {
2217 /*
2218 * Success.
2219 */
2220 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_SCREEN_TARGET;
2221 pBackendSurface->enmDxgiFormat = td.Format;
2222 pSurface->pBackendSurface = pBackendSurface;
2223 pSurface->idAssociatedContext = DX_CID_BACKEND;
2224 return VINF_SUCCESS;
2225 }
2226
2227 /* Failure. */
2228 D3D_RELEASE(pBackendSurface->staging.pTexture2D);
2229 D3D_RELEASE(pBackendSurface->dynamic.pTexture2D);
2230 D3D_RELEASE(pBackendSurface->u.pTexture2D);
2231 RTMemFree(pBackendSurface);
2232 return VERR_NO_MEMORY;
2233}
2234
2235
2236static UINT dxBindFlags(SVGA3dSurfaceAllFlags surfaceFlags)
2237{
2238 /* Catch unimplemented flags. */
2239 Assert(!RT_BOOL(surfaceFlags & (SVGA3D_SURFACE_BIND_LOGICOPS | SVGA3D_SURFACE_BIND_RAW_VIEWS)));
2240
2241 UINT BindFlags = 0;
2242
2243 if (surfaceFlags & (SVGA3D_SURFACE_BIND_VERTEX_BUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER))
2244 BindFlags |= D3D11_BIND_VERTEX_BUFFER;
2245 if (surfaceFlags & (SVGA3D_SURFACE_BIND_INDEX_BUFFER | SVGA3D_SURFACE_HINT_INDEXBUFFER))
2246 BindFlags |= D3D11_BIND_INDEX_BUFFER;
2247 if (surfaceFlags & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER) BindFlags |= D3D11_BIND_CONSTANT_BUFFER;
2248 if (surfaceFlags & SVGA3D_SURFACE_BIND_SHADER_RESOURCE) BindFlags |= D3D11_BIND_SHADER_RESOURCE;
2249 if (surfaceFlags & SVGA3D_SURFACE_BIND_RENDER_TARGET) BindFlags |= D3D11_BIND_RENDER_TARGET;
2250 if (surfaceFlags & SVGA3D_SURFACE_BIND_DEPTH_STENCIL) BindFlags |= D3D11_BIND_DEPTH_STENCIL;
2251 if (surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) BindFlags |= D3D11_BIND_STREAM_OUTPUT;
2252 if (surfaceFlags & SVGA3D_SURFACE_BIND_UAVIEW) BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
2253
2254 return BindFlags;
2255}
2256
2257
2258static DXDEVICE *dxSurfaceDevice(PVMSVGA3DSTATE p3dState, PVMSVGA3DSURFACE pSurface, PVMSVGA3DDXCONTEXT pDXContext, UINT *pMiscFlags)
2259{
2260 if (p3dState->pBackend->fSingleDevice)
2261 {
2262 *pMiscFlags = 0;
2263 return &p3dState->pBackend->dxDevice;
2264 }
2265
2266 if (dxIsSurfaceShareable(pSurface))
2267 {
2268 *pMiscFlags = D3D11_RESOURCE_MISC_SHARED;
2269 return &p3dState->pBackend->dxDevice;
2270 }
2271
2272 *pMiscFlags = 0;
2273 return &pDXContext->pBackendDXContext->dxDevice;
2274}
2275
2276
2277static DXGI_FORMAT dxGetDxgiTypelessFormat(DXGI_FORMAT dxgiFormat)
2278{
2279 switch (dxgiFormat)
2280 {
2281 case DXGI_FORMAT_R32G32B32A32_FLOAT:
2282 case DXGI_FORMAT_R32G32B32A32_UINT:
2283 case DXGI_FORMAT_R32G32B32A32_SINT:
2284 return DXGI_FORMAT_R32G32B32A32_TYPELESS; /* 1 */
2285 case DXGI_FORMAT_R32G32B32_FLOAT:
2286 case DXGI_FORMAT_R32G32B32_UINT:
2287 case DXGI_FORMAT_R32G32B32_SINT:
2288 return DXGI_FORMAT_R32G32B32_TYPELESS; /* 5 */
2289 case DXGI_FORMAT_R16G16B16A16_FLOAT:
2290 case DXGI_FORMAT_R16G16B16A16_UNORM:
2291 case DXGI_FORMAT_R16G16B16A16_UINT:
2292 case DXGI_FORMAT_R16G16B16A16_SNORM:
2293 case DXGI_FORMAT_R16G16B16A16_SINT:
2294 return DXGI_FORMAT_R16G16B16A16_TYPELESS; /* 9 */
2295 case DXGI_FORMAT_R32G32_FLOAT:
2296 case DXGI_FORMAT_R32G32_UINT:
2297 case DXGI_FORMAT_R32G32_SINT:
2298 return DXGI_FORMAT_R32G32_TYPELESS; /* 15 */
2299 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
2300 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
2301 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
2302 return DXGI_FORMAT_R32G8X24_TYPELESS; /* 19 */
2303 case DXGI_FORMAT_R10G10B10A2_UNORM:
2304 case DXGI_FORMAT_R10G10B10A2_UINT:
2305 return DXGI_FORMAT_R10G10B10A2_TYPELESS; /* 23 */
2306 case DXGI_FORMAT_R8G8B8A8_UNORM:
2307 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
2308 case DXGI_FORMAT_R8G8B8A8_UINT:
2309 case DXGI_FORMAT_R8G8B8A8_SNORM:
2310 case DXGI_FORMAT_R8G8B8A8_SINT:
2311 return DXGI_FORMAT_R8G8B8A8_TYPELESS; /* 27 */
2312 case DXGI_FORMAT_R16G16_FLOAT:
2313 case DXGI_FORMAT_R16G16_UNORM:
2314 case DXGI_FORMAT_R16G16_UINT:
2315 case DXGI_FORMAT_R16G16_SNORM:
2316 case DXGI_FORMAT_R16G16_SINT:
2317 return DXGI_FORMAT_R16G16_TYPELESS; /* 33 */
2318 case DXGI_FORMAT_D32_FLOAT:
2319 case DXGI_FORMAT_R32_FLOAT:
2320 case DXGI_FORMAT_R32_UINT:
2321 case DXGI_FORMAT_R32_SINT:
2322 return DXGI_FORMAT_R32_TYPELESS; /* 39 */
2323 case DXGI_FORMAT_D24_UNORM_S8_UINT:
2324 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
2325 case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
2326 return DXGI_FORMAT_R24G8_TYPELESS; /* 44 */
2327 case DXGI_FORMAT_R8G8_UNORM:
2328 case DXGI_FORMAT_R8G8_UINT:
2329 case DXGI_FORMAT_R8G8_SNORM:
2330 case DXGI_FORMAT_R8G8_SINT:
2331 return DXGI_FORMAT_R8G8_TYPELESS; /* 48*/
2332 case DXGI_FORMAT_R16_FLOAT:
2333 case DXGI_FORMAT_D16_UNORM:
2334 case DXGI_FORMAT_R16_UNORM:
2335 case DXGI_FORMAT_R16_UINT:
2336 case DXGI_FORMAT_R16_SNORM:
2337 case DXGI_FORMAT_R16_SINT:
2338 return DXGI_FORMAT_R16_TYPELESS; /* 53 */
2339 case DXGI_FORMAT_R8_UNORM:
2340 case DXGI_FORMAT_R8_UINT:
2341 case DXGI_FORMAT_R8_SNORM:
2342 case DXGI_FORMAT_R8_SINT:
2343 return DXGI_FORMAT_R8_TYPELESS; /* 60*/
2344 case DXGI_FORMAT_BC1_UNORM:
2345 case DXGI_FORMAT_BC1_UNORM_SRGB:
2346 return DXGI_FORMAT_BC1_TYPELESS; /* 70 */
2347 case DXGI_FORMAT_BC2_UNORM:
2348 case DXGI_FORMAT_BC2_UNORM_SRGB:
2349 return DXGI_FORMAT_BC2_TYPELESS; /* 73 */
2350 case DXGI_FORMAT_BC3_UNORM:
2351 case DXGI_FORMAT_BC3_UNORM_SRGB:
2352 return DXGI_FORMAT_BC3_TYPELESS; /* 76 */
2353 case DXGI_FORMAT_BC4_UNORM:
2354 case DXGI_FORMAT_BC4_SNORM:
2355 return DXGI_FORMAT_BC4_TYPELESS; /* 79 */
2356 case DXGI_FORMAT_BC5_UNORM:
2357 case DXGI_FORMAT_BC5_SNORM:
2358 return DXGI_FORMAT_BC5_TYPELESS; /* 82 */
2359 case DXGI_FORMAT_B8G8R8A8_UNORM:
2360 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
2361 return DXGI_FORMAT_B8G8R8A8_TYPELESS; /* 90 */
2362 case DXGI_FORMAT_B8G8R8X8_UNORM:
2363 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
2364 return DXGI_FORMAT_B8G8R8X8_TYPELESS; /* 92 */
2365 case DXGI_FORMAT_BC6H_UF16:
2366 case DXGI_FORMAT_BC6H_SF16:
2367 return DXGI_FORMAT_BC6H_TYPELESS; /* 94 */
2368 case DXGI_FORMAT_BC7_UNORM:
2369 case DXGI_FORMAT_BC7_UNORM_SRGB:
2370 return DXGI_FORMAT_BC7_TYPELESS; /* 97 */
2371 default:
2372 break;
2373 }
2374
2375 return dxgiFormat;
2376}
2377
2378
2379static bool dxIsDepthStencilFormat(DXGI_FORMAT dxgiFormat)
2380{
2381 switch (dxgiFormat)
2382 {
2383 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
2384 case DXGI_FORMAT_D32_FLOAT:
2385 case DXGI_FORMAT_D24_UNORM_S8_UINT:
2386 case DXGI_FORMAT_R16_FLOAT:
2387 return true;
2388 default:
2389 break;
2390 }
2391
2392 return false;
2393}
2394
2395
2396static int vmsvga3dBackSurfaceCreateTexture(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2397{
2398 PVMSVGA3DSTATE p3dState = pThisCC->svga.p3dState;
2399 AssertReturn(p3dState, VERR_INVALID_STATE);
2400
2401 PVMSVGA3DBACKEND pBackend = p3dState->pBackend;
2402 AssertReturn(pBackend, VERR_INVALID_STATE);
2403
2404 UINT MiscFlags;
2405 DXDEVICE *pDXDevice = dxSurfaceDevice(p3dState, pSurface, pDXContext, &MiscFlags);
2406 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
2407
2408 if (pSurface->pBackendSurface != NULL)
2409 {
2410 AssertFailed(); /** @todo Should the function not be used like that? */
2411 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
2412 }
2413
2414 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2415 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2416 AssertRCReturn(rc, rc);
2417
2418 uint32_t const cWidth = pSurface->paMipmapLevels[0].cBlocksX * pSurface->cxBlock;
2419 uint32_t const cHeight = pSurface->paMipmapLevels[0].cBlocksY * pSurface->cyBlock;
2420 uint32_t const cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth;
2421 uint32_t const numMipLevels = pSurface->cLevels;
2422
2423 DXGI_FORMAT dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
2424 AssertReturn(dxgiFormat != DXGI_FORMAT_UNKNOWN, E_FAIL);
2425
2426 /* Create typeless textures, unless it is a depth/stencil resource,
2427 * because D3D11_BIND_DEPTH_STENCIL requires a depth/stencil format.
2428 * Always use typeless format for staging/dynamic resources.
2429 */
2430 DXGI_FORMAT const dxgiFormatTypeless = dxGetDxgiTypelessFormat(dxgiFormat);
2431 if (!dxIsDepthStencilFormat(dxgiFormat))
2432 dxgiFormat = dxgiFormatTypeless;
2433
2434 /*
2435 * Create D3D11 texture object.
2436 */
2437 D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
2438 if (pSurface->paMipmapLevels[0].pSurfaceData)
2439 {
2440 /* Can happen for a non GBO surface or if GBO texture was updated prior to creation of the hardware resource. */
2441 uint32_t const cSubresource = numMipLevels * pSurface->surfaceDesc.numArrayElements;
2442 paInitialData = (D3D11_SUBRESOURCE_DATA *)RTMemAlloc(cSubresource * sizeof(D3D11_SUBRESOURCE_DATA));
2443 AssertPtrReturn(paInitialData, VERR_NO_MEMORY);
2444
2445 for (uint32_t i = 0; i < cSubresource; ++i)
2446 {
2447 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i];
2448 D3D11_SUBRESOURCE_DATA *p = &paInitialData[i];
2449 p->pSysMem = pMipmapLevel->pSurfaceData;
2450 p->SysMemPitch = pMipmapLevel->cbSurfacePitch;
2451 p->SysMemSlicePitch = pMipmapLevel->cbSurfacePlane;
2452 }
2453 }
2454
2455 HRESULT hr = S_OK;
2456 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET)
2457 {
2458 /*
2459 * Create the texture in backend device and open for the specified context.
2460 */
2461 D3D11_TEXTURE2D_DESC td;
2462 RT_ZERO(td);
2463 td.Width = pSurface->paMipmapLevels[0].mipmapSize.width;
2464 td.Height = pSurface->paMipmapLevels[0].mipmapSize.height;
2465 Assert(pSurface->cLevels == 1);
2466 td.MipLevels = 1;
2467 td.ArraySize = 1;
2468 td.Format = dxgiFormat;
2469 td.SampleDesc.Count = 1;
2470 td.SampleDesc.Quality = 0;
2471 td.Usage = D3D11_USAGE_DEFAULT;
2472 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
2473 td.CPUAccessFlags = 0;
2474 td.MiscFlags = MiscFlags;
2475
2476 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
2477 Assert(SUCCEEDED(hr));
2478 if (SUCCEEDED(hr))
2479 {
2480 /* Map-able texture. */
2481 td.Format = dxgiFormatTypeless;
2482 td.Usage = D3D11_USAGE_DYNAMIC;
2483 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2484 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2485 td.MiscFlags = 0;
2486 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->dynamic.pTexture2D);
2487 Assert(SUCCEEDED(hr));
2488 }
2489
2490 if (SUCCEEDED(hr))
2491 {
2492 /* Staging texture. */
2493 td.Usage = D3D11_USAGE_STAGING;
2494 td.BindFlags = 0; /* No flags allowed. */
2495 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2496 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->staging.pTexture2D);
2497 Assert(SUCCEEDED(hr));
2498 }
2499
2500 if (SUCCEEDED(hr))
2501 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2502
2503 if (SUCCEEDED(hr))
2504 {
2505 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_SCREEN_TARGET;
2506 }
2507 }
2508 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_CUBEMAP)
2509 {
2510 Assert(pSurface->cFaces == 6);
2511 Assert(cWidth == cHeight);
2512 Assert(cDepth == 1);
2513//DEBUG_BREAKPOINT_TEST();
2514
2515 D3D11_TEXTURE2D_DESC td;
2516 RT_ZERO(td);
2517 td.Width = cWidth;
2518 td.Height = cHeight;
2519 td.MipLevels = numMipLevels;
2520 td.ArraySize = pSurface->surfaceDesc.numArrayElements; /* This is 6 * numCubes */
2521 td.Format = dxgiFormat;
2522 td.SampleDesc.Count = 1;
2523 td.SampleDesc.Quality = 0;
2524 td.Usage = D3D11_USAGE_DEFAULT;
2525 td.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2526 td.CPUAccessFlags = 0; /** @todo */
2527 td.MiscFlags = MiscFlags | D3D11_RESOURCE_MISC_TEXTURECUBE; /** @todo */
2528 if ( numMipLevels > 1
2529 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2530 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2531
2532 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
2533 Assert(SUCCEEDED(hr));
2534 if (SUCCEEDED(hr))
2535 {
2536 /* Map-able texture. */
2537 td.Format = dxgiFormatTypeless;
2538 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2539 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2540 td.Usage = D3D11_USAGE_DYNAMIC;
2541 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2542 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2543 td.MiscFlags = 0;
2544 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->dynamic.pTexture2D);
2545 Assert(SUCCEEDED(hr));
2546 }
2547
2548 if (SUCCEEDED(hr))
2549 {
2550 /* Staging texture. */
2551 td.Usage = D3D11_USAGE_STAGING;
2552 td.BindFlags = 0; /* No flags allowed. */
2553 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2554 td.MiscFlags = 0;
2555 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->staging.pTexture2D);
2556 Assert(SUCCEEDED(hr));
2557 }
2558
2559 if (SUCCEEDED(hr))
2560 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2561
2562 if (SUCCEEDED(hr))
2563 {
2564 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_CUBE;
2565 }
2566 }
2567 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_1D)
2568 {
2569 /*
2570 * 1D texture.
2571 */
2572 Assert(pSurface->cFaces == 1);
2573
2574 D3D11_TEXTURE1D_DESC td;
2575 RT_ZERO(td);
2576 td.Width = cWidth;
2577 td.MipLevels = numMipLevels;
2578 td.ArraySize = pSurface->surfaceDesc.numArrayElements;
2579 td.Format = dxgiFormat;
2580 td.Usage = D3D11_USAGE_DEFAULT;
2581 td.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2582 td.CPUAccessFlags = 0;
2583 td.MiscFlags = MiscFlags; /** @todo */
2584 if ( numMipLevels > 1
2585 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2586 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2587
2588 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->u.pTexture1D);
2589 Assert(SUCCEEDED(hr));
2590 if (SUCCEEDED(hr))
2591 {
2592 /* Map-able texture. */
2593 td.Format = dxgiFormatTypeless;
2594 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2595 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2596 td.Usage = D3D11_USAGE_DYNAMIC;
2597 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2598 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2599 td.MiscFlags = 0;
2600 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->dynamic.pTexture1D);
2601 Assert(SUCCEEDED(hr));
2602 }
2603
2604 if (SUCCEEDED(hr))
2605 {
2606 /* Staging texture. */
2607 td.Usage = D3D11_USAGE_STAGING;
2608 td.BindFlags = 0; /* No flags allowed. */
2609 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2610 td.MiscFlags = 0;
2611 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->staging.pTexture1D);
2612 Assert(SUCCEEDED(hr));
2613 }
2614
2615 if (SUCCEEDED(hr))
2616 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2617
2618 if (SUCCEEDED(hr))
2619 {
2620 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_1D;
2621 }
2622 }
2623 else
2624 {
2625 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_VOLUME)
2626 {
2627 /*
2628 * Volume texture.
2629 */
2630 Assert(pSurface->cFaces == 1);
2631 Assert(pSurface->surfaceDesc.numArrayElements == 1);
2632
2633 D3D11_TEXTURE3D_DESC td;
2634 RT_ZERO(td);
2635 td.Width = cWidth;
2636 td.Height = cHeight;
2637 td.Depth = cDepth;
2638 td.MipLevels = numMipLevels;
2639 td.Format = dxgiFormat;
2640 td.Usage = D3D11_USAGE_DEFAULT;
2641 td.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2642 td.CPUAccessFlags = 0; /** @todo */
2643 td.MiscFlags = MiscFlags; /** @todo */
2644 if ( numMipLevels > 1
2645 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2646 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2647
2648 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->u.pTexture3D);
2649 Assert(SUCCEEDED(hr));
2650 if (SUCCEEDED(hr))
2651 {
2652 /* Map-able texture. */
2653 td.Format = dxgiFormatTypeless;
2654 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2655 td.Usage = D3D11_USAGE_DYNAMIC;
2656 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2657 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2658 td.MiscFlags = 0;
2659 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->dynamic.pTexture3D);
2660 Assert(SUCCEEDED(hr));
2661 }
2662
2663 if (SUCCEEDED(hr))
2664 {
2665 /* Staging texture. */
2666 td.Usage = D3D11_USAGE_STAGING;
2667 td.BindFlags = 0; /* No flags allowed. */
2668 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2669 td.MiscFlags = 0;
2670 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->staging.pTexture3D);
2671 Assert(SUCCEEDED(hr));
2672 }
2673
2674 if (SUCCEEDED(hr))
2675 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2676
2677 if (SUCCEEDED(hr))
2678 {
2679 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_3D;
2680 }
2681 }
2682 else
2683 {
2684 /*
2685 * 2D texture.
2686 */
2687 Assert(cDepth == 1);
2688 Assert(pSurface->cFaces == 1);
2689
2690 D3D11_TEXTURE2D_DESC td;
2691 RT_ZERO(td);
2692 td.Width = cWidth;
2693 td.Height = cHeight;
2694 td.MipLevels = numMipLevels;
2695 td.ArraySize = pSurface->surfaceDesc.numArrayElements;
2696 td.Format = dxgiFormat;
2697 td.SampleDesc.Count = 1;
2698 td.SampleDesc.Quality = 0;
2699 td.Usage = D3D11_USAGE_DEFAULT;
2700 td.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2701 td.CPUAccessFlags = 0; /** @todo */
2702 td.MiscFlags = MiscFlags; /** @todo */
2703 if ( numMipLevels > 1
2704 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2705 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2706
2707 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
2708 Assert(SUCCEEDED(hr));
2709 if (SUCCEEDED(hr))
2710 {
2711 /* Map-able texture. */
2712 td.Format = dxgiFormatTypeless;
2713 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2714 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2715 td.Usage = D3D11_USAGE_DYNAMIC;
2716 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2717 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2718 td.MiscFlags = 0;
2719 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->dynamic.pTexture2D);
2720 Assert(SUCCEEDED(hr));
2721 }
2722
2723 if (SUCCEEDED(hr))
2724 {
2725 /* Staging texture. */
2726 td.Usage = D3D11_USAGE_STAGING;
2727 td.BindFlags = 0; /* No flags allowed. */
2728 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2729 td.MiscFlags = 0;
2730 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->staging.pTexture2D);
2731 Assert(SUCCEEDED(hr));
2732 }
2733
2734 if (SUCCEEDED(hr))
2735 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2736
2737 if (SUCCEEDED(hr))
2738 {
2739 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_2D;
2740 }
2741 }
2742 }
2743
2744 Assert(hr == S_OK);
2745
2746 RTMemFree(paInitialData);
2747
2748 if (pSurface->autogenFilter != SVGA3D_TEX_FILTER_NONE)
2749 {
2750 }
2751
2752 if (SUCCEEDED(hr))
2753 {
2754 /*
2755 * Success.
2756 */
2757 LogFunc(("sid = %u\n", pSurface->id));
2758 pBackendSurface->enmDxgiFormat = dxgiFormat;
2759 pSurface->pBackendSurface = pBackendSurface;
2760 if (p3dState->pBackend->fSingleDevice || RT_BOOL(MiscFlags & D3D11_RESOURCE_MISC_SHARED))
2761 pSurface->idAssociatedContext = DX_CID_BACKEND;
2762 else
2763 pSurface->idAssociatedContext = pDXContext->cid;
2764 return VINF_SUCCESS;
2765 }
2766
2767 D3D_RELEASE(pBackendSurface->staging.pResource);
2768 D3D_RELEASE(pBackendSurface->dynamic.pResource);
2769 D3D_RELEASE(pBackendSurface->u.pResource);
2770 RTMemFree(pBackendSurface);
2771 return VERR_NO_MEMORY;
2772}
2773
2774
2775static int vmsvga3dBackSurfaceCreateBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2776{
2777 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2778 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2779
2780 /* Buffers should be created as such. */
2781 AssertReturn(RT_BOOL(pSurface->f.surfaceFlags & ( SVGA3D_SURFACE_HINT_INDEXBUFFER
2782 | SVGA3D_SURFACE_HINT_VERTEXBUFFER
2783 | SVGA3D_SURFACE_BIND_VERTEX_BUFFER
2784 | SVGA3D_SURFACE_BIND_INDEX_BUFFER
2785 )), VERR_INVALID_PARAMETER);
2786
2787 if (pSurface->pBackendSurface != NULL)
2788 {
2789 AssertFailed(); /** @todo Should the function not be used like that? */
2790 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
2791 }
2792
2793 PVMSVGA3DMIPMAPLEVEL pMipLevel;
2794 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
2795 AssertRCReturn(rc, rc);
2796
2797 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2798 rc = dxBackendSurfaceAlloc(&pBackendSurface);
2799 AssertRCReturn(rc, rc);
2800
2801 LogFunc(("sid = %u, size = %u\n", pSurface->id, pMipLevel->cbSurface));
2802
2803 /* Upload the current data, if any. */
2804 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2805 D3D11_SUBRESOURCE_DATA initialData;
2806 if (pMipLevel->pSurfaceData)
2807 {
2808 initialData.pSysMem = pMipLevel->pSurfaceData;
2809 initialData.SysMemPitch = pMipLevel->cbSurface;
2810 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
2811
2812 pInitialData = &initialData;
2813 }
2814
2815 D3D11_BUFFER_DESC bd;
2816 RT_ZERO(bd);
2817 bd.ByteWidth = pMipLevel->cbSurface;
2818 bd.Usage = D3D11_USAGE_DEFAULT;
2819 bd.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2820
2821 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2822 if (SUCCEEDED(hr))
2823 {
2824 /*
2825 * Success.
2826 */
2827 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2828 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2829 pSurface->pBackendSurface = pBackendSurface;
2830 pSurface->idAssociatedContext = pDXContext->cid;
2831 return VINF_SUCCESS;
2832 }
2833
2834 /* Failure. */
2835 D3D_RELEASE(pBackendSurface->u.pBuffer);
2836 RTMemFree(pBackendSurface);
2837 return VERR_NO_MEMORY;
2838}
2839
2840
2841static int vmsvga3dBackSurfaceCreateSoBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2842{
2843 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2844 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2845
2846 /* Buffers should be created as such. */
2847 AssertReturn(RT_BOOL(pSurface->f.surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT), VERR_INVALID_PARAMETER);
2848
2849 if (pSurface->pBackendSurface != NULL)
2850 {
2851 AssertFailed(); /** @todo Should the function not be used like that? */
2852 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
2853 }
2854
2855 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2856 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2857 AssertRCReturn(rc, rc);
2858
2859 D3D11_BUFFER_DESC bd;
2860 RT_ZERO(bd);
2861 bd.ByteWidth = pSurface->paMipmapLevels[0].cbSurface;
2862 bd.Usage = D3D11_USAGE_DEFAULT;
2863 bd.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2864 bd.CPUAccessFlags = 0; /// @todo ? D3D11_CPU_ACCESS_READ;
2865 bd.MiscFlags = 0;
2866 bd.StructureByteStride = 0;
2867
2868 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, 0, &pBackendSurface->u.pBuffer);
2869 if (SUCCEEDED(hr))
2870 {
2871 /*
2872 * Success.
2873 */
2874 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2875 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2876 pSurface->pBackendSurface = pBackendSurface;
2877 pSurface->idAssociatedContext = pDXContext->cid;
2878 return VINF_SUCCESS;
2879 }
2880
2881 /* Failure. */
2882 D3D_RELEASE(pBackendSurface->u.pBuffer);
2883 RTMemFree(pBackendSurface);
2884 return VERR_NO_MEMORY;
2885}
2886
2887#if 0
2888static int vmsvga3dBackSurfaceCreateConstantBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface, uint32_t offsetInBytes, uint32_t sizeInBytes)
2889{
2890 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2891 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2892
2893 /* Buffers should be created as such. */
2894 AssertReturn(RT_BOOL(pSurface->f.surfaceFlags & ( SVGA3D_SURFACE_BIND_CONSTANT_BUFFER)), VERR_INVALID_PARAMETER);
2895
2896 if (pSurface->pBackendSurface != NULL)
2897 {
2898 AssertFailed(); /** @todo Should the function not be used like that? */
2899 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
2900 }
2901
2902 PVMSVGA3DMIPMAPLEVEL pMipLevel;
2903 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
2904 AssertRCReturn(rc, rc);
2905
2906 ASSERT_GUEST_RETURN( offsetInBytes < pMipLevel->cbSurface
2907 && sizeInBytes <= pMipLevel->cbSurface - offsetInBytes, VERR_INVALID_PARAMETER);
2908
2909 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2910 rc = dxBackendSurfaceAlloc(&pBackendSurface);
2911 AssertRCReturn(rc, rc);
2912
2913 /* Upload the current data, if any. */
2914 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2915 D3D11_SUBRESOURCE_DATA initialData;
2916 if (pMipLevel->pSurfaceData)
2917 {
2918 initialData.pSysMem = (uint8_t *)pMipLevel->pSurfaceData + offsetInBytes;
2919 initialData.SysMemPitch = pMipLevel->cbSurface;
2920 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
2921
2922 pInitialData = &initialData;
2923
2924 // Log(("%.*Rhxd\n", sizeInBytes, initialData.pSysMem));
2925 }
2926
2927 D3D11_BUFFER_DESC bd;
2928 RT_ZERO(bd);
2929 bd.ByteWidth = sizeInBytes;
2930 bd.Usage = D3D11_USAGE_DYNAMIC;
2931 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
2932 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2933 bd.MiscFlags = 0;
2934 bd.StructureByteStride = 0;
2935
2936 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2937 if (SUCCEEDED(hr))
2938 {
2939 /*
2940 * Success.
2941 */
2942 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2943 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2944 pSurface->pBackendSurface = pBackendSurface;
2945 pSurface->idAssociatedContext = pDXContext->cid;
2946 return VINF_SUCCESS;
2947 }
2948
2949 /* Failure. */
2950 D3D_RELEASE(pBackendSurface->u.pBuffer);
2951 RTMemFree(pBackendSurface);
2952 return VERR_NO_MEMORY;
2953}
2954#endif
2955
2956static int vmsvga3dBackSurfaceCreateResource(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2957{
2958 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2959 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2960
2961 if (pSurface->pBackendSurface != NULL)
2962 {
2963 AssertFailed(); /** @todo Should the function not be used like that? */
2964 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
2965 }
2966
2967 PVMSVGA3DMIPMAPLEVEL pMipLevel;
2968 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
2969 AssertRCReturn(rc, rc);
2970
2971 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2972 rc = dxBackendSurfaceAlloc(&pBackendSurface);
2973 AssertRCReturn(rc, rc);
2974
2975 HRESULT hr;
2976
2977 /*
2978 * Figure out the type of the surface.
2979 */
2980 if (pSurface->format == SVGA3D_BUFFER)
2981 {
2982 /* Upload the current data, if any. */
2983 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2984 D3D11_SUBRESOURCE_DATA initialData;
2985 if (pMipLevel->pSurfaceData)
2986 {
2987 initialData.pSysMem = pMipLevel->pSurfaceData;
2988 initialData.SysMemPitch = pMipLevel->cbSurface;
2989 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
2990
2991 pInitialData = &initialData;
2992 }
2993
2994 D3D11_BUFFER_DESC bd;
2995 RT_ZERO(bd);
2996 bd.ByteWidth = pMipLevel->cbSurface;
2997
2998 if (pSurface->f.surfaceFlags & (SVGA3D_SURFACE_STAGING_UPLOAD | SVGA3D_SURFACE_STAGING_DOWNLOAD))
2999 bd.Usage = D3D11_USAGE_STAGING;
3000 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_HINT_DYNAMIC)
3001 bd.Usage = D3D11_USAGE_DYNAMIC;
3002 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_HINT_STATIC)
3003 bd.Usage = pInitialData ? D3D11_USAGE_IMMUTABLE : D3D11_USAGE_DEFAULT; /* Guest will update later. */
3004 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_HINT_INDIRECT_UPDATE)
3005 bd.Usage = D3D11_USAGE_DEFAULT;
3006
3007 bd.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
3008
3009 if (bd.Usage == D3D11_USAGE_STAGING)
3010 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
3011 else if (bd.Usage == D3D11_USAGE_DYNAMIC)
3012 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
3013
3014 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_DRAWINDIRECT_ARGS)
3015 bd.MiscFlags |= D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS;
3016 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_BIND_RAW_VIEWS)
3017 bd.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
3018 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_BUFFER_STRUCTURED)
3019 bd.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
3020 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_RESOURCE_CLAMP)
3021 bd.MiscFlags |= D3D11_RESOURCE_MISC_RESOURCE_CLAMP;
3022
3023 if (bd.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
3024 {
3025 SVGAOTableSurfaceEntry entrySurface;
3026 rc = vmsvgaR3OTableReadSurface(pThisCC->svga.pSvgaR3State, pSurface->id, &entrySurface);
3027 AssertRCReturn(rc, rc);
3028
3029 bd.StructureByteStride = entrySurface.bufferByteStride;
3030 }
3031
3032 hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
3033 Assert(SUCCEEDED(hr));
3034 if (SUCCEEDED(hr))
3035 {
3036 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
3037 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
3038 }
3039 }
3040 else
3041 {
3042 /** @todo Texture. Currently vmsvga3dBackSurfaceCreateTexture is called for textures. */
3043 AssertFailed();
3044 hr = E_FAIL;
3045 }
3046
3047 if (SUCCEEDED(hr))
3048 {
3049 /*
3050 * Success.
3051 */
3052 pSurface->pBackendSurface = pBackendSurface;
3053 pSurface->idAssociatedContext = pDXContext->cid;
3054 return VINF_SUCCESS;
3055 }
3056
3057 /* Failure. */
3058 RTMemFree(pBackendSurface);
3059 return VERR_NO_MEMORY;
3060}
3061
3062
3063static int dxStagingBufferRealloc(DXDEVICE *pDXDevice, uint32_t cbRequiredSize)
3064{
3065 AssertReturn(cbRequiredSize < SVGA3D_MAX_SURFACE_MEM_SIZE, VERR_INVALID_PARAMETER);
3066
3067 if (RT_LIKELY(cbRequiredSize <= pDXDevice->cbStagingBuffer))
3068 return VINF_SUCCESS;
3069
3070 D3D_RELEASE(pDXDevice->pStagingBuffer);
3071
3072 uint32_t const cbAlloc = RT_ALIGN_32(cbRequiredSize, _64K);
3073
3074 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
3075 D3D11_BUFFER_DESC bd;
3076 RT_ZERO(bd);
3077 bd.ByteWidth = cbAlloc;
3078 bd.Usage = D3D11_USAGE_STAGING;
3079 //bd.BindFlags = 0; /* No bind flags are allowed for staging resources. */
3080 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
3081
3082 int rc = VINF_SUCCESS;
3083 ID3D11Buffer *pBuffer;
3084 HRESULT hr = pDXDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBuffer);
3085 if (SUCCEEDED(hr))
3086 {
3087 pDXDevice->pStagingBuffer = pBuffer;
3088 pDXDevice->cbStagingBuffer = cbAlloc;
3089 }
3090 else
3091 {
3092 pDXDevice->cbStagingBuffer = 0;
3093 rc = VERR_NO_MEMORY;
3094 }
3095
3096 return rc;
3097}
3098
3099
3100static DECLCALLBACK(int) vmsvga3dBackInit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
3101{
3102 RT_NOREF(pDevIns, pThis);
3103
3104 int rc;
3105#ifdef RT_OS_LINUX /** @todo Remove, this is currently needed for loading the X11 library in order to call XInitThreads(). */
3106 rc = glLdrInit(pDevIns);
3107 if (RT_FAILURE(rc))
3108 {
3109 LogRel(("VMSVGA3d: Error loading OpenGL library and resolving necessary functions: %Rrc\n", rc));
3110 return rc;
3111 }
3112#endif
3113
3114 PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)RTMemAllocZ(sizeof(VMSVGA3DSTATE));
3115 AssertReturn(pState, VERR_NO_MEMORY);
3116 pThisCC->svga.p3dState = pState;
3117
3118 PVMSVGA3DBACKEND pBackend = (PVMSVGA3DBACKEND)RTMemAllocZ(sizeof(VMSVGA3DBACKEND));
3119 AssertReturn(pBackend, VERR_NO_MEMORY);
3120 pState->pBackend = pBackend;
3121
3122 rc = RTLdrLoadSystem(VBOX_D3D11_LIBRARY_NAME, /* fNoUnload = */ true, &pBackend->hD3D11);
3123 AssertRC(rc);
3124 if (RT_SUCCESS(rc))
3125 {
3126 rc = RTLdrGetSymbol(pBackend->hD3D11, "D3D11CreateDevice", (void **)&pBackend->pfnD3D11CreateDevice);
3127 AssertRC(rc);
3128 }
3129
3130 if (RT_SUCCESS(rc))
3131 {
3132 /* Failure to load the shader disassembler is ignored. */
3133 int rc2 = RTLdrLoadSystem("D3DCompiler_47", /* fNoUnload = */ true, &pBackend->hD3DCompiler);
3134 if (RT_SUCCESS(rc2))
3135 rc2 = RTLdrGetSymbol(pBackend->hD3DCompiler, "D3DDisassemble", (void **)&pBackend->pfnD3DDisassemble);
3136 Log6Func(("Load D3DDisassemble: %Rrc\n", rc2));
3137 }
3138
3139#if !defined(RT_OS_WINDOWS) || defined(DX_FORCE_SINGLE_DEVICE)
3140 pBackend->fSingleDevice = true;
3141#endif
3142
3143 LogRelMax(1, ("VMSVGA: Single DX device mode: %s\n", pBackend->fSingleDevice ? "enabled" : "disabled"));
3144
3145//DEBUG_BREAKPOINT_TEST();
3146 return rc;
3147}
3148
3149
3150static DECLCALLBACK(int) vmsvga3dBackPowerOn(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
3151{
3152 RT_NOREF(pDevIns, pThis);
3153
3154 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3155 AssertReturn(pState, VERR_INVALID_STATE);
3156
3157 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3158 AssertReturn(pBackend, VERR_INVALID_STATE);
3159
3160 int rc = dxDeviceCreate(pBackend, &pBackend->dxDevice);
3161 if (RT_SUCCESS(rc))
3162 {
3163 IDXGIAdapter *pAdapter = NULL;
3164 HRESULT hr = pBackend->dxDevice.pDxgiFactory->EnumAdapters(0, &pAdapter);
3165 if (SUCCEEDED(hr))
3166 {
3167 DXGI_ADAPTER_DESC desc;
3168 hr = pAdapter->GetDesc(&desc);
3169 if (SUCCEEDED(hr))
3170 {
3171 char sz[RT_ELEMENTS(desc.Description)];
3172 for (unsigned i = 0; i < RT_ELEMENTS(desc.Description); ++i)
3173 sz[i] = (char)desc.Description[i];
3174 LogRelMax(1, ("VMSVGA: Adapter [%s]\n", sz));
3175 }
3176
3177 pAdapter->Release();
3178 }
3179 }
3180 return rc;
3181}
3182
3183
3184static DECLCALLBACK(int) vmsvga3dBackReset(PVGASTATECC pThisCC)
3185{
3186 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3187 AssertReturn(pState, VERR_INVALID_STATE);
3188
3189 /** @todo This is generic code. Must be moved to in DevVGA-SVGA3d.cpp */
3190 /* Destroy all leftover surfaces. */
3191 for (uint32_t i = 0; i < pState->cSurfaces; i++)
3192 {
3193 if (pState->papSurfaces[i]->id != SVGA3D_INVALID_ID)
3194 vmsvga3dSurfaceDestroy(pThisCC, pState->papSurfaces[i]->id);
3195 }
3196
3197 /* Destroy all leftover DX contexts. */
3198 for (uint32_t i = 0; i < pState->cDXContexts; i++)
3199 {
3200 if (pState->papDXContexts[i]->cid != SVGA3D_INVALID_ID)
3201 vmsvga3dDXDestroyContext(pThisCC, pState->papDXContexts[i]->cid);
3202 }
3203
3204 return VINF_SUCCESS;
3205}
3206
3207
3208static DECLCALLBACK(int) vmsvga3dBackTerminate(PVGASTATECC pThisCC)
3209{
3210 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3211 AssertReturn(pState, VERR_INVALID_STATE);
3212
3213 if (pState->pBackend)
3214 {
3215 /* Clean up backends. For example release resources from surfaces. */
3216 vmsvga3dBackReset(pThisCC);
3217
3218 dxDeviceDestroy(pState->pBackend, &pState->pBackend->dxDevice);
3219
3220 RTMemFree(pState->pBackend);
3221 pState->pBackend = NULL;
3222 }
3223
3224 return VINF_SUCCESS;
3225}
3226
3227
3228/** @todo Such structures must be in VBoxVideo3D.h */
3229typedef struct VBOX3DNOTIFYDEFINESCREEN
3230{
3231 VBOX3DNOTIFY Core;
3232 uint32_t cWidth;
3233 uint32_t cHeight;
3234 int32_t xRoot;
3235 int32_t yRoot;
3236 uint32_t fPrimary;
3237 uint32_t cDpi;
3238} VBOX3DNOTIFYDEFINESCREEN;
3239
3240
3241static int vmsvga3dDrvNotifyDefineScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
3242{
3243 VBOX3DNOTIFYDEFINESCREEN n;
3244 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_CREATED;
3245 n.Core.iDisplay = pScreen->idScreen;
3246 n.Core.u32Reserved = 0;
3247 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
3248 RT_ZERO(n.Core.au8Data);
3249 n.cWidth = pScreen->cWidth;
3250 n.cHeight = pScreen->cHeight;
3251 n.xRoot = pScreen->xOrigin;
3252 n.yRoot = pScreen->yOrigin;
3253 n.fPrimary = RT_BOOL(pScreen->fuScreen & SVGA_SCREEN_IS_PRIMARY);
3254 n.cDpi = pScreen->cDpi;
3255
3256 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
3257}
3258
3259
3260static int vmsvga3dDrvNotifyDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
3261{
3262 VBOX3DNOTIFY n;
3263 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_DESTROYED;
3264 n.iDisplay = pScreen->idScreen;
3265 n.u32Reserved = 0;
3266 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
3267 RT_ZERO(n.au8Data);
3268
3269 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
3270}
3271
3272
3273static int vmsvga3dDrvNotifyBindSurface(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, HANDLE hSharedSurface)
3274{
3275 VBOX3DNOTIFY n;
3276 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_BIND_SURFACE;
3277 n.iDisplay = pScreen->idScreen;
3278 n.u32Reserved = 0;
3279 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
3280 *(uint64_t *)&n.au8Data[0] = (uint64_t)hSharedSurface;
3281
3282 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
3283}
3284
3285
3286typedef struct VBOX3DNOTIFYUPDATE
3287{
3288 VBOX3DNOTIFY Core;
3289 uint32_t x;
3290 uint32_t y;
3291 uint32_t w;
3292 uint32_t h;
3293} VBOX3DNOTIFYUPDATE;
3294
3295
3296static int vmsvga3dDrvNotifyUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
3297 uint32_t x, uint32_t y, uint32_t w, uint32_t h)
3298{
3299 VBOX3DNOTIFYUPDATE n;
3300 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_UPDATE_END;
3301 n.Core.iDisplay = pScreen->idScreen;
3302 n.Core.u32Reserved = 0;
3303 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
3304 RT_ZERO(n.Core.au8Data);
3305 n.x = x;
3306 n.y = y;
3307 n.w = w;
3308 n.h = h;
3309
3310 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
3311}
3312
3313static int vmsvga3dHwScreenCreate(PVMSVGA3DSTATE pState, uint32_t cWidth, uint32_t cHeight, VMSVGAHWSCREEN *p)
3314{
3315 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3316
3317 DXDEVICE *pDXDevice = &pBackend->dxDevice;
3318 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
3319
3320 D3D11_TEXTURE2D_DESC td;
3321 RT_ZERO(td);
3322 td.Width = cWidth;
3323 td.Height = cHeight;
3324 td.MipLevels = 1;
3325 td.ArraySize = 1;
3326 td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
3327 td.SampleDesc.Count = 1;
3328 td.SampleDesc.Quality = 0;
3329 td.Usage = D3D11_USAGE_DEFAULT;
3330 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
3331 td.CPUAccessFlags = 0;
3332 td.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
3333
3334 HRESULT hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &p->pTexture);
3335 if (SUCCEEDED(hr))
3336 {
3337 /* Get the shared handle. */
3338 hr = p->pTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&p->pDxgiResource);
3339 if (SUCCEEDED(hr))
3340 {
3341 hr = p->pDxgiResource->GetSharedHandle(&p->SharedHandle);
3342 if (SUCCEEDED(hr))
3343 hr = p->pTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&p->pDXGIKeyedMutex);
3344 }
3345 }
3346
3347 if (SUCCEEDED(hr))
3348 return VINF_SUCCESS;
3349
3350 AssertFailed();
3351 return VERR_NOT_SUPPORTED;
3352}
3353
3354
3355static void vmsvga3dHwScreenDestroy(PVMSVGA3DSTATE pState, VMSVGAHWSCREEN *p)
3356{
3357 RT_NOREF(pState);
3358 D3D_RELEASE(p->pDXGIKeyedMutex);
3359 D3D_RELEASE(p->pDxgiResource);
3360 D3D_RELEASE(p->pTexture);
3361 p->SharedHandle = 0;
3362 p->sidScreenTarget = SVGA_ID_INVALID;
3363}
3364
3365
3366static DECLCALLBACK(int) vmsvga3dBackDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
3367{
3368 RT_NOREF(pThis, pThisCC, pScreen);
3369
3370 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: screen %u\n", pScreen->idScreen));
3371
3372 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3373 AssertReturn(pState, VERR_INVALID_STATE);
3374
3375 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3376 AssertReturn(pBackend, VERR_INVALID_STATE);
3377
3378 Assert(pScreen->pHwScreen == NULL);
3379
3380 VMSVGAHWSCREEN *p = (VMSVGAHWSCREEN *)RTMemAllocZ(sizeof(VMSVGAHWSCREEN));
3381 AssertPtrReturn(p, VERR_NO_MEMORY);
3382
3383 p->sidScreenTarget = SVGA_ID_INVALID;
3384
3385 int rc = vmsvga3dDrvNotifyDefineScreen(pThisCC, pScreen);
3386 if (RT_SUCCESS(rc))
3387 {
3388 /* The frontend supports the screen. Create the actual resource. */
3389 rc = vmsvga3dHwScreenCreate(pState, pScreen->cWidth, pScreen->cHeight, p);
3390 if (RT_SUCCESS(rc))
3391 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: created\n"));
3392 }
3393
3394 if (RT_SUCCESS(rc))
3395 {
3396 LogRel(("VMSVGA: Using HW accelerated screen %u\n", pScreen->idScreen));
3397 pScreen->pHwScreen = p;
3398 }
3399 else
3400 {
3401 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: %Rrc\n", rc));
3402 vmsvga3dHwScreenDestroy(pState, p);
3403 RTMemFree(p);
3404 }
3405
3406 return rc;
3407}
3408
3409
3410static DECLCALLBACK(int) vmsvga3dBackDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
3411{
3412 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3413 AssertReturn(pState, VERR_INVALID_STATE);
3414
3415 vmsvga3dDrvNotifyDestroyScreen(pThisCC, pScreen);
3416
3417 if (pScreen->pHwScreen)
3418 {
3419 vmsvga3dHwScreenDestroy(pState, pScreen->pHwScreen);
3420 RTMemFree(pScreen->pHwScreen);
3421 pScreen->pHwScreen = NULL;
3422 }
3423
3424 return VINF_SUCCESS;
3425}
3426
3427
3428static DECLCALLBACK(int) vmsvga3dBackSurfaceBlitToScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
3429 SVGASignedRect destRect, SVGA3dSurfaceImageId srcImage,
3430 SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *paRects)
3431{
3432 RT_NOREF(pThisCC, pScreen, destRect, srcImage, srcRect, cRects, paRects);
3433
3434 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3435 AssertReturn(pState, VERR_INVALID_STATE);
3436
3437 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3438 AssertReturn(pBackend, VERR_INVALID_STATE);
3439
3440 VMSVGAHWSCREEN *p = pScreen->pHwScreen;
3441 AssertReturn(p, VERR_NOT_SUPPORTED);
3442
3443 PVMSVGA3DSURFACE pSurface;
3444 int rc = vmsvga3dSurfaceFromSid(pState, srcImage.sid, &pSurface);
3445 AssertRCReturn(rc, rc);
3446
3447 /** @todo Implement. */
3448 AssertFailed();
3449 return VERR_NOT_IMPLEMENTED;
3450}
3451
3452
3453static DECLCALLBACK(int) vmsvga3dBackSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox,
3454 VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap)
3455{
3456 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3457 AssertReturn(pState, VERR_INVALID_STATE);
3458
3459 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3460 AssertReturn(pBackend, VERR_INVALID_STATE);
3461
3462 PVMSVGA3DSURFACE pSurface;
3463 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
3464 AssertRCReturn(rc, rc);
3465
3466 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3467 AssertPtrReturn(pBackendSurface, VERR_INVALID_STATE);
3468
3469 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3470 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
3471 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3472
3473 /* A surface is always mapped by the DX context which has created the surface. */
3474 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
3475 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
3476
3477 SVGA3dBox clipBox;
3478 if (pBox)
3479 {
3480 clipBox = *pBox;
3481 vmsvgaR3ClipBox(&pMipLevel->mipmapSize, &clipBox);
3482 ASSERT_GUEST_RETURN(clipBox.w && clipBox.h && clipBox.d, VERR_INVALID_PARAMETER);
3483 }
3484 else
3485 {
3486 clipBox.x = 0;
3487 clipBox.y = 0;
3488 clipBox.z = 0;
3489 clipBox.w = pMipLevel->mipmapSize.width;
3490 clipBox.h = pMipLevel->mipmapSize.height;
3491 clipBox.d = pMipLevel->mipmapSize.depth;
3492 }
3493
3494 D3D11_MAP d3d11MapType;
3495 switch (enmMapType)
3496 {
3497 case VMSVGA3D_SURFACE_MAP_READ: d3d11MapType = D3D11_MAP_READ; break;
3498 case VMSVGA3D_SURFACE_MAP_WRITE: d3d11MapType = D3D11_MAP_WRITE; break;
3499 case VMSVGA3D_SURFACE_MAP_READ_WRITE: d3d11MapType = D3D11_MAP_READ_WRITE; break;
3500 case VMSVGA3D_SURFACE_MAP_WRITE_DISCARD: d3d11MapType = D3D11_MAP_WRITE_DISCARD; break;
3501 default:
3502 AssertFailed();
3503 return VERR_INVALID_PARAMETER;
3504 }
3505
3506 D3D11_MAPPED_SUBRESOURCE mappedResource;
3507 RT_ZERO(mappedResource);
3508
3509 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
3510 {
3511 Assert(pImage->face == 0 && pImage->mipmap == 0);
3512
3513 /* Wait for the surface to finish drawing. */
3514 dxSurfaceWait(pState, pSurface, pSurface->idAssociatedContext);
3515
3516 ID3D11Texture2D *pMappedTexture;
3517 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3518 {
3519 pMappedTexture = pBackendSurface->staging.pTexture2D;
3520
3521 /* Copy the texture content to the staging texture. */
3522 pDevice->pImmediateContext->CopyResource(pBackendSurface->staging.pTexture2D, pBackendSurface->u.pTexture2D);
3523 }
3524 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3525 pMappedTexture = pBackendSurface->staging.pTexture2D;
3526 else
3527 pMappedTexture = pBackendSurface->dynamic.pTexture2D;
3528
3529 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
3530 HRESULT hr = pDevice->pImmediateContext->Map(pMappedTexture, Subresource,
3531 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3532 if (SUCCEEDED(hr))
3533 vmsvga3dSurfaceMapInit(pMap, enmMapType, &clipBox, pSurface,
3534 mappedResource.pData, mappedResource.RowPitch, mappedResource.DepthPitch);
3535 else
3536 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3537 }
3538 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
3539 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
3540 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
3541 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3542 {
3543 dxSurfaceWait(pState, pSurface, pSurface->idAssociatedContext);
3544
3545 ID3D11Resource *pMappedResource;
3546 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3547 {
3548 pMappedResource = pBackendSurface->staging.pResource;
3549
3550 /* Copy the texture content to the staging texture.
3551 * The requested miplevel of the texture is copied to the miplevel 0 of the staging texture,
3552 * because the staging (and dynamic) structures do not have miplevels.
3553 * Always copy entire miplevel so all Dst are zero and pSrcBox is NULL, as D3D11 requires.
3554 */
3555 ID3D11Resource *pDstResource = pMappedResource;
3556 UINT DstSubresource = 0;
3557 UINT DstX = 0;
3558 UINT DstY = 0;
3559 UINT DstZ = 0;
3560 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3561 UINT SrcSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
3562 D3D11_BOX *pSrcBox = NULL;
3563 //D3D11_BOX SrcBox;
3564 //SrcBox.left = 0;
3565 //SrcBox.top = 0;
3566 //SrcBox.front = 0;
3567 //SrcBox.right = pMipLevel->mipmapSize.width;
3568 //SrcBox.bottom = pMipLevel->mipmapSize.height;
3569 //SrcBox.back = pMipLevel->mipmapSize.depth;
3570 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3571 pSrcResource, SrcSubresource, pSrcBox);
3572 }
3573 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3574 pMappedResource = pBackendSurface->staging.pResource;
3575 else
3576 pMappedResource = pBackendSurface->dynamic.pResource;
3577
3578 UINT const Subresource = 0; /* Dynamic or staging textures have one subresource. */
3579 HRESULT hr = pDevice->pImmediateContext->Map(pMappedResource, Subresource,
3580 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3581 if (SUCCEEDED(hr))
3582 vmsvga3dSurfaceMapInit(pMap, enmMapType, &clipBox, pSurface,
3583 mappedResource.pData, mappedResource.RowPitch, mappedResource.DepthPitch);
3584 else
3585 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3586 }
3587 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
3588 {
3589 /* Map the staging buffer. */
3590 rc = dxStagingBufferRealloc(pDevice, pMipLevel->cbSurface);
3591 if (RT_SUCCESS(rc))
3592 {
3593 /* The staging buffer does not allow D3D11_MAP_WRITE_DISCARD, so replace it. */
3594 if (d3d11MapType == D3D11_MAP_WRITE_DISCARD)
3595 d3d11MapType = D3D11_MAP_WRITE;
3596
3597 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3598 {
3599 /* Copy from the buffer to the staging buffer. */
3600 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
3601 UINT DstSubresource = 0;
3602 UINT DstX = clipBox.x;
3603 UINT DstY = clipBox.y;
3604 UINT DstZ = clipBox.z;
3605 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3606 UINT SrcSubresource = 0;
3607 D3D11_BOX SrcBox;
3608 SrcBox.left = clipBox.x;
3609 SrcBox.top = clipBox.y;
3610 SrcBox.front = clipBox.z;
3611 SrcBox.right = clipBox.w;
3612 SrcBox.bottom = clipBox.h;
3613 SrcBox.back = clipBox.d;
3614 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3615 pSrcResource, SrcSubresource, &SrcBox);
3616 }
3617
3618 UINT const Subresource = 0; /* Buffers have only one subresource. */
3619 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
3620 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3621 if (SUCCEEDED(hr))
3622 vmsvga3dSurfaceMapInit(pMap, enmMapType, &clipBox, pSurface,
3623 mappedResource.pData, mappedResource.RowPitch, mappedResource.DepthPitch);
3624 else
3625 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3626 }
3627 }
3628 else
3629 {
3630 // UINT D3D11CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT MipLevels);
3631 /** @todo Implement. */
3632 AssertFailed();
3633 rc = VERR_NOT_IMPLEMENTED;
3634 }
3635
3636 return rc;
3637}
3638
3639
3640static DECLCALLBACK(int) vmsvga3dBackSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten)
3641{
3642 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3643 AssertReturn(pState, VERR_INVALID_STATE);
3644
3645 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3646 AssertReturn(pBackend, VERR_INVALID_STATE);
3647
3648 PVMSVGA3DSURFACE pSurface;
3649 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
3650 AssertRCReturn(rc, rc);
3651
3652 /* The called should not use the function for system memory surfaces. */
3653 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3654 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
3655
3656 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3657 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
3658 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3659
3660 /* A surface is always mapped by the DX context which has created the surface. */
3661 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
3662 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
3663
3664 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
3665 {
3666 ID3D11Texture2D *pMappedTexture;
3667 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3668 pMappedTexture = pBackendSurface->staging.pTexture2D;
3669 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3670 pMappedTexture = pBackendSurface->staging.pTexture2D;
3671 else
3672 pMappedTexture = pBackendSurface->dynamic.pTexture2D;
3673
3674 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
3675 pDevice->pImmediateContext->Unmap(pMappedTexture, Subresource);
3676
3677 if ( fWritten
3678 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3679 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3680 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3681 {
3682 ID3D11Resource *pDstResource = pBackendSurface->u.pTexture2D;
3683 UINT DstSubresource = Subresource;
3684 UINT DstX = pMap->box.x;
3685 UINT DstY = pMap->box.y;
3686 UINT DstZ = pMap->box.z;
3687 ID3D11Resource *pSrcResource = pMappedTexture;
3688 UINT SrcSubresource = Subresource;
3689 D3D11_BOX SrcBox;
3690 SrcBox.left = pMap->box.x;
3691 SrcBox.top = pMap->box.y;
3692 SrcBox.front = pMap->box.z;
3693 SrcBox.right = pMap->box.x + pMap->box.w;
3694 SrcBox.bottom = pMap->box.y + pMap->box.h;
3695 SrcBox.back = pMap->box.z + pMap->box.d;
3696
3697 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3698 pSrcResource, SrcSubresource, &SrcBox);
3699
3700 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
3701 }
3702 }
3703 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
3704 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
3705 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
3706 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3707 {
3708 ID3D11Resource *pMappedResource;
3709 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3710 pMappedResource = pBackendSurface->staging.pResource;
3711 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3712 pMappedResource = pBackendSurface->staging.pResource;
3713 else
3714 pMappedResource = pBackendSurface->dynamic.pResource;
3715
3716 UINT const Subresource = 0; /* Staging or dynamic textures have one subresource. */
3717 pDevice->pImmediateContext->Unmap(pMappedResource, Subresource);
3718
3719 if ( fWritten
3720 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3721 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3722 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3723 {
3724 /* If entire resource must be copied then use pSrcBox = NULL and dst point (0,0,0)
3725 * Because DX11 insists on this for some resource types, for example DEPTH_STENCIL resources.
3726 */
3727 uint32_t const cWidth0 = pSurface->paMipmapLevels[0].mipmapSize.width;
3728 uint32_t const cHeight0 = pSurface->paMipmapLevels[0].mipmapSize.height;
3729 uint32_t const cDepth0 = pSurface->paMipmapLevels[0].mipmapSize.depth;
3730 /** @todo Entire subresource is always mapped. So find a way to copy it back, important for DEPTH_STENCIL mipmaps. */
3731 bool const fEntireResource = pMap->box.x == 0 && pMap->box.y == 0 && pMap->box.z == 0
3732 && pMap->box.w == cWidth0 && pMap->box.h == cHeight0 && pMap->box.d == cDepth0;
3733
3734 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
3735 UINT DstSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
3736 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
3737 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
3738 UINT DstZ = pMap->box.z;
3739 ID3D11Resource *pSrcResource = pMappedResource;
3740 UINT SrcSubresource = Subresource;
3741 D3D11_BOX *pSrcBox;
3742 D3D11_BOX SrcBox;
3743 if (fEntireResource)
3744 pSrcBox = NULL;
3745 else
3746 {
3747 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
3748 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
3749
3750 SrcBox.left = DstX;
3751 SrcBox.top = DstY;
3752 SrcBox.front = DstZ;
3753 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
3754 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
3755 SrcBox.back = DstZ + pMap->box.d;
3756 pSrcBox = &SrcBox;
3757 }
3758
3759 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3760 pSrcResource, SrcSubresource, pSrcBox);
3761
3762 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
3763 }
3764 }
3765 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
3766 {
3767 /* Unmap the staging buffer. */
3768 UINT const Subresource = 0; /* Buffers have only one subresource. */
3769 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
3770
3771 /* Copy from the staging buffer to the actual buffer */
3772 if ( fWritten
3773 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3774 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3775 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3776 {
3777 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
3778 UINT DstSubresource = 0;
3779 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
3780 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
3781 UINT DstZ = pMap->box.z;
3782 ID3D11Resource *pSrcResource = pDevice->pStagingBuffer;
3783 UINT SrcSubresource = 0;
3784 D3D11_BOX SrcBox;
3785
3786 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
3787 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
3788
3789 SrcBox.left = DstX;
3790 SrcBox.top = DstY;
3791 SrcBox.front = DstZ;
3792 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
3793 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
3794 SrcBox.back = DstZ + pMap->box.d;
3795
3796 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3797 pSrcResource, SrcSubresource, &SrcBox);
3798 }
3799 }
3800 else
3801 {
3802 AssertFailed();
3803 rc = VERR_NOT_IMPLEMENTED;
3804 }
3805
3806 return rc;
3807}
3808
3809
3810static DECLCALLBACK(int) vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid)
3811{
3812 int rc = VINF_SUCCESS;
3813
3814 PVMSVGA3DSURFACE pSurface;
3815 if (sid != SVGA_ID_INVALID)
3816 {
3817 /* Create the surface if does not yet exist. */
3818 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3819 AssertReturn(pState, VERR_INVALID_STATE);
3820
3821 rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
3822 AssertRCReturn(rc, rc);
3823
3824 if (!VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
3825 {
3826 /* Create the actual texture. */
3827 rc = vmsvga3dBackSurfaceCreateScreenTarget(pThisCC, pSurface);
3828 AssertRCReturn(rc, rc);
3829 }
3830 }
3831 else
3832 pSurface = NULL;
3833
3834 /* Notify the HW accelerated screen if it is used. */
3835 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
3836 if (!pHwScreen)
3837 return VINF_SUCCESS;
3838
3839 /* Same surface -> do nothing. */
3840 if (pHwScreen->sidScreenTarget == sid)
3841 return VINF_SUCCESS;
3842
3843 if (sid != SVGA_ID_INVALID)
3844 {
3845 AssertReturn( pSurface->pBackendSurface
3846 && pSurface->pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
3847
3848 HANDLE const hSharedSurface = pHwScreen->SharedHandle;
3849 rc = vmsvga3dDrvNotifyBindSurface(pThisCC, pScreen, hSharedSurface);
3850 }
3851
3852 if (RT_SUCCESS(rc))
3853 {
3854 pHwScreen->sidScreenTarget = sid;
3855 }
3856
3857 return rc;
3858}
3859
3860
3861static DECLCALLBACK(int) vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect)
3862{
3863 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
3864 AssertReturn(pHwScreen, VERR_NOT_SUPPORTED);
3865
3866 if (pHwScreen->sidScreenTarget == SVGA_ID_INVALID)
3867 return VINF_SUCCESS; /* No surface bound. */
3868
3869 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3870 AssertReturn(pState, VERR_INVALID_STATE);
3871
3872 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3873 AssertReturn(pBackend, VERR_INVALID_STATE);
3874
3875 PVMSVGA3DSURFACE pSurface;
3876 int rc = vmsvga3dSurfaceFromSid(pState, pHwScreen->sidScreenTarget, &pSurface);
3877 AssertRCReturn(rc, rc);
3878
3879 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3880 AssertReturn(pBackendSurface && pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
3881
3882 SVGA3dRect boundRect;
3883 boundRect.x = 0;
3884 boundRect.y = 0;
3885 boundRect.w = pSurface->paMipmapLevels[0].mipmapSize.width;
3886 boundRect.h = pSurface->paMipmapLevels[0].mipmapSize.height;
3887 SVGA3dRect clipRect = *pRect;
3888 vmsvgaR3Clip3dRect(&boundRect, &clipRect);
3889 ASSERT_GUEST_RETURN(clipRect.w && clipRect.h, VERR_INVALID_PARAMETER);
3890
3891 /* Wait for the surface to finish drawing. */
3892 dxSurfaceWait(pState, pSurface, DX_CID_BACKEND);
3893
3894 /* Copy the screen texture to the shared surface. */
3895 DWORD result = pHwScreen->pDXGIKeyedMutex->AcquireSync(0, 10000);
3896 if (result == S_OK)
3897 {
3898 pBackend->dxDevice.pImmediateContext->CopyResource(pHwScreen->pTexture, pBackendSurface->u.pTexture2D);
3899
3900 dxDeviceFlush(&pBackend->dxDevice);
3901
3902 result = pHwScreen->pDXGIKeyedMutex->ReleaseSync(1);
3903 }
3904 else
3905 AssertFailed();
3906
3907 rc = vmsvga3dDrvNotifyUpdate(pThisCC, pScreen, pRect->x, pRect->y, pRect->w, pRect->h);
3908 return rc;
3909}
3910
3911
3912/*
3913 *
3914 * 3D interface.
3915 *
3916 */
3917
3918static DECLCALLBACK(int) vmsvga3dBackQueryCaps(PVGASTATECC pThisCC, SVGA3dDevCapIndex idx3dCaps, uint32_t *pu32Val)
3919{
3920 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3921 AssertReturn(pState, VERR_INVALID_STATE);
3922
3923 int rc = VINF_SUCCESS;
3924
3925 *pu32Val = 0;
3926
3927 if (idx3dCaps > SVGA3D_DEVCAP_MAX)
3928 {
3929 LogRelMax(16, ("VMSVGA: unsupported SVGA3D_DEVCAP %d\n", idx3dCaps));
3930 return VERR_NOT_SUPPORTED;
3931 }
3932
3933 D3D_FEATURE_LEVEL const FeatureLevel = pState->pBackend->dxDevice.FeatureLevel;
3934
3935 /* Most values are taken from:
3936 * https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro
3937 *
3938 * Shader values are from
3939 * https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-models
3940 */
3941
3942 switch (idx3dCaps)
3943 {
3944 case SVGA3D_DEVCAP_3D:
3945 *pu32Val = 1;
3946 break;
3947
3948 case SVGA3D_DEVCAP_MAX_LIGHTS:
3949 *pu32Val = SVGA3D_NUM_LIGHTS; /* VGPU9. Not applicable to DX11. */
3950 break;
3951
3952 case SVGA3D_DEVCAP_MAX_TEXTURES:
3953 *pu32Val = SVGA3D_NUM_TEXTURE_UNITS; /* VGPU9. Not applicable to DX11. */
3954 break;
3955
3956 case SVGA3D_DEVCAP_MAX_CLIP_PLANES:
3957 *pu32Val = SVGA3D_NUM_CLIPPLANES;
3958 break;
3959
3960 case SVGA3D_DEVCAP_VERTEX_SHADER_VERSION:
3961 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3962 *pu32Val = SVGA3DVSVERSION_40;
3963 else
3964 *pu32Val = SVGA3DVSVERSION_30;
3965 break;
3966
3967 case SVGA3D_DEVCAP_VERTEX_SHADER:
3968 *pu32Val = 1;
3969 break;
3970
3971 case SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION:
3972 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3973 *pu32Val = SVGA3DPSVERSION_40;
3974 else
3975 *pu32Val = SVGA3DPSVERSION_30;
3976 break;
3977
3978 case SVGA3D_DEVCAP_FRAGMENT_SHADER:
3979 *pu32Val = 1;
3980 break;
3981
3982 case SVGA3D_DEVCAP_MAX_RENDER_TARGETS:
3983 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3984 *pu32Val = 8;
3985 else
3986 *pu32Val = 4;
3987 break;
3988
3989 case SVGA3D_DEVCAP_S23E8_TEXTURES:
3990 case SVGA3D_DEVCAP_S10E5_TEXTURES:
3991 /* Must be obsolete by now; surface format caps specify the same thing. */
3992 break;
3993
3994 case SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND:
3995 /* Obsolete */
3996 break;
3997
3998 /*
3999 * 2. The BUFFER_FORMAT capabilities are deprecated, and they always
4000 * return TRUE. Even on physical hardware that does not support
4001 * these formats natively, the SVGA3D device will provide an emulation
4002 * which should be invisible to the guest OS.
4003 */
4004 case SVGA3D_DEVCAP_D16_BUFFER_FORMAT:
4005 case SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT:
4006 case SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT:
4007 *pu32Val = 1;
4008 break;
4009
4010 case SVGA3D_DEVCAP_QUERY_TYPES:
4011 /* Obsolete */
4012 break;
4013
4014 case SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING:
4015 /* Obsolete */
4016 break;
4017
4018 case SVGA3D_DEVCAP_MAX_POINT_SIZE:
4019 AssertCompile(sizeof(uint32_t) == sizeof(float));
4020 *(float *)pu32Val = 256.0f; /* VGPU9. Not applicable to DX11. */
4021 break;
4022
4023 case SVGA3D_DEVCAP_MAX_SHADER_TEXTURES:
4024 /* Obsolete */
4025 break;
4026
4027 case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
4028 case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
4029 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
4030 *pu32Val = 16384;
4031 else if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4032 *pu32Val = 8192;
4033 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
4034 *pu32Val = 4096;
4035 else
4036 *pu32Val = 2048;
4037 break;
4038
4039 case SVGA3D_DEVCAP_MAX_VOLUME_EXTENT:
4040 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4041 *pu32Val = 2048;
4042 else
4043 *pu32Val = 256;
4044 break;
4045
4046 case SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT:
4047 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
4048 *pu32Val = 16384;
4049 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
4050 *pu32Val = 8192;
4051 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
4052 *pu32Val = 2048;
4053 else
4054 *pu32Val = 128;
4055 break;
4056
4057 case SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO:
4058 /* Obsolete */
4059 break;
4060
4061 case SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY:
4062 if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
4063 *pu32Val = D3D11_REQ_MAXANISOTROPY;
4064 else
4065 *pu32Val = 2; // D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
4066 break;
4067
4068 case SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT:
4069 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4070 *pu32Val = UINT32_MAX;
4071 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
4072 *pu32Val = 1048575; // D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
4073 else
4074 *pu32Val = 65535; // D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
4075 break;
4076
4077 case SVGA3D_DEVCAP_MAX_VERTEX_INDEX:
4078 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4079 *pu32Val = UINT32_MAX;
4080 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
4081 *pu32Val = 1048575;
4082 else
4083 *pu32Val = 65534;
4084 break;
4085
4086 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS:
4087 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4088 *pu32Val = UINT32_MAX;
4089 else
4090 *pu32Val = 512;
4091 break;
4092
4093 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS:
4094 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4095 *pu32Val = UINT32_MAX;
4096 else
4097 *pu32Val = 512;
4098 break;
4099
4100 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS:
4101 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4102 *pu32Val = 4096;
4103 else
4104 *pu32Val = 32;
4105 break;
4106
4107 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS:
4108 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4109 *pu32Val = 4096;
4110 else
4111 *pu32Val = 32;
4112 break;
4113
4114 case SVGA3D_DEVCAP_TEXTURE_OPS:
4115 /* Obsolete */
4116 break;
4117
4118 case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
4119 case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
4120 case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
4121 case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
4122 case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
4123 case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
4124 case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
4125 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16:
4126 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8:
4127 case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8:
4128 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8:
4129 case SVGA3D_DEVCAP_SURFACEFMT_Z_D16:
4130 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8:
4131 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8:
4132 case SVGA3D_DEVCAP_SURFACEFMT_DXT1:
4133 case SVGA3D_DEVCAP_SURFACEFMT_DXT2:
4134 case SVGA3D_DEVCAP_SURFACEFMT_DXT3:
4135 case SVGA3D_DEVCAP_SURFACEFMT_DXT4:
4136 case SVGA3D_DEVCAP_SURFACEFMT_DXT5:
4137 case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8:
4138 case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10:
4139 case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8:
4140 case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8:
4141 case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8:
4142 case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5:
4143 case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8:
4144 case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5:
4145 case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8:
4146 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5:
4147 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8:
4148 case SVGA3D_DEVCAP_SURFACEFMT_V16U16:
4149 case SVGA3D_DEVCAP_SURFACEFMT_G16R16:
4150 case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16:
4151 case SVGA3D_DEVCAP_SURFACEFMT_UYVY:
4152 case SVGA3D_DEVCAP_SURFACEFMT_YUY2:
4153 case SVGA3D_DEVCAP_SURFACEFMT_NV12:
4154 case SVGA3D_DEVCAP_DEAD10: /* SVGA3D_DEVCAP_SURFACEFMT_AYUV */
4155 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16:
4156 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24:
4157 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT:
4158 case SVGA3D_DEVCAP_SURFACEFMT_ATI1:
4159 case SVGA3D_DEVCAP_SURFACEFMT_ATI2:
4160 case SVGA3D_DEVCAP_SURFACEFMT_YV12:
4161 {
4162 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapSurfaceFmt2Format(idx3dCaps);
4163 rc = vmsvgaDXCheckFormatSupportPreDX(pState, enmFormat, pu32Val);
4164 break;
4165 }
4166
4167 case SVGA3D_DEVCAP_MISSING62:
4168 /* Unused */
4169 break;
4170
4171 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES:
4172 /* Obsolete */
4173 break;
4174
4175 case SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS:
4176 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4177 *pu32Val = 8;
4178 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
4179 *pu32Val = 4; // D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT
4180 else
4181 *pu32Val = 1; // D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT
4182 break;
4183
4184 case SVGA3D_DEVCAP_DEAD4: /* SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES */
4185 case SVGA3D_DEVCAP_DEAD5: /* SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES */
4186 *pu32Val = (1 << (2-1)) | (1 << (4-1)) | (1 << (8-1)); /* 2x, 4x, 8x */
4187 break;
4188
4189 case SVGA3D_DEVCAP_DEAD7: /* SVGA3D_DEVCAP_ALPHATOCOVERAGE */
4190 /* Obsolete */
4191 break;
4192
4193 case SVGA3D_DEVCAP_DEAD6: /* SVGA3D_DEVCAP_SUPERSAMPLE */
4194 /* Obsolete */
4195 break;
4196
4197 case SVGA3D_DEVCAP_AUTOGENMIPMAPS:
4198 *pu32Val = 1;
4199 break;
4200
4201 case SVGA3D_DEVCAP_MAX_CONTEXT_IDS:
4202 *pu32Val = SVGA3D_MAX_CONTEXT_IDS;
4203 break;
4204
4205 case SVGA3D_DEVCAP_MAX_SURFACE_IDS:
4206 *pu32Val = SVGA3D_MAX_SURFACE_IDS;
4207 break;
4208
4209 case SVGA3D_DEVCAP_DEAD1:
4210 /* Obsolete */
4211 break;
4212
4213 case SVGA3D_DEVCAP_DEAD8: /* SVGA3D_DEVCAP_VIDEO_DECODE */
4214 /* Obsolete */
4215 break;
4216
4217 case SVGA3D_DEVCAP_DEAD9: /* SVGA3D_DEVCAP_VIDEO_PROCESS */
4218 /* Obsolete */
4219 break;
4220
4221 case SVGA3D_DEVCAP_LINE_AA:
4222 *pu32Val = 1;
4223 break;
4224
4225 case SVGA3D_DEVCAP_LINE_STIPPLE:
4226 *pu32Val = 0; /* DX11 does not seem to support this directly. */
4227 break;
4228
4229 case SVGA3D_DEVCAP_MAX_LINE_WIDTH:
4230 AssertCompile(sizeof(uint32_t) == sizeof(float));
4231 *(float *)pu32Val = 1.0f;
4232 break;
4233
4234 case SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH:
4235 AssertCompile(sizeof(uint32_t) == sizeof(float));
4236 *(float *)pu32Val = 1.0f;
4237 break;
4238
4239 case SVGA3D_DEVCAP_DEAD3: /* Old SVGA3D_DEVCAP_LOGICOPS */
4240 /* Deprecated. */
4241 AssertCompile(SVGA3D_DEVCAP_DEAD3 == 92); /* Newer SVGA headers redefine this. */
4242 break;
4243
4244 case SVGA3D_DEVCAP_TS_COLOR_KEY:
4245 *pu32Val = 0; /* DX11 does not seem to support this directly. */
4246 break;
4247
4248 case SVGA3D_DEVCAP_DEAD2:
4249 break;
4250
4251 case SVGA3D_DEVCAP_DXCONTEXT:
4252 *pu32Val = 1;
4253 break;
4254
4255 case SVGA3D_DEVCAP_DEAD11: /* SVGA3D_DEVCAP_MAX_TEXTURE_ARRAY_SIZE */
4256 *pu32Val = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
4257 break;
4258
4259 case SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS:
4260 *pu32Val = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT;
4261 break;
4262
4263 case SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS:
4264 *pu32Val = D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT;
4265 break;
4266
4267 case SVGA3D_DEVCAP_DX_PROVOKING_VERTEX:
4268 *pu32Val = 0; /* boolean */
4269 break;
4270
4271 case SVGA3D_DEVCAP_DXFMT_X8R8G8B8:
4272 case SVGA3D_DEVCAP_DXFMT_A8R8G8B8:
4273 case SVGA3D_DEVCAP_DXFMT_R5G6B5:
4274 case SVGA3D_DEVCAP_DXFMT_X1R5G5B5:
4275 case SVGA3D_DEVCAP_DXFMT_A1R5G5B5:
4276 case SVGA3D_DEVCAP_DXFMT_A4R4G4B4:
4277 case SVGA3D_DEVCAP_DXFMT_Z_D32:
4278 case SVGA3D_DEVCAP_DXFMT_Z_D16:
4279 case SVGA3D_DEVCAP_DXFMT_Z_D24S8:
4280 case SVGA3D_DEVCAP_DXFMT_Z_D15S1:
4281 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8:
4282 case SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4:
4283 case SVGA3D_DEVCAP_DXFMT_LUMINANCE16:
4284 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8:
4285 case SVGA3D_DEVCAP_DXFMT_DXT1:
4286 case SVGA3D_DEVCAP_DXFMT_DXT2:
4287 case SVGA3D_DEVCAP_DXFMT_DXT3:
4288 case SVGA3D_DEVCAP_DXFMT_DXT4:
4289 case SVGA3D_DEVCAP_DXFMT_DXT5:
4290 case SVGA3D_DEVCAP_DXFMT_BUMPU8V8:
4291 case SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5:
4292 case SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8:
4293 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1:
4294 case SVGA3D_DEVCAP_DXFMT_ARGB_S10E5:
4295 case SVGA3D_DEVCAP_DXFMT_ARGB_S23E8:
4296 case SVGA3D_DEVCAP_DXFMT_A2R10G10B10:
4297 case SVGA3D_DEVCAP_DXFMT_V8U8:
4298 case SVGA3D_DEVCAP_DXFMT_Q8W8V8U8:
4299 case SVGA3D_DEVCAP_DXFMT_CxV8U8:
4300 case SVGA3D_DEVCAP_DXFMT_X8L8V8U8:
4301 case SVGA3D_DEVCAP_DXFMT_A2W10V10U10:
4302 case SVGA3D_DEVCAP_DXFMT_ALPHA8:
4303 case SVGA3D_DEVCAP_DXFMT_R_S10E5:
4304 case SVGA3D_DEVCAP_DXFMT_R_S23E8:
4305 case SVGA3D_DEVCAP_DXFMT_RG_S10E5:
4306 case SVGA3D_DEVCAP_DXFMT_RG_S23E8:
4307 case SVGA3D_DEVCAP_DXFMT_BUFFER:
4308 case SVGA3D_DEVCAP_DXFMT_Z_D24X8:
4309 case SVGA3D_DEVCAP_DXFMT_V16U16:
4310 case SVGA3D_DEVCAP_DXFMT_G16R16:
4311 case SVGA3D_DEVCAP_DXFMT_A16B16G16R16:
4312 case SVGA3D_DEVCAP_DXFMT_UYVY:
4313 case SVGA3D_DEVCAP_DXFMT_YUY2:
4314 case SVGA3D_DEVCAP_DXFMT_NV12:
4315 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2: /* SVGA3D_DEVCAP_DXFMT_AYUV */
4316 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS:
4317 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT:
4318 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT:
4319 case SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS:
4320 case SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT:
4321 case SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT:
4322 case SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT:
4323 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS:
4324 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT:
4325 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM:
4326 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT:
4327 case SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS:
4328 case SVGA3D_DEVCAP_DXFMT_R32G32_UINT:
4329 case SVGA3D_DEVCAP_DXFMT_R32G32_SINT:
4330 case SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS:
4331 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT:
4332 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24:
4333 case SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT:
4334 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS:
4335 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT:
4336 case SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT:
4337 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS:
4338 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM:
4339 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB:
4340 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT:
4341 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT:
4342 case SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS:
4343 case SVGA3D_DEVCAP_DXFMT_R16G16_UINT:
4344 case SVGA3D_DEVCAP_DXFMT_R16G16_SINT:
4345 case SVGA3D_DEVCAP_DXFMT_R32_TYPELESS:
4346 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT:
4347 case SVGA3D_DEVCAP_DXFMT_R32_UINT:
4348 case SVGA3D_DEVCAP_DXFMT_R32_SINT:
4349 case SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS:
4350 case SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT:
4351 case SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8:
4352 case SVGA3D_DEVCAP_DXFMT_X24_G8_UINT:
4353 case SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS:
4354 case SVGA3D_DEVCAP_DXFMT_R8G8_UNORM:
4355 case SVGA3D_DEVCAP_DXFMT_R8G8_UINT:
4356 case SVGA3D_DEVCAP_DXFMT_R8G8_SINT:
4357 case SVGA3D_DEVCAP_DXFMT_R16_TYPELESS:
4358 case SVGA3D_DEVCAP_DXFMT_R16_UNORM:
4359 case SVGA3D_DEVCAP_DXFMT_R16_UINT:
4360 case SVGA3D_DEVCAP_DXFMT_R16_SNORM:
4361 case SVGA3D_DEVCAP_DXFMT_R16_SINT:
4362 case SVGA3D_DEVCAP_DXFMT_R8_TYPELESS:
4363 case SVGA3D_DEVCAP_DXFMT_R8_UNORM:
4364 case SVGA3D_DEVCAP_DXFMT_R8_UINT:
4365 case SVGA3D_DEVCAP_DXFMT_R8_SNORM:
4366 case SVGA3D_DEVCAP_DXFMT_R8_SINT:
4367 case SVGA3D_DEVCAP_DXFMT_P8:
4368 case SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP:
4369 case SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM:
4370 case SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM:
4371 case SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS:
4372 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB:
4373 case SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS:
4374 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB:
4375 case SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS:
4376 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB:
4377 case SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS:
4378 case SVGA3D_DEVCAP_DXFMT_ATI1:
4379 case SVGA3D_DEVCAP_DXFMT_BC4_SNORM:
4380 case SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS:
4381 case SVGA3D_DEVCAP_DXFMT_ATI2:
4382 case SVGA3D_DEVCAP_DXFMT_BC5_SNORM:
4383 case SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM:
4384 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS:
4385 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB:
4386 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS:
4387 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB:
4388 case SVGA3D_DEVCAP_DXFMT_Z_DF16:
4389 case SVGA3D_DEVCAP_DXFMT_Z_DF24:
4390 case SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT:
4391 case SVGA3D_DEVCAP_DXFMT_YV12:
4392 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT:
4393 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT:
4394 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM:
4395 case SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT:
4396 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM:
4397 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM:
4398 case SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT:
4399 case SVGA3D_DEVCAP_DXFMT_R16G16_UNORM:
4400 case SVGA3D_DEVCAP_DXFMT_R16G16_SNORM:
4401 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT:
4402 case SVGA3D_DEVCAP_DXFMT_R8G8_SNORM:
4403 case SVGA3D_DEVCAP_DXFMT_R16_FLOAT:
4404 case SVGA3D_DEVCAP_DXFMT_D16_UNORM:
4405 case SVGA3D_DEVCAP_DXFMT_A8_UNORM:
4406 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM:
4407 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM:
4408 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM:
4409 case SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM:
4410 case SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM:
4411 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM:
4412 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM:
4413 case SVGA3D_DEVCAP_DXFMT_BC4_UNORM:
4414 case SVGA3D_DEVCAP_DXFMT_BC5_UNORM:
4415 case SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS:
4416 case SVGA3D_DEVCAP_DXFMT_BC6H_UF16:
4417 case SVGA3D_DEVCAP_DXFMT_BC6H_SF16:
4418 case SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS:
4419 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM:
4420 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB:
4421 {
4422 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapDxfmt2Format(idx3dCaps);
4423 rc = vmsvgaDXCheckFormatSupport(pState, enmFormat, pu32Val);
4424 break;
4425 }
4426
4427 case SVGA3D_DEVCAP_SM41:
4428 *pu32Val = 0; /* boolean */
4429 break;
4430
4431 case SVGA3D_DEVCAP_MULTISAMPLE_2X:
4432 *pu32Val = 0; /* boolean */
4433 break;
4434
4435 case SVGA3D_DEVCAP_MULTISAMPLE_4X:
4436 *pu32Val = 0; /* boolean */
4437 break;
4438
4439 case SVGA3D_DEVCAP_MS_FULL_QUALITY:
4440 *pu32Val = 0; /* boolean */
4441 break;
4442
4443 case SVGA3D_DEVCAP_LOGICOPS:
4444 AssertCompile(SVGA3D_DEVCAP_LOGICOPS == 248);
4445 *pu32Val = 0; /* boolean */
4446 break;
4447
4448 case SVGA3D_DEVCAP_LOGIC_BLENDOPS:
4449 *pu32Val = 0; /* boolean */
4450 break;
4451
4452 case SVGA3D_DEVCAP_RESERVED_1:
4453 break;
4454
4455 case SVGA3D_DEVCAP_RESERVED_2:
4456 break;
4457
4458 case SVGA3D_DEVCAP_SM5:
4459 *pu32Val = 0; /* boolean */
4460 break;
4461
4462 case SVGA3D_DEVCAP_MULTISAMPLE_8X:
4463 *pu32Val = 0; /* boolean */
4464 break;
4465
4466 case SVGA3D_DEVCAP_MAX:
4467 case SVGA3D_DEVCAP_INVALID:
4468 rc = VERR_NOT_SUPPORTED;
4469 break;
4470 }
4471
4472 return rc;
4473}
4474
4475
4476static DECLCALLBACK(int) vmsvga3dBackChangeMode(PVGASTATECC pThisCC)
4477{
4478 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4479 AssertReturn(pState, VERR_INVALID_STATE);
4480
4481 return VINF_SUCCESS;
4482}
4483
4484
4485static DECLCALLBACK(int) vmsvga3dBackSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
4486 uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
4487{
4488 RT_NOREF(cCopyBoxes, pBox);
4489
4490 LogFunc(("src sid %d -> dst sid %d\n", src.sid, dest.sid));
4491
4492 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4493 AssertReturn(pState, VERR_INVALID_STATE);
4494
4495 PVMSVGA3DBACKEND pBackend = pState->pBackend;
4496
4497 PVMSVGA3DSURFACE pSrcSurface;
4498 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, src.sid, &pSrcSurface);
4499 AssertRCReturn(rc, rc);
4500
4501 PVMSVGA3DSURFACE pDstSurface;
4502 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dest.sid, &pDstSurface);
4503 AssertRCReturn(rc, rc);
4504
4505 LogFunc(("src%s cid %d -> dst%s cid %d\n",
4506 pSrcSurface->pBackendSurface ? "" : " sysmem",
4507 pSrcSurface ? pSrcSurface->idAssociatedContext : SVGA_ID_INVALID,
4508 pDstSurface->pBackendSurface ? "" : " sysmem",
4509 pDstSurface ? pDstSurface->idAssociatedContext : SVGA_ID_INVALID));
4510
4511 //DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
4512 //AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4513
4514 if (pSrcSurface->pBackendSurface)
4515 {
4516 if (pDstSurface->pBackendSurface == NULL)
4517 {
4518 /* Create the target if it can be used as a device context shared resource (render or screen target). */
4519 if (pBackend->fSingleDevice || dxIsSurfaceShareable(pDstSurface))
4520 {
4521 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, NULL, pDstSurface);
4522 AssertRCReturn(rc, rc);
4523 }
4524 }
4525
4526 if (pDstSurface->pBackendSurface)
4527 {
4528 /* Surface -> Surface. */
4529 /* Expect both of them to be shared surfaces created by the backend context. */
4530 Assert(pSrcSurface->idAssociatedContext == DX_CID_BACKEND && pDstSurface->idAssociatedContext == DX_CID_BACKEND);
4531
4532 /* Wait for the source surface to finish drawing. */
4533 dxSurfaceWait(pState, pSrcSurface, DX_CID_BACKEND);
4534
4535 DXDEVICE *pDXDevice = &pBackend->dxDevice;
4536
4537 /* Clip the box. */
4538 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
4539 rc = vmsvga3dMipmapLevel(pSrcSurface, src.face, src.mipmap, &pSrcMipLevel);
4540 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4541
4542 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
4543 rc = vmsvga3dMipmapLevel(pDstSurface, dest.face, dest.mipmap, &pDstMipLevel);
4544 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4545
4546 SVGA3dCopyBox clipBox = *pBox;
4547 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
4548
4549 UINT DstSubresource = vmsvga3dCalcSubresource(dest.mipmap, dest.face, pDstSurface->cLevels);
4550 UINT DstX = clipBox.x;
4551 UINT DstY = clipBox.y;
4552 UINT DstZ = clipBox.z;
4553
4554 UINT SrcSubresource = vmsvga3dCalcSubresource(src.mipmap, src.face, pSrcSurface->cLevels);
4555 D3D11_BOX SrcBox;
4556 SrcBox.left = clipBox.srcx;
4557 SrcBox.top = clipBox.srcy;
4558 SrcBox.front = clipBox.srcz;
4559 SrcBox.right = clipBox.srcx + clipBox.w;
4560 SrcBox.bottom = clipBox.srcy + clipBox.h;
4561 SrcBox.back = clipBox.srcz + clipBox.d;
4562
4563 Assert(cCopyBoxes == 1); /** @todo */
4564
4565 ID3D11Resource *pDstResource;
4566 ID3D11Resource *pSrcResource;
4567 pDstResource = dxResource(pState, pDstSurface, NULL);
4568 pSrcResource = dxResource(pState, pSrcSurface, NULL);
4569
4570 pDXDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
4571 pSrcResource, SrcSubresource, &SrcBox);
4572
4573 pDstSurface->pBackendSurface->cidDrawing = DX_CID_BACKEND;
4574 }
4575 else
4576 {
4577 /* Surface -> Memory. */
4578 AssertFailed(); /** @todo implement */
4579 }
4580 }
4581 else
4582 {
4583 /* Memory -> Surface. */
4584 AssertFailed(); /** @todo implement */
4585 }
4586
4587 return rc;
4588}
4589
4590
4591static DECLCALLBACK(void) vmsvga3dBackUpdateHostScreenViewport(PVGASTATECC pThisCC, uint32_t idScreen, VMSVGAVIEWPORT const *pOldViewport)
4592{
4593 RT_NOREF(pThisCC, idScreen, pOldViewport);
4594 /** @todo Scroll the screen content without requiring the guest to redraw. */
4595}
4596
4597
4598static DECLCALLBACK(int) vmsvga3dBackSurfaceUpdateHeapBuffers(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
4599{
4600 /** @todo */
4601 RT_NOREF(pThisCC, pSurface);
4602 return VERR_NOT_IMPLEMENTED;
4603}
4604
4605
4606/*
4607 *
4608 * VGPU9 callbacks. Not implemented.
4609 *
4610 */
4611/** @todo later */
4612
4613/**
4614 * Create a new 3d context
4615 *
4616 * @returns VBox status code.
4617 * @param pThisCC The VGA/VMSVGA state for ring-3.
4618 * @param cid Context id
4619 */
4620static DECLCALLBACK(int) vmsvga3dBackContextDefine(PVGASTATECC pThisCC, uint32_t cid)
4621{
4622 RT_NOREF(cid);
4623
4624 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4625 AssertReturn(pState, VERR_INVALID_STATE);
4626
4627 DEBUG_BREAKPOINT_TEST();
4628 return VERR_NOT_IMPLEMENTED;
4629}
4630
4631
4632/**
4633 * Destroy an existing 3d context
4634 *
4635 * @returns VBox status code.
4636 * @param pThisCC The VGA/VMSVGA state for ring-3.
4637 * @param cid Context id
4638 */
4639static DECLCALLBACK(int) vmsvga3dBackContextDestroy(PVGASTATECC pThisCC, uint32_t cid)
4640{
4641 RT_NOREF(cid);
4642
4643 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4644 AssertReturn(pState, VERR_INVALID_STATE);
4645
4646 DEBUG_BREAKPOINT_TEST();
4647 return VINF_SUCCESS;
4648}
4649
4650
4651static DECLCALLBACK(int) vmsvga3dBackSetTransform(PVGASTATECC pThisCC, uint32_t cid, SVGA3dTransformType type, float matrix[16])
4652{
4653 RT_NOREF(cid, type, matrix);
4654
4655 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4656 AssertReturn(pState, VERR_INVALID_STATE);
4657
4658 DEBUG_BREAKPOINT_TEST();
4659 return VINF_SUCCESS;
4660}
4661
4662
4663static DECLCALLBACK(int) vmsvga3dBackSetZRange(PVGASTATECC pThisCC, uint32_t cid, SVGA3dZRange zRange)
4664{
4665 RT_NOREF(cid, zRange);
4666
4667 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4668 AssertReturn(pState, VERR_INVALID_STATE);
4669
4670 DEBUG_BREAKPOINT_TEST();
4671 return VINF_SUCCESS;
4672}
4673
4674
4675static DECLCALLBACK(int) vmsvga3dBackSetRenderState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
4676{
4677 RT_NOREF(cid, cRenderStates, pRenderState);
4678
4679 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4680 AssertReturn(pState, VERR_INVALID_STATE);
4681
4682 DEBUG_BREAKPOINT_TEST();
4683 return VINF_SUCCESS;
4684}
4685
4686
4687static DECLCALLBACK(int) vmsvga3dBackSetRenderTarget(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
4688{
4689 RT_NOREF(cid, type, target);
4690
4691 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4692 AssertReturn(pState, VERR_INVALID_STATE);
4693
4694 DEBUG_BREAKPOINT_TEST();
4695 return VINF_SUCCESS;
4696}
4697
4698
4699static DECLCALLBACK(int) vmsvga3dBackSetTextureState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
4700{
4701 RT_NOREF(cid, cTextureStates, pTextureState);
4702
4703 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4704 AssertReturn(pState, VERR_INVALID_STATE);
4705
4706 DEBUG_BREAKPOINT_TEST();
4707 return VINF_SUCCESS;
4708}
4709
4710
4711static DECLCALLBACK(int) vmsvga3dBackSetMaterial(PVGASTATECC pThisCC, uint32_t cid, SVGA3dFace face, SVGA3dMaterial *pMaterial)
4712{
4713 RT_NOREF(cid, face, pMaterial);
4714
4715 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4716 AssertReturn(pState, VERR_INVALID_STATE);
4717
4718 DEBUG_BREAKPOINT_TEST();
4719 return VINF_SUCCESS;
4720}
4721
4722
4723static DECLCALLBACK(int) vmsvga3dBackSetLightData(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, SVGA3dLightData *pData)
4724{
4725 RT_NOREF(cid, index, pData);
4726
4727 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4728 AssertReturn(pState, VERR_INVALID_STATE);
4729
4730 DEBUG_BREAKPOINT_TEST();
4731 return VINF_SUCCESS;
4732}
4733
4734
4735static DECLCALLBACK(int) vmsvga3dBackSetLightEnabled(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, uint32_t enabled)
4736{
4737 RT_NOREF(cid, index, enabled);
4738
4739 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4740 AssertReturn(pState, VERR_INVALID_STATE);
4741
4742 DEBUG_BREAKPOINT_TEST();
4743 return VINF_SUCCESS;
4744}
4745
4746
4747static DECLCALLBACK(int) vmsvga3dBackSetViewPort(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
4748{
4749 RT_NOREF(cid, pRect);
4750
4751 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4752 AssertReturn(pState, VERR_INVALID_STATE);
4753
4754 DEBUG_BREAKPOINT_TEST();
4755 return VINF_SUCCESS;
4756}
4757
4758
4759static DECLCALLBACK(int) vmsvga3dBackSetClipPlane(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, float plane[4])
4760{
4761 RT_NOREF(cid, index, plane);
4762
4763 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4764 AssertReturn(pState, VERR_INVALID_STATE);
4765
4766 DEBUG_BREAKPOINT_TEST();
4767 return VINF_SUCCESS;
4768}
4769
4770
4771static DECLCALLBACK(int) vmsvga3dBackCommandClear(PVGASTATECC pThisCC, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth,
4772 uint32_t stencil, uint32_t cRects, SVGA3dRect *pRect)
4773{
4774 /* From SVGA3D_BeginClear comments:
4775 *
4776 * Clear is not affected by clipping, depth test, or other
4777 * render state which affects the fragment pipeline.
4778 *
4779 * Therefore this code must ignore the current scissor rect.
4780 */
4781
4782 RT_NOREF(cid, clearFlag, color, depth, stencil, cRects, pRect);
4783
4784 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4785 AssertReturn(pState, VERR_INVALID_STATE);
4786
4787 DEBUG_BREAKPOINT_TEST();
4788 return VINF_SUCCESS;
4789}
4790
4791
4792static DECLCALLBACK(int) vmsvga3dBackDrawPrimitives(PVGASTATECC pThisCC, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl,
4793 uint32_t numRanges, SVGA3dPrimitiveRange *pRange,
4794 uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
4795{
4796 RT_NOREF(cid, numVertexDecls, pVertexDecl, numRanges, pRange, cVertexDivisor, pVertexDivisor);
4797
4798 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4799 AssertReturn(pState, VERR_INVALID_STATE);
4800
4801 DEBUG_BREAKPOINT_TEST();
4802 return VINF_SUCCESS;
4803}
4804
4805
4806static DECLCALLBACK(int) vmsvga3dBackSetScissorRect(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
4807{
4808 RT_NOREF(cid, pRect);
4809
4810 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4811 AssertReturn(pState, VERR_INVALID_STATE);
4812
4813 DEBUG_BREAKPOINT_TEST();
4814 return VINF_SUCCESS;
4815}
4816
4817
4818static DECLCALLBACK(int) vmsvga3dBackGenerateMipmaps(PVGASTATECC pThisCC, uint32_t sid, SVGA3dTextureFilter filter)
4819{
4820 RT_NOREF(sid, filter);
4821
4822 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4823 AssertReturn(pState, VERR_INVALID_STATE);
4824
4825 DEBUG_BREAKPOINT_TEST();
4826 return VINF_SUCCESS;
4827}
4828
4829
4830static DECLCALLBACK(int) vmsvga3dBackShaderDefine(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type,
4831 uint32_t cbData, uint32_t *pShaderData)
4832{
4833 RT_NOREF(cid, shid, type, cbData, pShaderData);
4834
4835 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4836 AssertReturn(pState, VERR_INVALID_STATE);
4837
4838 DEBUG_BREAKPOINT_TEST();
4839 return VINF_SUCCESS;
4840}
4841
4842
4843static DECLCALLBACK(int) vmsvga3dBackShaderDestroy(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type)
4844{
4845 RT_NOREF(cid, shid, type);
4846
4847 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4848 AssertReturn(pState, VERR_INVALID_STATE);
4849
4850 DEBUG_BREAKPOINT_TEST();
4851 return VINF_SUCCESS;
4852}
4853
4854
4855static DECLCALLBACK(int) vmsvga3dBackShaderSet(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
4856{
4857 RT_NOREF(pContext, cid, type, shid);
4858
4859 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4860 AssertReturn(pState, VERR_INVALID_STATE);
4861
4862 DEBUG_BREAKPOINT_TEST();
4863 return VINF_SUCCESS;
4864}
4865
4866
4867static DECLCALLBACK(int) vmsvga3dBackShaderSetConst(PVGASTATECC pThisCC, uint32_t cid, uint32_t reg, SVGA3dShaderType type,
4868 SVGA3dShaderConstType ctype, uint32_t cRegisters, uint32_t *pValues)
4869{
4870 RT_NOREF(cid, reg, type, ctype, cRegisters, pValues);
4871
4872 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4873 AssertReturn(pState, VERR_INVALID_STATE);
4874
4875 DEBUG_BREAKPOINT_TEST();
4876 return VINF_SUCCESS;
4877}
4878
4879static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryCreate(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4880{
4881 RT_NOREF(pThisCC, pContext);
4882 DEBUG_BREAKPOINT_TEST();
4883 return VINF_SUCCESS;
4884}
4885
4886static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryDelete(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4887{
4888 RT_NOREF(pThisCC, pContext);
4889 DEBUG_BREAKPOINT_TEST();
4890 return VINF_SUCCESS;
4891}
4892
4893static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryBegin(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4894{
4895 RT_NOREF(pThisCC, pContext);
4896 DEBUG_BREAKPOINT_TEST();
4897 return VINF_SUCCESS;
4898}
4899
4900static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryEnd(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4901{
4902 RT_NOREF(pThisCC, pContext);
4903 DEBUG_BREAKPOINT_TEST();
4904 return VINF_SUCCESS;
4905}
4906
4907static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryGetData(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t *pu32Pixels)
4908{
4909 RT_NOREF(pThisCC, pContext, pu32Pixels);
4910 DEBUG_BREAKPOINT_TEST();
4911 return VINF_SUCCESS;
4912}
4913
4914
4915/**
4916 * Destroy backend specific surface bits (part of SVGA_3D_CMD_SURFACE_DESTROY).
4917 *
4918 * @param pThisCC The device context.
4919 * @param fClearCOTableEntry Whether to clear the corresponding COTable entry.
4920 * @param pSurface The surface being destroyed.
4921 */
4922static DECLCALLBACK(void) vmsvga3dBackSurfaceDestroy(PVGASTATECC pThisCC, bool fClearCOTableEntry, PVMSVGA3DSURFACE pSurface)
4923{
4924 RT_NOREF(pThisCC);
4925
4926 /* The caller should not use the function for system memory surfaces. */
4927 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4928 if (!pBackendSurface)
4929 return;
4930 pSurface->pBackendSurface = NULL;
4931
4932 LogFunc(("sid=%u\n", pSurface->id));
4933
4934 /* If any views have been created for this resource, then also release them. */
4935 DXVIEW *pIter, *pNext;
4936 RTListForEachSafe(&pBackendSurface->listView, pIter, pNext, DXVIEW, nodeSurfaceView)
4937 {
4938 LogFunc(("pIter=%p, pNext=%p\n", pIter, pNext));
4939
4940 /** @todo The common DX code should track the views and clean COTable on a surface destruction. */
4941 if (fClearCOTableEntry)
4942 {
4943 PVMSVGA3DDXCONTEXT pDXContext;
4944 int rc = vmsvga3dDXContextFromCid(pThisCC->svga.p3dState, pIter->cid, &pDXContext);
4945 AssertRC(rc);
4946 if (RT_SUCCESS(rc))
4947 {
4948 switch (pIter->enmViewType)
4949 {
4950 case VMSVGA3D_VIEWTYPE_RENDERTARGET:
4951 {
4952 SVGACOTableDXRTViewEntry *pEntry = &pDXContext->cot.paRTView[pIter->viewId];
4953 RT_ZERO(*pEntry);
4954 break;
4955 }
4956 case VMSVGA3D_VIEWTYPE_DEPTHSTENCIL:
4957 {
4958 SVGACOTableDXDSViewEntry *pEntry = &pDXContext->cot.paDSView[pIter->viewId];
4959 RT_ZERO(*pEntry);
4960 break;
4961 }
4962 case VMSVGA3D_VIEWTYPE_SHADERRESOURCE:
4963 {
4964 SVGACOTableDXSRViewEntry *pEntry = &pDXContext->cot.paSRView[pIter->viewId];
4965 RT_ZERO(*pEntry);
4966 break;
4967 }
4968 case VMSVGA3D_VIEWTYPE_UNORDEREDACCESS:
4969 {
4970 SVGACOTableDXUAViewEntry *pEntry = &pDXContext->cot.paUAView[pIter->viewId];
4971 RT_ZERO(*pEntry);
4972 break;
4973 }
4974 default:
4975 AssertFailed();
4976 }
4977 }
4978 }
4979
4980 dxViewDestroy(pIter);
4981 }
4982
4983 if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET
4984 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
4985 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
4986 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
4987 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4988 {
4989 D3D_RELEASE(pBackendSurface->staging.pResource);
4990 D3D_RELEASE(pBackendSurface->dynamic.pResource);
4991 D3D_RELEASE(pBackendSurface->u.pResource);
4992 }
4993 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
4994 {
4995 D3D_RELEASE(pBackendSurface->u.pBuffer);
4996 }
4997 else
4998 {
4999 AssertFailed();
5000 }
5001
5002 RTMemFree(pBackendSurface);
5003
5004 /* No context has created the surface, because the surface does not exist anymore. */
5005 pSurface->idAssociatedContext = SVGA_ID_INVALID;
5006}
5007
5008
5009static DECLCALLBACK(void) vmsvga3dBackSurfaceInvalidateImage(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface, uint32_t uFace, uint32_t uMipmap)
5010{
5011 RT_NOREF(pThisCC, uFace, uMipmap);
5012
5013 /* The caller should not use the function for system memory surfaces. */
5014 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
5015 if (!pBackendSurface)
5016 return;
5017
5018 LogFunc(("sid=%u\n", pSurface->id));
5019
5020 /* The guest uses this to invalidate a buffer. */
5021 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
5022 {
5023 Assert(uFace == 0 && uMipmap == 0); /* The caller ensures this. */
5024 /** @todo This causes flickering when a buffer is invalidated and re-created right before a draw call. */
5025 //vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
5026 }
5027 else
5028 {
5029 /** @todo Delete views that have been created for this mipmap.
5030 * For now just delete all views, they will be recte=reated if necessary.
5031 */
5032 ASSERT_GUEST_FAILED();
5033 DXVIEW *pIter, *pNext;
5034 RTListForEachSafe(&pBackendSurface->listView, pIter, pNext, DXVIEW, nodeSurfaceView)
5035 {
5036 dxViewDestroy(pIter);
5037 }
5038 }
5039}
5040
5041
5042/**
5043 * Backend worker for implementing SVGA_3D_CMD_SURFACE_STRETCHBLT.
5044 *
5045 * @returns VBox status code.
5046 * @param pThis The VGA device instance.
5047 * @param pState The VMSVGA3d state.
5048 * @param pDstSurface The destination host surface.
5049 * @param uDstFace The destination face (valid).
5050 * @param uDstMipmap The destination mipmap level (valid).
5051 * @param pDstBox The destination box.
5052 * @param pSrcSurface The source host surface.
5053 * @param uSrcFace The destination face (valid).
5054 * @param uSrcMipmap The source mimap level (valid).
5055 * @param pSrcBox The source box.
5056 * @param enmMode The strecht blt mode .
5057 * @param pContext The VMSVGA3d context (already current for OGL).
5058 */
5059static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
5060 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
5061 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
5062 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext)
5063{
5064 RT_NOREF(pThis, pState, pDstSurface, uDstFace, uDstMipmap, pDstBox,
5065 pSrcSurface, uSrcFace, uSrcMipmap, pSrcBox, enmMode, pContext);
5066
5067 AssertFailed();
5068 return VINF_SUCCESS;
5069}
5070
5071
5072/**
5073 * Backend worker for implementing SVGA_3D_CMD_SURFACE_DMA that copies one box.
5074 *
5075 * @returns Failure status code or @a rc.
5076 * @param pThis The shared VGA/VMSVGA instance data.
5077 * @param pThisCC The VGA/VMSVGA state for ring-3.
5078 * @param pState The VMSVGA3d state.
5079 * @param pSurface The host surface.
5080 * @param pMipLevel Mipmap level. The caller knows it already.
5081 * @param uHostFace The host face (valid).
5082 * @param uHostMipmap The host mipmap level (valid).
5083 * @param GuestPtr The guest pointer.
5084 * @param cbGuestPitch The guest pitch.
5085 * @param transfer The transfer direction.
5086 * @param pBox The box to copy (clipped, valid, except for guest's srcx, srcy, srcz).
5087 * @param pContext The context (for OpenGL).
5088 * @param rc The current rc for all boxes.
5089 * @param iBox The current box number (for Direct 3D).
5090 */
5091static DECLCALLBACK(int) vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVGASTATECC pThisCC, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
5092 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
5093 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
5094 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox)
5095{
5096 RT_NOREF(pState, pMipLevel, pContext, iBox);
5097
5098 /* The called should not use the function for system memory surfaces. */
5099 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
5100 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
5101
5102 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
5103 {
5104 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
5105 AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
5106
5107 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
5108 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
5109 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
5110 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
5111 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
5112 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
5113 AssertMsgReturn(cBlocksX && cBlocksY, ("Empty box %dx%d\n", pBox->w, pBox->h), VERR_INTERNAL_ERROR);
5114
5115 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
5116 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
5117 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
5118 */
5119 uint64_t const uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
5120 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
5121
5122 SVGA3dSurfaceImageId image;
5123 image.sid = pSurface->id;
5124 image.face = uHostFace;
5125 image.mipmap = uHostMipmap;
5126
5127 SVGA3dBox box;
5128 box.x = pBox->x;
5129 box.y = pBox->y;
5130 box.z = 0;
5131 box.w = pBox->w;
5132 box.h = pBox->h;
5133 box.d = 1;
5134
5135 VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
5136 ? VMSVGA3D_SURFACE_MAP_WRITE
5137 : VMSVGA3D_SURFACE_MAP_READ;
5138
5139 VMSVGA3D_MAPPED_SURFACE map;
5140 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, &box, enmMap, &map);
5141 if (RT_SUCCESS(rc))
5142 {
5143 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
5144 * and offset of the first scanline.
5145 */
5146 uint32_t const cbLockedBuf = map.cbRowPitch * cBlocksY;
5147 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
5148 uint32_t const offLockedBuf = 0;
5149
5150 rc = vmsvgaR3GmrTransfer(pThis,
5151 pThisCC,
5152 transfer,
5153 pu8LockedBuf,
5154 cbLockedBuf,
5155 offLockedBuf,
5156 map.cbRowPitch,
5157 GuestPtr,
5158 (uint32_t)uGuestOffset,
5159 cbGuestPitch,
5160 cBlocksX * pSurface->cbBlock,
5161 cBlocksY);
5162 AssertRC(rc);
5163
5164 // Log4(("first line:\n%.*Rhxd\n", cBlocksX * pSurface->cbBlock, LockedRect.pBits));
5165
5166 //vmsvga3dMapWriteBmpFile(&map, "Dynamic");
5167
5168 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ true);
5169 }
5170#if 0
5171 //DEBUG_BREAKPOINT_TEST();
5172 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
5173 if (RT_SUCCESS(rc))
5174 {
5175 vmsvga3dMapWriteBmpFile(&map, "Staging");
5176
5177 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
5178 }
5179#endif
5180 }
5181 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
5182 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
5183 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
5184 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
5185 {
5186 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
5187 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
5188 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
5189 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
5190 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
5191 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
5192 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
5193 AssertMsgReturn(cBlocksX && cBlocksY && pBox->d, ("Empty box %dx%dx%d\n", pBox->w, pBox->h, pBox->d), VERR_INTERNAL_ERROR);
5194
5195 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
5196 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
5197 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
5198 */
5199 uint64_t uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
5200 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
5201
5202 /* 3D texture needs additional processing. */
5203 ASSERT_GUEST_RETURN( pBox->z < D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
5204 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
5205 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION - pBox->z,
5206 VERR_INVALID_PARAMETER);
5207 ASSERT_GUEST_RETURN( pBox->srcz < D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
5208 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
5209 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION - pBox->srcz,
5210 VERR_INVALID_PARAMETER);
5211
5212 uGuestOffset += pBox->srcz * pMipLevel->cbSurfacePlane;
5213
5214 SVGA3dSurfaceImageId image;
5215 image.sid = pSurface->id;
5216 image.face = uHostFace;
5217 image.mipmap = uHostMipmap;
5218
5219 SVGA3dBox box;
5220 box.x = pBox->x;
5221 box.y = pBox->y;
5222 box.z = pBox->z;
5223 box.w = pBox->w;
5224 box.h = pBox->h;
5225 box.d = pBox->d;
5226
5227 VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
5228 ? VMSVGA3D_SURFACE_MAP_WRITE
5229 : VMSVGA3D_SURFACE_MAP_READ;
5230
5231 VMSVGA3D_MAPPED_SURFACE map;
5232 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, &box, enmMap, &map);
5233 if (RT_SUCCESS(rc))
5234 {
5235#if 0
5236 if (box.w == 250 && box.h == 250 && box.d == 1 && enmMap == VMSVGA3D_SURFACE_MAP_READ)
5237 {
5238 DEBUG_BREAKPOINT_TEST();
5239 vmsvga3dMapWriteBmpFile(&map, "P");
5240 }
5241#endif
5242 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
5243 * and offset of the first scanline.
5244 */
5245 uint32_t cbLockedBuf = map.cbRowPitch * cBlocksY;
5246 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
5247 cbLockedBuf += map.cbDepthPitch * (pBox->d - 1); /// @todo why map does not compute this for 2D textures
5248 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
5249 uint32_t offLockedBuf = 0;
5250
5251 for (uint32_t iPlane = 0; iPlane < pBox->d; ++iPlane)
5252 {
5253 AssertBreak(uGuestOffset < UINT32_MAX);
5254
5255 rc = vmsvgaR3GmrTransfer(pThis,
5256 pThisCC,
5257 transfer,
5258 pu8LockedBuf,
5259 cbLockedBuf,
5260 offLockedBuf,
5261 map.cbRowPitch,
5262 GuestPtr,
5263 (uint32_t)uGuestOffset,
5264 cbGuestPitch,
5265 cBlocksX * pSurface->cbBlock,
5266 cBlocksY);
5267 AssertRC(rc);
5268
5269 uGuestOffset += pMipLevel->cbSurfacePlane;
5270 offLockedBuf += map.cbDepthPitch;
5271 }
5272
5273 bool const fWritten = (transfer == SVGA3D_WRITE_HOST_VRAM);
5274 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, fWritten);
5275 }
5276 }
5277 else
5278 {
5279 AssertMsgFailed(("Unsupported surface type %d\n", pBackendSurface->enmResType));
5280 rc = VERR_NOT_IMPLEMENTED;
5281 }
5282
5283 return rc;
5284}
5285
5286
5287/**
5288 * Create D3D/OpenGL texture object for the specified surface.
5289 *
5290 * Surfaces are created when needed.
5291 *
5292 * @param pThisCC The device context.
5293 * @param pContext The context.
5294 * @param idAssociatedContext Probably the same as pContext->id.
5295 * @param pSurface The surface to create the texture for.
5296 */
5297static DECLCALLBACK(int) vmsvga3dBackCreateTexture(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
5298 PVMSVGA3DSURFACE pSurface)
5299
5300{
5301 RT_NOREF(pThisCC, pContext, idAssociatedContext, pSurface);
5302
5303 AssertFailed();
5304 return VINF_SUCCESS;
5305}
5306
5307
5308/*
5309 * DX callbacks.
5310 */
5311
5312static DECLCALLBACK(int) vmsvga3dBackDXDefineContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5313{
5314 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5315
5316 /* Allocate a backend specific context structure. */
5317 PVMSVGA3DBACKENDDXCONTEXT pBackendDXContext = (PVMSVGA3DBACKENDDXCONTEXT)RTMemAllocZ(sizeof(VMSVGA3DBACKENDDXCONTEXT));
5318 AssertPtrReturn(pBackendDXContext, VERR_NO_MEMORY);
5319 pDXContext->pBackendDXContext = pBackendDXContext;
5320
5321 LogFunc(("cid %d\n", pDXContext->cid));
5322
5323 int rc = dxDeviceCreate(pBackend, &pBackendDXContext->dxDevice);
5324 return rc;
5325}
5326
5327
5328static DECLCALLBACK(int) vmsvga3dBackDXDestroyContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5329{
5330 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5331
5332 LogFunc(("cid %d\n", pDXContext->cid));
5333
5334 if (pDXContext->pBackendDXContext)
5335 {
5336 /* Clean up context resources. */
5337 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
5338
5339 for (uint32_t idxShaderState = 0; idxShaderState < RT_ELEMENTS(pBackendDXContext->resources.shaderState); ++idxShaderState)
5340 {
5341 ID3D11Buffer **papConstantBuffer = &pBackendDXContext->resources.shaderState[idxShaderState].constantBuffers[0];
5342 D3D_RELEASE_ARRAY(RT_ELEMENTS(pBackendDXContext->resources.shaderState[idxShaderState].constantBuffers), papConstantBuffer);
5343 }
5344
5345 for (uint32_t i = 0; i < RT_ELEMENTS(pBackendDXContext->resources.inputAssembly.vertexBuffers); ++i)
5346 {
5347 D3D_RELEASE(pBackendDXContext->resources.inputAssembly.vertexBuffers[i].pBuffer);
5348 }
5349
5350 D3D_RELEASE(pBackendDXContext->resources.inputAssembly.indexBuffer.pBuffer);
5351
5352 if (pBackendDXContext->dxDevice.pImmediateContext)
5353 dxDeviceFlush(&pBackendDXContext->dxDevice); /* Make sure that any pending draw calls are finished. */
5354
5355 if (pBackendDXContext->paRenderTargetView)
5356 {
5357 for (uint32_t i = 0; i < pBackendDXContext->cRenderTargetView; ++i)
5358 D3D_RELEASE(pBackendDXContext->paRenderTargetView[i].u.pRenderTargetView);
5359 }
5360 if (pBackendDXContext->paDepthStencilView)
5361 {
5362 for (uint32_t i = 0; i < pBackendDXContext->cDepthStencilView; ++i)
5363 D3D_RELEASE(pBackendDXContext->paDepthStencilView[i].u.pDepthStencilView);
5364 }
5365 if (pBackendDXContext->paShaderResourceView)
5366 {
5367 for (uint32_t i = 0; i < pBackendDXContext->cShaderResourceView; ++i)
5368 D3D_RELEASE(pBackendDXContext->paShaderResourceView[i].u.pShaderResourceView);
5369 }
5370 if (pBackendDXContext->paElementLayout)
5371 {
5372 for (uint32_t i = 0; i < pBackendDXContext->cElementLayout; ++i)
5373 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
5374 }
5375 if (pBackendDXContext->papBlendState)
5376 D3D_RELEASE_ARRAY(pBackendDXContext->cBlendState, pBackendDXContext->papBlendState);
5377 if (pBackendDXContext->papDepthStencilState)
5378 D3D_RELEASE_ARRAY(pBackendDXContext->cDepthStencilState, pBackendDXContext->papDepthStencilState);
5379 if (pBackendDXContext->papRasterizerState)
5380 D3D_RELEASE_ARRAY(pBackendDXContext->cRasterizerState, pBackendDXContext->papRasterizerState);
5381 if (pBackendDXContext->papSamplerState)
5382 D3D_RELEASE_ARRAY(pBackendDXContext->cSamplerState, pBackendDXContext->papSamplerState);
5383 if (pBackendDXContext->paQuery)
5384 {
5385 for (uint32_t i = 0; i < pBackendDXContext->cQuery; ++i)
5386 dxDestroyQuery(&pBackendDXContext->paQuery[i]);
5387 }
5388 if (pBackendDXContext->paShader)
5389 {
5390 for (uint32_t i = 0; i < pBackendDXContext->cShader; ++i)
5391 dxDestroyShader(&pBackendDXContext->paShader[i]);
5392 }
5393 if (pBackendDXContext->paStreamOutput)
5394 {
5395 for (uint32_t i = 0; i < pBackendDXContext->cStreamOutput; ++i)
5396 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
5397 }
5398
5399 RTMemFreeZ(pBackendDXContext->papBlendState, sizeof(pBackendDXContext->papBlendState[0]) * pBackendDXContext->cBlendState);
5400 RTMemFreeZ(pBackendDXContext->papDepthStencilState, sizeof(pBackendDXContext->papDepthStencilState[0]) * pBackendDXContext->cDepthStencilState);
5401 RTMemFreeZ(pBackendDXContext->papSamplerState, sizeof(pBackendDXContext->papSamplerState[0]) * pBackendDXContext->cSamplerState);
5402 RTMemFreeZ(pBackendDXContext->papRasterizerState, sizeof(pBackendDXContext->papRasterizerState[0]) * pBackendDXContext->cRasterizerState);
5403 RTMemFreeZ(pBackendDXContext->paElementLayout, sizeof(pBackendDXContext->paElementLayout[0]) * pBackendDXContext->cElementLayout);
5404 RTMemFreeZ(pBackendDXContext->paRenderTargetView, sizeof(pBackendDXContext->paRenderTargetView[0]) * pBackendDXContext->cRenderTargetView);
5405 RTMemFreeZ(pBackendDXContext->paDepthStencilView, sizeof(pBackendDXContext->paDepthStencilView[0]) * pBackendDXContext->cDepthStencilView);
5406 RTMemFreeZ(pBackendDXContext->paShaderResourceView, sizeof(pBackendDXContext->paShaderResourceView[0]) * pBackendDXContext->cShaderResourceView);
5407 RTMemFreeZ(pBackendDXContext->paQuery, sizeof(pBackendDXContext->paQuery[0]) * pBackendDXContext->cQuery);
5408 RTMemFreeZ(pBackendDXContext->paShader, sizeof(pBackendDXContext->paShader[0]) * pBackendDXContext->cShader);
5409 RTMemFreeZ(pBackendDXContext->paStreamOutput, sizeof(pBackendDXContext->paStreamOutput[0]) * pBackendDXContext->cStreamOutput);
5410
5411 /* Destroy backend surfaces which belong to this context. */
5412 /** @todo The context should have a list of surfaces (and also shared resources). */
5413 /** @todo This should not be needed in fSingleDevice mode. */
5414 for (uint32_t sid = 0; sid < pThisCC->svga.p3dState->cSurfaces; ++sid)
5415 {
5416 PVMSVGA3DSURFACE const pSurface = pThisCC->svga.p3dState->papSurfaces[sid];
5417 if ( pSurface
5418 && pSurface->id == sid)
5419 {
5420 if (pSurface->idAssociatedContext == pDXContext->cid)
5421 {
5422 if (pSurface->pBackendSurface)
5423 vmsvga3dBackSurfaceDestroy(pThisCC, true, pSurface);
5424 }
5425 else if (pSurface->idAssociatedContext == DX_CID_BACKEND)
5426 {
5427 /* May have shared resources in this context. */
5428 if (pSurface->pBackendSurface)
5429 {
5430 DXSHAREDTEXTURE *pSharedTexture = (DXSHAREDTEXTURE *)RTAvlU32Get(&pSurface->pBackendSurface->SharedTextureTree, pDXContext->cid);
5431 if (pSharedTexture)
5432 {
5433 Assert(pSharedTexture->sid == sid);
5434 RTAvlU32Remove(&pSurface->pBackendSurface->SharedTextureTree, pDXContext->cid);
5435 D3D_RELEASE(pSharedTexture->pTexture);
5436 RTMemFreeZ(pSharedTexture, sizeof(*pSharedTexture));
5437 }
5438 }
5439 }
5440 }
5441 }
5442
5443 dxDeviceDestroy(pBackend, &pBackendDXContext->dxDevice);
5444
5445 RTMemFreeZ(pBackendDXContext, sizeof(*pBackendDXContext));
5446 pDXContext->pBackendDXContext = NULL;
5447 }
5448 return VINF_SUCCESS;
5449}
5450
5451
5452static DECLCALLBACK(int) vmsvga3dBackDXBindContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5453{
5454 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5455 RT_NOREF(pBackend, pDXContext);
5456 return VINF_SUCCESS;
5457}
5458
5459
5460static DECLCALLBACK(int) vmsvga3dBackDXSwitchContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5461{
5462 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5463 if (!pBackend->fSingleDevice)
5464 return VINF_NOT_IMPLEMENTED; /* Not required. */
5465
5466 /* The new context state will be applied by the generic DX code. */
5467 RT_NOREF(pDXContext);
5468 return VINF_SUCCESS;
5469}
5470
5471
5472static DECLCALLBACK(int) vmsvga3dBackDXReadbackContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5473{
5474 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5475 RT_NOREF(pBackend, pDXContext);
5476 return VINF_SUCCESS;
5477}
5478
5479
5480static DECLCALLBACK(int) vmsvga3dBackDXInvalidateContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5481{
5482 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5483
5484 RT_NOREF(pBackend, pDXContext);
5485 AssertFailed(); /** @todo Implement */
5486 return VERR_NOT_IMPLEMENTED;
5487}
5488
5489
5490static DECLCALLBACK(int) vmsvga3dBackDXSetSingleConstantBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t slot, SVGA3dShaderType type, SVGA3dSurfaceId sid, uint32_t offsetInBytes, uint32_t sizeInBytes)
5491{
5492 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5493 RT_NOREF(pBackend);
5494
5495 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5496 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5497
5498 if (sid == SVGA_ID_INVALID)
5499 {
5500 uint32_t const idxShaderState = type - SVGA3D_SHADERTYPE_MIN;
5501 D3D_RELEASE(pDXContext->pBackendDXContext->resources.shaderState[idxShaderState].constantBuffers[slot]);
5502 return VINF_SUCCESS;
5503 }
5504
5505 PVMSVGA3DSURFACE pSurface;
5506 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5507 AssertRCReturn(rc, rc);
5508
5509 PVMSVGA3DMIPMAPLEVEL pMipLevel;
5510 rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
5511 AssertRCReturn(rc, rc);
5512
5513 uint32_t const cbSurface = pMipLevel->cbSurface;
5514 ASSERT_GUEST_RETURN( offsetInBytes < cbSurface
5515 && sizeInBytes <= cbSurface - offsetInBytes, VERR_INVALID_PARAMETER);
5516
5517 /* Constant buffers are created on demand. */
5518 Assert(pSurface->pBackendSurface == NULL);
5519
5520 /* Upload the current data, if any. */
5521 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
5522 D3D11_SUBRESOURCE_DATA initialData;
5523 if (pMipLevel->pSurfaceData)
5524 {
5525 initialData.pSysMem = (uint8_t *)pMipLevel->pSurfaceData + offsetInBytes;
5526 initialData.SysMemPitch = sizeInBytes;
5527 initialData.SysMemSlicePitch = sizeInBytes;
5528
5529 pInitialData = &initialData;
5530
5531 // Log(("%.*Rhxd\n", sizeInBytes, initialData.pSysMem));
5532 }
5533
5534 D3D11_BUFFER_DESC bd;
5535 RT_ZERO(bd);
5536 bd.ByteWidth = sizeInBytes;
5537 bd.Usage = D3D11_USAGE_DEFAULT;
5538 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
5539 bd.CPUAccessFlags = 0;
5540 bd.MiscFlags = 0;
5541 bd.StructureByteStride = 0;
5542
5543 ID3D11Buffer *pBuffer = 0;
5544 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBuffer);
5545 if (SUCCEEDED(hr))
5546 {
5547 uint32_t const idxShaderState = type - SVGA3D_SHADERTYPE_MIN;
5548 ID3D11Buffer **ppOldBuffer = &pDXContext->pBackendDXContext->resources.shaderState[idxShaderState].constantBuffers[slot];
5549 LogFunc(("constant buffer: [%u][%u]: sid = %u, %u, %u (%p -> %p)\n",
5550 idxShaderState, slot, sid, offsetInBytes, sizeInBytes, *ppOldBuffer, pBuffer));
5551 D3D_RELEASE(*ppOldBuffer);
5552 *ppOldBuffer = pBuffer;
5553 }
5554
5555 return VINF_SUCCESS;
5556}
5557
5558static int dxSetShaderResources(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderType type)
5559{
5560 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5561 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5562
5563//DEBUG_BREAKPOINT_TEST();
5564 AssertReturn(type >= SVGA3D_SHADERTYPE_MIN && type < SVGA3D_SHADERTYPE_MAX, VERR_INVALID_PARAMETER);
5565 uint32_t const idxShaderState = type - SVGA3D_SHADERTYPE_MIN;
5566 uint32_t const *pSRIds = &pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[0];
5567 ID3D11ShaderResourceView *papShaderResourceView[SVGA3D_DX_MAX_SRVIEWS];
5568 for (uint32_t i = 0; i < SVGA3D_DX_MAX_SRVIEWS; ++i)
5569 {
5570 SVGA3dShaderResourceViewId shaderResourceViewId = pSRIds[i];
5571 if (shaderResourceViewId != SVGA3D_INVALID_ID)
5572 {
5573 ASSERT_GUEST_RETURN(shaderResourceViewId < pDXContext->pBackendDXContext->cShaderResourceView, VERR_INVALID_PARAMETER);
5574
5575 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId];
5576 Assert(pDXView->u.pShaderResourceView);
5577 papShaderResourceView[i] = pDXView->u.pShaderResourceView;
5578 }
5579 else
5580 papShaderResourceView[i] = NULL;
5581 }
5582
5583 dxShaderResourceViewSet(pDevice, type, 0, SVGA3D_DX_MAX_SRVIEWS, papShaderResourceView);
5584 return VINF_SUCCESS;
5585}
5586
5587
5588static DECLCALLBACK(int) vmsvga3dBackDXSetShaderResources(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startView, SVGA3dShaderType type, uint32_t cShaderResourceViewId, SVGA3dShaderResourceViewId const *paShaderResourceViewId)
5589{
5590 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5591 RT_NOREF(pBackend);
5592
5593 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5594 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5595
5596 RT_NOREF(startView, type, cShaderResourceViewId, paShaderResourceViewId);
5597
5598 return VINF_SUCCESS;
5599}
5600
5601
5602static DECLCALLBACK(int) vmsvga3dBackDXSetShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGA3dShaderType type)
5603{
5604 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5605 RT_NOREF(pBackend);
5606
5607 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5608 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5609
5610 RT_NOREF(shaderId, type);
5611
5612 return VINF_SUCCESS;
5613}
5614
5615
5616static DECLCALLBACK(int) vmsvga3dBackDXSetSamplers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startSampler, SVGA3dShaderType type, uint32_t cSamplerId, SVGA3dSamplerId const *paSamplerId)
5617{
5618 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5619 RT_NOREF(pBackend);
5620
5621 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5622 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5623
5624 ID3D11SamplerState *papSamplerState[SVGA3D_DX_MAX_SAMPLERS];
5625 for (uint32_t i = 0; i < cSamplerId; ++i)
5626 {
5627 SVGA3dSamplerId samplerId = paSamplerId[i];
5628 if (samplerId != SVGA3D_INVALID_ID)
5629 {
5630 ASSERT_GUEST_RETURN(samplerId < pDXContext->pBackendDXContext->cSamplerState, VERR_INVALID_PARAMETER);
5631 papSamplerState[i] = pDXContext->pBackendDXContext->papSamplerState[samplerId];
5632 }
5633 else
5634 papSamplerState[i] = NULL;
5635 }
5636
5637 dxSamplerSet(pDevice, type, startSampler, cSamplerId, papSamplerState);
5638 return VINF_SUCCESS;
5639}
5640
5641
5642static void vboxDXMatchShaderInput(DXSHADER *pDXShader, DXSHADER *pDXShaderPrior)
5643{
5644 /* For each input generic attribute of the shader find corresponding entry in the prior shader. */
5645 for (uint32_t i = 0; i < pDXShader->shaderInfo.cInputSignature; ++i)
5646 {
5647 SVGA3dDXSignatureEntry const *pSignatureEntry = &pDXShader->shaderInfo.aInputSignature[i];
5648 DXShaderAttributeSemantic *pSemantic = &pDXShader->shaderInfo.aInputSemantic[i];
5649
5650 if (pSignatureEntry->semanticName != SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED)
5651 continue;
5652
5653 int iMatch = -1;
5654 for (uint32_t iPrior = 0; iPrior < pDXShaderPrior->shaderInfo.cOutputSignature; ++iPrior)
5655 {
5656 SVGA3dDXSignatureEntry const *pPriorSignatureEntry = &pDXShaderPrior->shaderInfo.aOutputSignature[iPrior];
5657
5658 if (pPriorSignatureEntry->semanticName != SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED)
5659 continue;
5660
5661 if (pPriorSignatureEntry->registerIndex == pSignatureEntry->registerIndex)
5662 {
5663 iMatch = iPrior;
5664 if (pPriorSignatureEntry->mask == pSignatureEntry->mask)
5665 break; /* Exact match, no need to continue search. */
5666 }
5667 }
5668
5669 if (iMatch >= 0)
5670 {
5671 SVGA3dDXSignatureEntry const *pPriorSignatureEntry = &pDXShaderPrior->shaderInfo.aOutputSignature[iMatch];
5672 DXShaderAttributeSemantic const *pPriorSemantic = &pDXShaderPrior->shaderInfo.aOutputSemantic[iMatch];
5673
5674 Assert(pPriorSignatureEntry->registerIndex == pSignatureEntry->registerIndex);
5675 Assert(pPriorSignatureEntry->mask == pSignatureEntry->mask);
5676 RT_NOREF(pPriorSignatureEntry);
5677
5678 pSemantic->SemanticIndex = pPriorSemantic->SemanticIndex;
5679 }
5680 }
5681}
5682
5683
5684static void vboxDXMatchShaderSignatures(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, DXSHADER *pDXShader)
5685{
5686 SVGA3dShaderId const shaderIdVS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_VS - SVGA3D_SHADERTYPE_MIN].shaderId;
5687 SVGA3dShaderId const shaderIdHS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_HS - SVGA3D_SHADERTYPE_MIN].shaderId;
5688 SVGA3dShaderId const shaderIdDS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_DS - SVGA3D_SHADERTYPE_MIN].shaderId;
5689 SVGA3dShaderId const shaderIdGS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_GS - SVGA3D_SHADERTYPE_MIN].shaderId;
5690 SVGA3dShaderId const shaderIdPS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_PS - SVGA3D_SHADERTYPE_MIN].shaderId;
5691
5692 /* Try to fix the input semantic indices. Output is usually not changed. */
5693 switch (pDXShader->enmShaderType)
5694 {
5695 case SVGA3D_SHADERTYPE_VS:
5696 {
5697 /* Match input to input layout, which sets generic semantic indices to the source registerIndex (dxCreateInputLayout). */
5698 for (uint32_t i = 0; i < pDXShader->shaderInfo.cInputSignature; ++i)
5699 {
5700 SVGA3dDXSignatureEntry const *pSignatureEntry = &pDXShader->shaderInfo.aInputSignature[i];
5701 DXShaderAttributeSemantic *pSemantic = &pDXShader->shaderInfo.aInputSemantic[i];
5702
5703 if (pSignatureEntry->semanticName != SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED)
5704 continue;
5705
5706 pSemantic->SemanticIndex = pSignatureEntry->registerIndex;
5707 }
5708 break;
5709 }
5710 case SVGA3D_SHADERTYPE_HS:
5711 {
5712 /* Input of a HS shader is the output of VS. */
5713 DXSHADER *pDXShaderPrior;
5714 if (shaderIdVS != SVGA3D_INVALID_ID)
5715 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdVS];
5716 else
5717 pDXShaderPrior = NULL;
5718
5719 if (pDXShaderPrior)
5720 vboxDXMatchShaderInput(pDXShader, pDXShaderPrior);
5721
5722 break;
5723 }
5724 case SVGA3D_SHADERTYPE_DS:
5725 {
5726 /* Input of a DS shader is the output of HS. */
5727 DXSHADER *pDXShaderPrior;
5728 if (shaderIdHS != SVGA3D_INVALID_ID)
5729 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdHS];
5730 else
5731 pDXShaderPrior = NULL;
5732
5733 if (pDXShaderPrior)
5734 vboxDXMatchShaderInput(pDXShader, pDXShaderPrior);
5735
5736 break;
5737 }
5738 case SVGA3D_SHADERTYPE_GS:
5739 {
5740 /* Input signature of a GS shader is the output of DS or VS. */
5741 DXSHADER *pDXShaderPrior;
5742 if (shaderIdDS != SVGA3D_INVALID_ID)
5743 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdDS];
5744 else if (shaderIdVS != SVGA3D_INVALID_ID)
5745 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdVS];
5746 else
5747 pDXShaderPrior = NULL;
5748
5749 if (pDXShaderPrior)
5750 {
5751 /* If GS shader does not have input signature (Windows guest can do that),
5752 * then assign the prior shader signature as GS input.
5753 */
5754 if (pDXShader->shaderInfo.cInputSignature == 0)
5755 {
5756 pDXShader->shaderInfo.cInputSignature = pDXShaderPrior->shaderInfo.cOutputSignature;
5757 memcpy(pDXShader->shaderInfo.aInputSignature,
5758 pDXShaderPrior->shaderInfo.aOutputSignature,
5759 pDXShaderPrior->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
5760 memcpy(pDXShader->shaderInfo.aInputSemantic,
5761 pDXShaderPrior->shaderInfo.aOutputSemantic,
5762 pDXShaderPrior->shaderInfo.cOutputSignature * sizeof(DXShaderAttributeSemantic));
5763 }
5764 else
5765 vboxDXMatchShaderInput(pDXShader, pDXShaderPrior);
5766 }
5767
5768 /* Output signature of a GS shader is the input of the pixel shader. */
5769 if (shaderIdPS != SVGA3D_INVALID_ID)
5770 {
5771 /* If GS shader does not have output signature (Windows guest can do that),
5772 * then assign the PS shader signature as GS output.
5773 */
5774 if (pDXShader->shaderInfo.cOutputSignature == 0)
5775 {
5776 DXSHADER const *pDXShaderPosterior = &pDXContext->pBackendDXContext->paShader[shaderIdPS];
5777 pDXShader->shaderInfo.cOutputSignature = pDXShaderPosterior->shaderInfo.cInputSignature;
5778 memcpy(pDXShader->shaderInfo.aOutputSignature,
5779 pDXShaderPosterior->shaderInfo.aInputSignature,
5780 pDXShaderPosterior->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
5781 memcpy(pDXShader->shaderInfo.aOutputSemantic,
5782 pDXShaderPosterior->shaderInfo.aInputSemantic,
5783 pDXShaderPosterior->shaderInfo.cInputSignature * sizeof(DXShaderAttributeSemantic));
5784 }
5785 }
5786
5787 SVGA3dStreamOutputId const soid = pDXContext->svgaDXContext.streamOut.soid;
5788 if (soid != SVGA3D_INVALID_ID)
5789 {
5790 ASSERT_GUEST_RETURN_VOID(soid < pDXContext->pBackendDXContext->cStreamOutput);
5791
5792 /* Set semantic names and indices for SO declaration entries according to the shader output. */
5793 SVGACOTableDXStreamOutputEntry const *pStreamOutputEntry = &pDXContext->cot.paStreamOutput[soid];
5794 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
5795
5796 if (pDXStreamOutput->cDeclarationEntry == 0)
5797 {
5798 int rc = dxDefineStreamOutput(pThisCC, pDXContext, soid, pStreamOutputEntry, pDXShader);
5799 AssertRCReturnVoid(rc);
5800#ifdef LOG_ENABLED
5801 Log6(("Stream output declaration:\n\n"));
5802 Log6(("Stream SemanticName SemanticIndex StartComponent ComponentCount OutputSlot\n"));
5803 Log6(("------ -------------- ------------- -------------- -------------- ----------\n"));
5804 for (unsigned i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
5805 {
5806 D3D11_SO_DECLARATION_ENTRY *p = &pDXStreamOutput->aDeclarationEntry[i];
5807 Log6(("%d %-14s %d %d %d %d\n",
5808 p->Stream, p->SemanticName, p->SemanticIndex, p->StartComponent, p->ComponentCount, p->OutputSlot));
5809 }
5810 Log6(("\n"));
5811#endif
5812
5813 }
5814 }
5815 break;
5816 }
5817 case SVGA3D_SHADERTYPE_PS:
5818 {
5819 /* Input of a PS shader is the output of GS, DS or VS. */
5820 DXSHADER *pDXShaderPrior;
5821 if (shaderIdGS != SVGA3D_INVALID_ID)
5822 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdGS];
5823 else if (shaderIdDS != SVGA3D_INVALID_ID)
5824 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdDS];
5825 else if (shaderIdVS != SVGA3D_INVALID_ID)
5826 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdVS];
5827 else
5828 pDXShaderPrior = NULL;
5829
5830 if (pDXShaderPrior)
5831 vboxDXMatchShaderInput(pDXShader, pDXShaderPrior);
5832 break;
5833 }
5834 default:
5835 break;
5836 }
5837
5838 /* Intermediate shaders normally have both input and output signatures. However it is ok if they do not.
5839 * Just catch this unusual case in order to see if everything is fine.
5840 */
5841 Assert( ( pDXShader->enmShaderType == SVGA3D_SHADERTYPE_VS
5842 || pDXShader->enmShaderType == SVGA3D_SHADERTYPE_PS
5843 || pDXShader->enmShaderType == SVGA3D_SHADERTYPE_CS)
5844 || (pDXShader->shaderInfo.cInputSignature && pDXShader->shaderInfo.cOutputSignature));
5845}
5846
5847
5848static void dxCreateInputLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, DXSHADER *pDXShader)
5849{
5850 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5851 AssertReturnVoid(pDevice->pDevice);
5852
5853 SVGACOTableDXElementLayoutEntry const *pEntry = &pDXContext->cot.paElementLayout[elementLayoutId];
5854 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
5855
5856 if (pDXElementLayout->cElementDesc == 0)
5857 {
5858 /* Semantic name is not interpreted by D3D, therefore arbitrary names can be used
5859 * if they are consistent between the element layout and shader input signature.
5860 * "In general, data passed between pipeline stages is completely generic and is not uniquely
5861 * interpreted by the system; arbitrary semantics are allowed ..."
5862 *
5863 * However D3D runtime insists that "SemanticName string ("POSITIO1") cannot end with a number."
5864 *
5865 * System-Value semantics ("SV_*") between shaders require proper names of course.
5866 * But they are irrelevant for input attributes.
5867 */
5868 pDXElementLayout->cElementDesc = pEntry->numDescs;
5869 for (uint32_t i = 0; i < pEntry->numDescs; ++i)
5870 {
5871 D3D11_INPUT_ELEMENT_DESC *pDst = &pDXElementLayout->aElementDesc[i];
5872 SVGA3dInputElementDesc const *pSrc = &pEntry->descs[i];
5873 pDst->SemanticName = "ATTRIB";
5874 pDst->SemanticIndex = pSrc->inputRegister;
5875 pDst->Format = vmsvgaDXSurfaceFormat2Dxgi(pSrc->format);
5876 Assert(pDst->Format != DXGI_FORMAT_UNKNOWN);
5877 pDst->InputSlot = pSrc->inputSlot;
5878 pDst->AlignedByteOffset = pSrc->alignedByteOffset;
5879 pDst->InputSlotClass = (D3D11_INPUT_CLASSIFICATION)pSrc->inputSlotClass;
5880 pDst->InstanceDataStepRate = pSrc->instanceDataStepRate;
5881 }
5882 }
5883
5884 HRESULT hr = pDevice->pDevice->CreateInputLayout(pDXElementLayout->aElementDesc,
5885 pDXElementLayout->cElementDesc,
5886 pDXShader->pvDXBC,
5887 pDXShader->cbDXBC,
5888 &pDXElementLayout->pElementLayout);
5889 Assert(SUCCEEDED(hr)); RT_NOREF(hr);
5890}
5891
5892
5893static void dxSetConstantBuffers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5894{
5895//DEBUG_BREAKPOINT_TEST();
5896 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5897 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5898 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
5899
5900 AssertCompile(RT_ELEMENTS(pBackendDXContext->resources.shaderState[0].constantBuffers) == SVGA3D_DX_MAX_CONSTBUFFERS);
5901
5902 for (uint32_t idxShaderState = 0; idxShaderState < SVGA3D_NUM_SHADERTYPE; ++idxShaderState)
5903 {
5904 SVGA3dShaderType const shaderType = (SVGA3dShaderType)(idxShaderState + SVGA3D_SHADERTYPE_MIN);
5905 for (uint32_t idxSlot = 0; idxSlot < SVGA3D_DX_MAX_CONSTBUFFERS; ++idxSlot)
5906 {
5907 ID3D11Buffer **pBufferContext = &pBackendDXContext->resources.shaderState[idxShaderState].constantBuffers[idxSlot];
5908 ID3D11Buffer **pBufferPipeline = &pBackend->resources.shaderState[idxShaderState].constantBuffers[idxSlot];
5909 if (*pBufferContext != *pBufferPipeline)
5910 {
5911 LogFunc(("constant buffer: [%u][%u]: %p -> %p\n",
5912 idxShaderState, idxSlot, *pBufferPipeline, *pBufferContext));
5913 dxConstantBufferSet(pDXDevice, idxSlot, shaderType, *pBufferContext);
5914
5915 if (*pBufferContext)
5916 (*pBufferContext)->AddRef();
5917 D3D_RELEASE(*pBufferPipeline);
5918 *pBufferPipeline = *pBufferContext;
5919 }
5920 }
5921 }
5922}
5923
5924static void dxSetVertexBuffers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5925{
5926//DEBUG_BREAKPOINT_TEST();
5927 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5928 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5929 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
5930
5931 AssertCompile(RT_ELEMENTS(pBackendDXContext->resources.inputAssembly.vertexBuffers) == SVGA3D_DX_MAX_VERTEXBUFFERS);
5932
5933 ID3D11Buffer *paResources[SVGA3D_DX_MAX_VERTEXBUFFERS];
5934 UINT paStride[SVGA3D_DX_MAX_VERTEXBUFFERS];
5935 UINT paOffset[SVGA3D_DX_MAX_VERTEXBUFFERS];
5936
5937 int32_t idxMaxSlot = -1;
5938 for (uint32_t i = 0; i < SVGA3D_DX_MAX_VERTEXBUFFERS; ++i)
5939 {
5940 DXBOUNDVERTEXBUFFER *pBufferContext = &pBackendDXContext->resources.inputAssembly.vertexBuffers[i];
5941 DXBOUNDVERTEXBUFFER *pBufferPipeline = &pBackend->resources.inputAssembly.vertexBuffers[i];
5942 if ( pBufferContext->pBuffer != pBufferPipeline->pBuffer
5943 || pBufferContext->stride != pBufferPipeline->stride
5944 || pBufferContext->offset != pBufferPipeline->offset)
5945 {
5946 LogFunc(("vertex buffer: [%u]: sid = %u, %p -> %p\n",
5947 i, pDXContext->svgaDXContext.inputAssembly.vertexBuffers[i].bufferId, pBufferPipeline->pBuffer, pBufferContext->pBuffer));
5948
5949 if (pBufferContext->pBuffer != pBufferPipeline->pBuffer)
5950 {
5951 if (pBufferContext->pBuffer)
5952 pBufferContext->pBuffer->AddRef();
5953 D3D_RELEASE(pBufferPipeline->pBuffer);
5954 }
5955 *pBufferPipeline = *pBufferContext;
5956
5957 idxMaxSlot = i;
5958 }
5959
5960 paResources[i] = pBufferContext->pBuffer;
5961 if (pBufferContext->pBuffer)
5962 {
5963 paStride[i] = pBufferContext->stride;
5964 paOffset[i] = pBufferContext->offset;
5965 }
5966 else
5967 {
5968 paStride[i] = 0;
5969 paOffset[i] = 0;
5970 }
5971 }
5972
5973 if (idxMaxSlot >= 0)
5974 pDXDevice->pImmediateContext->IASetVertexBuffers(0, idxMaxSlot + 1, paResources, paStride, paOffset);
5975}
5976
5977static void dxSetIndexBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5978{
5979//DEBUG_BREAKPOINT_TEST();
5980 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5981 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5982 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
5983
5984 DXBOUNDINDEXBUFFER *pBufferContext = &pBackendDXContext->resources.inputAssembly.indexBuffer;
5985 DXBOUNDINDEXBUFFER *pBufferPipeline = &pBackend->resources.inputAssembly.indexBuffer;
5986 if ( pBufferContext->pBuffer != pBufferPipeline->pBuffer
5987 || pBufferContext->indexBufferOffset != pBufferPipeline->indexBufferOffset
5988 || pBufferContext->indexBufferFormat != pBufferPipeline->indexBufferFormat)
5989 {
5990 LogFunc(("index_buffer: sid = %u, %p -> %p\n",
5991 pDXContext->svgaDXContext.inputAssembly.indexBufferSid, pBufferPipeline->pBuffer, pBufferContext->pBuffer));
5992
5993 if (pBufferContext->pBuffer != pBufferPipeline->pBuffer)
5994 {
5995 if (pBufferContext->pBuffer)
5996 pBufferContext->pBuffer->AddRef();
5997 D3D_RELEASE(pBufferPipeline->pBuffer);
5998 }
5999 *pBufferPipeline = *pBufferContext;
6000
6001 pDXDevice->pImmediateContext->IASetIndexBuffer(pBufferContext->pBuffer, pBufferContext->indexBufferFormat, pBufferContext->indexBufferOffset);
6002 }
6003}
6004
6005static void dxSetupPipeline(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6006{
6007 /* Make sure that any draw operations on shader resource views have finished. */
6008 AssertCompile(RT_ELEMENTS(pDXContext->svgaDXContext.shaderState) == SVGA3D_NUM_SHADERTYPE);
6009 AssertCompile(RT_ELEMENTS(pDXContext->svgaDXContext.shaderState[0].shaderResources) == SVGA3D_DX_MAX_SRVIEWS);
6010
6011 int rc;
6012
6013 /* Unbind render target views because they mught be (re-)used as shader resource views. */
6014 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6015 pDXDevice->pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 0, NULL, NULL);
6016 for (unsigned i = 0; i < SVGA3D_DX11_1_MAX_UAVIEWS; ++i)
6017 {
6018 ID3D11UnorderedAccessView *pNullUA = 0;
6019 pDXDevice->pImmediateContext->CSSetUnorderedAccessViews(i, 1, &pNullUA, NULL);
6020 }
6021
6022 dxSetConstantBuffers(pThisCC, pDXContext);
6023 dxSetVertexBuffers(pThisCC, pDXContext);
6024 dxSetIndexBuffer(pThisCC, pDXContext);
6025
6026 /*
6027 * Shader resources
6028 */
6029
6030 /* Make sure that the shader resource views exist. */
6031 for (uint32_t idxShaderState = 0; idxShaderState < SVGA3D_NUM_SHADERTYPE; ++idxShaderState)
6032 {
6033 for (uint32_t idxSR = 0; idxSR < SVGA3D_DX_MAX_SRVIEWS; ++idxSR)
6034 {
6035 SVGA3dShaderResourceViewId const shaderResourceViewId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[idxSR];
6036 if (shaderResourceViewId != SVGA3D_INVALID_ID)
6037 {
6038 ASSERT_GUEST_RETURN_VOID(shaderResourceViewId < pDXContext->pBackendDXContext->cShaderResourceView);
6039
6040 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
6041 AssertContinue(pSRViewEntry != NULL);
6042
6043 uint32_t const sid = pSRViewEntry->sid;
6044
6045 PVMSVGA3DSURFACE pSurface;
6046 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
6047 if (RT_FAILURE(rc))
6048 {
6049 AssertMsgFailed(("sid = %u, rc = %Rrc\n", sid, rc));
6050 continue;
6051 }
6052
6053 /* The guest might have invalidated the surface in which case pSurface->pBackendSurface is NULL. */
6054 /** @todo This is not needed for "single DX device" mode. */
6055 if (pSurface->pBackendSurface)
6056 {
6057 /* Wait for the surface to finish drawing. */
6058 dxSurfaceWait(pThisCC->svga.p3dState, pSurface, pDXContext->cid);
6059 }
6060
6061 /* If a view has not been created yet, do it now. */
6062 if (!pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId].u.pView)
6063 {
6064//DEBUG_BREAKPOINT_TEST();
6065 LogFunc(("Re-creating SRV: sid=%u srvid = %u\n", sid, shaderResourceViewId));
6066 rc = dxDefineShaderResourceView(pThisCC, pDXContext, shaderResourceViewId, pSRViewEntry);
6067 AssertContinue(RT_SUCCESS(rc));
6068 }
6069
6070 LogFunc(("srv[%d][%d] sid = %u, srvid = %u\n", idxShaderState, idxSR, sid, shaderResourceViewId));
6071
6072#ifdef DUMP_BITMAPS
6073 SVGA3dSurfaceImageId image;
6074 image.sid = sid;
6075 image.face = 0;
6076 image.mipmap = 0;
6077 VMSVGA3D_MAPPED_SURFACE map;
6078 int rc2 = vmsvga3dSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
6079 if (RT_SUCCESS(rc2))
6080 {
6081 vmsvga3dMapWriteBmpFile(&map, "sr-");
6082 vmsvga3dSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
6083 }
6084 else
6085 Log(("Map failed %Rrc\n", rc));
6086#endif
6087 }
6088 }
6089
6090 /* Set shader resources. */
6091 rc = dxSetShaderResources(pThisCC, pDXContext, (SVGA3dShaderType)(idxShaderState + SVGA3D_SHADERTYPE_MIN));
6092 AssertRC(rc);
6093 }
6094
6095 /*
6096 * Compute shader unordered access views
6097 */
6098
6099 for (uint32_t idxUA = 0; idxUA < SVGA3D_DX11_1_MAX_UAVIEWS; ++idxUA)
6100 {
6101 SVGA3dUAViewId const uaViewId = pDXContext->svgaDXContext.csuaViewIds[idxUA];
6102 if (uaViewId != SVGA3D_INVALID_ID)
6103 {
6104//DEBUG_BREAKPOINT_TEST();
6105 ASSERT_GUEST_RETURN_VOID(uaViewId < pDXContext->pBackendDXContext->cUnorderedAccessView);
6106
6107 SVGACOTableDXUAViewEntry const *pUAViewEntry = dxGetUnorderedAccessViewEntry(pDXContext, uaViewId);
6108 AssertContinue(pUAViewEntry != NULL);
6109
6110 uint32_t const sid = pUAViewEntry->sid;
6111
6112 PVMSVGA3DSURFACE pSurface;
6113 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
6114 AssertRCReturnVoid(rc);
6115
6116 /* The guest might have invalidated the surface in which case pSurface->pBackendSurface is NULL. */
6117 /** @todo This is not needed for "single DX device" mode. */
6118 if (pSurface->pBackendSurface)
6119 {
6120 /* Wait for the surface to finish drawing. */
6121 dxSurfaceWait(pThisCC->svga.p3dState, pSurface, pDXContext->cid);
6122 }
6123
6124 /* If a view has not been created yet, do it now. */
6125 if (!pDXContext->pBackendDXContext->paUnorderedAccessView[uaViewId].u.pView)
6126 {
6127 LogFunc(("Re-creating UAV: sid=%u uaid = %u\n", sid, uaViewId));
6128 rc = dxDefineUnorderedAccessView(pThisCC, pDXContext, uaViewId, pUAViewEntry);
6129 AssertContinue(RT_SUCCESS(rc));
6130 }
6131
6132 LogFunc(("csuav[%d] sid = %u, uaid = %u\n", idxUA, sid, uaViewId));
6133 }
6134 }
6135
6136 /* Set views. */
6137 rc = dxSetCSUnorderedAccessViews(pThisCC, pDXContext);
6138 AssertRC(rc);
6139
6140 /*
6141 * Render targets and unordered access views.
6142 */
6143
6144 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6145 AssertReturnVoid(pDevice->pDevice);
6146
6147 /* Make sure that the render target views exist. Similar to SRVs. */
6148 if (pDXContext->svgaDXContext.renderState.depthStencilViewId != SVGA3D_INVALID_ID)
6149 {
6150 uint32_t const viewId = pDXContext->svgaDXContext.renderState.depthStencilViewId;
6151
6152 ASSERT_GUEST_RETURN_VOID(viewId < pDXContext->pBackendDXContext->cDepthStencilView);
6153
6154 SVGACOTableDXDSViewEntry const *pDSViewEntry = dxGetDepthStencilViewEntry(pDXContext, viewId);
6155 AssertReturnVoid(pDSViewEntry != NULL);
6156
6157 PVMSVGA3DSURFACE pSurface;
6158 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pDSViewEntry->sid, &pSurface);
6159 AssertRCReturnVoid(rc);
6160
6161 /* If a view has not been created yet, do it now. */
6162 if (!pDXContext->pBackendDXContext->paDepthStencilView[viewId].u.pView)
6163 {
6164//DEBUG_BREAKPOINT_TEST();
6165 LogFunc(("Re-creating DSV: sid=%u dsvid = %u\n", pDSViewEntry->sid, viewId));
6166 rc = dxDefineDepthStencilView(pThisCC, pDXContext, viewId, pDSViewEntry);
6167 AssertReturnVoid(RT_SUCCESS(rc));
6168 }
6169
6170 LogFunc(("dsv sid = %u, dsvid = %u\n", pDSViewEntry->sid, viewId));
6171 }
6172
6173 for (uint32_t i = 0; i < SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS; ++i)
6174 {
6175 if (pDXContext->svgaDXContext.renderState.renderTargetViewIds[i] != SVGA3D_INVALID_ID)
6176 {
6177 uint32_t const viewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
6178
6179 ASSERT_GUEST_RETURN_VOID(viewId < pDXContext->pBackendDXContext->cRenderTargetView);
6180
6181 SVGACOTableDXRTViewEntry const *pRTViewEntry = dxGetRenderTargetViewEntry(pDXContext, viewId);
6182 AssertReturnVoid(pRTViewEntry != NULL);
6183
6184 PVMSVGA3DSURFACE pSurface;
6185 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pRTViewEntry->sid, &pSurface);
6186 AssertRCReturnVoid(rc);
6187
6188 /* If a view has not been created yet, do it now. */
6189 if (!pDXContext->pBackendDXContext->paRenderTargetView[viewId].u.pView)
6190 {
6191//DEBUG_BREAKPOINT_TEST();
6192 LogFunc(("Re-creating RTV: sid=%u rtvid = %u\n", pRTViewEntry->sid, viewId));
6193 rc = dxDefineRenderTargetView(pThisCC, pDXContext, viewId, pRTViewEntry);
6194 AssertReturnVoid(RT_SUCCESS(rc));
6195 }
6196
6197 LogFunc(("rtv sid = %u, rtvid = %u\n", pRTViewEntry->sid, viewId));
6198 }
6199 }
6200
6201 for (uint32_t idxUA = 0; idxUA < SVGA3D_DX11_1_MAX_UAVIEWS; ++idxUA)
6202 {
6203 SVGA3dUAViewId const uaViewId = pDXContext->svgaDXContext.uaViewIds[idxUA];
6204 if (uaViewId != SVGA3D_INVALID_ID)
6205 {
6206//DEBUG_BREAKPOINT_TEST();
6207 ASSERT_GUEST_RETURN_VOID(uaViewId < pDXContext->pBackendDXContext->cUnorderedAccessView);
6208
6209 SVGACOTableDXUAViewEntry const *pUAViewEntry = dxGetUnorderedAccessViewEntry(pDXContext, uaViewId);
6210 AssertContinue(pUAViewEntry != NULL);
6211
6212 uint32_t const sid = pUAViewEntry->sid;
6213
6214 PVMSVGA3DSURFACE pSurface;
6215 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
6216 AssertRCReturnVoid(rc);
6217
6218 /* The guest might have invalidated the surface in which case pSurface->pBackendSurface is NULL. */
6219 /** @todo This is not needed for "single DX device" mode. */
6220 if (pSurface->pBackendSurface)
6221 {
6222 /* Wait for the surface to finish drawing. */
6223 dxSurfaceWait(pThisCC->svga.p3dState, pSurface, pDXContext->cid);
6224 }
6225
6226 /* If a view has not been created yet, do it now. */
6227 if (!pDXContext->pBackendDXContext->paUnorderedAccessView[uaViewId].u.pView)
6228 {
6229 LogFunc(("Re-creating UAV: sid=%u uaid = %u\n", sid, uaViewId));
6230 rc = dxDefineUnorderedAccessView(pThisCC, pDXContext, uaViewId, pUAViewEntry);
6231 AssertContinue(RT_SUCCESS(rc));
6232 }
6233
6234 LogFunc(("uav[%d] sid = %u, uaid = %u\n", idxUA, sid, uaViewId));
6235 }
6236 }
6237
6238 /* Set render targets. */
6239 rc = dxSetRenderTargets(pThisCC, pDXContext);
6240 AssertRC(rc);
6241
6242 /*
6243 * Shaders
6244 */
6245
6246 for (uint32_t idxShaderState = 0; idxShaderState < SVGA3D_NUM_SHADERTYPE; ++idxShaderState)
6247 {
6248 DXSHADER *pDXShader;
6249 SVGA3dShaderType const shaderType = (SVGA3dShaderType)(idxShaderState + SVGA3D_SHADERTYPE_MIN);
6250 SVGA3dShaderId const shaderId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId;
6251
6252 if (shaderId != SVGA3D_INVALID_ID)
6253 {
6254 pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6255 if (pDXShader->pShader == NULL)
6256 {
6257 /* Create a new shader. */
6258
6259 /* Apply resource types to a pixel shader. */
6260 if (shaderType == SVGA3D_SHADERTYPE_PS) /* Others too? */
6261 {
6262 VGPU10_RESOURCE_DIMENSION aResourceDimension[SVGA3D_DX_MAX_SRVIEWS];
6263 RT_ZERO(aResourceDimension);
6264 VGPU10_RESOURCE_RETURN_TYPE aResourceReturnType[SVGA3D_DX_MAX_SRVIEWS];
6265 RT_ZERO(aResourceReturnType);
6266 uint32_t cResources = 0;
6267
6268 for (uint32_t idxSR = 0; idxSR < SVGA3D_DX_MAX_SRVIEWS; ++idxSR)
6269 {
6270 SVGA3dShaderResourceViewId const shaderResourceViewId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[idxSR];
6271 if (shaderResourceViewId != SVGA3D_INVALID_ID)
6272 {
6273 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
6274 AssertContinue(pSRViewEntry != NULL);
6275
6276 PVMSVGA3DSURFACE pSurface;
6277 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pSRViewEntry->sid, &pSurface);
6278 AssertRCReturnVoid(rc);
6279
6280 aResourceReturnType[idxSR] = DXShaderResourceReturnTypeFromFormat(pSRViewEntry->format);
6281
6282 switch (pSRViewEntry->resourceDimension)
6283 {
6284 case SVGA3D_RESOURCE_BUFFEREX:
6285 case SVGA3D_RESOURCE_BUFFER:
6286 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_BUFFER;
6287 break;
6288 case SVGA3D_RESOURCE_TEXTURE1D:
6289 if (pSurface->surfaceDesc.numArrayElements <= 1)
6290 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE1D;
6291 else
6292 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE1DARRAY;
6293 break;
6294 case SVGA3D_RESOURCE_TEXTURE2D:
6295 if (pSurface->surfaceDesc.numArrayElements <= 1)
6296 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
6297 else
6298 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE2DARRAY;
6299 break;
6300 case SVGA3D_RESOURCE_TEXTURE3D:
6301 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE3D;
6302 break;
6303 case SVGA3D_RESOURCE_TEXTURECUBE:
6304 if (pSurface->surfaceDesc.numArrayElements <= 6)
6305 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURECUBE;
6306 else
6307 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURECUBEARRAY;
6308 break;
6309 default:
6310 ASSERT_GUEST_FAILED();
6311 aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
6312 }
6313
6314 cResources = idxSR + 1;
6315 }
6316 }
6317
6318 rc = DXShaderUpdateResources(&pDXShader->shaderInfo, aResourceDimension, aResourceReturnType, cResources);
6319 AssertRC(rc); /* Ignore rc because the shader will most likely work anyway. */
6320 }
6321
6322 vboxDXMatchShaderSignatures(pThisCC, pDXContext, pDXShader);
6323
6324 rc = DXShaderCreateDXBC(&pDXShader->shaderInfo, &pDXShader->pvDXBC, &pDXShader->cbDXBC);
6325 if (RT_SUCCESS(rc))
6326 {
6327#ifdef LOG_ENABLED
6328 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6329 if (pBackend->pfnD3DDisassemble && LogIs6Enabled())
6330 {
6331 ID3D10Blob *pBlob = 0;
6332 HRESULT hr2 = pBackend->pfnD3DDisassemble(pDXShader->pvDXBC, pDXShader->cbDXBC, 0, NULL, &pBlob);
6333 if (SUCCEEDED(hr2) && pBlob && pBlob->GetBufferSize())
6334 Log6(("%s\n", pBlob->GetBufferPointer()));
6335 else
6336 AssertFailed();
6337 D3D_RELEASE(pBlob);
6338 }
6339#endif
6340
6341 HRESULT hr = dxShaderCreate(pThisCC, pDXContext, pDXShader);
6342 if (FAILED(hr))
6343 rc = VERR_INVALID_STATE;
6344 }
6345 }
6346
6347 LogFunc(("Shader: cid=%u shid=%u type=%d, GuestSignatures %d, %Rrc\n", pDXContext->cid, shaderId, pDXShader->enmShaderType, pDXShader->shaderInfo.fGuestSignatures, rc));
6348 }
6349 else
6350 pDXShader = NULL;
6351
6352 if (RT_SUCCESS(rc))
6353 dxShaderSet(pThisCC, pDXContext, shaderType, pDXShader);
6354
6355 AssertRC(rc);
6356 }
6357
6358 /*
6359 * InputLayout
6360 */
6361 SVGA3dElementLayoutId const elementLayoutId = pDXContext->svgaDXContext.inputAssembly.layoutId;
6362 ID3D11InputLayout *pInputLayout = NULL;
6363 if (elementLayoutId != SVGA3D_INVALID_ID)
6364 {
6365 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
6366 if (!pDXElementLayout->pElementLayout)
6367 {
6368 uint32_t const idxShaderState = SVGA3D_SHADERTYPE_VS - SVGA3D_SHADERTYPE_MIN;
6369 uint32_t const shid = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId;
6370 if (shid < pDXContext->pBackendDXContext->cShader)
6371 {
6372 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shid];
6373 if (pDXShader->pvDXBC)
6374 dxCreateInputLayout(pThisCC, pDXContext, elementLayoutId, pDXShader);
6375 else
6376 LogRelMax(16, ("VMSVGA: DX shader bytecode is not available in DXSetInputLayout: shid = %u\n", shid));
6377 }
6378 else
6379 LogRelMax(16, ("VMSVGA: DX shader is not set in DXSetInputLayout: shid = 0x%x\n", shid));
6380 }
6381
6382 pInputLayout = pDXElementLayout->pElementLayout;
6383
6384 LogFunc(("Input layout id %u\n", elementLayoutId));
6385 }
6386
6387 pDevice->pImmediateContext->IASetInputLayout(pInputLayout);
6388}
6389
6390
6391static DECLCALLBACK(int) vmsvga3dBackDXDraw(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t vertexCount, uint32_t startVertexLocation)
6392{
6393 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6394 RT_NOREF(pBackend);
6395
6396 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6397 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6398
6399 dxSetupPipeline(pThisCC, pDXContext);
6400
6401 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
6402 pDevice->pImmediateContext->Draw(vertexCount, startVertexLocation);
6403 else
6404 {
6405 /*
6406 * Emulate SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of a triangle list.
6407 */
6408
6409 /* Make sure that 16 bit indices are enough. */
6410 if (vertexCount > 65535)
6411 {
6412 LogRelMax(1, ("VMSVGA: ignore Draw(TRIANGLEFAN, %u)\n", vertexCount));
6413 return VERR_NOT_SUPPORTED;
6414 }
6415
6416 /* Generate indices. */
6417 UINT const IndexCount = 3 * (vertexCount - 2); /* 3_per_triangle * num_triangles */
6418 UINT const cbAlloc = IndexCount * sizeof(USHORT);
6419 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
6420 AssertReturn(paIndices, VERR_NO_MEMORY);
6421 USHORT iVertex = 1;
6422 for (UINT i = 0; i < IndexCount; i+= 3)
6423 {
6424 paIndices[i] = 0;
6425 paIndices[i + 1] = iVertex;
6426 ++iVertex;
6427 paIndices[i + 2] = iVertex;
6428 }
6429
6430 D3D11_SUBRESOURCE_DATA InitData;
6431 InitData.pSysMem = paIndices;
6432 InitData.SysMemPitch = cbAlloc;
6433 InitData.SysMemSlicePitch = cbAlloc;
6434
6435 D3D11_BUFFER_DESC bd;
6436 RT_ZERO(bd);
6437 bd.ByteWidth = cbAlloc;
6438 bd.Usage = D3D11_USAGE_IMMUTABLE;
6439 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
6440 //bd.CPUAccessFlags = 0;
6441 //bd.MiscFlags = 0;
6442 //bd.StructureByteStride = 0;
6443
6444 ID3D11Buffer *pIndexBuffer = 0;
6445 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
6446 Assert(SUCCEEDED(hr));RT_NOREF(hr);
6447
6448 /* Save the current index buffer. */
6449 ID3D11Buffer *pSavedIndexBuffer = 0;
6450 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
6451 UINT SavedOffset = 0;
6452 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
6453
6454 /* Set up the device state. */
6455 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
6456 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
6457
6458 UINT const StartIndexLocation = 0;
6459 INT const BaseVertexLocation = startVertexLocation;
6460 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
6461
6462 /* Restore the device state. */
6463 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
6464 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
6465 D3D_RELEASE(pSavedIndexBuffer);
6466
6467 /* Cleanup. */
6468 D3D_RELEASE(pIndexBuffer);
6469 RTMemFree(paIndices);
6470 }
6471
6472 /* Note which surfaces are being drawn. */
6473 dxTrackRenderTargets(pThisCC, pDXContext);
6474
6475 return VINF_SUCCESS;
6476}
6477
6478static int dxReadBuffer(DXDEVICE *pDevice, ID3D11Buffer *pBuffer, UINT Offset, UINT Bytes, void **ppvData, uint32_t *pcbData)
6479{
6480 D3D11_BUFFER_DESC desc;
6481 RT_ZERO(desc);
6482 pBuffer->GetDesc(&desc);
6483
6484 AssertReturn( Offset < desc.ByteWidth
6485 && Bytes <= desc.ByteWidth - Offset, VERR_INVALID_STATE);
6486
6487 void *pvData = RTMemAlloc(Bytes);
6488 if (!pvData)
6489 return VERR_NO_MEMORY;
6490
6491 *ppvData = pvData;
6492 *pcbData = Bytes;
6493
6494 int rc = dxStagingBufferRealloc(pDevice, Bytes);
6495 if (RT_SUCCESS(rc))
6496 {
6497 /* Copy from the buffer to the staging buffer. */
6498 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
6499 UINT DstSubresource = 0;
6500 UINT DstX = Offset;
6501 UINT DstY = 0;
6502 UINT DstZ = 0;
6503 ID3D11Resource *pSrcResource = pBuffer;
6504 UINT SrcSubresource = 0;
6505 D3D11_BOX SrcBox;
6506 SrcBox.left = 0;
6507 SrcBox.top = 0;
6508 SrcBox.front = 0;
6509 SrcBox.right = Bytes;
6510 SrcBox.bottom = 1;
6511 SrcBox.back = 1;
6512 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
6513 pSrcResource, SrcSubresource, &SrcBox);
6514
6515 D3D11_MAPPED_SUBRESOURCE mappedResource;
6516 UINT const Subresource = 0; /* Buffers have only one subresource. */
6517 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
6518 D3D11_MAP_READ, /* MapFlags = */ 0, &mappedResource);
6519 if (SUCCEEDED(hr))
6520 {
6521 memcpy(pvData, mappedResource.pData, Bytes);
6522
6523 /* Unmap the staging buffer. */
6524 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
6525 }
6526 else
6527 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
6528
6529 }
6530
6531 if (RT_FAILURE(rc))
6532 {
6533 RTMemFree(*ppvData);
6534 *ppvData = NULL;
6535 *pcbData = 0;
6536 }
6537
6538 return rc;
6539}
6540
6541
6542static int dxDrawIndexedTriangleFan(DXDEVICE *pDevice, uint32_t IndexCountTF, uint32_t StartIndexLocationTF, int32_t BaseVertexLocationTF)
6543{
6544 /*
6545 * Emulate an indexed SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of triangle list.
6546 */
6547
6548 /* Make sure that 16 bit indices are enough. */
6549 if (IndexCountTF > 65535)
6550 {
6551 LogRelMax(1, ("VMSVGA: ignore DrawIndexed(TRIANGLEFAN, %u)\n", IndexCountTF));
6552 return VERR_NOT_SUPPORTED;
6553 }
6554
6555 /* Save the current index buffer. */
6556 ID3D11Buffer *pSavedIndexBuffer = 0;
6557 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
6558 UINT SavedOffset = 0;
6559 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
6560
6561 AssertReturn( SavedFormat == DXGI_FORMAT_R16_UINT
6562 || SavedFormat == DXGI_FORMAT_R32_UINT, VERR_NOT_SUPPORTED);
6563
6564 /* How many bytes are used by triangle fan indices. */
6565 UINT const BytesPerIndexTF = SavedFormat == DXGI_FORMAT_R16_UINT ? 2 : 4;
6566 UINT const BytesTF = BytesPerIndexTF * IndexCountTF;
6567
6568 /* Read the current index buffer content to obtain indices. */
6569 void *pvDataTF;
6570 uint32_t cbDataTF;
6571 int rc = dxReadBuffer(pDevice, pSavedIndexBuffer, StartIndexLocationTF, BytesTF, &pvDataTF, &cbDataTF);
6572 AssertRCReturn(rc, rc);
6573 AssertReturnStmt(cbDataTF >= BytesPerIndexTF, RTMemFree(pvDataTF), VERR_INVALID_STATE);
6574
6575 /* Generate indices for triangle list. */
6576 UINT const IndexCount = 3 * (IndexCountTF - 2); /* 3_per_triangle * num_triangles */
6577 UINT const cbAlloc = IndexCount * sizeof(USHORT);
6578 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
6579 AssertReturnStmt(paIndices, RTMemFree(pvDataTF), VERR_NO_MEMORY);
6580
6581 USHORT iVertex = 1;
6582 if (BytesPerIndexTF == 2)
6583 {
6584 USHORT *paIndicesTF = (USHORT *)pvDataTF;
6585 for (UINT i = 0; i < IndexCount; i+= 3)
6586 {
6587 paIndices[i] = paIndicesTF[0];
6588 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
6589 paIndices[i + 1] = paIndicesTF[iVertex];
6590 ++iVertex;
6591 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
6592 paIndices[i + 2] = paIndicesTF[iVertex];
6593 }
6594 }
6595 else
6596 {
6597 UINT *paIndicesTF = (UINT *)pvDataTF;
6598 for (UINT i = 0; i < IndexCount; i+= 3)
6599 {
6600 paIndices[i] = paIndicesTF[0];
6601 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
6602 paIndices[i + 1] = paIndicesTF[iVertex];
6603 ++iVertex;
6604 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
6605 paIndices[i + 2] = paIndicesTF[iVertex];
6606 }
6607 }
6608
6609 D3D11_SUBRESOURCE_DATA InitData;
6610 InitData.pSysMem = paIndices;
6611 InitData.SysMemPitch = cbAlloc;
6612 InitData.SysMemSlicePitch = cbAlloc;
6613
6614 D3D11_BUFFER_DESC bd;
6615 RT_ZERO(bd);
6616 bd.ByteWidth = cbAlloc;
6617 bd.Usage = D3D11_USAGE_IMMUTABLE;
6618 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
6619 //bd.CPUAccessFlags = 0;
6620 //bd.MiscFlags = 0;
6621 //bd.StructureByteStride = 0;
6622
6623 ID3D11Buffer *pIndexBuffer = 0;
6624 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
6625 Assert(SUCCEEDED(hr));RT_NOREF(hr);
6626
6627 /* Set up the device state. */
6628 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
6629 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
6630
6631 UINT const StartIndexLocation = 0;
6632 INT const BaseVertexLocation = BaseVertexLocationTF;
6633 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
6634
6635 /* Restore the device state. */
6636 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
6637 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
6638 D3D_RELEASE(pSavedIndexBuffer);
6639
6640 /* Cleanup. */
6641 D3D_RELEASE(pIndexBuffer);
6642 RTMemFree(paIndices);
6643 RTMemFree(pvDataTF);
6644
6645 return VINF_SUCCESS;
6646}
6647
6648
6649static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexed(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t indexCount, uint32_t startIndexLocation, int32_t baseVertexLocation)
6650{
6651 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6652 RT_NOREF(pBackend);
6653
6654 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6655 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6656
6657 dxSetupPipeline(pThisCC, pDXContext);
6658
6659 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
6660 pDevice->pImmediateContext->DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
6661 else
6662 {
6663 dxDrawIndexedTriangleFan(pDevice, indexCount, startIndexLocation, baseVertexLocation);
6664 }
6665
6666 /* Note which surfaces are being drawn. */
6667 dxTrackRenderTargets(pThisCC, pDXContext);
6668
6669 return VINF_SUCCESS;
6670}
6671
6672
6673static DECLCALLBACK(int) vmsvga3dBackDXDrawInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6674 uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation)
6675{
6676 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6677 RT_NOREF(pBackend);
6678
6679 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6680 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6681
6682 dxSetupPipeline(pThisCC, pDXContext);
6683
6684 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
6685
6686 pDevice->pImmediateContext->DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
6687
6688 /* Note which surfaces are being drawn. */
6689 dxTrackRenderTargets(pThisCC, pDXContext);
6690
6691 return VINF_SUCCESS;
6692}
6693
6694
6695static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6696 uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation)
6697{
6698 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6699 RT_NOREF(pBackend);
6700
6701 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6702 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6703
6704 dxSetupPipeline(pThisCC, pDXContext);
6705
6706 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
6707
6708 pDevice->pImmediateContext->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
6709
6710 /* Note which surfaces are being drawn. */
6711 dxTrackRenderTargets(pThisCC, pDXContext);
6712
6713 return VINF_SUCCESS;
6714}
6715
6716
6717static DECLCALLBACK(int) vmsvga3dBackDXDrawAuto(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6718{
6719 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6720 RT_NOREF(pBackend);
6721
6722 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6723 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6724
6725 dxSetupPipeline(pThisCC, pDXContext);
6726
6727 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
6728
6729 pDevice->pImmediateContext->DrawAuto();
6730
6731 /* Note which surfaces are being drawn. */
6732 dxTrackRenderTargets(pThisCC, pDXContext);
6733
6734 return VINF_SUCCESS;
6735}
6736
6737
6738static DECLCALLBACK(int) vmsvga3dBackDXSetInputLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId)
6739{
6740 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6741 RT_NOREF(pBackend);
6742
6743 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6744 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6745
6746 RT_NOREF(elementLayoutId);
6747
6748 return VINF_SUCCESS;
6749}
6750
6751
6752static DECLCALLBACK(int) vmsvga3dBackDXSetVertexBuffers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startBuffer, uint32_t cVertexBuffer, SVGA3dVertexBuffer const *paVertexBuffer)
6753{
6754 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6755 RT_NOREF(pBackend);
6756
6757 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6758 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6759
6760 for (uint32_t i = 0; i < cVertexBuffer; ++i)
6761 {
6762 uint32_t const idxVertexBuffer = startBuffer + i;
6763
6764 /* Get corresponding resource. Create the buffer if does not yet exist. */
6765 if (paVertexBuffer[i].sid != SVGA_ID_INVALID)
6766 {
6767 PVMSVGA3DSURFACE pSurface;
6768 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paVertexBuffer[i].sid, &pSurface);
6769 AssertRCReturn(rc, rc);
6770
6771 if (pSurface->pBackendSurface == NULL)
6772 {
6773 /* Create the resource and initialize it with the current surface data. */
6774 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
6775 AssertRCReturn(rc, rc);
6776 }
6777 Assert(pSurface->pBackendSurface->u.pBuffer);
6778
6779 DXBOUNDVERTEXBUFFER *pBoundBuffer = &pDXContext->pBackendDXContext->resources.inputAssembly.vertexBuffers[idxVertexBuffer];
6780 if ( pBoundBuffer->pBuffer != pSurface->pBackendSurface->u.pBuffer
6781 || pBoundBuffer->stride != paVertexBuffer[i].stride
6782 || pBoundBuffer->offset != paVertexBuffer[i].offset)
6783 {
6784 LogFunc(("vertex buffer: [%u]: sid = %u, offset %u, stride %u (%p -> %p)\n",
6785 idxVertexBuffer, paVertexBuffer[i].sid, paVertexBuffer[i].offset, paVertexBuffer[i].stride, pBoundBuffer->pBuffer, pSurface->pBackendSurface->u.pBuffer));
6786
6787 if (pBoundBuffer->pBuffer != pSurface->pBackendSurface->u.pBuffer)
6788 {
6789 D3D_RELEASE(pBoundBuffer->pBuffer);
6790 pBoundBuffer->pBuffer = pSurface->pBackendSurface->u.pBuffer;
6791 pBoundBuffer->pBuffer->AddRef();
6792 }
6793 pBoundBuffer->stride = paVertexBuffer[i].stride;
6794 pBoundBuffer->offset = paVertexBuffer[i].offset;
6795 }
6796 }
6797 else
6798 {
6799 DXBOUNDVERTEXBUFFER *pBoundBuffer = &pDXContext->pBackendDXContext->resources.inputAssembly.vertexBuffers[idxVertexBuffer];
6800 D3D_RELEASE(pBoundBuffer->pBuffer);
6801 pBoundBuffer->stride = 0;
6802 pBoundBuffer->offset = 0;
6803 }
6804 }
6805
6806 return VINF_SUCCESS;
6807}
6808
6809
6810static DECLCALLBACK(int) vmsvga3dBackDXSetIndexBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId sid, SVGA3dSurfaceFormat format, uint32_t offset)
6811{
6812 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6813 RT_NOREF(pBackend);
6814
6815 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6816 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6817
6818 /* Get corresponding resource. Create the buffer if does not yet exist. */
6819 if (sid != SVGA_ID_INVALID)
6820 {
6821 PVMSVGA3DSURFACE pSurface;
6822 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
6823 AssertRCReturn(rc, rc);
6824
6825 if (pSurface->pBackendSurface == NULL)
6826 {
6827 /* Create the resource and initialize it with the current surface data. */
6828 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
6829 AssertRCReturn(rc, rc);
6830 }
6831
6832 DXGI_FORMAT const enmDxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(format);
6833 AssertReturn(enmDxgiFormat == DXGI_FORMAT_R16_UINT || enmDxgiFormat == DXGI_FORMAT_R32_UINT, VERR_INVALID_PARAMETER);
6834
6835 DXBOUNDINDEXBUFFER *pBoundBuffer = &pDXContext->pBackendDXContext->resources.inputAssembly.indexBuffer;
6836 if ( pBoundBuffer->pBuffer != pSurface->pBackendSurface->u.pBuffer
6837 || pBoundBuffer->indexBufferOffset != offset
6838 || pBoundBuffer->indexBufferFormat != enmDxgiFormat)
6839 {
6840 LogFunc(("index_buffer: sid = %u, offset %u, (%p -> %p)\n",
6841 sid, offset, pBoundBuffer->pBuffer, pSurface->pBackendSurface->u.pBuffer));
6842
6843 if (pBoundBuffer->pBuffer != pSurface->pBackendSurface->u.pBuffer)
6844 {
6845 D3D_RELEASE(pBoundBuffer->pBuffer);
6846 pBoundBuffer->pBuffer = pSurface->pBackendSurface->u.pBuffer;
6847 pBoundBuffer->pBuffer->AddRef();
6848 }
6849 pBoundBuffer->indexBufferOffset = offset;
6850 pBoundBuffer->indexBufferFormat = enmDxgiFormat;
6851 }
6852 }
6853 else
6854 {
6855 DXBOUNDINDEXBUFFER *pBoundBuffer = &pDXContext->pBackendDXContext->resources.inputAssembly.indexBuffer;
6856 D3D_RELEASE(pBoundBuffer->pBuffer);
6857 pBoundBuffer->indexBufferOffset = 0;
6858 pBoundBuffer->indexBufferFormat = DXGI_FORMAT_UNKNOWN;
6859 }
6860
6861 return VINF_SUCCESS;
6862}
6863
6864static D3D11_PRIMITIVE_TOPOLOGY dxTopology(SVGA3dPrimitiveType primitiveType)
6865{
6866 static D3D11_PRIMITIVE_TOPOLOGY const aD3D11PrimitiveTopology[SVGA3D_PRIMITIVE_MAX] =
6867 {
6868 D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED,
6869 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
6870 D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
6871 D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
6872 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
6873 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
6874 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* SVGA3D_PRIMITIVE_TRIANGLEFAN: No FAN in D3D11. */
6875 D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
6876 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
6877 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
6878 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
6879 D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST,
6880 D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST,
6881 D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
6882 D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST,
6883 D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST,
6884 D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST,
6885 D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST,
6886 D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST,
6887 D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST,
6888 D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST,
6889 D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST,
6890 D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST,
6891 D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST,
6892 D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST,
6893 D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST,
6894 D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST,
6895 D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST,
6896 D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST,
6897 D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST,
6898 D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST,
6899 D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST,
6900 D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST,
6901 D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST,
6902 D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST,
6903 D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST,
6904 D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST,
6905 D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST,
6906 D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST,
6907 D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST,
6908 D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST,
6909 D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST,
6910 D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST,
6911 };
6912 return aD3D11PrimitiveTopology[primitiveType];
6913}
6914
6915static DECLCALLBACK(int) vmsvga3dBackDXSetTopology(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dPrimitiveType topology)
6916{
6917 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6918 RT_NOREF(pBackend);
6919
6920 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6921 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6922
6923 D3D11_PRIMITIVE_TOPOLOGY const enmTopology = dxTopology(topology);
6924 pDevice->pImmediateContext->IASetPrimitiveTopology(enmTopology);
6925 return VINF_SUCCESS;
6926}
6927
6928
6929static int dxSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6930{
6931 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6932 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6933
6934 UINT UAVStartSlot = 0;
6935 UINT NumUAVs = 0;
6936 ID3D11UnorderedAccessView *apUnorderedAccessViews[SVGA3D_DX11_1_MAX_UAVIEWS];
6937 UINT aUAVInitialCounts[SVGA3D_DX11_1_MAX_UAVIEWS];
6938 for (uint32_t idxUA = 0; idxUA < SVGA3D_DX11_1_MAX_UAVIEWS; ++idxUA)
6939 {
6940 SVGA3dUAViewId const uaViewId = pDXContext->svgaDXContext.uaViewIds[idxUA];
6941 if (uaViewId != SVGA3D_INVALID_ID)
6942 {
6943 if (NumUAVs == 0)
6944 UAVStartSlot = idxUA;
6945 NumUAVs = idxUA - UAVStartSlot + 1;
6946 apUnorderedAccessViews[idxUA] = pDXContext->pBackendDXContext->paUnorderedAccessView[uaViewId].u.pUnorderedAccessView;
6947
6948 SVGACOTableDXUAViewEntry const *pEntry = dxGetUnorderedAccessViewEntry(pDXContext, uaViewId);
6949 aUAVInitialCounts[idxUA] = pEntry->structureCount;
6950 }
6951 else
6952 {
6953 apUnorderedAccessViews[idxUA] = NULL;
6954 aUAVInitialCounts[idxUA] = (UINT)-1;
6955 }
6956 }
6957
6958 UINT NumRTVs = 0;
6959 ID3D11RenderTargetView *apRenderTargetViews[SVGA3D_MAX_RENDER_TARGETS];
6960 RT_ZERO(apRenderTargetViews);
6961 for (uint32_t i = 0; i < pDXContext->cRenderTargets; ++i)
6962 {
6963 SVGA3dRenderTargetViewId const renderTargetViewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
6964 if (renderTargetViewId != SVGA3D_INVALID_ID)
6965 {
6966 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->pBackendDXContext->cRenderTargetView, VERR_INVALID_PARAMETER);
6967 apRenderTargetViews[i] = pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId].u.pRenderTargetView;
6968 ++NumRTVs;
6969 }
6970 }
6971
6972 /* RTVs are followed by UAVs. */
6973 Assert(NumRTVs <= pDXContext->svgaDXContext.uavSpliceIndex);
6974
6975 ID3D11DepthStencilView *pDepthStencilView = NULL;
6976 SVGA3dDepthStencilViewId const depthStencilViewId = pDXContext->svgaDXContext.renderState.depthStencilViewId;
6977 if (depthStencilViewId != SVGA_ID_INVALID)
6978 pDepthStencilView = pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId].u.pDepthStencilView;
6979
6980 pDevice->pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(NumRTVs,
6981 apRenderTargetViews,
6982 pDepthStencilView,
6983 pDXContext->svgaDXContext.uavSpliceIndex,
6984 NumUAVs,
6985 apUnorderedAccessViews,
6986 aUAVInitialCounts);
6987 return VINF_SUCCESS;
6988}
6989
6990
6991static DECLCALLBACK(int) vmsvga3dBackDXSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, uint32_t cRenderTargetViewId, SVGA3dRenderTargetViewId const *paRenderTargetViewId)
6992{
6993 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6994 RT_NOREF(pBackend);
6995
6996 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6997 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6998
6999 RT_NOREF(depthStencilViewId, cRenderTargetViewId, paRenderTargetViewId);
7000
7001 return VINF_SUCCESS;
7002}
7003
7004
7005static DECLCALLBACK(int) vmsvga3dBackDXSetBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dBlendStateId blendId, float const blendFactor[4], uint32_t sampleMask)
7006{
7007 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7008 RT_NOREF(pBackend);
7009
7010 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7011 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7012
7013 if (blendId != SVGA3D_INVALID_ID)
7014 {
7015 ID3D11BlendState *pBlendState = pDXContext->pBackendDXContext->papBlendState[blendId];
7016 pDevice->pImmediateContext->OMSetBlendState(pBlendState, blendFactor, sampleMask);
7017 }
7018 else
7019 pDevice->pImmediateContext->OMSetBlendState(NULL, NULL, 0);
7020
7021 return VINF_SUCCESS;
7022}
7023
7024
7025static DECLCALLBACK(int) vmsvga3dBackDXSetDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, uint32_t stencilRef)
7026{
7027 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7028 RT_NOREF(pBackend);
7029
7030 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7031 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7032
7033 if (depthStencilId != SVGA3D_INVALID_ID)
7034 {
7035 ID3D11DepthStencilState *pDepthStencilState = pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId];
7036 pDevice->pImmediateContext->OMSetDepthStencilState(pDepthStencilState, stencilRef);
7037 }
7038 else
7039 pDevice->pImmediateContext->OMSetDepthStencilState(NULL, 0);
7040
7041 return VINF_SUCCESS;
7042}
7043
7044
7045static DECLCALLBACK(int) vmsvga3dBackDXSetRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId)
7046{
7047 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7048 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7049 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7050
7051 RT_NOREF(pBackend);
7052
7053 if (rasterizerId != SVGA3D_INVALID_ID)
7054 {
7055 ID3D11RasterizerState *pRasterizerState = pDXContext->pBackendDXContext->papRasterizerState[rasterizerId];
7056 pDevice->pImmediateContext->RSSetState(pRasterizerState);
7057 }
7058 else
7059 pDevice->pImmediateContext->RSSetState(NULL);
7060
7061 return VINF_SUCCESS;
7062}
7063
7064
7065typedef struct VGPU10QUERYINFO
7066{
7067 SVGA3dQueryType svgaQueryType;
7068 uint32_t cbDataVMSVGA;
7069 D3D11_QUERY dxQueryType;
7070 uint32_t cbDataD3D11;
7071} VGPU10QUERYINFO;
7072
7073static VGPU10QUERYINFO const *dxQueryInfo(SVGA3dQueryType type)
7074{
7075 static VGPU10QUERYINFO const aQueryInfo[SVGA3D_QUERYTYPE_MAX] =
7076 {
7077 { SVGA3D_QUERYTYPE_OCCLUSION, sizeof(SVGADXOcclusionQueryResult),
7078 D3D11_QUERY_OCCLUSION, sizeof(UINT64) },
7079 { SVGA3D_QUERYTYPE_TIMESTAMP, sizeof(SVGADXTimestampQueryResult),
7080 D3D11_QUERY_TIMESTAMP, sizeof(UINT64) },
7081 { SVGA3D_QUERYTYPE_TIMESTAMPDISJOINT, sizeof(SVGADXTimestampDisjointQueryResult),
7082 D3D11_QUERY_TIMESTAMP_DISJOINT, sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT) },
7083 { SVGA3D_QUERYTYPE_PIPELINESTATS, sizeof(SVGADXPipelineStatisticsQueryResult),
7084 D3D11_QUERY_PIPELINE_STATISTICS, sizeof(D3D11_QUERY_DATA_PIPELINE_STATISTICS) },
7085 { SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE, sizeof(SVGADXOcclusionPredicateQueryResult),
7086 D3D11_QUERY_OCCLUSION_PREDICATE, sizeof(BOOL) },
7087 { SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS, sizeof(SVGADXStreamOutStatisticsQueryResult),
7088 D3D11_QUERY_SO_STATISTICS, sizeof(D3D11_QUERY_DATA_SO_STATISTICS) },
7089 { SVGA3D_QUERYTYPE_STREAMOVERFLOWPREDICATE, sizeof(SVGADXStreamOutPredicateQueryResult),
7090 D3D11_QUERY_SO_OVERFLOW_PREDICATE, sizeof(BOOL) },
7091 { SVGA3D_QUERYTYPE_OCCLUSION64, sizeof(SVGADXOcclusion64QueryResult),
7092 D3D11_QUERY_OCCLUSION, sizeof(UINT64) },
7093 { SVGA3D_QUERYTYPE_SOSTATS_STREAM0, sizeof(SVGADXStreamOutStatisticsQueryResult),
7094 D3D11_QUERY_SO_STATISTICS_STREAM0, sizeof(D3D11_QUERY_DATA_SO_STATISTICS) },
7095 { SVGA3D_QUERYTYPE_SOSTATS_STREAM1, sizeof(SVGADXStreamOutStatisticsQueryResult),
7096 D3D11_QUERY_SO_STATISTICS_STREAM1, sizeof(D3D11_QUERY_DATA_SO_STATISTICS) },
7097 { SVGA3D_QUERYTYPE_SOSTATS_STREAM2, sizeof(SVGADXStreamOutStatisticsQueryResult),
7098 D3D11_QUERY_SO_STATISTICS_STREAM2, sizeof(D3D11_QUERY_DATA_SO_STATISTICS) },
7099 { SVGA3D_QUERYTYPE_SOSTATS_STREAM3, sizeof(SVGADXStreamOutStatisticsQueryResult),
7100 D3D11_QUERY_SO_STATISTICS_STREAM3, sizeof(D3D11_QUERY_DATA_SO_STATISTICS) },
7101 { SVGA3D_QUERYTYPE_SOP_STREAM0, sizeof(SVGADXStreamOutPredicateQueryResult),
7102 D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0, sizeof(BOOL) },
7103 { SVGA3D_QUERYTYPE_SOP_STREAM1, sizeof(SVGADXStreamOutPredicateQueryResult),
7104 D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1, sizeof(BOOL) },
7105 { SVGA3D_QUERYTYPE_SOP_STREAM2, sizeof(SVGADXStreamOutPredicateQueryResult),
7106 D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2, sizeof(BOOL) },
7107 { SVGA3D_QUERYTYPE_SOP_STREAM3, sizeof(SVGADXStreamOutPredicateQueryResult),
7108 D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3, sizeof(BOOL) },
7109 };
7110
7111 ASSERT_GUEST_RETURN(type < RT_ELEMENTS(aQueryInfo), NULL);
7112 return &aQueryInfo[type];
7113}
7114
7115static int dxDefineQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId, SVGACOTableDXQueryEntry const *pEntry)
7116{
7117 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7118 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
7119
7120 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
7121 VGPU10QUERYINFO const *pQueryInfo = dxQueryInfo((SVGA3dQueryType)pEntry->type);
7122 if (!pQueryInfo)
7123 return VERR_INVALID_PARAMETER;
7124
7125 D3D11_QUERY_DESC desc;
7126 desc.Query = pQueryInfo->dxQueryType;
7127 desc.MiscFlags = 0;
7128 if (pEntry->flags & SVGA3D_DXQUERY_FLAG_PREDICATEHINT)
7129 desc.MiscFlags |= (UINT)D3D11_QUERY_MISC_PREDICATEHINT;
7130
7131 HRESULT hr = pDXDevice->pDevice->CreateQuery(&desc, &pDXQuery->pQuery);
7132 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
7133
7134 return VINF_SUCCESS;
7135}
7136
7137
7138static int dxDestroyQuery(DXQUERY *pDXQuery)
7139{
7140 D3D_RELEASE(pDXQuery->pQuery);
7141 return VINF_SUCCESS;
7142}
7143
7144
7145static DECLCALLBACK(int) vmsvga3dBackDXDefineQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId, SVGACOTableDXQueryEntry const *pEntry)
7146{
7147 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7148 RT_NOREF(pBackend);
7149
7150 return dxDefineQuery(pThisCC, pDXContext, queryId, pEntry);
7151}
7152
7153
7154static DECLCALLBACK(int) vmsvga3dBackDXDestroyQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId)
7155{
7156 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7157 RT_NOREF(pBackend);
7158
7159 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
7160 dxDestroyQuery(pDXQuery);
7161
7162 return VINF_SUCCESS;
7163}
7164
7165
7166/** @todo queryId makes pDXQuery redundant */
7167static int dxBeginQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId, DXQUERY *pDXQuery)
7168{
7169 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7170 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
7171
7172 /* Begin is disabled for some queries. */
7173 SVGACOTableDXQueryEntry *pEntry = &pDXContext->cot.paQuery[queryId];
7174 if (pEntry->type == SVGA3D_QUERYTYPE_TIMESTAMP)
7175 return VINF_SUCCESS;
7176
7177 pDXDevice->pImmediateContext->Begin(pDXQuery->pQuery);
7178 return VINF_SUCCESS;
7179}
7180
7181
7182static DECLCALLBACK(int) vmsvga3dBackDXBeginQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId)
7183{
7184 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7185 RT_NOREF(pBackend);
7186
7187 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
7188 int rc = dxBeginQuery(pThisCC, pDXContext, queryId, pDXQuery);
7189 return rc;
7190}
7191
7192
7193static int dxGetQueryResult(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId,
7194 SVGADXQueryResultUnion *pQueryResult, uint32_t *pcbOut)
7195{
7196 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7197 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
7198
7199 typedef union _DXQUERYRESULT
7200 {
7201 UINT64 occlusion;
7202 UINT64 timestamp;
7203 D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timestampDisjoint;
7204 D3D11_QUERY_DATA_PIPELINE_STATISTICS pipelineStatistics;
7205 BOOL occlusionPredicate;
7206 D3D11_QUERY_DATA_SO_STATISTICS soStatistics;
7207 BOOL soOverflowPredicate;
7208 } DXQUERYRESULT;
7209
7210 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
7211 SVGACOTableDXQueryEntry *pEntry = &pDXContext->cot.paQuery[queryId];
7212 VGPU10QUERYINFO const *pQueryInfo = dxQueryInfo((SVGA3dQueryType)pEntry->type);
7213 if (!pQueryInfo)
7214 return VERR_INVALID_PARAMETER;
7215
7216 DXQUERYRESULT dxQueryResult;
7217 while (pDXDevice->pImmediateContext->GetData(pDXQuery->pQuery, &dxQueryResult, pQueryInfo->cbDataD3D11, 0) != S_OK)
7218 {
7219 RTThreadYield();
7220 }
7221
7222 /* Copy back the result. */
7223 switch (pEntry->type)
7224 {
7225 case SVGA3D_QUERYTYPE_OCCLUSION:
7226 pQueryResult->occ.samplesRendered = (uint32_t)dxQueryResult.occlusion;
7227 break;
7228 case SVGA3D_QUERYTYPE_TIMESTAMP:
7229 pQueryResult->ts.timestamp = dxQueryResult.timestamp;
7230 break;
7231 case SVGA3D_QUERYTYPE_TIMESTAMPDISJOINT:
7232 pQueryResult->tsDisjoint.realFrequency = dxQueryResult.timestampDisjoint.Frequency;
7233 pQueryResult->tsDisjoint.disjoint = dxQueryResult.timestampDisjoint.Disjoint;
7234 break;
7235 case SVGA3D_QUERYTYPE_PIPELINESTATS:
7236 pQueryResult->pipelineStats.inputAssemblyVertices = dxQueryResult.pipelineStatistics.IAVertices;
7237 pQueryResult->pipelineStats.inputAssemblyPrimitives = dxQueryResult.pipelineStatistics.IAPrimitives;
7238 pQueryResult->pipelineStats.vertexShaderInvocations = dxQueryResult.pipelineStatistics.VSInvocations;
7239 pQueryResult->pipelineStats.geometryShaderInvocations = dxQueryResult.pipelineStatistics.GSInvocations;
7240 pQueryResult->pipelineStats.geometryShaderPrimitives = dxQueryResult.pipelineStatistics.GSPrimitives;
7241 pQueryResult->pipelineStats.clipperInvocations = dxQueryResult.pipelineStatistics.CInvocations;
7242 pQueryResult->pipelineStats.clipperPrimitives = dxQueryResult.pipelineStatistics.CPrimitives;
7243 pQueryResult->pipelineStats.pixelShaderInvocations = dxQueryResult.pipelineStatistics.PSInvocations;
7244 pQueryResult->pipelineStats.hullShaderInvocations = dxQueryResult.pipelineStatistics.HSInvocations;
7245 pQueryResult->pipelineStats.domainShaderInvocations = dxQueryResult.pipelineStatistics.DSInvocations;
7246 pQueryResult->pipelineStats.computeShaderInvocations = dxQueryResult.pipelineStatistics.CSInvocations;
7247 break;
7248 case SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE:
7249 pQueryResult->occPred.anySamplesRendered = dxQueryResult.occlusionPredicate;
7250 break;
7251 case SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS:
7252 case SVGA3D_QUERYTYPE_SOSTATS_STREAM0:
7253 case SVGA3D_QUERYTYPE_SOSTATS_STREAM1:
7254 case SVGA3D_QUERYTYPE_SOSTATS_STREAM2:
7255 case SVGA3D_QUERYTYPE_SOSTATS_STREAM3:
7256 pQueryResult->soStats.numPrimitivesWritten = dxQueryResult.soStatistics.NumPrimitivesWritten;
7257 pQueryResult->soStats.numPrimitivesRequired = dxQueryResult.soStatistics.PrimitivesStorageNeeded;
7258 break;
7259 case SVGA3D_QUERYTYPE_STREAMOVERFLOWPREDICATE:
7260 case SVGA3D_QUERYTYPE_SOP_STREAM0:
7261 case SVGA3D_QUERYTYPE_SOP_STREAM1:
7262 case SVGA3D_QUERYTYPE_SOP_STREAM2:
7263 case SVGA3D_QUERYTYPE_SOP_STREAM3:
7264 pQueryResult->soPred.overflowed = dxQueryResult.soOverflowPredicate;
7265 break;
7266 case SVGA3D_QUERYTYPE_OCCLUSION64:
7267 pQueryResult->occ64.samplesRendered = dxQueryResult.occlusion;
7268 break;
7269 }
7270
7271 *pcbOut = pQueryInfo->cbDataVMSVGA;
7272 return VINF_SUCCESS;
7273}
7274
7275static int dxEndQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId,
7276 SVGADXQueryResultUnion *pQueryResult, uint32_t *pcbOut)
7277{
7278 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7279 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
7280
7281 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
7282 pDXDevice->pImmediateContext->End(pDXQuery->pQuery);
7283
7284 /** @todo Consider issuing QueryEnd and getting data later in FIFO thread loop. */
7285 return dxGetQueryResult(pThisCC, pDXContext, queryId, pQueryResult, pcbOut);
7286}
7287
7288
7289static DECLCALLBACK(int) vmsvga3dBackDXEndQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
7290 SVGA3dQueryId queryId, SVGADXQueryResultUnion *pQueryResult, uint32_t *pcbOut)
7291{
7292 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7293 RT_NOREF(pBackend);
7294
7295 int rc = dxEndQuery(pThisCC, pDXContext, queryId, pQueryResult, pcbOut);
7296 return rc;
7297}
7298
7299
7300static DECLCALLBACK(int) vmsvga3dBackDXSetPredication(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId, uint32_t predicateValue)
7301{
7302 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7303 RT_NOREF(pBackend);
7304
7305 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7306 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
7307
7308 if (queryId != SVGA3D_INVALID_ID)
7309 {
7310 DEBUG_BREAKPOINT_TEST();
7311 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
7312 SVGACOTableDXQueryEntry *pEntry = &pDXContext->cot.paQuery[queryId];
7313
7314 VGPU10QUERYINFO const *pQueryInfo = dxQueryInfo((SVGA3dQueryType)pEntry->type);
7315 if (!pQueryInfo)
7316 return VERR_INVALID_PARAMETER;
7317
7318 D3D_RELEASE(pDXQuery->pQuery);
7319
7320 D3D11_QUERY_DESC desc;
7321 desc.Query = pQueryInfo->dxQueryType;
7322 desc.MiscFlags = 0;
7323 if (pEntry->flags & SVGA3D_DXQUERY_FLAG_PREDICATEHINT)
7324 desc.MiscFlags |= (UINT)D3D11_QUERY_MISC_PREDICATEHINT;
7325
7326 HRESULT hr = pDXDevice->pDevice->CreatePredicate(&desc, &pDXQuery->pPredicate);
7327 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
7328
7329 pDXDevice->pImmediateContext->SetPredication(pDXQuery->pPredicate, RT_BOOL(predicateValue));
7330 }
7331 else
7332 pDXDevice->pImmediateContext->SetPredication(NULL, FALSE);
7333
7334 return VINF_SUCCESS;
7335}
7336
7337
7338static DECLCALLBACK(int) vmsvga3dBackDXSetSOTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cSOTarget, SVGA3dSoTarget const *paSoTarget)
7339{
7340 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7341 RT_NOREF(pBackend);
7342
7343 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7344 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7345
7346 /* For each paSoTarget[i]:
7347 * If the stream outout buffer object does not exist then create it.
7348 * If the surface has been updated by the guest then update the buffer object.
7349 * Use SOSetTargets to set the buffers.
7350 */
7351
7352 ID3D11Buffer *paResource[SVGA3D_DX_MAX_SOTARGETS];
7353 UINT paOffset[SVGA3D_DX_MAX_SOTARGETS];
7354
7355 /* Always re-bind all 4 SO targets. They can be NULL. */
7356 for (uint32_t i = 0; i < SVGA3D_DX_MAX_SOTARGETS; ++i)
7357 {
7358 /* Get corresponding resource. Create the buffer if does not yet exist. */
7359 if (i < cSOTarget && paSoTarget[i].sid != SVGA_ID_INVALID)
7360 {
7361 PVMSVGA3DSURFACE pSurface;
7362 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paSoTarget[i].sid, &pSurface);
7363 AssertRCReturn(rc, rc);
7364
7365 if (pSurface->pBackendSurface == NULL)
7366 {
7367 /* Create the resource. */
7368 rc = vmsvga3dBackSurfaceCreateSoBuffer(pThisCC, pDXContext, pSurface);
7369 AssertRCReturn(rc, rc);
7370 }
7371
7372 /** @todo How paSoTarget[i].sizeInBytes is used? Maybe when the buffer is created? */
7373 paResource[i] = pSurface->pBackendSurface->u.pBuffer;
7374 paOffset[i] = paSoTarget[i].offset;
7375 }
7376 else
7377 {
7378 paResource[i] = NULL;
7379 paOffset[i] = 0;
7380 }
7381 }
7382
7383 pDevice->pImmediateContext->SOSetTargets(SVGA3D_DX_MAX_SOTARGETS, paResource, paOffset);
7384
7385 pDXContext->pBackendDXContext->cSOTarget = cSOTarget;
7386
7387 return VINF_SUCCESS;
7388}
7389
7390
7391static DECLCALLBACK(int) vmsvga3dBackDXSetViewports(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cViewport, SVGA3dViewport const *paViewport)
7392{
7393 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7394 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7395 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7396
7397 RT_NOREF(pBackend);
7398
7399 /* D3D11_VIEWPORT is identical to SVGA3dViewport. */
7400 D3D11_VIEWPORT *pViewports = (D3D11_VIEWPORT *)paViewport;
7401
7402 pDevice->pImmediateContext->RSSetViewports(cViewport, pViewports);
7403 return VINF_SUCCESS;
7404}
7405
7406
7407static DECLCALLBACK(int) vmsvga3dBackDXSetScissorRects(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cRect, SVGASignedRect const *paRect)
7408{
7409 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7410 RT_NOREF(pBackend);
7411
7412 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7413 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7414
7415 /* D3D11_RECT is identical to SVGASignedRect. */
7416 D3D11_RECT *pRects = (D3D11_RECT *)paRect;
7417
7418 pDevice->pImmediateContext->RSSetScissorRects(cRect, pRects);
7419 return VINF_SUCCESS;
7420}
7421
7422
7423static DECLCALLBACK(int) vmsvga3dBackDXClearRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGA3dRGBAFloat const *pRGBA)
7424{
7425 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7426 RT_NOREF(pBackend);
7427
7428 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7429 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7430
7431 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId];
7432 if (!pDXView->u.pRenderTargetView)
7433 {
7434//DEBUG_BREAKPOINT_TEST();
7435 /* (Re-)create the render target view, because a creation of a view is deferred until a draw or a clear call. */
7436 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[renderTargetViewId];
7437 int rc = dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
7438 AssertRCReturn(rc, rc);
7439 }
7440 pDevice->pImmediateContext->ClearRenderTargetView(pDXView->u.pRenderTargetView, pRGBA->value);
7441 return VINF_SUCCESS;
7442}
7443
7444
7445static DECLCALLBACK(int) vmsvga3dBackVBDXClearRenderTargetViewRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId,
7446 SVGA3dRGBAFloat const *pColor, uint32_t cRect, SVGASignedRect const *paRect)
7447{
7448 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7449 RT_NOREF(pBackend);
7450
7451 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7452 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7453
7454 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId];
7455 if (!pDXView->u.pRenderTargetView)
7456 {
7457 /* (Re-)create the render target view, because a creation of a view is deferred until a draw or a clear call. */
7458 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[renderTargetViewId];
7459 int rc = dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
7460 AssertRCReturn(rc, rc);
7461 }
7462 pDevice->pImmediateContext->ClearView(pDXView->u.pRenderTargetView, pColor->value, (D3D11_RECT *)paRect, cRect);
7463 return VINF_SUCCESS;
7464}
7465
7466
7467static DECLCALLBACK(int) vmsvga3dBackDXClearDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t flags, SVGA3dDepthStencilViewId depthStencilViewId, float depth, uint8_t stencil)
7468{
7469 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7470 RT_NOREF(pBackend);
7471
7472 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7473 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7474
7475 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId];
7476 if (!pDXView->u.pDepthStencilView)
7477 {
7478//DEBUG_BREAKPOINT_TEST();
7479 /* (Re-)create the depth stencil view, because a creation of a view is deferred until a draw or a clear call. */
7480 SVGACOTableDXDSViewEntry const *pEntry = &pDXContext->cot.paDSView[depthStencilViewId];
7481 int rc = dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
7482 AssertRCReturn(rc, rc);
7483 }
7484 pDevice->pImmediateContext->ClearDepthStencilView(pDXView->u.pDepthStencilView, flags, depth, stencil);
7485 return VINF_SUCCESS;
7486}
7487
7488
7489static DECLCALLBACK(int) vmsvga3dBackDXPredCopyRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId dstSid, uint32_t dstSubResource, SVGA3dSurfaceId srcSid, uint32_t srcSubResource, SVGA3dCopyBox const *pBox)
7490{
7491 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7492 RT_NOREF(pBackend);
7493
7494 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7495 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7496
7497 PVMSVGA3DSURFACE pSrcSurface;
7498 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, srcSid, &pSrcSurface);
7499 AssertRCReturn(rc, rc);
7500
7501 PVMSVGA3DSURFACE pDstSurface;
7502 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dstSid, &pDstSurface);
7503 AssertRCReturn(rc, rc);
7504
7505 if (pSrcSurface->pBackendSurface == NULL)
7506 {
7507 /* Create the resource. */
7508 if (pSrcSurface->format != SVGA3D_BUFFER)
7509 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSrcSurface);
7510 else
7511 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSrcSurface);
7512 AssertRCReturn(rc, rc);
7513 }
7514
7515 if (pDstSurface->pBackendSurface == NULL)
7516 {
7517 /* Create the resource. */
7518 if (pSrcSurface->format != SVGA3D_BUFFER)
7519 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pDstSurface);
7520 else
7521 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pDstSurface);
7522 AssertRCReturn(rc, rc);
7523 }
7524
7525 LogFunc(("cid %d: src cid %d%s -> dst cid %d%s\n",
7526 pDXContext->cid, pSrcSurface->idAssociatedContext,
7527 (pSrcSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : "",
7528 pDstSurface->idAssociatedContext,
7529 (pDstSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : ""));
7530
7531 /* Clip the box. */
7532 /** @todo Use [src|dst]SubResource to index p[Src|Dst]Surface->paMipmapLevels array directly. */
7533 uint32_t iSrcFace;
7534 uint32_t iSrcMipmap;
7535 vmsvga3dCalcMipmapAndFace(pSrcSurface->cLevels, srcSubResource, &iSrcMipmap, &iSrcFace);
7536
7537 uint32_t iDstFace;
7538 uint32_t iDstMipmap;
7539 vmsvga3dCalcMipmapAndFace(pDstSurface->cLevels, dstSubResource, &iDstMipmap, &iDstFace);
7540
7541 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
7542 rc = vmsvga3dMipmapLevel(pSrcSurface, iSrcFace, iSrcMipmap, &pSrcMipLevel);
7543 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
7544
7545 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
7546 rc = vmsvga3dMipmapLevel(pDstSurface, iDstFace, iDstMipmap, &pDstMipLevel);
7547 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
7548
7549 SVGA3dCopyBox clipBox = *pBox;
7550 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
7551
7552 UINT DstSubresource = dstSubResource;
7553 UINT DstX = clipBox.x;
7554 UINT DstY = clipBox.y;
7555 UINT DstZ = clipBox.z;
7556
7557 UINT SrcSubresource = srcSubResource;
7558 D3D11_BOX SrcBox;
7559 SrcBox.left = clipBox.srcx;
7560 SrcBox.top = clipBox.srcy;
7561 SrcBox.front = clipBox.srcz;
7562 SrcBox.right = clipBox.srcx + clipBox.w;
7563 SrcBox.bottom = clipBox.srcy + clipBox.h;
7564 SrcBox.back = clipBox.srcz + clipBox.d;
7565
7566 ID3D11Resource *pDstResource;
7567 ID3D11Resource *pSrcResource;
7568
7569 pDstResource = dxResource(pThisCC->svga.p3dState, pDstSurface, pDXContext);
7570 pSrcResource = dxResource(pThisCC->svga.p3dState, pSrcSurface, pDXContext);
7571
7572 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
7573 pSrcResource, SrcSubresource, &SrcBox);
7574
7575 pDstSurface->pBackendSurface->cidDrawing = pDXContext->cid;
7576 return VINF_SUCCESS;
7577}
7578
7579
7580static DECLCALLBACK(int) vmsvga3dBackDXPredCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId dstSid, SVGA3dSurfaceId srcSid)
7581{
7582 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7583 RT_NOREF(pBackend);
7584
7585 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7586 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7587
7588 PVMSVGA3DSURFACE pSrcSurface;
7589 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, srcSid, &pSrcSurface);
7590 AssertRCReturn(rc, rc);
7591
7592 PVMSVGA3DSURFACE pDstSurface;
7593 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dstSid, &pDstSurface);
7594 AssertRCReturn(rc, rc);
7595
7596 if (pSrcSurface->pBackendSurface == NULL)
7597 {
7598 /* Create the resource. */
7599 if (pSrcSurface->format != SVGA3D_BUFFER)
7600 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSrcSurface);
7601 else
7602 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSrcSurface);
7603 AssertRCReturn(rc, rc);
7604 }
7605
7606 if (pDstSurface->pBackendSurface == NULL)
7607 {
7608 /* Create the resource. */
7609 if (pSrcSurface->format != SVGA3D_BUFFER)
7610 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pDstSurface);
7611 else
7612 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pDstSurface);
7613 AssertRCReturn(rc, rc);
7614 }
7615
7616 LogFunc(("cid %d: src cid %d%s -> dst cid %d%s\n",
7617 pDXContext->cid, pSrcSurface->idAssociatedContext,
7618 (pSrcSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : "",
7619 pDstSurface->idAssociatedContext,
7620 (pDstSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : ""));
7621
7622 ID3D11Resource *pDstResource = dxResource(pThisCC->svga.p3dState, pDstSurface, pDXContext);
7623 ID3D11Resource *pSrcResource = dxResource(pThisCC->svga.p3dState, pSrcSurface, pDXContext);
7624
7625 pDevice->pImmediateContext->CopyResource(pDstResource, pSrcResource);
7626
7627 pDstSurface->pBackendSurface->cidDrawing = pDXContext->cid;
7628 return VINF_SUCCESS;
7629}
7630
7631
7632#include "shaders/d3d11blitter.hlsl.vs.h"
7633#include "shaders/d3d11blitter.hlsl.ps.h"
7634
7635#define HTEST(stmt) \
7636 hr = stmt; \
7637 AssertReturn(SUCCEEDED(hr), hr)
7638
7639
7640static void BlitRelease(D3D11BLITTER *pBlitter)
7641{
7642 D3D_RELEASE(pBlitter->pVertexShader);
7643 D3D_RELEASE(pBlitter->pPixelShader);
7644 D3D_RELEASE(pBlitter->pSamplerState);
7645 D3D_RELEASE(pBlitter->pRasterizerState);
7646 D3D_RELEASE(pBlitter->pBlendState);
7647 RT_ZERO(*pBlitter);
7648}
7649
7650
7651static HRESULT BlitInit(D3D11BLITTER *pBlitter, ID3D11Device *pDevice, ID3D11DeviceContext *pImmediateContext)
7652{
7653 HRESULT hr;
7654
7655 RT_ZERO(*pBlitter);
7656
7657 pBlitter->pDevice = pDevice;
7658 pBlitter->pImmediateContext = pImmediateContext;
7659
7660 HTEST(pBlitter->pDevice->CreateVertexShader(g_vs_blitter, sizeof(g_vs_blitter), NULL, &pBlitter->pVertexShader));
7661 HTEST(pBlitter->pDevice->CreatePixelShader(g_ps_blitter, sizeof(g_ps_blitter), NULL, &pBlitter->pPixelShader));
7662
7663 D3D11_SAMPLER_DESC SamplerDesc;
7664 SamplerDesc.Filter = D3D11_FILTER_ANISOTROPIC;
7665 SamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
7666 SamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
7667 SamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
7668 SamplerDesc.MipLODBias = 0.0f;
7669 SamplerDesc.MaxAnisotropy = 4;
7670 SamplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
7671 SamplerDesc.BorderColor[0] = 0.0f;
7672 SamplerDesc.BorderColor[1] = 0.0f;
7673 SamplerDesc.BorderColor[2] = 0.0f;
7674 SamplerDesc.BorderColor[3] = 0.0f;
7675 SamplerDesc.MinLOD = 0.0f;
7676 SamplerDesc.MaxLOD = 0.0f;
7677 HTEST(pBlitter->pDevice->CreateSamplerState(&SamplerDesc, &pBlitter->pSamplerState));
7678
7679 D3D11_RASTERIZER_DESC RasterizerDesc;
7680 RasterizerDesc.FillMode = D3D11_FILL_SOLID;
7681 RasterizerDesc.CullMode = D3D11_CULL_NONE;
7682 RasterizerDesc.FrontCounterClockwise = FALSE;
7683 RasterizerDesc.DepthBias = 0;
7684 RasterizerDesc.DepthBiasClamp = 0.0f;
7685 RasterizerDesc.SlopeScaledDepthBias = 0.0f;
7686 RasterizerDesc.DepthClipEnable = FALSE;
7687 RasterizerDesc.ScissorEnable = FALSE;
7688 RasterizerDesc.MultisampleEnable = FALSE;
7689 RasterizerDesc.AntialiasedLineEnable = FALSE;
7690 HTEST(pBlitter->pDevice->CreateRasterizerState(&RasterizerDesc, &pBlitter->pRasterizerState));
7691
7692 D3D11_BLEND_DESC BlendDesc;
7693 BlendDesc.AlphaToCoverageEnable = FALSE;
7694 BlendDesc.IndependentBlendEnable = FALSE;
7695 for (unsigned i = 0; i < RT_ELEMENTS(BlendDesc.RenderTarget); ++i)
7696 {
7697 BlendDesc.RenderTarget[i].BlendEnable = FALSE;
7698 BlendDesc.RenderTarget[i].SrcBlend = D3D11_BLEND_SRC_COLOR;
7699 BlendDesc.RenderTarget[i].DestBlend = D3D11_BLEND_ZERO;
7700 BlendDesc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
7701 BlendDesc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
7702 BlendDesc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO;
7703 BlendDesc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;
7704 BlendDesc.RenderTarget[i].RenderTargetWriteMask = 0xF;
7705 }
7706 HTEST(pBlitter->pDevice->CreateBlendState(&BlendDesc, &pBlitter->pBlendState));
7707
7708 return S_OK;
7709}
7710
7711
7712static HRESULT BlitFromTexture(D3D11BLITTER *pBlitter, ID3D11RenderTargetView *pDstRenderTargetView,
7713 float cDstWidth, float cDstHeight, D3D11_RECT const &rectDst,
7714 ID3D11ShaderResourceView *pSrcShaderResourceView)
7715{
7716 HRESULT hr;
7717
7718 /*
7719 * Save pipeline state.
7720 */
7721 struct
7722 {
7723 D3D11_PRIMITIVE_TOPOLOGY Topology;
7724 ID3D11InputLayout *pInputLayout;
7725 ID3D11Buffer *pConstantBuffer;
7726 ID3D11VertexShader *pVertexShader;
7727 ID3D11HullShader *pHullShader;
7728 ID3D11DomainShader *pDomainShader;
7729 ID3D11GeometryShader *pGeometryShader;
7730 ID3D11ShaderResourceView *pShaderResourceView;
7731 ID3D11PixelShader *pPixelShader;
7732 ID3D11SamplerState *pSamplerState;
7733 ID3D11RasterizerState *pRasterizerState;
7734 ID3D11BlendState *pBlendState;
7735 FLOAT BlendFactor[4];
7736 UINT SampleMask;
7737 ID3D11RenderTargetView *apRenderTargetView[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
7738 ID3D11DepthStencilView *pDepthStencilView;
7739 UINT NumViewports;
7740 D3D11_VIEWPORT aViewport[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
7741 } SavedState;
7742
7743 pBlitter->pImmediateContext->IAGetPrimitiveTopology(&SavedState.Topology);
7744 pBlitter->pImmediateContext->IAGetInputLayout(&SavedState.pInputLayout);
7745 pBlitter->pImmediateContext->VSGetConstantBuffers(0, 1, &SavedState.pConstantBuffer);
7746 pBlitter->pImmediateContext->VSGetShader(&SavedState.pVertexShader, NULL, NULL);
7747 pBlitter->pImmediateContext->HSGetShader(&SavedState.pHullShader, NULL, NULL);
7748 pBlitter->pImmediateContext->DSGetShader(&SavedState.pDomainShader, NULL, NULL);
7749 pBlitter->pImmediateContext->GSGetShader(&SavedState.pGeometryShader, NULL, NULL);
7750 pBlitter->pImmediateContext->PSGetShaderResources(0, 1, &SavedState.pShaderResourceView);
7751 pBlitter->pImmediateContext->PSGetShader(&SavedState.pPixelShader, NULL, NULL);
7752 pBlitter->pImmediateContext->PSGetSamplers(0, 1, &SavedState.pSamplerState);
7753 pBlitter->pImmediateContext->RSGetState(&SavedState.pRasterizerState);
7754 pBlitter->pImmediateContext->OMGetBlendState(&SavedState.pBlendState, SavedState.BlendFactor, &SavedState.SampleMask);
7755 pBlitter->pImmediateContext->OMGetRenderTargets(RT_ELEMENTS(SavedState.apRenderTargetView), SavedState.apRenderTargetView, &SavedState.pDepthStencilView);
7756 SavedState.NumViewports = RT_ELEMENTS(SavedState.aViewport);
7757 pBlitter->pImmediateContext->RSGetViewports(&SavedState.NumViewports, &SavedState.aViewport[0]);
7758
7759 /*
7760 * Setup pipeline for the blitter.
7761 */
7762
7763 /* Render target is first.
7764 * If the source texture is bound as a render target, then this call will unbind it
7765 * and allow to use it as the shader resource.
7766 */
7767 pBlitter->pImmediateContext->OMSetRenderTargets(1, &pDstRenderTargetView, NULL);
7768
7769 /* Input assembler. */
7770 pBlitter->pImmediateContext->IASetInputLayout(NULL);
7771 pBlitter->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
7772
7773 /* Constant buffer. */
7774 struct
7775 {
7776 float scaleX;
7777 float scaleY;
7778 float offsetX;
7779 float offsetY;
7780 } VSConstantBuffer;
7781 VSConstantBuffer.scaleX = (float)(rectDst.right - rectDst.left) / cDstWidth;
7782 VSConstantBuffer.scaleY = (float)(rectDst.bottom - rectDst.top) / cDstHeight;
7783 VSConstantBuffer.offsetX = (float)(rectDst.right + rectDst.left) / cDstWidth - 1.0f;
7784 VSConstantBuffer.offsetY = -((float)(rectDst.bottom + rectDst.top) / cDstHeight - 1.0f);
7785
7786 D3D11_SUBRESOURCE_DATA initialData;
7787 initialData.pSysMem = &VSConstantBuffer;
7788 initialData.SysMemPitch = sizeof(VSConstantBuffer);
7789 initialData.SysMemSlicePitch = sizeof(VSConstantBuffer);
7790
7791 D3D11_BUFFER_DESC bd;
7792 RT_ZERO(bd);
7793 bd.ByteWidth = sizeof(VSConstantBuffer);
7794 bd.Usage = D3D11_USAGE_IMMUTABLE;
7795 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
7796
7797 ID3D11Buffer *pConstantBuffer;
7798 HTEST(pBlitter->pDevice->CreateBuffer(&bd, &initialData, &pConstantBuffer));
7799 pBlitter->pImmediateContext->VSSetConstantBuffers(0, 1, &pConstantBuffer);
7800 D3D_RELEASE(pConstantBuffer); /* xSSetConstantBuffers "will hold a reference to the interfaces passed in." */
7801
7802 /* Vertex shader. */
7803 pBlitter->pImmediateContext->VSSetShader(pBlitter->pVertexShader, NULL, 0);
7804
7805 /* Unused shaders. */
7806 pBlitter->pImmediateContext->HSSetShader(NULL, NULL, 0);
7807 pBlitter->pImmediateContext->DSSetShader(NULL, NULL, 0);
7808 pBlitter->pImmediateContext->GSSetShader(NULL, NULL, 0);
7809
7810 /* Shader resource view. */
7811 pBlitter->pImmediateContext->PSSetShaderResources(0, 1, &pSrcShaderResourceView);
7812
7813 /* Pixel shader. */
7814 pBlitter->pImmediateContext->PSSetShader(pBlitter->pPixelShader, NULL, 0);
7815
7816 /* Sampler. */
7817 pBlitter->pImmediateContext->PSSetSamplers(0, 1, &pBlitter->pSamplerState);
7818
7819 /* Rasterizer. */
7820 pBlitter->pImmediateContext->RSSetState(pBlitter->pRasterizerState);
7821
7822 /* Blend state. */
7823 static FLOAT const BlendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
7824 pBlitter->pImmediateContext->OMSetBlendState(pBlitter->pBlendState, BlendFactor, 0xffffffff);
7825
7826 /* Viewport. */
7827 D3D11_VIEWPORT Viewport;
7828 Viewport.TopLeftX = 0;
7829 Viewport.TopLeftY = 0;
7830 Viewport.Width = cDstWidth;
7831 Viewport.Height = cDstHeight;
7832 Viewport.MinDepth = 0.0f;
7833 Viewport.MaxDepth = 1.0f;
7834 pBlitter->pImmediateContext->RSSetViewports(1, &Viewport);
7835
7836 /* Draw. */
7837 pBlitter->pImmediateContext->Draw(4, 0);
7838
7839 /*
7840 * Restore pipeline state.
7841 */
7842 pBlitter->pImmediateContext->IASetPrimitiveTopology(SavedState.Topology);
7843 pBlitter->pImmediateContext->IASetInputLayout(SavedState.pInputLayout);
7844 D3D_RELEASE(SavedState.pInputLayout);
7845 pBlitter->pImmediateContext->VSSetConstantBuffers(0, 1, &SavedState.pConstantBuffer);
7846 D3D_RELEASE(SavedState.pConstantBuffer);
7847 pBlitter->pImmediateContext->VSSetShader(SavedState.pVertexShader, NULL, 0);
7848 D3D_RELEASE(SavedState.pVertexShader);
7849
7850 pBlitter->pImmediateContext->HSSetShader(SavedState.pHullShader, NULL, 0);
7851 D3D_RELEASE(SavedState.pHullShader);
7852 pBlitter->pImmediateContext->DSSetShader(SavedState.pDomainShader, NULL, 0);
7853 D3D_RELEASE(SavedState.pDomainShader);
7854 pBlitter->pImmediateContext->GSSetShader(SavedState.pGeometryShader, NULL, 0);
7855 D3D_RELEASE(SavedState.pGeometryShader);
7856
7857 pBlitter->pImmediateContext->PSSetShaderResources(0, 1, &SavedState.pShaderResourceView);
7858 D3D_RELEASE(SavedState.pShaderResourceView);
7859 pBlitter->pImmediateContext->PSSetShader(SavedState.pPixelShader, NULL, 0);
7860 D3D_RELEASE(SavedState.pPixelShader);
7861 pBlitter->pImmediateContext->PSSetSamplers(0, 1, &SavedState.pSamplerState);
7862 D3D_RELEASE(SavedState.pSamplerState);
7863 pBlitter->pImmediateContext->RSSetState(SavedState.pRasterizerState);
7864 D3D_RELEASE(SavedState.pRasterizerState);
7865 pBlitter->pImmediateContext->OMSetBlendState(SavedState.pBlendState, SavedState.BlendFactor, SavedState.SampleMask);
7866 D3D_RELEASE(SavedState.pBlendState);
7867 pBlitter->pImmediateContext->OMSetRenderTargets(RT_ELEMENTS(SavedState.apRenderTargetView), SavedState.apRenderTargetView, SavedState.pDepthStencilView);
7868 D3D_RELEASE_ARRAY(RT_ELEMENTS(SavedState.apRenderTargetView), SavedState.apRenderTargetView);
7869 D3D_RELEASE(SavedState.pDepthStencilView);
7870 pBlitter->pImmediateContext->RSSetViewports(SavedState.NumViewports, &SavedState.aViewport[0]);
7871
7872 return S_OK;
7873}
7874
7875
7876static DECLCALLBACK(int) vmsvga3dBackDXPresentBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
7877 SVGA3dSurfaceId dstSid, uint32_t dstSubResource, SVGA3dBox const *pBoxDst,
7878 SVGA3dSurfaceId srcSid, uint32_t srcSubResource, SVGA3dBox const *pBoxSrc,
7879 SVGA3dDXPresentBltMode mode)
7880{
7881 RT_NOREF(mode);
7882
7883 ASSERT_GUEST_RETURN(pBoxDst->z == 0 && pBoxDst->d == 1, VERR_INVALID_PARAMETER);
7884 ASSERT_GUEST_RETURN(pBoxSrc->z == 0 && pBoxSrc->d == 1, VERR_INVALID_PARAMETER);
7885
7886 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7887 RT_NOREF(pBackend);
7888
7889 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7890 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7891
7892 PVMSVGA3DSURFACE pSrcSurface;
7893 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, srcSid, &pSrcSurface);
7894 AssertRCReturn(rc, rc);
7895
7896 PVMSVGA3DSURFACE pDstSurface;
7897 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dstSid, &pDstSurface);
7898 AssertRCReturn(rc, rc);
7899
7900 if (pSrcSurface->pBackendSurface == NULL)
7901 {
7902 /* Create the resource. */
7903 if (pSrcSurface->format != SVGA3D_BUFFER)
7904 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSrcSurface);
7905 else
7906 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSrcSurface);
7907 AssertRCReturn(rc, rc);
7908 }
7909
7910 if (pDstSurface->pBackendSurface == NULL)
7911 {
7912 /* Create the resource. */
7913 if (pSrcSurface->format != SVGA3D_BUFFER)
7914 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pDstSurface);
7915 else
7916 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pDstSurface);
7917 AssertRCReturn(rc, rc);
7918 }
7919
7920 LogFunc(("cid %d: src cid %d%s -> dst cid %d%s\n",
7921 pDXContext->cid, pSrcSurface->idAssociatedContext,
7922 (pSrcSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : "",
7923 pDstSurface->idAssociatedContext,
7924 (pDstSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : ""));
7925
7926 /* Clip the box. */
7927 /** @todo Use [src|dst]SubResource to index p[Src|Dst]Surface->paMipmapLevels array directly. */
7928 uint32_t iSrcFace;
7929 uint32_t iSrcMipmap;
7930 vmsvga3dCalcMipmapAndFace(pSrcSurface->cLevels, srcSubResource, &iSrcMipmap, &iSrcFace);
7931
7932 uint32_t iDstFace;
7933 uint32_t iDstMipmap;
7934 vmsvga3dCalcMipmapAndFace(pDstSurface->cLevels, dstSubResource, &iDstMipmap, &iDstFace);
7935
7936 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
7937 rc = vmsvga3dMipmapLevel(pSrcSurface, iSrcFace, iSrcMipmap, &pSrcMipLevel);
7938 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
7939
7940 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
7941 rc = vmsvga3dMipmapLevel(pDstSurface, iDstFace, iDstMipmap, &pDstMipLevel);
7942 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
7943
7944 SVGA3dBox clipBoxSrc = *pBoxSrc;
7945 vmsvgaR3ClipBox(&pSrcMipLevel->mipmapSize, &clipBoxSrc);
7946
7947 SVGA3dBox clipBoxDst = *pBoxDst;
7948 vmsvgaR3ClipBox(&pDstMipLevel->mipmapSize, &clipBoxDst);
7949
7950 ID3D11Resource *pDstResource = dxResource(pThisCC->svga.p3dState, pDstSurface, pDXContext);
7951 ID3D11Resource *pSrcResource = dxResource(pThisCC->svga.p3dState, pSrcSurface, pDXContext);
7952
7953 D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
7954 RT_ZERO(RTVDesc);
7955 RTVDesc.Format = vmsvgaDXSurfaceFormat2Dxgi(pDstSurface->format);;
7956 RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
7957 RTVDesc.Texture2D.MipSlice = dstSubResource;
7958
7959 ID3D11RenderTargetView *pDstRenderTargetView;
7960 HRESULT hr = pDevice->pDevice->CreateRenderTargetView(pDstResource, &RTVDesc, &pDstRenderTargetView);
7961 AssertReturn(SUCCEEDED(hr), VERR_NOT_SUPPORTED);
7962
7963 D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
7964 RT_ZERO(SRVDesc);
7965 SRVDesc.Format = vmsvgaDXSurfaceFormat2Dxgi(pSrcSurface->format);
7966 SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
7967 SRVDesc.Texture2D.MostDetailedMip = srcSubResource;
7968 SRVDesc.Texture2D.MipLevels = 1;
7969
7970 ID3D11ShaderResourceView *pSrcShaderResourceView;
7971 hr = pDevice->pDevice->CreateShaderResourceView(pSrcResource, &SRVDesc, &pSrcShaderResourceView);
7972 AssertReturnStmt(SUCCEEDED(hr), D3D_RELEASE(pDstRenderTargetView), VERR_NOT_SUPPORTED);
7973
7974 D3D11_RECT rectDst;
7975 rectDst.left = pBoxDst->x;
7976 rectDst.top = pBoxDst->y;
7977 rectDst.right = pBoxDst->x + pBoxDst->w;
7978 rectDst.bottom = pBoxDst->y + pBoxDst->h;
7979
7980 BlitFromTexture(&pDevice->Blitter, pDstRenderTargetView, (float)pDstMipLevel->mipmapSize.width, (float)pDstMipLevel->mipmapSize.height,
7981 rectDst, pSrcShaderResourceView);
7982
7983 D3D_RELEASE(pSrcShaderResourceView);
7984 D3D_RELEASE(pDstRenderTargetView);
7985
7986 pDstSurface->pBackendSurface->cidDrawing = pDXContext->cid;
7987 return VINF_SUCCESS;
7988}
7989
7990
7991static DECLCALLBACK(int) vmsvga3dBackDXGenMips(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
7992{
7993 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7994 RT_NOREF(pBackend);
7995
7996 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
7997 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
7998
7999 ID3D11ShaderResourceView *pShaderResourceView = pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId].u.pShaderResourceView;
8000 AssertReturn(pShaderResourceView, VERR_INVALID_STATE);
8001
8002 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
8003 AssertReturn(pSRViewEntry, VERR_INVALID_STATE);
8004
8005 uint32_t const sid = pSRViewEntry->sid;
8006
8007 PVMSVGA3DSURFACE pSurface;
8008 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
8009 AssertRCReturn(rc, rc);
8010 AssertReturn(pSurface->pBackendSurface, VERR_INVALID_STATE);
8011
8012 pDevice->pImmediateContext->GenerateMips(pShaderResourceView);
8013
8014 pSurface->pBackendSurface->cidDrawing = pDXContext->cid;
8015 return VINF_SUCCESS;
8016}
8017
8018
8019static int dxDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
8020{
8021 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
8022 PVMSVGA3DSURFACE pSurface;
8023 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
8024 AssertRCReturn(rc, rc);
8025
8026 ID3D11ShaderResourceView *pShaderResourceView;
8027 DXVIEW *pView = &pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId];
8028 Assert(pView->u.pView == NULL);
8029
8030 if (pSurface->pBackendSurface == NULL)
8031 {
8032 /* Create the actual texture or buffer. */
8033 /** @todo One function to create all resources from surfaces. */
8034 if (pSurface->format != SVGA3D_BUFFER)
8035 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
8036 else
8037 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSurface);
8038
8039 AssertRCReturn(rc, rc);
8040 }
8041
8042 HRESULT hr = dxShaderResourceViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pShaderResourceView);
8043 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
8044
8045 return dxViewInit(pView, pSurface, pDXContext, shaderResourceViewId, VMSVGA3D_VIEWTYPE_SHADERRESOURCE, pShaderResourceView);
8046}
8047
8048
8049static DECLCALLBACK(int) vmsvga3dBackDXDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
8050{
8051 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8052 RT_NOREF(pBackend);
8053
8054 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8055 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8056
8057 /** @todo Probably not necessary because SRVs are defined in setupPipeline. */
8058 return dxDefineShaderResourceView(pThisCC, pDXContext, shaderResourceViewId, pEntry);
8059}
8060
8061
8062static DECLCALLBACK(int) vmsvga3dBackDXDestroyShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
8063{
8064 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8065 RT_NOREF(pBackend);
8066
8067 return dxViewDestroy(&pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId]);
8068}
8069
8070
8071static int dxDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
8072{
8073 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
8074 PVMSVGA3DSURFACE pSurface;
8075 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
8076 AssertRCReturn(rc, rc);
8077
8078 DXVIEW *pView = &pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId];
8079 Assert(pView->u.pView == NULL);
8080
8081 if (pSurface->pBackendSurface == NULL)
8082 {
8083 /* Create the actual texture. */
8084 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
8085 AssertRCReturn(rc, rc);
8086 }
8087
8088 ID3D11RenderTargetView *pRenderTargetView;
8089 HRESULT hr = dxRenderTargetViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pRenderTargetView);
8090 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
8091
8092 return dxViewInit(pView, pSurface, pDXContext, renderTargetViewId, VMSVGA3D_VIEWTYPE_RENDERTARGET, pRenderTargetView);
8093}
8094
8095
8096static DECLCALLBACK(int) vmsvga3dBackDXDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
8097{
8098 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8099 RT_NOREF(pBackend);
8100
8101 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8102 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8103
8104 return dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
8105}
8106
8107
8108static DECLCALLBACK(int) vmsvga3dBackDXDestroyRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId)
8109{
8110 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8111 RT_NOREF(pBackend);
8112
8113 return dxViewDestroy(&pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId]);
8114}
8115
8116
8117static int dxDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
8118{
8119 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
8120 PVMSVGA3DSURFACE pSurface;
8121 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
8122 AssertRCReturn(rc, rc);
8123
8124 DXVIEW *pView = &pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId];
8125 Assert(pView->u.pView == NULL);
8126
8127 if (pSurface->pBackendSurface == NULL)
8128 {
8129 /* Create the actual texture. */
8130 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
8131 AssertRCReturn(rc, rc);
8132 }
8133
8134 ID3D11DepthStencilView *pDepthStencilView;
8135 HRESULT hr = dxDepthStencilViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDepthStencilView);
8136 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
8137
8138 return dxViewInit(pView, pSurface, pDXContext, depthStencilViewId, VMSVGA3D_VIEWTYPE_DEPTHSTENCIL, pDepthStencilView);
8139}
8140
8141static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
8142{
8143 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8144 RT_NOREF(pBackend);
8145
8146 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8147 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8148
8149 return dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
8150}
8151
8152
8153static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId)
8154{
8155 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8156 RT_NOREF(pBackend);
8157
8158 return dxViewDestroy(&pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId]);
8159}
8160
8161
8162static int dxDefineElementLayout(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
8163{
8164 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
8165 D3D_RELEASE(pDXElementLayout->pElementLayout);
8166 pDXElementLayout->cElementDesc = 0;
8167 RT_ZERO(pDXElementLayout->aElementDesc);
8168
8169 RT_NOREF(pEntry);
8170
8171 return VINF_SUCCESS;
8172}
8173
8174
8175static int dxDestroyElementLayout(DXELEMENTLAYOUT *pDXElementLayout)
8176{
8177 D3D_RELEASE(pDXElementLayout->pElementLayout);
8178 pDXElementLayout->cElementDesc = 0;
8179 RT_ZERO(pDXElementLayout->aElementDesc);
8180 return VINF_SUCCESS;
8181}
8182
8183
8184static DECLCALLBACK(int) vmsvga3dBackDXDefineElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
8185{
8186 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8187 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8188 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8189
8190 RT_NOREF(pBackend);
8191
8192 /* Not much can be done here because ID3D11Device::CreateInputLayout requires
8193 * a pShaderBytecodeWithInputSignature which is not known at this moment.
8194 * InputLayout object will be created in setupPipeline.
8195 */
8196
8197 Assert(elementLayoutId == pEntry->elid);
8198
8199 return dxDefineElementLayout(pDXContext, elementLayoutId, pEntry);
8200}
8201
8202
8203static DECLCALLBACK(int) vmsvga3dBackDXDestroyElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId)
8204{
8205 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8206 RT_NOREF(pBackend);
8207
8208 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
8209 dxDestroyElementLayout(pDXElementLayout);
8210
8211 return VINF_SUCCESS;
8212}
8213
8214
8215static int dxDefineBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
8216 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
8217{
8218 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8219 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8220
8221 HRESULT hr = dxBlendStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papBlendState[blendId]);
8222 if (SUCCEEDED(hr))
8223 return VINF_SUCCESS;
8224 return VERR_INVALID_STATE;
8225}
8226
8227
8228static DECLCALLBACK(int) vmsvga3dBackDXDefineBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
8229 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
8230{
8231 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8232 RT_NOREF(pBackend);
8233
8234 return dxDefineBlendState(pThisCC, pDXContext, blendId, pEntry);
8235}
8236
8237
8238static DECLCALLBACK(int) vmsvga3dBackDXDestroyBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dBlendStateId blendId)
8239{
8240 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8241 RT_NOREF(pBackend);
8242
8243 D3D_RELEASE(pDXContext->pBackendDXContext->papBlendState[blendId]);
8244 return VINF_SUCCESS;
8245}
8246
8247
8248static int dxDefineDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
8249{
8250 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8251 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8252
8253 HRESULT hr = dxDepthStencilStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId]);
8254 if (SUCCEEDED(hr))
8255 return VINF_SUCCESS;
8256 return VERR_INVALID_STATE;
8257}
8258
8259
8260static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
8261{
8262 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8263 RT_NOREF(pBackend);
8264
8265 return dxDefineDepthStencilState(pThisCC, pDXContext, depthStencilId, pEntry);
8266}
8267
8268
8269static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId)
8270{
8271 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8272 RT_NOREF(pBackend);
8273
8274 D3D_RELEASE(pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId]);
8275 return VINF_SUCCESS;
8276}
8277
8278
8279static int dxDefineRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
8280{
8281 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8282 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8283
8284 HRESULT hr = dxRasterizerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
8285 if (SUCCEEDED(hr))
8286 return VINF_SUCCESS;
8287 return VERR_INVALID_STATE;
8288}
8289
8290
8291static DECLCALLBACK(int) vmsvga3dBackDXDefineRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
8292{
8293 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8294 RT_NOREF(pBackend);
8295
8296 return dxDefineRasterizerState(pThisCC, pDXContext, rasterizerId, pEntry);
8297}
8298
8299
8300static DECLCALLBACK(int) vmsvga3dBackDXDestroyRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId)
8301{
8302 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8303 RT_NOREF(pBackend);
8304
8305 D3D_RELEASE(pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
8306 return VINF_SUCCESS;
8307}
8308
8309
8310static int dxDefineSamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
8311{
8312 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8313 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8314
8315 HRESULT hr = dxSamplerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papSamplerState[samplerId]);
8316 if (SUCCEEDED(hr))
8317 return VINF_SUCCESS;
8318 return VERR_INVALID_STATE;
8319}
8320
8321
8322static DECLCALLBACK(int) vmsvga3dBackDXDefineSamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
8323{
8324 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8325 RT_NOREF(pBackend);
8326
8327 return dxDefineSamplerState(pThisCC, pDXContext, samplerId, pEntry);
8328}
8329
8330
8331static DECLCALLBACK(int) vmsvga3dBackDXDestroySamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId)
8332{
8333 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8334 RT_NOREF(pBackend);
8335
8336 D3D_RELEASE(pDXContext->pBackendDXContext->papSamplerState[samplerId]);
8337 return VINF_SUCCESS;
8338}
8339
8340
8341static int dxDefineShader(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
8342{
8343 /** @todo A common approach for creation of COTable backend objects: runtime, empty DX COTable, live DX COTable. */
8344 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
8345 Assert(pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID);
8346
8347 /* Init the backend shader structure, if the shader has not been created yet. */
8348 pDXShader->enmShaderType = pEntry->type;
8349 pDXShader->pShader = NULL;
8350 pDXShader->soid = SVGA_ID_INVALID;
8351
8352 return VINF_SUCCESS;
8353}
8354
8355
8356static int dxDestroyShader(DXSHADER *pDXShader)
8357{
8358 pDXShader->enmShaderType = SVGA3D_SHADERTYPE_INVALID;
8359 D3D_RELEASE(pDXShader->pShader);
8360 RTMemFree(pDXShader->pvDXBC);
8361 pDXShader->pvDXBC = NULL;
8362 pDXShader->cbDXBC = 0;
8363 pDXShader->soid = SVGA_ID_INVALID;
8364 return VINF_SUCCESS;
8365}
8366
8367
8368static DECLCALLBACK(int) vmsvga3dBackDXDefineShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
8369{
8370 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8371 RT_NOREF(pBackend);
8372
8373 return dxDefineShader(pDXContext, shaderId, pEntry);
8374}
8375
8376
8377static DECLCALLBACK(int) vmsvga3dBackDXDestroyShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId)
8378{
8379 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8380 RT_NOREF(pBackend);
8381
8382 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
8383 dxDestroyShader(pDXShader);
8384
8385 return VINF_SUCCESS;
8386}
8387
8388
8389static DECLCALLBACK(int) vmsvga3dBackDXBindShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, DXShaderInfo const *pShaderInfo)
8390{
8391 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8392 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
8393 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
8394
8395 RT_NOREF(pBackend);
8396
8397 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
8398 if (pDXShader->pvDXBC)
8399 {
8400 /* New DXBC code and new shader must be created. */
8401 D3D_RELEASE(pDXShader->pShader);
8402 RTMemFree(pDXShader->pvDXBC);
8403 pDXShader->pvDXBC = NULL;
8404 pDXShader->cbDXBC = 0;
8405 }
8406
8407 pDXShader->shaderInfo = *pShaderInfo;
8408
8409 return VINF_SUCCESS;
8410}
8411
8412
8413static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid, SVGACOTableDXStreamOutputEntry const *pEntry)
8414{
8415 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8416 RT_NOREF(pBackend);
8417
8418 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
8419 dxDestroyStreamOutput(pDXStreamOutput);
8420
8421 RT_NOREF(pEntry);
8422 return VINF_SUCCESS;
8423}
8424
8425
8426static DECLCALLBACK(int) vmsvga3dBackDXDestroyStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
8427{
8428 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8429 RT_NOREF(pBackend);
8430
8431 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
8432 dxDestroyStreamOutput(pDXStreamOutput);
8433
8434 return VINF_SUCCESS;
8435}
8436
8437
8438static DECLCALLBACK(int) vmsvga3dBackDXSetStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
8439{
8440 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8441 RT_NOREF(pBackend, pDXContext, soid);
8442
8443 return VINF_SUCCESS;
8444}
8445
8446
8447static int dxCOTableRealloc(void **ppvCOTable, uint32_t *pcCOTable, uint32_t cbEntry, uint32_t cEntries, uint32_t cValidEntries)
8448{
8449 uint32_t const cCOTableCurrent = *pcCOTable;
8450
8451 if (*pcCOTable != cEntries)
8452 {
8453 /* Grow/shrink the array. */
8454 if (cEntries)
8455 {
8456 void *pvNew = RTMemRealloc(*ppvCOTable, cEntries * cbEntry);
8457 AssertReturn(pvNew, VERR_NO_MEMORY);
8458 *ppvCOTable = pvNew;
8459 }
8460 else
8461 {
8462 RTMemFree(*ppvCOTable);
8463 *ppvCOTable = NULL;
8464 }
8465
8466 *pcCOTable = cEntries;
8467 }
8468
8469 if (*ppvCOTable)
8470 {
8471 uint32_t const cEntriesToKeep = RT_MIN(cCOTableCurrent, cValidEntries);
8472 memset((uint8_t *)(*ppvCOTable) + cEntriesToKeep * cbEntry, 0, (cEntries - cEntriesToKeep) * cbEntry);
8473 }
8474
8475 return VINF_SUCCESS;
8476}
8477
8478static DECLCALLBACK(int) vmsvga3dBackDXSetCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableType type, uint32_t cValidEntries)
8479{
8480 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8481 RT_NOREF(pBackend);
8482
8483 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
8484
8485 int rc = VINF_SUCCESS;
8486
8487 /*
8488 * 1) Release current backend table, if exists;
8489 * 2) Reallocate memory for the new backend table;
8490 * 3) If cValidEntries is not zero, then re-define corresponding backend table elements.
8491 */
8492 switch (type)
8493 {
8494 case SVGA_COTABLE_RTVIEW:
8495 /* Clear current entries. */
8496 if (pBackendDXContext->paRenderTargetView)
8497 {
8498 for (uint32_t i = 0; i < pBackendDXContext->cRenderTargetView; ++i)
8499 {
8500 DXVIEW *pDXView = &pBackendDXContext->paRenderTargetView[i];
8501 if (i < cValidEntries)
8502 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
8503 else
8504 dxViewDestroy(pDXView);
8505 }
8506 }
8507
8508 rc = dxCOTableRealloc((void **)&pBackendDXContext->paRenderTargetView, &pBackendDXContext->cRenderTargetView,
8509 sizeof(pBackendDXContext->paRenderTargetView[0]), pDXContext->cot.cRTView, cValidEntries);
8510 AssertRCBreak(rc);
8511
8512 for (uint32_t i = 0; i < cValidEntries; ++i)
8513 {
8514 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[i];
8515 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8516 continue; /* Skip uninitialized entry. */
8517
8518 /* Define views which were not defined yet in backend. */
8519 DXVIEW *pDXView = &pBackendDXContext->paRenderTargetView[i];
8520 /** @todo Verify that the pEntry content still corresponds to the view. */
8521 if (pDXView->u.pView)
8522 dxViewAddToList(pThisCC, pDXView);
8523 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
8524 dxDefineRenderTargetView(pThisCC, pDXContext, i, pEntry);
8525 }
8526 break;
8527 case SVGA_COTABLE_DSVIEW:
8528 if (pBackendDXContext->paDepthStencilView)
8529 {
8530 for (uint32_t i = 0; i < pBackendDXContext->cDepthStencilView; ++i)
8531 {
8532 DXVIEW *pDXView = &pBackendDXContext->paDepthStencilView[i];
8533 if (i < cValidEntries)
8534 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
8535 else
8536 dxViewDestroy(pDXView);
8537 }
8538 }
8539
8540 rc = dxCOTableRealloc((void **)&pBackendDXContext->paDepthStencilView, &pBackendDXContext->cDepthStencilView,
8541 sizeof(pBackendDXContext->paDepthStencilView[0]), pDXContext->cot.cDSView, cValidEntries);
8542 AssertRCBreak(rc);
8543
8544 for (uint32_t i = 0; i < cValidEntries; ++i)
8545 {
8546 SVGACOTableDXDSViewEntry const *pEntry = &pDXContext->cot.paDSView[i];
8547 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8548 continue; /* Skip uninitialized entry. */
8549
8550 /* Define views which were not defined yet in backend. */
8551 DXVIEW *pDXView = &pBackendDXContext->paDepthStencilView[i];
8552 /** @todo Verify that the pEntry content still corresponds to the view. */
8553 if (pDXView->u.pView)
8554 dxViewAddToList(pThisCC, pDXView);
8555 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
8556 dxDefineDepthStencilView(pThisCC, pDXContext, i, pEntry);
8557 }
8558 break;
8559 case SVGA_COTABLE_SRVIEW:
8560 if (pBackendDXContext->paShaderResourceView)
8561 {
8562 for (uint32_t i = 0; i < pBackendDXContext->cShaderResourceView; ++i)
8563 {
8564 DXVIEW *pDXView = &pBackendDXContext->paShaderResourceView[i];
8565 if (i < cValidEntries)
8566 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
8567 else
8568 dxViewDestroy(pDXView);
8569 }
8570 }
8571
8572 rc = dxCOTableRealloc((void **)&pBackendDXContext->paShaderResourceView, &pBackendDXContext->cShaderResourceView,
8573 sizeof(pBackendDXContext->paShaderResourceView[0]), pDXContext->cot.cSRView, cValidEntries);
8574 AssertRCBreak(rc);
8575
8576 for (uint32_t i = 0; i < cValidEntries; ++i)
8577 {
8578 SVGACOTableDXSRViewEntry const *pEntry = &pDXContext->cot.paSRView[i];
8579 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8580 continue; /* Skip uninitialized entry. */
8581
8582 /* Define views which were not defined yet in backend. */
8583 DXVIEW *pDXView = &pBackendDXContext->paShaderResourceView[i];
8584 /** @todo Verify that the pEntry content still corresponds to the view. */
8585 if (pDXView->u.pView)
8586 dxViewAddToList(pThisCC, pDXView);
8587 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
8588 dxDefineShaderResourceView(pThisCC, pDXContext, i, pEntry);
8589 }
8590 break;
8591 case SVGA_COTABLE_ELEMENTLAYOUT:
8592 if (pBackendDXContext->paElementLayout)
8593 {
8594 for (uint32_t i = cValidEntries; i < pBackendDXContext->cElementLayout; ++i)
8595 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
8596 }
8597
8598 rc = dxCOTableRealloc((void **)&pBackendDXContext->paElementLayout, &pBackendDXContext->cElementLayout,
8599 sizeof(pBackendDXContext->paElementLayout[0]), pDXContext->cot.cElementLayout, cValidEntries);
8600 AssertRCBreak(rc);
8601
8602 for (uint32_t i = 0; i < cValidEntries; ++i)
8603 {
8604 SVGACOTableDXElementLayoutEntry const *pEntry = &pDXContext->cot.paElementLayout[i];
8605 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8606 continue; /* Skip uninitialized entry. */
8607
8608 dxDefineElementLayout(pDXContext, i, pEntry);
8609 }
8610 break;
8611 case SVGA_COTABLE_BLENDSTATE:
8612 if (pBackendDXContext->papBlendState)
8613 {
8614 for (uint32_t i = cValidEntries; i < pBackendDXContext->cBlendState; ++i)
8615 D3D_RELEASE(pBackendDXContext->papBlendState[i]);
8616 }
8617
8618 rc = dxCOTableRealloc((void **)&pBackendDXContext->papBlendState, &pBackendDXContext->cBlendState,
8619 sizeof(pBackendDXContext->papBlendState[0]), pDXContext->cot.cBlendState, cValidEntries);
8620 AssertRCBreak(rc);
8621
8622 for (uint32_t i = 0; i < cValidEntries; ++i)
8623 {
8624 SVGACOTableDXBlendStateEntry const *pEntry = &pDXContext->cot.paBlendState[i];
8625 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8626 continue; /* Skip uninitialized entry. */
8627
8628 dxDefineBlendState(pThisCC, pDXContext, i, pEntry);
8629 }
8630 break;
8631 case SVGA_COTABLE_DEPTHSTENCIL:
8632 if (pBackendDXContext->papDepthStencilState)
8633 {
8634 for (uint32_t i = cValidEntries; i < pBackendDXContext->cDepthStencilState; ++i)
8635 D3D_RELEASE(pBackendDXContext->papDepthStencilState[i]);
8636 }
8637
8638 rc = dxCOTableRealloc((void **)&pBackendDXContext->papDepthStencilState, &pBackendDXContext->cDepthStencilState,
8639 sizeof(pBackendDXContext->papDepthStencilState[0]), pDXContext->cot.cDepthStencil, cValidEntries);
8640 AssertRCBreak(rc);
8641
8642 for (uint32_t i = 0; i < cValidEntries; ++i)
8643 {
8644 SVGACOTableDXDepthStencilEntry const *pEntry = &pDXContext->cot.paDepthStencil[i];
8645 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8646 continue; /* Skip uninitialized entry. */
8647
8648 dxDefineDepthStencilState(pThisCC, pDXContext, i, pEntry);
8649 }
8650 break;
8651 case SVGA_COTABLE_RASTERIZERSTATE:
8652 if (pBackendDXContext->papRasterizerState)
8653 {
8654 for (uint32_t i = cValidEntries; i < pBackendDXContext->cRasterizerState; ++i)
8655 D3D_RELEASE(pBackendDXContext->papRasterizerState[i]);
8656 }
8657
8658 rc = dxCOTableRealloc((void **)&pBackendDXContext->papRasterizerState, &pBackendDXContext->cRasterizerState,
8659 sizeof(pBackendDXContext->papRasterizerState[0]), pDXContext->cot.cRasterizerState, cValidEntries);
8660 AssertRCBreak(rc);
8661
8662 for (uint32_t i = 0; i < cValidEntries; ++i)
8663 {
8664 SVGACOTableDXRasterizerStateEntry const *pEntry = &pDXContext->cot.paRasterizerState[i];
8665 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8666 continue; /* Skip uninitialized entry. */
8667
8668 dxDefineRasterizerState(pThisCC, pDXContext, i, pEntry);
8669 }
8670 break;
8671 case SVGA_COTABLE_SAMPLER:
8672 if (pBackendDXContext->papSamplerState)
8673 {
8674 for (uint32_t i = cValidEntries; i < pBackendDXContext->cSamplerState; ++i)
8675 D3D_RELEASE(pBackendDXContext->papSamplerState[i]);
8676 }
8677
8678 rc = dxCOTableRealloc((void **)&pBackendDXContext->papSamplerState, &pBackendDXContext->cSamplerState,
8679 sizeof(pBackendDXContext->papSamplerState[0]), pDXContext->cot.cSampler, cValidEntries);
8680 AssertRCBreak(rc);
8681
8682 for (uint32_t i = 0; i < cValidEntries; ++i)
8683 {
8684 SVGACOTableDXSamplerEntry const *pEntry = &pDXContext->cot.paSampler[i];
8685 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8686 continue; /* Skip uninitialized entry. */
8687
8688 dxDefineSamplerState(pThisCC, pDXContext, i, pEntry);
8689 }
8690 break;
8691 case SVGA_COTABLE_STREAMOUTPUT:
8692 if (pBackendDXContext->paStreamOutput)
8693 {
8694 for (uint32_t i = cValidEntries; i < pBackendDXContext->cStreamOutput; ++i)
8695 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
8696 }
8697
8698 rc = dxCOTableRealloc((void **)&pBackendDXContext->paStreamOutput, &pBackendDXContext->cStreamOutput,
8699 sizeof(pBackendDXContext->paStreamOutput[0]), pDXContext->cot.cStreamOutput, cValidEntries);
8700 AssertRCBreak(rc);
8701
8702 for (uint32_t i = 0; i < cValidEntries; ++i)
8703 {
8704 SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[i];
8705 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
8706 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8707 continue; /* Skip uninitialized entry. */
8708
8709 /* Reset the stream output backend data. It will be re-created when a GS shader with this streamoutput
8710 * will be set in setupPipeline.
8711 */
8712 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[i];
8713 dxDestroyStreamOutput(pDXStreamOutput);
8714 }
8715 break;
8716 case SVGA_COTABLE_DXQUERY:
8717 if (pBackendDXContext->paQuery)
8718 {
8719 /* Destroy the no longer used entries. */
8720 for (uint32_t i = cValidEntries; i < pBackendDXContext->cQuery; ++i)
8721 dxDestroyQuery(&pBackendDXContext->paQuery[i]);
8722 }
8723
8724 rc = dxCOTableRealloc((void **)&pBackendDXContext->paQuery, &pBackendDXContext->cQuery,
8725 sizeof(pBackendDXContext->paQuery[0]), pDXContext->cot.cQuery, cValidEntries);
8726 AssertRCBreak(rc);
8727
8728 for (uint32_t i = 0; i < cValidEntries; ++i)
8729 {
8730 SVGACOTableDXQueryEntry const *pEntry = &pDXContext->cot.paQuery[i];
8731 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8732 continue; /* Skip uninitialized entry. */
8733
8734 /* Define queries which were not defined yet in backend. */
8735 DXQUERY *pDXQuery = &pBackendDXContext->paQuery[i];
8736 if ( pEntry->type != SVGA3D_QUERYTYPE_INVALID
8737 && pDXQuery->pQuery == NULL)
8738 dxDefineQuery(pThisCC, pDXContext, i, pEntry);
8739 else
8740 Assert(pEntry->type == SVGA3D_QUERYTYPE_INVALID || pDXQuery->pQuery);
8741 }
8742 break;
8743 case SVGA_COTABLE_DXSHADER:
8744 if (pBackendDXContext->paShader)
8745 {
8746 /* Destroy the no longer used entries. */
8747 for (uint32_t i = cValidEntries; i < pBackendDXContext->cShader; ++i)
8748 dxDestroyShader(&pBackendDXContext->paShader[i]);
8749 }
8750
8751 rc = dxCOTableRealloc((void **)&pBackendDXContext->paShader, &pBackendDXContext->cShader,
8752 sizeof(pBackendDXContext->paShader[0]), pDXContext->cot.cShader, cValidEntries);
8753 AssertRCBreak(rc);
8754
8755 for (uint32_t i = 0; i < cValidEntries; ++i)
8756 {
8757 SVGACOTableDXShaderEntry const *pEntry = &pDXContext->cot.paShader[i];
8758 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
8759 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8760 continue; /* Skip uninitialized entry. */
8761
8762 /* Define shaders which were not defined yet in backend. */
8763 DXSHADER *pDXShader = &pBackendDXContext->paShader[i];
8764 if ( pEntry->type != SVGA3D_SHADERTYPE_INVALID
8765 && pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
8766 dxDefineShader(pDXContext, i, pEntry);
8767 else
8768 Assert(pEntry->type == pDXShader->enmShaderType);
8769
8770 }
8771 break;
8772 case SVGA_COTABLE_UAVIEW:
8773 if (pBackendDXContext->paUnorderedAccessView)
8774 {
8775 for (uint32_t i = 0; i < pBackendDXContext->cUnorderedAccessView; ++i)
8776 {
8777 DXVIEW *pDXView = &pBackendDXContext->paUnorderedAccessView[i];
8778 if (i < cValidEntries)
8779 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
8780 else
8781 dxViewDestroy(pDXView);
8782 }
8783 }
8784
8785 rc = dxCOTableRealloc((void **)&pBackendDXContext->paUnorderedAccessView, &pBackendDXContext->cUnorderedAccessView,
8786 sizeof(pBackendDXContext->paUnorderedAccessView[0]), pDXContext->cot.cUAView, cValidEntries);
8787 AssertRCBreak(rc);
8788
8789 for (uint32_t i = 0; i < cValidEntries; ++i)
8790 {
8791 SVGACOTableDXUAViewEntry const *pEntry = &pDXContext->cot.paUAView[i];
8792 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
8793 continue; /* Skip uninitialized entry. */
8794
8795 /* Define views which were not defined yet in backend. */
8796 DXVIEW *pDXView = &pBackendDXContext->paUnorderedAccessView[i];
8797 /** @todo Verify that the pEntry content still corresponds to the view. */
8798 if (pDXView->u.pView)
8799 dxViewAddToList(pThisCC, pDXView);
8800 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
8801 dxDefineUnorderedAccessView(pThisCC, pDXContext, i, pEntry);
8802 }
8803 break;
8804 case SVGA_COTABLE_MAX: break; /* Compiler warning */
8805 }
8806 return rc;
8807}
8808
8809
8810static DECLCALLBACK(int) vmsvga3dBackDXBufferCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8811{
8812 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8813
8814 RT_NOREF(pBackend, pDXContext);
8815 AssertFailed(); /** @todo Implement */
8816 return VERR_NOT_IMPLEMENTED;
8817}
8818
8819
8820static DECLCALLBACK(int) vmsvga3dBackDXSurfaceCopyAndReadback(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8821{
8822 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8823
8824 RT_NOREF(pBackend, pDXContext);
8825 AssertFailed(); /** @todo Implement */
8826 return VERR_NOT_IMPLEMENTED;
8827}
8828
8829
8830static DECLCALLBACK(int) vmsvga3dBackDXMoveQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8831{
8832 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8833
8834 RT_NOREF(pBackend, pDXContext);
8835 AssertFailed(); /** @todo Implement */
8836 return VERR_NOT_IMPLEMENTED;
8837}
8838
8839
8840static DECLCALLBACK(int) vmsvga3dBackDXBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8841{
8842 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8843
8844 RT_NOREF(pBackend, pDXContext);
8845 AssertFailed(); /** @todo Implement */
8846 return VERR_NOT_IMPLEMENTED;
8847}
8848
8849
8850static DECLCALLBACK(int) vmsvga3dBackDXHint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8851{
8852 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8853
8854 RT_NOREF(pBackend, pDXContext);
8855 AssertFailed(); /** @todo Implement */
8856 return VERR_NOT_IMPLEMENTED;
8857}
8858
8859
8860static DECLCALLBACK(int) vmsvga3dBackDXBufferUpdate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8861{
8862 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8863
8864 RT_NOREF(pBackend, pDXContext);
8865 AssertFailed(); /** @todo Implement */
8866 return VERR_NOT_IMPLEMENTED;
8867}
8868
8869
8870static DECLCALLBACK(int) vmsvga3dBackDXSetVSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8871{
8872 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8873
8874 RT_NOREF(pBackend, pDXContext);
8875 AssertFailed(); /** @todo Implement */
8876 return VERR_NOT_IMPLEMENTED;
8877}
8878
8879
8880static DECLCALLBACK(int) vmsvga3dBackDXSetPSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8881{
8882 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8883
8884 RT_NOREF(pBackend, pDXContext);
8885 AssertFailed(); /** @todo Implement */
8886 return VERR_NOT_IMPLEMENTED;
8887}
8888
8889
8890static DECLCALLBACK(int) vmsvga3dBackDXSetGSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8891{
8892 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8893
8894 RT_NOREF(pBackend, pDXContext);
8895 AssertFailed(); /** @todo Implement */
8896 return VERR_NOT_IMPLEMENTED;
8897}
8898
8899
8900static DECLCALLBACK(int) vmsvga3dBackDXSetHSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8901{
8902 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8903
8904 RT_NOREF(pBackend, pDXContext);
8905 AssertFailed(); /** @todo Implement */
8906 return VERR_NOT_IMPLEMENTED;
8907}
8908
8909
8910static DECLCALLBACK(int) vmsvga3dBackDXSetDSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8911{
8912 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8913
8914 RT_NOREF(pBackend, pDXContext);
8915 AssertFailed(); /** @todo Implement */
8916 return VERR_NOT_IMPLEMENTED;
8917}
8918
8919
8920static DECLCALLBACK(int) vmsvga3dBackDXSetCSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8921{
8922 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8923
8924 RT_NOREF(pBackend, pDXContext);
8925 AssertFailed(); /** @todo Implement */
8926 return VERR_NOT_IMPLEMENTED;
8927}
8928
8929
8930static DECLCALLBACK(int) vmsvga3dBackDXCondBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8931{
8932 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8933
8934 RT_NOREF(pBackend, pDXContext);
8935 AssertFailed(); /** @todo Implement */
8936 return VERR_NOT_IMPLEMENTED;
8937}
8938
8939
8940static DECLCALLBACK(int) vmsvga3dBackScreenCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8941{
8942 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8943
8944 RT_NOREF(pBackend, pDXContext);
8945 AssertFailed(); /** @todo Implement */
8946 return VERR_NOT_IMPLEMENTED;
8947}
8948
8949
8950static DECLCALLBACK(int) vmsvga3dBackIntraSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8951{
8952 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8953
8954 RT_NOREF(pBackend, pDXContext);
8955 AssertFailed(); /** @todo Implement */
8956 return VERR_NOT_IMPLEMENTED;
8957}
8958
8959
8960static DECLCALLBACK(int) vmsvga3dBackDXResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8961{
8962 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8963
8964 RT_NOREF(pBackend, pDXContext);
8965 AssertFailed(); /** @todo Implement */
8966 return VERR_NOT_IMPLEMENTED;
8967}
8968
8969
8970static DECLCALLBACK(int) vmsvga3dBackDXPredResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8971{
8972 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8973
8974 RT_NOREF(pBackend, pDXContext);
8975 AssertFailed(); /** @todo Implement */
8976 return VERR_NOT_IMPLEMENTED;
8977}
8978
8979
8980static DECLCALLBACK(int) vmsvga3dBackDXPredConvertRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8981{
8982 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8983
8984 RT_NOREF(pBackend, pDXContext);
8985 AssertFailed(); /** @todo Implement */
8986 return VERR_NOT_IMPLEMENTED;
8987}
8988
8989
8990static DECLCALLBACK(int) vmsvga3dBackDXPredConvert(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
8991{
8992 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
8993
8994 RT_NOREF(pBackend, pDXContext);
8995 AssertFailed(); /** @todo Implement */
8996 return VERR_NOT_IMPLEMENTED;
8997}
8998
8999
9000static DECLCALLBACK(int) vmsvga3dBackWholeSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9001{
9002 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9003
9004 RT_NOREF(pBackend, pDXContext);
9005 AssertFailed(); /** @todo Implement */
9006 return VERR_NOT_IMPLEMENTED;
9007}
9008
9009
9010static int dxDefineUnorderedAccessView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dUAViewId uaViewId, SVGACOTableDXUAViewEntry const *pEntry)
9011{
9012 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
9013 PVMSVGA3DSURFACE pSurface;
9014 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
9015 AssertRCReturn(rc, rc);
9016
9017 ID3D11UnorderedAccessView *pUnorderedAccessView;
9018 DXVIEW *pView = &pDXContext->pBackendDXContext->paUnorderedAccessView[uaViewId];
9019 Assert(pView->u.pView == NULL);
9020
9021 if (pSurface->pBackendSurface == NULL)
9022 {
9023 /* Create the actual texture or buffer. */
9024 /** @todo One function to create all resources from surfaces. */
9025 if (pSurface->format != SVGA3D_BUFFER)
9026 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
9027 else
9028 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSurface);
9029
9030 AssertRCReturn(rc, rc);
9031 }
9032
9033 HRESULT hr = dxUnorderedAccessViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pUnorderedAccessView);
9034 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
9035
9036 return dxViewInit(pView, pSurface, pDXContext, uaViewId, VMSVGA3D_VIEWTYPE_UNORDEREDACCESS, pUnorderedAccessView);
9037}
9038
9039
9040static DECLCALLBACK(int) vmsvga3dBackDXDefineUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dUAViewId uaViewId, SVGACOTableDXUAViewEntry const *pEntry)
9041{
9042 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9043 RT_NOREF(pBackend);
9044
9045 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9046 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9047
9048 /** @todo Probably not necessary because UAVs are defined in setupPipeline. */
9049 return dxDefineUnorderedAccessView(pThisCC, pDXContext, uaViewId, pEntry);
9050}
9051
9052
9053static DECLCALLBACK(int) vmsvga3dBackDXDestroyUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dUAViewId uaViewId)
9054{
9055 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9056 RT_NOREF(pBackend);
9057
9058 return dxViewDestroy(&pDXContext->pBackendDXContext->paUnorderedAccessView[uaViewId]);
9059}
9060
9061
9062static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewUint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dUAViewId uaViewId, uint32_t const aValues[4])
9063{
9064 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9065 RT_NOREF(pBackend);
9066
9067 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9068 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9069
9070 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paUnorderedAccessView[uaViewId];
9071 if (!pDXView->u.pUnorderedAccessView)
9072 {
9073 /* (Re-)create the view, because a creation of a view is deferred until a draw or a clear call. */
9074 SVGACOTableDXUAViewEntry const *pEntry = dxGetUnorderedAccessViewEntry(pDXContext, uaViewId);
9075 int rc = dxDefineUnorderedAccessView(pThisCC, pDXContext, uaViewId, pEntry);
9076 AssertRCReturn(rc, rc);
9077 }
9078 pDevice->pImmediateContext->ClearUnorderedAccessViewUint(pDXView->u.pUnorderedAccessView, aValues);
9079 return VINF_SUCCESS;
9080}
9081
9082
9083static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewFloat(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dUAViewId uaViewId, float const aValues[4])
9084{
9085 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9086 RT_NOREF(pBackend);
9087
9088 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9089 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9090
9091 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paUnorderedAccessView[uaViewId];
9092 if (!pDXView->u.pUnorderedAccessView)
9093 {
9094 /* (Re-)create the view, because a creation of a view is deferred until a draw or a clear call. */
9095 SVGACOTableDXUAViewEntry const *pEntry = &pDXContext->cot.paUAView[uaViewId];
9096 int rc = dxDefineUnorderedAccessView(pThisCC, pDXContext, uaViewId, pEntry);
9097 AssertRCReturn(rc, rc);
9098 }
9099 pDevice->pImmediateContext->ClearUnorderedAccessViewFloat(pDXView->u.pUnorderedAccessView, aValues);
9100 return VINF_SUCCESS;
9101}
9102
9103
9104static DECLCALLBACK(int) vmsvga3dBackDXCopyStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dUAViewId srcUAViewId, SVGA3dSurfaceId destSid, uint32_t destByteOffset)
9105{
9106 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9107 RT_NOREF(pBackend);
9108
9109 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9110 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9111
9112 /* Get corresponding resource. Create the buffer if does not yet exist. */
9113 ID3D11Buffer *pDstBuffer;
9114 if (destSid != SVGA3D_INVALID_ID)
9115 {
9116 PVMSVGA3DSURFACE pSurface;
9117 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, destSid, &pSurface);
9118 AssertRCReturn(rc, rc);
9119
9120 if (pSurface->pBackendSurface == NULL)
9121 {
9122 /* Create the resource and initialize it with the current surface data. */
9123 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSurface);
9124 AssertRCReturn(rc, rc);
9125 }
9126
9127 pDstBuffer = pSurface->pBackendSurface->u.pBuffer;
9128 }
9129 else
9130 pDstBuffer = NULL;
9131
9132 ID3D11UnorderedAccessView *pSrcView;
9133 if (srcUAViewId != SVGA3D_INVALID_ID)
9134 {
9135 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paUnorderedAccessView[srcUAViewId];
9136 AssertReturn(pDXView->u.pUnorderedAccessView, VERR_INVALID_STATE);
9137 pSrcView = pDXView->u.pUnorderedAccessView;
9138 }
9139 else
9140 pSrcView = NULL;
9141
9142 pDevice->pImmediateContext->CopyStructureCount(pDstBuffer, destByteOffset, pSrcView);
9143
9144 return VINF_SUCCESS;
9145}
9146
9147
9148static DECLCALLBACK(int) vmsvga3dBackDXSetUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t uavSpliceIndex, uint32_t cUAViewId, SVGA3dUAViewId const *paUAViewId)
9149{
9150 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9151 RT_NOREF(pBackend);
9152
9153 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9154 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9155
9156 RT_NOREF(uavSpliceIndex, cUAViewId, paUAViewId);
9157
9158 return VINF_SUCCESS;
9159}
9160
9161
9162static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId argsBufferSid, uint32_t byteOffsetForArgs)
9163{
9164 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9165 RT_NOREF(pBackend);
9166
9167 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9168 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9169
9170 /* Get corresponding resource. Create the buffer if does not yet exist. */
9171 ID3D11Buffer *pBufferForArgs;
9172 if (argsBufferSid != SVGA_ID_INVALID)
9173 {
9174 PVMSVGA3DSURFACE pSurface;
9175 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, argsBufferSid, &pSurface);
9176 AssertRCReturn(rc, rc);
9177
9178 if (pSurface->pBackendSurface == NULL)
9179 {
9180 /* Create the resource and initialize it with the current surface data. */
9181 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSurface);
9182 AssertRCReturn(rc, rc);
9183 }
9184
9185 pBufferForArgs = pSurface->pBackendSurface->u.pBuffer;
9186 }
9187 else
9188 pBufferForArgs = NULL;
9189
9190 dxSetupPipeline(pThisCC, pDXContext);
9191
9192 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
9193
9194 pDevice->pImmediateContext->DrawIndexedInstancedIndirect(pBufferForArgs, byteOffsetForArgs);
9195
9196 /* Note which surfaces are being drawn. */
9197 dxTrackRenderTargets(pThisCC, pDXContext);
9198
9199 return VINF_SUCCESS;
9200}
9201
9202
9203static DECLCALLBACK(int) vmsvga3dBackDXDrawInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId argsBufferSid, uint32_t byteOffsetForArgs)
9204{
9205 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9206 RT_NOREF(pBackend);
9207
9208 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9209 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9210
9211 /* Get corresponding resource. Create the buffer if does not yet exist. */
9212 ID3D11Buffer *pBufferForArgs;
9213 if (argsBufferSid != SVGA_ID_INVALID)
9214 {
9215 PVMSVGA3DSURFACE pSurface;
9216 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, argsBufferSid, &pSurface);
9217 AssertRCReturn(rc, rc);
9218
9219 if (pSurface->pBackendSurface == NULL)
9220 {
9221 /* Create the resource and initialize it with the current surface data. */
9222 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSurface);
9223 AssertRCReturn(rc, rc);
9224 }
9225
9226 pBufferForArgs = pSurface->pBackendSurface->u.pBuffer;
9227 }
9228 else
9229 pBufferForArgs = NULL;
9230
9231 dxSetupPipeline(pThisCC, pDXContext);
9232
9233 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
9234
9235 pDevice->pImmediateContext->DrawInstancedIndirect(pBufferForArgs, byteOffsetForArgs);
9236
9237 /* Note which surfaces are being drawn. */
9238 dxTrackRenderTargets(pThisCC, pDXContext);
9239
9240 return VINF_SUCCESS;
9241}
9242
9243
9244static DECLCALLBACK(int) vmsvga3dBackDXDispatch(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ)
9245{
9246 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9247 RT_NOREF(pBackend);
9248
9249 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9250 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9251
9252 dxSetupPipeline(pThisCC, pDXContext);
9253
9254 pDevice->pImmediateContext->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
9255
9256 return VINF_SUCCESS;
9257}
9258
9259
9260static DECLCALLBACK(int) vmsvga3dBackDXDispatchIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9261{
9262 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9263
9264 RT_NOREF(pBackend, pDXContext);
9265 AssertFailed(); /** @todo Implement */
9266 return VERR_NOT_IMPLEMENTED;
9267}
9268
9269
9270static DECLCALLBACK(int) vmsvga3dBackWriteZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9271{
9272 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9273
9274 RT_NOREF(pBackend, pDXContext);
9275 AssertFailed(); /** @todo Implement */
9276 return VERR_NOT_IMPLEMENTED;
9277}
9278
9279
9280static DECLCALLBACK(int) vmsvga3dBackHintZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9281{
9282 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9283
9284 RT_NOREF(pBackend, pDXContext);
9285 AssertFailed(); /** @todo Implement */
9286 return VERR_NOT_IMPLEMENTED;
9287}
9288
9289
9290static DECLCALLBACK(int) vmsvga3dBackDXTransferToBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9291{
9292 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9293
9294 RT_NOREF(pBackend, pDXContext);
9295 AssertFailed(); /** @todo Implement */
9296 return VERR_NOT_IMPLEMENTED;
9297}
9298
9299
9300static DECLCALLBACK(int) vmsvga3dBackLogicOpsBitBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9301{
9302 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9303
9304 RT_NOREF(pBackend, pDXContext);
9305 AssertFailed(); /** @todo Implement */
9306 return VERR_NOT_IMPLEMENTED;
9307}
9308
9309
9310static DECLCALLBACK(int) vmsvga3dBackLogicOpsTransBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9311{
9312 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9313
9314 RT_NOREF(pBackend, pDXContext);
9315 AssertFailed(); /** @todo Implement */
9316 return VERR_NOT_IMPLEMENTED;
9317}
9318
9319
9320static DECLCALLBACK(int) vmsvga3dBackLogicOpsStretchBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9321{
9322 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9323
9324 RT_NOREF(pBackend, pDXContext);
9325 AssertFailed(); /** @todo Implement */
9326 return VERR_NOT_IMPLEMENTED;
9327}
9328
9329
9330static DECLCALLBACK(int) vmsvga3dBackLogicOpsColorFill(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9331{
9332 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9333
9334 RT_NOREF(pBackend, pDXContext);
9335 AssertFailed(); /** @todo Implement */
9336 return VERR_NOT_IMPLEMENTED;
9337}
9338
9339
9340static DECLCALLBACK(int) vmsvga3dBackLogicOpsAlphaBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9341{
9342 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9343
9344 RT_NOREF(pBackend, pDXContext);
9345 AssertFailed(); /** @todo Implement */
9346 return VERR_NOT_IMPLEMENTED;
9347}
9348
9349
9350static DECLCALLBACK(int) vmsvga3dBackLogicOpsClearTypeBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9351{
9352 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9353
9354 RT_NOREF(pBackend, pDXContext);
9355 AssertFailed(); /** @todo Implement */
9356 return VERR_NOT_IMPLEMENTED;
9357}
9358
9359
9360static int dxSetCSUnorderedAccessViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9361{
9362 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9363 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9364
9365//DEBUG_BREAKPOINT_TEST();
9366 uint32_t const *pUAIds = &pDXContext->svgaDXContext.csuaViewIds[0];
9367 ID3D11UnorderedAccessView *papUnorderedAccessView[SVGA3D_DX11_1_MAX_UAVIEWS];
9368 UINT aUAVInitialCounts[SVGA3D_DX11_1_MAX_UAVIEWS];
9369 for (uint32_t i = 0; i < SVGA3D_DX11_1_MAX_UAVIEWS; ++i)
9370 {
9371 SVGA3dUAViewId const uaViewId = pUAIds[i];
9372 if (uaViewId != SVGA3D_INVALID_ID)
9373 {
9374 ASSERT_GUEST_RETURN(uaViewId < pDXContext->pBackendDXContext->cUnorderedAccessView, VERR_INVALID_PARAMETER);
9375
9376 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paUnorderedAccessView[uaViewId];
9377 Assert(pDXView->u.pUnorderedAccessView);
9378 papUnorderedAccessView[i] = pDXView->u.pUnorderedAccessView;
9379
9380 SVGACOTableDXUAViewEntry const *pEntry = dxGetUnorderedAccessViewEntry(pDXContext, uaViewId);
9381 aUAVInitialCounts[i] = pEntry->structureCount;
9382 }
9383 else
9384 {
9385 papUnorderedAccessView[i] = NULL;
9386 aUAVInitialCounts[i] = (UINT)-1;
9387 }
9388 }
9389
9390 dxCSUnorderedAccessViewSet(pDevice, 0, SVGA3D_DX11_1_MAX_UAVIEWS, papUnorderedAccessView, aUAVInitialCounts);
9391 return VINF_SUCCESS;
9392}
9393
9394
9395static DECLCALLBACK(int) vmsvga3dBackDXSetCSUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startIndex, uint32_t cUAViewId, SVGA3dUAViewId const *paUAViewId)
9396{
9397 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9398 RT_NOREF(pBackend);
9399
9400 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
9401 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
9402
9403 RT_NOREF(startIndex, cUAViewId, paUAViewId);
9404
9405 return VINF_SUCCESS;
9406}
9407
9408
9409static DECLCALLBACK(int) vmsvga3dBackDXSetMinLOD(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9410{
9411 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9412
9413 RT_NOREF(pBackend, pDXContext);
9414 AssertFailed(); /** @todo Implement */
9415 return VERR_NOT_IMPLEMENTED;
9416}
9417
9418
9419static DECLCALLBACK(int) vmsvga3dBackDXSetShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9420{
9421 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9422
9423 RT_NOREF(pBackend, pDXContext);
9424 AssertFailed(); /** @todo Implement */
9425 return VERR_NOT_IMPLEMENTED;
9426}
9427
9428
9429static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBltNonMSToMS(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9430{
9431 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9432
9433 RT_NOREF(pBackend, pDXContext);
9434 AssertFailed(); /** @todo Implement */
9435 return VERR_NOT_IMPLEMENTED;
9436}
9437
9438
9439static DECLCALLBACK(int) vmsvga3dBackDXBindShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
9440{
9441 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
9442
9443 RT_NOREF(pBackend, pDXContext);
9444 AssertFailed(); /** @todo Implement */
9445 return VERR_NOT_IMPLEMENTED;
9446}
9447
9448
9449static DECLCALLBACK(int) vmsvga3dBackDXLoadState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM)
9450{
9451 RT_NOREF(pThisCC);
9452 uint32_t u32;
9453 int rc;
9454
9455 rc = pHlp->pfnSSMGetU32(pSSM, &u32);
9456 AssertLogRelRCReturn(rc, rc);
9457 AssertLogRelRCReturn(u32 == pDXContext->pBackendDXContext->cShader, VERR_INVALID_STATE);
9458
9459 for (uint32_t i = 0; i < pDXContext->pBackendDXContext->cShader; ++i)
9460 {
9461 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[i];
9462
9463 rc = pHlp->pfnSSMGetU32(pSSM, &u32);
9464 AssertLogRelRCReturn(rc, rc);
9465 AssertLogRelReturn((SVGA3dShaderType)u32 == pDXShader->enmShaderType, VERR_INVALID_STATE);
9466
9467 if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
9468 continue;
9469
9470 pHlp->pfnSSMGetU32(pSSM, &pDXShader->soid);
9471
9472 pHlp->pfnSSMGetU32(pSSM, &u32);
9473 pDXShader->shaderInfo.enmProgramType = (VGPU10_PROGRAM_TYPE)u32;
9474
9475 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cbBytecode);
9476 AssertLogRelRCReturn(rc, rc);
9477 AssertLogRelReturn(pDXShader->shaderInfo.cbBytecode <= 2 * SVGA3D_MAX_SHADER_MEMORY_BYTES, VERR_INVALID_STATE);
9478
9479 if (pDXShader->shaderInfo.cbBytecode)
9480 {
9481 pDXShader->shaderInfo.pvBytecode = RTMemAlloc(pDXShader->shaderInfo.cbBytecode);
9482 AssertPtrReturn(pDXShader->shaderInfo.pvBytecode, VERR_NO_MEMORY);
9483 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.pvBytecode, pDXShader->shaderInfo.cbBytecode);
9484 }
9485
9486 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cInputSignature);
9487 AssertLogRelRCReturn(rc, rc);
9488 AssertLogRelReturn(pDXShader->shaderInfo.cInputSignature <= 32, VERR_INVALID_STATE);
9489 if (pDXShader->shaderInfo.cInputSignature)
9490 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aInputSignature, pDXShader->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
9491
9492 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cOutputSignature);
9493 AssertLogRelRCReturn(rc, rc);
9494 AssertLogRelReturn(pDXShader->shaderInfo.cOutputSignature <= 32, VERR_INVALID_STATE);
9495 if (pDXShader->shaderInfo.cOutputSignature)
9496 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aOutputSignature, pDXShader->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
9497
9498 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cPatchConstantSignature);
9499 AssertLogRelRCReturn(rc, rc);
9500 AssertLogRelReturn(pDXShader->shaderInfo.cPatchConstantSignature <= 32, VERR_INVALID_STATE);
9501 if (pDXShader->shaderInfo.cPatchConstantSignature)
9502 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aPatchConstantSignature, pDXShader->shaderInfo.cPatchConstantSignature * sizeof(SVGA3dDXSignatureEntry));
9503
9504 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cDclResource);
9505 AssertLogRelRCReturn(rc, rc);
9506 AssertLogRelReturn(pDXShader->shaderInfo.cDclResource <= SVGA3D_DX_MAX_SRVIEWS, VERR_INVALID_STATE);
9507 if (pDXShader->shaderInfo.cDclResource)
9508 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aOffDclResource, pDXShader->shaderInfo.cDclResource * sizeof(uint32_t));
9509
9510 DXShaderGenerateSemantics(&pDXShader->shaderInfo);
9511 }
9512
9513 rc = pHlp->pfnSSMGetU32(pSSM, &pDXContext->pBackendDXContext->cSOTarget);
9514 AssertLogRelRCReturn(rc, rc);
9515
9516 return VINF_SUCCESS;
9517}
9518
9519
9520static DECLCALLBACK(int) vmsvga3dBackDXSaveState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM)
9521{
9522 RT_NOREF(pThisCC);
9523 int rc;
9524
9525 pHlp->pfnSSMPutU32(pSSM, pDXContext->pBackendDXContext->cShader);
9526 for (uint32_t i = 0; i < pDXContext->pBackendDXContext->cShader; ++i)
9527 {
9528 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[i];
9529
9530 pHlp->pfnSSMPutU32(pSSM, (uint32_t)pDXShader->enmShaderType);
9531 if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
9532 continue;
9533
9534 pHlp->pfnSSMPutU32(pSSM, pDXShader->soid);
9535
9536 pHlp->pfnSSMPutU32(pSSM, (uint32_t)pDXShader->shaderInfo.enmProgramType);
9537
9538 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cbBytecode);
9539 if (pDXShader->shaderInfo.cbBytecode)
9540 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.pvBytecode, pDXShader->shaderInfo.cbBytecode);
9541
9542 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cInputSignature);
9543 if (pDXShader->shaderInfo.cInputSignature)
9544 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aInputSignature, pDXShader->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
9545
9546 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cOutputSignature);
9547 if (pDXShader->shaderInfo.cOutputSignature)
9548 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aOutputSignature, pDXShader->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
9549
9550 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cPatchConstantSignature);
9551 if (pDXShader->shaderInfo.cPatchConstantSignature)
9552 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aPatchConstantSignature, pDXShader->shaderInfo.cPatchConstantSignature * sizeof(SVGA3dDXSignatureEntry));
9553
9554 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cDclResource);
9555 if (pDXShader->shaderInfo.cDclResource)
9556 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aOffDclResource, pDXShader->shaderInfo.cDclResource * sizeof(uint32_t));
9557 }
9558 rc = pHlp->pfnSSMPutU32(pSSM, pDXContext->pBackendDXContext->cSOTarget);
9559 AssertLogRelRCReturn(rc, rc);
9560
9561 return VINF_SUCCESS;
9562}
9563
9564
9565static DECLCALLBACK(int) vmsvga3dBackQueryInterface(PVGASTATECC pThisCC, char const *pszInterfaceName, void *pvInterfaceFuncs, size_t cbInterfaceFuncs)
9566{
9567 RT_NOREF(pThisCC);
9568
9569 int rc = VINF_SUCCESS;
9570 if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_DX) == 0)
9571 {
9572 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSDX))
9573 {
9574 if (pvInterfaceFuncs)
9575 {
9576 VMSVGA3DBACKENDFUNCSDX *p = (VMSVGA3DBACKENDFUNCSDX *)pvInterfaceFuncs;
9577 p->pfnDXSaveState = vmsvga3dBackDXSaveState;
9578 p->pfnDXLoadState = vmsvga3dBackDXLoadState;
9579 p->pfnDXDefineContext = vmsvga3dBackDXDefineContext;
9580 p->pfnDXDestroyContext = vmsvga3dBackDXDestroyContext;
9581 p->pfnDXBindContext = vmsvga3dBackDXBindContext;
9582 p->pfnDXSwitchContext = vmsvga3dBackDXSwitchContext;
9583 p->pfnDXReadbackContext = vmsvga3dBackDXReadbackContext;
9584 p->pfnDXInvalidateContext = vmsvga3dBackDXInvalidateContext;
9585 p->pfnDXSetSingleConstantBuffer = vmsvga3dBackDXSetSingleConstantBuffer;
9586 p->pfnDXSetShaderResources = vmsvga3dBackDXSetShaderResources;
9587 p->pfnDXSetShader = vmsvga3dBackDXSetShader;
9588 p->pfnDXSetSamplers = vmsvga3dBackDXSetSamplers;
9589 p->pfnDXDraw = vmsvga3dBackDXDraw;
9590 p->pfnDXDrawIndexed = vmsvga3dBackDXDrawIndexed;
9591 p->pfnDXDrawInstanced = vmsvga3dBackDXDrawInstanced;
9592 p->pfnDXDrawIndexedInstanced = vmsvga3dBackDXDrawIndexedInstanced;
9593 p->pfnDXDrawAuto = vmsvga3dBackDXDrawAuto;
9594 p->pfnDXSetInputLayout = vmsvga3dBackDXSetInputLayout;
9595 p->pfnDXSetVertexBuffers = vmsvga3dBackDXSetVertexBuffers;
9596 p->pfnDXSetIndexBuffer = vmsvga3dBackDXSetIndexBuffer;
9597 p->pfnDXSetTopology = vmsvga3dBackDXSetTopology;
9598 p->pfnDXSetRenderTargets = vmsvga3dBackDXSetRenderTargets;
9599 p->pfnDXSetBlendState = vmsvga3dBackDXSetBlendState;
9600 p->pfnDXSetDepthStencilState = vmsvga3dBackDXSetDepthStencilState;
9601 p->pfnDXSetRasterizerState = vmsvga3dBackDXSetRasterizerState;
9602 p->pfnDXDefineQuery = vmsvga3dBackDXDefineQuery;
9603 p->pfnDXDestroyQuery = vmsvga3dBackDXDestroyQuery;
9604 p->pfnDXBeginQuery = vmsvga3dBackDXBeginQuery;
9605 p->pfnDXEndQuery = vmsvga3dBackDXEndQuery;
9606 p->pfnDXSetPredication = vmsvga3dBackDXSetPredication;
9607 p->pfnDXSetSOTargets = vmsvga3dBackDXSetSOTargets;
9608 p->pfnDXSetViewports = vmsvga3dBackDXSetViewports;
9609 p->pfnDXSetScissorRects = vmsvga3dBackDXSetScissorRects;
9610 p->pfnDXClearRenderTargetView = vmsvga3dBackDXClearRenderTargetView;
9611 p->pfnDXClearDepthStencilView = vmsvga3dBackDXClearDepthStencilView;
9612 p->pfnDXPredCopyRegion = vmsvga3dBackDXPredCopyRegion;
9613 p->pfnDXPredCopy = vmsvga3dBackDXPredCopy;
9614 p->pfnDXPresentBlt = vmsvga3dBackDXPresentBlt;
9615 p->pfnDXGenMips = vmsvga3dBackDXGenMips;
9616 p->pfnDXDefineShaderResourceView = vmsvga3dBackDXDefineShaderResourceView;
9617 p->pfnDXDestroyShaderResourceView = vmsvga3dBackDXDestroyShaderResourceView;
9618 p->pfnDXDefineRenderTargetView = vmsvga3dBackDXDefineRenderTargetView;
9619 p->pfnDXDestroyRenderTargetView = vmsvga3dBackDXDestroyRenderTargetView;
9620 p->pfnDXDefineDepthStencilView = vmsvga3dBackDXDefineDepthStencilView;
9621 p->pfnDXDestroyDepthStencilView = vmsvga3dBackDXDestroyDepthStencilView;
9622 p->pfnDXDefineElementLayout = vmsvga3dBackDXDefineElementLayout;
9623 p->pfnDXDestroyElementLayout = vmsvga3dBackDXDestroyElementLayout;
9624 p->pfnDXDefineBlendState = vmsvga3dBackDXDefineBlendState;
9625 p->pfnDXDestroyBlendState = vmsvga3dBackDXDestroyBlendState;
9626 p->pfnDXDefineDepthStencilState = vmsvga3dBackDXDefineDepthStencilState;
9627 p->pfnDXDestroyDepthStencilState = vmsvga3dBackDXDestroyDepthStencilState;
9628 p->pfnDXDefineRasterizerState = vmsvga3dBackDXDefineRasterizerState;
9629 p->pfnDXDestroyRasterizerState = vmsvga3dBackDXDestroyRasterizerState;
9630 p->pfnDXDefineSamplerState = vmsvga3dBackDXDefineSamplerState;
9631 p->pfnDXDestroySamplerState = vmsvga3dBackDXDestroySamplerState;
9632 p->pfnDXDefineShader = vmsvga3dBackDXDefineShader;
9633 p->pfnDXDestroyShader = vmsvga3dBackDXDestroyShader;
9634 p->pfnDXBindShader = vmsvga3dBackDXBindShader;
9635 p->pfnDXDefineStreamOutput = vmsvga3dBackDXDefineStreamOutput;
9636 p->pfnDXDestroyStreamOutput = vmsvga3dBackDXDestroyStreamOutput;
9637 p->pfnDXSetStreamOutput = vmsvga3dBackDXSetStreamOutput;
9638 p->pfnDXSetCOTable = vmsvga3dBackDXSetCOTable;
9639 p->pfnDXBufferCopy = vmsvga3dBackDXBufferCopy;
9640 p->pfnDXSurfaceCopyAndReadback = vmsvga3dBackDXSurfaceCopyAndReadback;
9641 p->pfnDXMoveQuery = vmsvga3dBackDXMoveQuery;
9642 p->pfnDXBindAllShader = vmsvga3dBackDXBindAllShader;
9643 p->pfnDXHint = vmsvga3dBackDXHint;
9644 p->pfnDXBufferUpdate = vmsvga3dBackDXBufferUpdate;
9645 p->pfnDXSetVSConstantBufferOffset = vmsvga3dBackDXSetVSConstantBufferOffset;
9646 p->pfnDXSetPSConstantBufferOffset = vmsvga3dBackDXSetPSConstantBufferOffset;
9647 p->pfnDXSetGSConstantBufferOffset = vmsvga3dBackDXSetGSConstantBufferOffset;
9648 p->pfnDXSetHSConstantBufferOffset = vmsvga3dBackDXSetHSConstantBufferOffset;
9649 p->pfnDXSetDSConstantBufferOffset = vmsvga3dBackDXSetDSConstantBufferOffset;
9650 p->pfnDXSetCSConstantBufferOffset = vmsvga3dBackDXSetCSConstantBufferOffset;
9651 p->pfnDXCondBindAllShader = vmsvga3dBackDXCondBindAllShader;
9652 p->pfnScreenCopy = vmsvga3dBackScreenCopy;
9653 p->pfnIntraSurfaceCopy = vmsvga3dBackIntraSurfaceCopy;
9654 p->pfnDXResolveCopy = vmsvga3dBackDXResolveCopy;
9655 p->pfnDXPredResolveCopy = vmsvga3dBackDXPredResolveCopy;
9656 p->pfnDXPredConvertRegion = vmsvga3dBackDXPredConvertRegion;
9657 p->pfnDXPredConvert = vmsvga3dBackDXPredConvert;
9658 p->pfnWholeSurfaceCopy = vmsvga3dBackWholeSurfaceCopy;
9659 p->pfnDXDefineUAView = vmsvga3dBackDXDefineUAView;
9660 p->pfnDXDestroyUAView = vmsvga3dBackDXDestroyUAView;
9661 p->pfnDXClearUAViewUint = vmsvga3dBackDXClearUAViewUint;
9662 p->pfnDXClearUAViewFloat = vmsvga3dBackDXClearUAViewFloat;
9663 p->pfnDXCopyStructureCount = vmsvga3dBackDXCopyStructureCount;
9664 p->pfnDXSetUAViews = vmsvga3dBackDXSetUAViews;
9665 p->pfnDXDrawIndexedInstancedIndirect = vmsvga3dBackDXDrawIndexedInstancedIndirect;
9666 p->pfnDXDrawInstancedIndirect = vmsvga3dBackDXDrawInstancedIndirect;
9667 p->pfnDXDispatch = vmsvga3dBackDXDispatch;
9668 p->pfnDXDispatchIndirect = vmsvga3dBackDXDispatchIndirect;
9669 p->pfnWriteZeroSurface = vmsvga3dBackWriteZeroSurface;
9670 p->pfnHintZeroSurface = vmsvga3dBackHintZeroSurface;
9671 p->pfnDXTransferToBuffer = vmsvga3dBackDXTransferToBuffer;
9672 p->pfnLogicOpsBitBlt = vmsvga3dBackLogicOpsBitBlt;
9673 p->pfnLogicOpsTransBlt = vmsvga3dBackLogicOpsTransBlt;
9674 p->pfnLogicOpsStretchBlt = vmsvga3dBackLogicOpsStretchBlt;
9675 p->pfnLogicOpsColorFill = vmsvga3dBackLogicOpsColorFill;
9676 p->pfnLogicOpsAlphaBlend = vmsvga3dBackLogicOpsAlphaBlend;
9677 p->pfnLogicOpsClearTypeBlend = vmsvga3dBackLogicOpsClearTypeBlend;
9678 p->pfnDXSetCSUAViews = vmsvga3dBackDXSetCSUAViews;
9679 p->pfnDXSetMinLOD = vmsvga3dBackDXSetMinLOD;
9680 p->pfnDXSetShaderIface = vmsvga3dBackDXSetShaderIface;
9681 p->pfnSurfaceStretchBltNonMSToMS = vmsvga3dBackSurfaceStretchBltNonMSToMS;
9682 p->pfnDXBindShaderIface = vmsvga3dBackDXBindShaderIface;
9683 p->pfnVBDXClearRenderTargetViewRegion = vmsvga3dBackVBDXClearRenderTargetViewRegion;
9684 }
9685 }
9686 else
9687 {
9688 AssertFailed();
9689 rc = VERR_INVALID_PARAMETER;
9690 }
9691 }
9692 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_MAP) == 0)
9693 {
9694 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSMAP))
9695 {
9696 if (pvInterfaceFuncs)
9697 {
9698 VMSVGA3DBACKENDFUNCSMAP *p = (VMSVGA3DBACKENDFUNCSMAP *)pvInterfaceFuncs;
9699 p->pfnSurfaceMap = vmsvga3dBackSurfaceMap;
9700 p->pfnSurfaceUnmap = vmsvga3dBackSurfaceUnmap;
9701 }
9702 }
9703 else
9704 {
9705 AssertFailed();
9706 rc = VERR_INVALID_PARAMETER;
9707 }
9708 }
9709 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_GBO) == 0)
9710 {
9711 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSGBO))
9712 {
9713 if (pvInterfaceFuncs)
9714 {
9715 VMSVGA3DBACKENDFUNCSGBO *p = (VMSVGA3DBACKENDFUNCSGBO *)pvInterfaceFuncs;
9716 p->pfnScreenTargetBind = vmsvga3dScreenTargetBind;
9717 p->pfnScreenTargetUpdate = vmsvga3dScreenTargetUpdate;
9718 }
9719 }
9720 else
9721 {
9722 AssertFailed();
9723 rc = VERR_INVALID_PARAMETER;
9724 }
9725 }
9726 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_3D) == 0)
9727 {
9728 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCS3D))
9729 {
9730 if (pvInterfaceFuncs)
9731 {
9732 VMSVGA3DBACKENDFUNCS3D *p = (VMSVGA3DBACKENDFUNCS3D *)pvInterfaceFuncs;
9733 p->pfnInit = vmsvga3dBackInit;
9734 p->pfnPowerOn = vmsvga3dBackPowerOn;
9735 p->pfnTerminate = vmsvga3dBackTerminate;
9736 p->pfnReset = vmsvga3dBackReset;
9737 p->pfnQueryCaps = vmsvga3dBackQueryCaps;
9738 p->pfnChangeMode = vmsvga3dBackChangeMode;
9739 p->pfnCreateTexture = vmsvga3dBackCreateTexture;
9740 p->pfnSurfaceDestroy = vmsvga3dBackSurfaceDestroy;
9741 p->pfnSurfaceInvalidateImage = vmsvga3dBackSurfaceInvalidateImage;
9742 p->pfnSurfaceCopy = vmsvga3dBackSurfaceCopy;
9743 p->pfnSurfaceDMACopyBox = vmsvga3dBackSurfaceDMACopyBox;
9744 p->pfnSurfaceStretchBlt = vmsvga3dBackSurfaceStretchBlt;
9745 p->pfnUpdateHostScreenViewport = vmsvga3dBackUpdateHostScreenViewport;
9746 p->pfnDefineScreen = vmsvga3dBackDefineScreen;
9747 p->pfnDestroyScreen = vmsvga3dBackDestroyScreen;
9748 p->pfnSurfaceBlitToScreen = vmsvga3dBackSurfaceBlitToScreen;
9749 p->pfnSurfaceUpdateHeapBuffers = vmsvga3dBackSurfaceUpdateHeapBuffers;
9750 }
9751 }
9752 else
9753 {
9754 AssertFailed();
9755 rc = VERR_INVALID_PARAMETER;
9756 }
9757 }
9758 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_VGPU9) == 0)
9759 {
9760 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSVGPU9))
9761 {
9762 if (pvInterfaceFuncs)
9763 {
9764 VMSVGA3DBACKENDFUNCSVGPU9 *p = (VMSVGA3DBACKENDFUNCSVGPU9 *)pvInterfaceFuncs;
9765 p->pfnContextDefine = vmsvga3dBackContextDefine;
9766 p->pfnContextDestroy = vmsvga3dBackContextDestroy;
9767 p->pfnSetTransform = vmsvga3dBackSetTransform;
9768 p->pfnSetZRange = vmsvga3dBackSetZRange;
9769 p->pfnSetRenderState = vmsvga3dBackSetRenderState;
9770 p->pfnSetRenderTarget = vmsvga3dBackSetRenderTarget;
9771 p->pfnSetTextureState = vmsvga3dBackSetTextureState;
9772 p->pfnSetMaterial = vmsvga3dBackSetMaterial;
9773 p->pfnSetLightData = vmsvga3dBackSetLightData;
9774 p->pfnSetLightEnabled = vmsvga3dBackSetLightEnabled;
9775 p->pfnSetViewPort = vmsvga3dBackSetViewPort;
9776 p->pfnSetClipPlane = vmsvga3dBackSetClipPlane;
9777 p->pfnCommandClear = vmsvga3dBackCommandClear;
9778 p->pfnDrawPrimitives = vmsvga3dBackDrawPrimitives;
9779 p->pfnSetScissorRect = vmsvga3dBackSetScissorRect;
9780 p->pfnGenerateMipmaps = vmsvga3dBackGenerateMipmaps;
9781 p->pfnShaderDefine = vmsvga3dBackShaderDefine;
9782 p->pfnShaderDestroy = vmsvga3dBackShaderDestroy;
9783 p->pfnShaderSet = vmsvga3dBackShaderSet;
9784 p->pfnShaderSetConst = vmsvga3dBackShaderSetConst;
9785 p->pfnOcclusionQueryCreate = vmsvga3dBackOcclusionQueryCreate;
9786 p->pfnOcclusionQueryDelete = vmsvga3dBackOcclusionQueryDelete;
9787 p->pfnOcclusionQueryBegin = vmsvga3dBackOcclusionQueryBegin;
9788 p->pfnOcclusionQueryEnd = vmsvga3dBackOcclusionQueryEnd;
9789 p->pfnOcclusionQueryGetData = vmsvga3dBackOcclusionQueryGetData;
9790 }
9791 }
9792 else
9793 {
9794 AssertFailed();
9795 rc = VERR_INVALID_PARAMETER;
9796 }
9797 }
9798 else
9799 rc = VERR_NOT_IMPLEMENTED;
9800 return rc;
9801}
9802
9803
9804extern VMSVGA3DBACKENDDESC const g_BackendDX =
9805{
9806 "DX",
9807 vmsvga3dBackQueryInterface
9808};
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