VirtualBox

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

Last change on this file since 103013 was 103005, checked in by vboxsync, 13 months ago

iprt/asm.h,*: Split out the ASMMem* and related stuff into a separate header, asm-mem.h, so that we can get the RT_ASM_PAGE_SIZE stuff out of the way.

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

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