VirtualBox

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

Last change on this file was 105704, checked in by vboxsync, 7 weeks ago

Devices/Graphics: Report RASTERIZER_STATE_V2 only if the host supports it too.

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