VirtualBox

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

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

Devices/Graphics: multisampling.

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