VirtualBox

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

Last change on this file since 106137 was 106137, checked in by vboxsync, 5 months ago

3D: A sysmem->sysmem transfers in vmsvga3dBackSurfaceCopy implemented using memcpy (no 3D backend involved). bugref:10580

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