VirtualBox

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

最後變更 在這個檔案從95739是 95739,由 vboxsync 提交於 3 年 前

Devices/Graphics: corrected asserts. bugref:9830

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette