VirtualBox

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

最後變更 在這個檔案從104853是 104813,由 vboxsync 提交於 10 月 前

Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp: removed obsolete code which used multiple D3D11 devices: cleanup. bugref:9830

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

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