VirtualBox

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

Last change on this file was 103574, checked in by vboxsync, 3 months ago

Devices/Graphics,WDDM: translate ClearDepthStencilView flags

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

© 2023 Oracle
ContactPrivacy policyTerms of Use