VirtualBox

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

Last change on this file since 100710 was 100157, checked in by vboxsync, 18 months ago

Devices/Graphics: merged SCREEN_TARGET resource type with TEXTURE_2D. bugref:9830

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

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