VirtualBox

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

Last change on this file since 106154 was 106154, checked in by vboxsync, 7 months ago

Devices/Graphics: logging

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