VirtualBox

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

Last change on this file since 102656 was 102626, checked in by vboxsync, 16 months ago

Devices/Graphics: create render target, depth stencil and unordered access views on demand.

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

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