1 /**************************************************************************
2 *
3 * Copyright 2012-2021 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 **************************************************************************/
27
28 /*
29 * DxgiFns.cpp --
30 * DXGI related functions.
31 */
32
33 #include <stdio.h>
34
35 #include "DxgiFns.h"
36 #include "Format.h"
37 #include "State.h"
38
39 #include "Debug.h"
40
41 #include "util/format/u_format.h"
42
43
44 /*
45 * ----------------------------------------------------------------------
46 *
47 * _Present --
48 *
49 * This is turned into kernel callbacks rather than directly emitted
50 * as fifo packets.
51 *
52 * ----------------------------------------------------------------------
53 */
54
55 HRESULT APIENTRY
_Present(DXGI_DDI_ARG_PRESENT * pPresentData)56 _Present(DXGI_DDI_ARG_PRESENT *pPresentData)
57 {
58
59 LOG_ENTRYPOINT();
60
61 struct Device *device = CastDevice(pPresentData->hDevice);
62 Resource *pSrcResource = CastResource(pPresentData->hSurfaceToPresent);
63
64 device->pipe->screen->flush_frontbuffer(device->pipe->screen, device->pipe,
65 pSrcResource->resource, 0, 0, pPresentData->pDXGIContext, 0, NULL);
66
67 return S_OK;
68 }
69
70
71 /*
72 * ----------------------------------------------------------------------
73 *
74 * _GetGammaCaps --
75 *
76 * Return gamma capabilities.
77 *
78 * ----------------------------------------------------------------------
79 */
80
81 HRESULT APIENTRY
_GetGammaCaps(DXGI_DDI_ARG_GET_GAMMA_CONTROL_CAPS * GetCaps)82 _GetGammaCaps( DXGI_DDI_ARG_GET_GAMMA_CONTROL_CAPS *GetCaps )
83 {
84 LOG_ENTRYPOINT();
85
86 DXGI_GAMMA_CONTROL_CAPABILITIES *pCaps;
87
88 pCaps = GetCaps->pGammaCapabilities;
89
90 pCaps->ScaleAndOffsetSupported = false;
91 pCaps->MinConvertedValue = 0.0;
92 pCaps->MaxConvertedValue = 1.0;
93 pCaps->NumGammaControlPoints = 17;
94
95 for (UINT i = 0; i < pCaps->NumGammaControlPoints; i++) {
96 pCaps->ControlPointPositions[i] = (float)i / (float)(pCaps->NumGammaControlPoints - 1);
97 }
98
99 return S_OK;
100 }
101
102
103 /*
104 * ----------------------------------------------------------------------
105 *
106 * _SetDisplayMode --
107 *
108 * Set the resource that is used to scan out to the display.
109 *
110 * ----------------------------------------------------------------------
111 */
112
113 HRESULT APIENTRY
_SetDisplayMode(DXGI_DDI_ARG_SETDISPLAYMODE * SetDisplayMode)114 _SetDisplayMode( DXGI_DDI_ARG_SETDISPLAYMODE *SetDisplayMode )
115 {
116 LOG_UNSUPPORTED_ENTRYPOINT();
117
118 return S_OK;
119 }
120
121
122 /*
123 * ----------------------------------------------------------------------
124 *
125 * _SetResourcePriority --
126 *
127 * ----------------------------------------------------------------------
128 */
129
130 HRESULT APIENTRY
_SetResourcePriority(DXGI_DDI_ARG_SETRESOURCEPRIORITY * SetResourcePriority)131 _SetResourcePriority( DXGI_DDI_ARG_SETRESOURCEPRIORITY *SetResourcePriority )
132 {
133 LOG_ENTRYPOINT();
134
135 /* ignore */
136
137 return S_OK;
138 }
139
140
141 /*
142 * ----------------------------------------------------------------------
143 *
144 * _QueryResourceResidency --
145 *
146 * ----------------------------------------------------------------------
147 */
148
149 HRESULT APIENTRY
_QueryResourceResidency(DXGI_DDI_ARG_QUERYRESOURCERESIDENCY * QueryResourceResidency)150 _QueryResourceResidency( DXGI_DDI_ARG_QUERYRESOURCERESIDENCY *QueryResourceResidency )
151 {
152 LOG_ENTRYPOINT();
153
154 for (UINT i = 0; i < QueryResourceResidency->Resources; ++i) {
155 QueryResourceResidency->pStatus[i] = DXGI_DDI_RESIDENCY_FULLY_RESIDENT;
156 }
157
158 return S_OK;
159 }
160
161
162 /*
163 * ----------------------------------------------------------------------
164 *
165 * _RotateResourceIdentities --
166 *
167 * Rotate a list of resources by recreating their views with
168 * the updated rotations.
169 *
170 * ----------------------------------------------------------------------
171 */
172
173 HRESULT APIENTRY
_RotateResourceIdentities(DXGI_DDI_ARG_ROTATE_RESOURCE_IDENTITIES * RotateResourceIdentities)174 _RotateResourceIdentities( DXGI_DDI_ARG_ROTATE_RESOURCE_IDENTITIES *RotateResourceIdentities )
175 {
176 LOG_ENTRYPOINT();
177
178 if (RotateResourceIdentities->Resources <= 1) {
179 return S_OK;
180 }
181
182 struct pipe_context *pipe = CastPipeDevice(RotateResourceIdentities->hDevice);
183 struct pipe_screen *screen = pipe->screen;
184
185 struct pipe_resource *resource0 = CastPipeResource(RotateResourceIdentities->pResources[0]);
186
187 assert(resource0);
188 LOG_UNSUPPORTED(resource0->last_level);
189
190 /*
191 * XXX: Copying is not very efficient, but it is much simpler than the
192 * alternative of recreating all views.
193 */
194
195 struct pipe_resource *temp_resource;
196 temp_resource = screen->resource_create(screen, resource0);
197 assert(temp_resource);
198 if (!temp_resource) {
199 return E_OUTOFMEMORY;
200 }
201
202 struct pipe_box src_box;
203 src_box.x = 0;
204 src_box.y = 0;
205 src_box.z = 0;
206 src_box.width = resource0->width0;
207 src_box.height = resource0->height0;
208 src_box.depth = resource0->depth0;
209
210 for (UINT i = 0; i < RotateResourceIdentities->Resources + 1; ++i) {
211 struct pipe_resource *src_resource;
212 struct pipe_resource *dst_resource;
213
214 if (i < RotateResourceIdentities->Resources) {
215 src_resource = CastPipeResource(RotateResourceIdentities->pResources[i]);
216 } else {
217 src_resource = temp_resource;
218 }
219
220 if (i > 0) {
221 dst_resource = CastPipeResource(RotateResourceIdentities->pResources[i - 1]);
222 } else {
223 dst_resource = temp_resource;
224 }
225
226 assert(dst_resource);
227 assert(src_resource);
228
229 pipe->resource_copy_region(pipe,
230 dst_resource,
231 0, // dst_level
232 0, 0, 0, // dst_x,y,z
233 src_resource,
234 0, // src_level
235 &src_box);
236 }
237
238 pipe_resource_reference(&temp_resource, NULL);
239
240 return S_OK;
241 }
242
243
244 /*
245 * ----------------------------------------------------------------------
246 *
247 * _Blt --
248 *
249 * Do a blt between two subresources. Apply MSAA resolve, format
250 * conversion and stretching.
251 *
252 * ----------------------------------------------------------------------
253 */
254
255 HRESULT APIENTRY
_Blt(DXGI_DDI_ARG_BLT * Blt)256 _Blt(DXGI_DDI_ARG_BLT *Blt)
257 {
258 LOG_UNSUPPORTED_ENTRYPOINT();
259
260 return S_OK;
261 }
262