VirtualBox

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

Last change on this file since 104932 was 104890, checked in by vboxsync, 10 months ago

Devices/Graphics: D3D_RELEASE cleanup. bugref:9830

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

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