VirtualBox

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

Last change on this file was 106156, checked in by vboxsync, 6 weeks ago

Devices/Graphics: BindFlags cleanup

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

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