VirtualBox

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

Last change on this file since 102520 was 102520, checked in by vboxsync, 14 months ago

Devices/Graphics: planar textures; video commands. bugref:10529

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

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