1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub
8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom
9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_ci#include "adapter9.h"
24bf215546Sopenharmony_ci#include "device9ex.h"
25bf215546Sopenharmony_ci#include "nine_helpers.h"
26bf215546Sopenharmony_ci#include "nine_defines.h"
27bf215546Sopenharmony_ci#include "nine_pipe.h"
28bf215546Sopenharmony_ci#include "nine_dump.h"
29bf215546Sopenharmony_ci#include "util/u_math.h"
30bf215546Sopenharmony_ci#include "util/format/u_format.h"
31bf215546Sopenharmony_ci#include "util/u_dump.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "pipe/p_screen.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci#define DBG_CHANNEL DBG_ADAPTER
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_cistatic bool
38bf215546Sopenharmony_cihas_sm3(struct pipe_screen *hal)
39bf215546Sopenharmony_ci{
40bf215546Sopenharmony_ci    return hal->get_param(hal, PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD) &&
41bf215546Sopenharmony_ci           hal->get_param(hal, PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES);
42bf215546Sopenharmony_ci}
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ciHRESULT
45bf215546Sopenharmony_ciNineAdapter9_ctor( struct NineAdapter9 *This,
46bf215546Sopenharmony_ci                   struct NineUnknownParams *pParams,
47bf215546Sopenharmony_ci                   struct d3dadapter9_context *pCTX )
48bf215546Sopenharmony_ci{
49bf215546Sopenharmony_ci    struct pipe_screen *hal = pCTX->hal;
50bf215546Sopenharmony_ci    HRESULT hr = NineUnknown_ctor(&This->base, pParams);
51bf215546Sopenharmony_ci    if (FAILED(hr)) { return hr; }
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ci    DBG("This=%p pParams=%p pCTX=%p\n", This, pParams, pCTX);
54bf215546Sopenharmony_ci    nine_dump_D3DADAPTER_IDENTIFIER9(DBG_CHANNEL, &pCTX->identifier);
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci    This->ctx = pCTX;
57bf215546Sopenharmony_ci    if (!hal->get_param(hal, PIPE_CAP_CLIP_HALFZ)) {
58bf215546Sopenharmony_ci        ERR("Driver doesn't support d3d9 coordinates\n");
59bf215546Sopenharmony_ci        return D3DERR_DRIVERINTERNALERROR;
60bf215546Sopenharmony_ci    }
61bf215546Sopenharmony_ci    if (This->ctx->ref &&
62bf215546Sopenharmony_ci        !This->ctx->ref->get_param(This->ctx->ref, PIPE_CAP_CLIP_HALFZ)) {
63bf215546Sopenharmony_ci        ERR("Warning: Sotware rendering driver doesn't support d3d9 coordinates\n");
64bf215546Sopenharmony_ci    }
65bf215546Sopenharmony_ci    /* Old cards had tricks to bypass some restrictions to implement
66bf215546Sopenharmony_ci     * everything and fit tight the requirements: number of constants,
67bf215546Sopenharmony_ci     * number of temp registers, special behaviours, etc. Since we don't
68bf215546Sopenharmony_ci     * have access to all this, we need a bit more than what dx9 required.
69bf215546Sopenharmony_ci     * For example we have to use more than 32 temp registers to emulate
70bf215546Sopenharmony_ci     * behaviours, while some dx9 hw don't have more. As for sm2 hardware,
71bf215546Sopenharmony_ci     * we could support vs2 / ps2 for them but it needs some more care, and
72bf215546Sopenharmony_ci     * as these are very old, we choose to drop support for them */
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci    /* checks minimum requirements, most are vs3/ps3 strict requirements */
75bf215546Sopenharmony_ci    if (!has_sm3(hal) ||
76bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
77bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE) < 256 * sizeof(float[4]) ||
78bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
79bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE) < 244 * sizeof(float[4]) ||
80bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
81bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_TEMPS) < 32 ||
82bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
83bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_TEMPS) < 32 ||
84bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
85bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_INPUTS) < 16 ||
86bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
87bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_INPUTS) < 10 ||
88bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
89bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS) < 16) {
90bf215546Sopenharmony_ci        ERR("Your card is not supported by Gallium Nine. Minimum requirement "
91bf215546Sopenharmony_ci            "is >= r500, >= nv50, >= i965\n");
92bf215546Sopenharmony_ci        return D3DERR_DRIVERINTERNALERROR;
93bf215546Sopenharmony_ci    }
94bf215546Sopenharmony_ci    /* for r500 */
95bf215546Sopenharmony_ci    if (hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
96bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE) < 276 * sizeof(float[4]) || /* we put bool and int constants with float constants */
97bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
98bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_TEMPS) < 40 || /* we use some more temp registers */
99bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
100bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_TEMPS) < 40 ||
101bf215546Sopenharmony_ci        hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
102bf215546Sopenharmony_ci                              PIPE_SHADER_CAP_MAX_INPUTS) < 20) /* we don't pack inputs as much as we could */
103bf215546Sopenharmony_ci        ERR("Your card is at the limit of Gallium Nine requirements. Some games "
104bf215546Sopenharmony_ci            "may run into issues because requirements are too tight\n");
105bf215546Sopenharmony_ci    return D3D_OK;
106bf215546Sopenharmony_ci}
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_civoid
109bf215546Sopenharmony_ciNineAdapter9_dtor( struct NineAdapter9 *This )
110bf215546Sopenharmony_ci{
111bf215546Sopenharmony_ci    struct d3dadapter9_context *ctx = This->ctx;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci    DBG("This=%p\n", This);
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci    NineUnknown_dtor(&This->base);
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci    /* special case, call backend-specific dtor AFTER destroying this object
118bf215546Sopenharmony_ci     * completely. */
119bf215546Sopenharmony_ci    if (ctx) {
120bf215546Sopenharmony_ci        if (ctx->destroy) { ctx->destroy(ctx); }
121bf215546Sopenharmony_ci    }
122bf215546Sopenharmony_ci}
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_cistatic HRESULT
125bf215546Sopenharmony_ciNineAdapter9_GetScreen( struct NineAdapter9 *This,
126bf215546Sopenharmony_ci                        D3DDEVTYPE DevType,
127bf215546Sopenharmony_ci                        struct pipe_screen **ppScreen )
128bf215546Sopenharmony_ci{
129bf215546Sopenharmony_ci    const char *force_sw = getenv("D3D_ALWAYS_SOFTWARE");
130bf215546Sopenharmony_ci    switch (DevType) {
131bf215546Sopenharmony_ci        case D3DDEVTYPE_HAL:
132bf215546Sopenharmony_ci            if (force_sw && !strcmp(force_sw, "1") && This->ctx->ref) {
133bf215546Sopenharmony_ci                *ppScreen = This->ctx->ref;
134bf215546Sopenharmony_ci                break;
135bf215546Sopenharmony_ci            }
136bf215546Sopenharmony_ci            *ppScreen = This->ctx->hal;
137bf215546Sopenharmony_ci            break;
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci        case D3DDEVTYPE_REF:
140bf215546Sopenharmony_ci        case D3DDEVTYPE_NULLREF:
141bf215546Sopenharmony_ci        case D3DDEVTYPE_SW:
142bf215546Sopenharmony_ci            if (force_sw && !strcmp(force_sw, "0")) {
143bf215546Sopenharmony_ci                *ppScreen = This->ctx->hal;
144bf215546Sopenharmony_ci                break;
145bf215546Sopenharmony_ci            }
146bf215546Sopenharmony_ci            *ppScreen = This->ctx->ref;
147bf215546Sopenharmony_ci            break;
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci        default:
150bf215546Sopenharmony_ci            user_assert(!"Invalid device type", D3DERR_INVALIDCALL);
151bf215546Sopenharmony_ci    }
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci    if (!*ppScreen) { return D3DERR_NOTAVAILABLE; }
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci    return D3D_OK;
156bf215546Sopenharmony_ci}
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ciHRESULT NINE_WINAPI
159bf215546Sopenharmony_ciNineAdapter9_GetAdapterIdentifier( struct NineAdapter9 *This,
160bf215546Sopenharmony_ci                                   DWORD Flags,
161bf215546Sopenharmony_ci                                   D3DADAPTER_IDENTIFIER9 *pIdentifier )
162bf215546Sopenharmony_ci{
163bf215546Sopenharmony_ci    DBG("This=%p Flags=%x pIdentifier=%p\n", This, Flags, pIdentifier);
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci    /* regarding flags, MSDN has this to say:
166bf215546Sopenharmony_ci     *  Flags sets the WHQLLevel member of D3DADAPTER_IDENTIFIER9. Flags can be
167bf215546Sopenharmony_ci     *  set to either 0 or D3DENUM_WHQL_LEVEL. If D3DENUM_WHQL_LEVEL is
168bf215546Sopenharmony_ci     *  specified, this call can connect to the Internet to download new
169bf215546Sopenharmony_ci     *  Microsoft Windows Hardware Quality Labs (WHQL) certificates.
170bf215546Sopenharmony_ci     * so let's just ignore it. */
171bf215546Sopenharmony_ci    *pIdentifier = This->ctx->identifier;
172bf215546Sopenharmony_ci    return D3D_OK;
173bf215546Sopenharmony_ci}
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_cistatic inline boolean
176bf215546Sopenharmony_cibackbuffer_format( D3DFORMAT dfmt,
177bf215546Sopenharmony_ci                   D3DFORMAT bfmt,
178bf215546Sopenharmony_ci                   boolean win )
179bf215546Sopenharmony_ci{
180bf215546Sopenharmony_ci    if (dfmt == D3DFMT_A2R10G10B10 && win) { return FALSE; }
181bf215546Sopenharmony_ci
182bf215546Sopenharmony_ci    if ((dfmt == D3DFMT_A2R10G10B10 && bfmt == dfmt) ||
183bf215546Sopenharmony_ci        (dfmt == D3DFMT_X8R8G8B8 && (bfmt == dfmt ||
184bf215546Sopenharmony_ci                                     bfmt == D3DFMT_A8R8G8B8)) ||
185bf215546Sopenharmony_ci        (dfmt == D3DFMT_X1R5G5B5 && (bfmt == dfmt ||
186bf215546Sopenharmony_ci                                     bfmt == D3DFMT_A1R5G5B5)) ||
187bf215546Sopenharmony_ci        (dfmt == D3DFMT_R5G6B5 && bfmt == dfmt)) {
188bf215546Sopenharmony_ci        return TRUE;
189bf215546Sopenharmony_ci    }
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci    return FALSE;
192bf215546Sopenharmony_ci}
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ciHRESULT NINE_WINAPI
195bf215546Sopenharmony_ciNineAdapter9_CheckDeviceType( struct NineAdapter9 *This,
196bf215546Sopenharmony_ci                              D3DDEVTYPE DevType,
197bf215546Sopenharmony_ci                              D3DFORMAT AdapterFormat,
198bf215546Sopenharmony_ci                              D3DFORMAT BackBufferFormat,
199bf215546Sopenharmony_ci                              BOOL bWindowed )
200bf215546Sopenharmony_ci{
201bf215546Sopenharmony_ci    struct pipe_screen *screen;
202bf215546Sopenharmony_ci    enum pipe_format dfmt, bfmt;
203bf215546Sopenharmony_ci    HRESULT hr;
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci    DBG("This=%p DevType=%s AdapterFormat=%s BackBufferFormat=%s "
206bf215546Sopenharmony_ci        "bWindowed=%i\n", This, nine_D3DDEVTYPE_to_str(DevType),
207bf215546Sopenharmony_ci        d3dformat_to_string(AdapterFormat),
208bf215546Sopenharmony_ci        d3dformat_to_string(BackBufferFormat), bWindowed);
209bf215546Sopenharmony_ci
210bf215546Sopenharmony_ci    user_assert(backbuffer_format(AdapterFormat, BackBufferFormat, bWindowed),
211bf215546Sopenharmony_ci                D3DERR_NOTAVAILABLE);
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci    hr = NineAdapter9_GetScreen(This, DevType, &screen);
214bf215546Sopenharmony_ci    if (FAILED(hr)) { return hr; }
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci    /* The display format is not handled in Nine. We always present an XRGB8888
217bf215546Sopenharmony_ci     * buffer (and the display server will eventually do the conversion). We probably
218bf215546Sopenharmony_ci     * don't need to check for anything for the adapter format support, since if the
219bf215546Sopenharmony_ci     * display server advertise support, it will likely be able to do the conversion.
220bf215546Sopenharmony_ci     * We do the approximation that a format is available in the display server if
221bf215546Sopenharmony_ci     * the format passes with NINE_BIND_BACKBUFFER_FLAGS */
222bf215546Sopenharmony_ci    dfmt = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D,
223bf215546Sopenharmony_ci                                       1,
224bf215546Sopenharmony_ci                                       NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
225bf215546Sopenharmony_ci    bfmt = d3d9_to_pipe_format_checked(screen, BackBufferFormat, PIPE_TEXTURE_2D,
226bf215546Sopenharmony_ci                                       1,
227bf215546Sopenharmony_ci                                       NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
228bf215546Sopenharmony_ci    if (dfmt == PIPE_FORMAT_NONE || bfmt == PIPE_FORMAT_NONE) {
229bf215546Sopenharmony_ci        DBG("Unsupported Adapter/BackBufferFormat.\n");
230bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
231bf215546Sopenharmony_ci    }
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ci    return D3D_OK;
234bf215546Sopenharmony_ci}
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_cistatic inline boolean
237bf215546Sopenharmony_cidisplay_format( D3DFORMAT fmt,
238bf215546Sopenharmony_ci                boolean win )
239bf215546Sopenharmony_ci{
240bf215546Sopenharmony_ci    /* http://msdn.microsoft.com/en-us/library/bb172558(v=VS.85).aspx#BackBuffer_or_Display_Formats */
241bf215546Sopenharmony_ci    static const D3DFORMAT allowed[] = {
242bf215546Sopenharmony_ci        D3DFMT_A2R10G10B10,
243bf215546Sopenharmony_ci        D3DFMT_X8R8G8B8,
244bf215546Sopenharmony_ci        D3DFMT_X1R5G5B5,
245bf215546Sopenharmony_ci        D3DFMT_R5G6B5,
246bf215546Sopenharmony_ci    };
247bf215546Sopenharmony_ci    unsigned i;
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_ci    if (fmt == D3DFMT_A2R10G10B10 && win) { return FALSE; }
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci    for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) {
252bf215546Sopenharmony_ci        if (fmt == allowed[i]) { return TRUE; }
253bf215546Sopenharmony_ci    }
254bf215546Sopenharmony_ci    return FALSE;
255bf215546Sopenharmony_ci}
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_cistatic inline boolean
258bf215546Sopenharmony_ciadapter_format( D3DFORMAT fmt )
259bf215546Sopenharmony_ci{
260bf215546Sopenharmony_ci    /* Formats that are compatible to display_format (modulo alpha bits) */
261bf215546Sopenharmony_ci    static const D3DFORMAT allowed[] = {
262bf215546Sopenharmony_ci        D3DFMT_A2R10G10B10,
263bf215546Sopenharmony_ci        D3DFMT_X8R8G8B8,
264bf215546Sopenharmony_ci        D3DFMT_A8R8G8B8,
265bf215546Sopenharmony_ci        D3DFMT_X1R5G5B5,
266bf215546Sopenharmony_ci        D3DFMT_A1R5G5B5,
267bf215546Sopenharmony_ci        D3DFMT_R5G6B5,
268bf215546Sopenharmony_ci    };
269bf215546Sopenharmony_ci    unsigned i;
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci    for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) {
272bf215546Sopenharmony_ci        if (fmt == allowed[i]) { return TRUE; }
273bf215546Sopenharmony_ci    }
274bf215546Sopenharmony_ci    return FALSE;
275bf215546Sopenharmony_ci}
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ciHRESULT NINE_WINAPI
278bf215546Sopenharmony_ciNineAdapter9_CheckDeviceFormat( struct NineAdapter9 *This,
279bf215546Sopenharmony_ci                                D3DDEVTYPE DeviceType,
280bf215546Sopenharmony_ci                                D3DFORMAT AdapterFormat,
281bf215546Sopenharmony_ci                                DWORD Usage,
282bf215546Sopenharmony_ci                                D3DRESOURCETYPE RType,
283bf215546Sopenharmony_ci                                D3DFORMAT CheckFormat )
284bf215546Sopenharmony_ci{
285bf215546Sopenharmony_ci    struct pipe_screen *screen;
286bf215546Sopenharmony_ci    HRESULT hr;
287bf215546Sopenharmony_ci    enum pipe_format pf;
288bf215546Sopenharmony_ci    enum pipe_texture_target target;
289bf215546Sopenharmony_ci    unsigned bind = 0;
290bf215546Sopenharmony_ci    boolean srgb;
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci    /* Check adapter format. */
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ci    DBG("This=%p DeviceType=%s AdapterFormat=%s\n", This,
295bf215546Sopenharmony_ci        nine_D3DDEVTYPE_to_str(DeviceType), d3dformat_to_string(AdapterFormat));
296bf215546Sopenharmony_ci    DBG("Usage=%x RType=%u CheckFormat=%s\n", Usage, RType,
297bf215546Sopenharmony_ci        d3dformat_to_string(CheckFormat));
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci    /* Wine tests, but suspicious. Needs more tests. */
300bf215546Sopenharmony_ci    user_assert(adapter_format(AdapterFormat), D3DERR_INVALIDCALL);
301bf215546Sopenharmony_ci    user_assert(display_format(AdapterFormat, FALSE), D3DERR_NOTAVAILABLE);
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_ci    hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
304bf215546Sopenharmony_ci    if (FAILED(hr))
305bf215546Sopenharmony_ci        return hr;
306bf215546Sopenharmony_ci    pf = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D, 0,
307bf215546Sopenharmony_ci                                     PIPE_BIND_DISPLAY_TARGET |
308bf215546Sopenharmony_ci                                     PIPE_BIND_SHARED, FALSE, FALSE);
309bf215546Sopenharmony_ci    if (pf == PIPE_FORMAT_NONE) {
310bf215546Sopenharmony_ci        DBG("AdapterFormat %s not available.\n",
311bf215546Sopenharmony_ci            d3dformat_to_string(AdapterFormat));
312bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
313bf215546Sopenharmony_ci    }
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci    /* Check actual format. */
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ci    switch (RType) {
318bf215546Sopenharmony_ci    case D3DRTYPE_SURFACE:       target = PIPE_TEXTURE_2D; break;
319bf215546Sopenharmony_ci    case D3DRTYPE_TEXTURE:       target = PIPE_TEXTURE_2D; break;
320bf215546Sopenharmony_ci    case D3DRTYPE_CUBETEXTURE:   target = PIPE_TEXTURE_CUBE; break;
321bf215546Sopenharmony_ci    case D3DRTYPE_VOLUME:        target = PIPE_TEXTURE_3D; break;
322bf215546Sopenharmony_ci    case D3DRTYPE_VOLUMETEXTURE: target = PIPE_TEXTURE_3D; break;
323bf215546Sopenharmony_ci    case D3DRTYPE_VERTEXBUFFER:  target = PIPE_BUFFER; break;
324bf215546Sopenharmony_ci    case D3DRTYPE_INDEXBUFFER:   target = PIPE_BUFFER; break;
325bf215546Sopenharmony_ci    default:
326bf215546Sopenharmony_ci        user_assert(0, D3DERR_INVALIDCALL);
327bf215546Sopenharmony_ci    }
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci    bind = 0;
330bf215546Sopenharmony_ci    if (Usage & D3DUSAGE_RENDERTARGET) {
331bf215546Sopenharmony_ci        if (depth_stencil_format(CheckFormat))
332bf215546Sopenharmony_ci            return D3DERR_NOTAVAILABLE;
333bf215546Sopenharmony_ci        bind |= PIPE_BIND_RENDER_TARGET;
334bf215546Sopenharmony_ci    }
335bf215546Sopenharmony_ci    if (Usage & D3DUSAGE_DEPTHSTENCIL) {
336bf215546Sopenharmony_ci        if (!depth_stencil_format(CheckFormat))
337bf215546Sopenharmony_ci            return D3DERR_NOTAVAILABLE;
338bf215546Sopenharmony_ci        bind |= d3d9_get_pipe_depth_format_bindings(CheckFormat);
339bf215546Sopenharmony_ci    }
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci    if ((Usage & D3DUSAGE_QUERY_VERTEXTEXTURE) &&
342bf215546Sopenharmony_ci        !screen->get_shader_param(screen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS))
343bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci    /* API hack because setting RT[0] to NULL is forbidden */
346bf215546Sopenharmony_ci    if (CheckFormat == D3DFMT_NULL && bind == PIPE_BIND_RENDER_TARGET &&
347bf215546Sopenharmony_ci        (RType == D3DRTYPE_SURFACE ||
348bf215546Sopenharmony_ci         RType == D3DRTYPE_TEXTURE))
349bf215546Sopenharmony_ci        return D3D_OK;
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci    /* RESZ hack */
352bf215546Sopenharmony_ci    if (CheckFormat == D3DFMT_RESZ && bind == PIPE_BIND_RENDER_TARGET &&
353bf215546Sopenharmony_ci        RType == D3DRTYPE_SURFACE)
354bf215546Sopenharmony_ci        return screen->get_param(screen, PIPE_CAP_MULTISAMPLE_Z_RESOLVE) ?
355bf215546Sopenharmony_ci               D3D_OK : D3DERR_NOTAVAILABLE;
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ci    /* ATOC hack */
358bf215546Sopenharmony_ci    if (CheckFormat == D3DFMT_ATOC && RType == D3DRTYPE_SURFACE)
359bf215546Sopenharmony_ci        return D3D_OK;
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci    if ((Usage & D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) &&
362bf215546Sopenharmony_ci        (Usage & D3DUSAGE_RENDERTARGET))
363bf215546Sopenharmony_ci        bind |= PIPE_BIND_BLENDABLE;
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ci    if (Usage & D3DUSAGE_DMAP) {
366bf215546Sopenharmony_ci        DBG("D3DUSAGE_DMAP not available\n");
367bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE; /* TODO: displacement mapping */
368bf215546Sopenharmony_ci    }
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci    switch (RType) {
371bf215546Sopenharmony_ci    case D3DRTYPE_TEXTURE:       bind |= PIPE_BIND_SAMPLER_VIEW; break;
372bf215546Sopenharmony_ci    case D3DRTYPE_CUBETEXTURE:   bind |= PIPE_BIND_SAMPLER_VIEW; break;
373bf215546Sopenharmony_ci    case D3DRTYPE_VOLUMETEXTURE: bind |= PIPE_BIND_SAMPLER_VIEW; break;
374bf215546Sopenharmony_ci    case D3DRTYPE_VERTEXBUFFER:  bind |= PIPE_BIND_VERTEX_BUFFER; break;
375bf215546Sopenharmony_ci    case D3DRTYPE_INDEXBUFFER:   bind |= PIPE_BIND_INDEX_BUFFER; break;
376bf215546Sopenharmony_ci    case D3DRTYPE_SURFACE:
377bf215546Sopenharmony_ci        if (!(Usage & D3DUSAGE_DEPTHSTENCIL))
378bf215546Sopenharmony_ci            bind |= PIPE_BIND_SAMPLER_VIEW; /* StretchRect */
379bf215546Sopenharmony_ci        /* Offscreen surface support: Usage = 0.
380bf215546Sopenharmony_ci         * In practice drivers are very restrictive on the formats supported.
381bf215546Sopenharmony_ci         * Basically a few common formats + YUV and compressed formats. The
382bf215546Sopenharmony_ci         * reason is that offscreen surface are useful only for directdraw
383bf215546Sopenharmony_ci         * compatibility (a WONTIMPL of nine) + format conversion (useful in
384bf215546Sopenharmony_ci         * particular for YUV because the format was not advertised for textures
385bf215546Sopenharmony_ci         * on NV chips). */
386bf215546Sopenharmony_ci        if (Usage == 0)
387bf215546Sopenharmony_ci            bind |= PIPE_BIND_RENDER_TARGET; /* A current requirement of our impl, which we should get rid of. */
388bf215546Sopenharmony_ci        break;
389bf215546Sopenharmony_ci    default:
390bf215546Sopenharmony_ci        break;
391bf215546Sopenharmony_ci    }
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ci    srgb = (Usage & (D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE)) != 0;
395bf215546Sopenharmony_ci    pf = d3d9_to_pipe_format_checked(screen, CheckFormat, target,
396bf215546Sopenharmony_ci                                     0, bind, srgb, FALSE);
397bf215546Sopenharmony_ci    if (pf == PIPE_FORMAT_NONE) {
398bf215546Sopenharmony_ci        DBG("NOT AVAILABLE\n");
399bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
400bf215546Sopenharmony_ci    }
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci    /* we support ATI1 and ATI2 hack only for 2D and Cube textures */
403bf215546Sopenharmony_ci    if (RType != D3DRTYPE_TEXTURE && RType != D3DRTYPE_CUBETEXTURE &&
404bf215546Sopenharmony_ci        (CheckFormat == D3DFMT_ATI1 || CheckFormat == D3DFMT_ATI2))
405bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
406bf215546Sopenharmony_ci    /* if (Usage & D3DUSAGE_NONSECURE) { don't know the implications of this } */
407bf215546Sopenharmony_ci    /* if (Usage & D3DUSAGE_SOFTWAREPROCESSING) { we can always support this } */
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_ci    if ((Usage & D3DUSAGE_AUTOGENMIPMAP) && !(bind & PIPE_BIND_SAMPLER_VIEW))
410bf215546Sopenharmony_ci        return D3DOK_NOAUTOGEN;
411bf215546Sopenharmony_ci    return D3D_OK;
412bf215546Sopenharmony_ci}
413bf215546Sopenharmony_ci
414bf215546Sopenharmony_ciHRESULT NINE_WINAPI
415bf215546Sopenharmony_ciNineAdapter9_CheckDeviceMultiSampleType( struct NineAdapter9 *This,
416bf215546Sopenharmony_ci                                         D3DDEVTYPE DeviceType,
417bf215546Sopenharmony_ci                                         D3DFORMAT SurfaceFormat,
418bf215546Sopenharmony_ci                                         BOOL Windowed,
419bf215546Sopenharmony_ci                                         D3DMULTISAMPLE_TYPE MultiSampleType,
420bf215546Sopenharmony_ci                                         DWORD *pQualityLevels )
421bf215546Sopenharmony_ci{
422bf215546Sopenharmony_ci    struct pipe_screen *screen;
423bf215546Sopenharmony_ci    HRESULT hr;
424bf215546Sopenharmony_ci    enum pipe_format pf;
425bf215546Sopenharmony_ci    unsigned bind;
426bf215546Sopenharmony_ci
427bf215546Sopenharmony_ci    DBG("This=%p DeviceType=%s SurfaceFormat=%s Windowed=%i MultiSampleType=%u "
428bf215546Sopenharmony_ci        "pQualityLevels=%p\n", This, nine_D3DDEVTYPE_to_str(DeviceType),
429bf215546Sopenharmony_ci        d3dformat_to_string(SurfaceFormat), Windowed, MultiSampleType,
430bf215546Sopenharmony_ci        pQualityLevels);
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci    if (pQualityLevels) {
433bf215546Sopenharmony_ci        /* In error cases return only 1 quality level supported */
434bf215546Sopenharmony_ci        *pQualityLevels = 1;
435bf215546Sopenharmony_ci    }
436bf215546Sopenharmony_ci    user_assert(MultiSampleType <= D3DMULTISAMPLE_16_SAMPLES, D3DERR_INVALIDCALL);
437bf215546Sopenharmony_ci
438bf215546Sopenharmony_ci    hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
439bf215546Sopenharmony_ci    if (FAILED(hr))
440bf215546Sopenharmony_ci        return hr;
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci    if (depth_stencil_format(SurfaceFormat))
443bf215546Sopenharmony_ci        bind = d3d9_get_pipe_depth_format_bindings(SurfaceFormat);
444bf215546Sopenharmony_ci    else /* render-target */
445bf215546Sopenharmony_ci        bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci    pf = d3d9_to_pipe_format_checked(screen, SurfaceFormat, PIPE_TEXTURE_2D,
448bf215546Sopenharmony_ci                                     0, PIPE_BIND_SAMPLER_VIEW, FALSE, FALSE);
449bf215546Sopenharmony_ci
450bf215546Sopenharmony_ci    if (pf == PIPE_FORMAT_NONE && SurfaceFormat != D3DFMT_NULL) {
451bf215546Sopenharmony_ci        DBG("%s not available.\n", d3dformat_to_string(SurfaceFormat));
452bf215546Sopenharmony_ci        return D3DERR_INVALIDCALL;
453bf215546Sopenharmony_ci    }
454bf215546Sopenharmony_ci
455bf215546Sopenharmony_ci    pf = d3d9_to_pipe_format_checked(screen, SurfaceFormat, PIPE_TEXTURE_2D,
456bf215546Sopenharmony_ci                                     MultiSampleType, bind, FALSE, FALSE);
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_ci    if (pf == PIPE_FORMAT_NONE && SurfaceFormat != D3DFMT_NULL) {
459bf215546Sopenharmony_ci        DBG("%s with %u samples not available.\n",
460bf215546Sopenharmony_ci            d3dformat_to_string(SurfaceFormat), MultiSampleType);
461bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
462bf215546Sopenharmony_ci    }
463bf215546Sopenharmony_ci
464bf215546Sopenharmony_ci    if (pQualityLevels) {
465bf215546Sopenharmony_ci        /* NONMASKABLE MultiSampleType might have more than one quality level,
466bf215546Sopenharmony_ci         * while MASKABLE MultiSampleTypes have only one level.
467bf215546Sopenharmony_ci         * Advertise quality levels and map each level to a sample count. */
468bf215546Sopenharmony_ci         (void ) d3dmultisample_type_check(screen, SurfaceFormat,
469bf215546Sopenharmony_ci                 &MultiSampleType, D3DMULTISAMPLE_16_SAMPLES, pQualityLevels);
470bf215546Sopenharmony_ci         DBG("advertising %u quality levels\n", *pQualityLevels);
471bf215546Sopenharmony_ci    }
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci    return D3D_OK;
474bf215546Sopenharmony_ci}
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ciHRESULT NINE_WINAPI
477bf215546Sopenharmony_ciNineAdapter9_CheckDepthStencilMatch( struct NineAdapter9 *This,
478bf215546Sopenharmony_ci                                     D3DDEVTYPE DeviceType,
479bf215546Sopenharmony_ci                                     D3DFORMAT AdapterFormat,
480bf215546Sopenharmony_ci                                     D3DFORMAT RenderTargetFormat,
481bf215546Sopenharmony_ci                                     D3DFORMAT DepthStencilFormat )
482bf215546Sopenharmony_ci{
483bf215546Sopenharmony_ci    struct pipe_screen *screen;
484bf215546Sopenharmony_ci    enum pipe_format dfmt, bfmt, zsfmt;
485bf215546Sopenharmony_ci    HRESULT hr;
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_ci    DBG("This=%p DeviceType=%s AdapterFormat=%s "
488bf215546Sopenharmony_ci        "RenderTargetFormat=%s DepthStencilFormat=%s\n", This,
489bf215546Sopenharmony_ci        nine_D3DDEVTYPE_to_str(DeviceType), d3dformat_to_string(AdapterFormat),
490bf215546Sopenharmony_ci        d3dformat_to_string(RenderTargetFormat),
491bf215546Sopenharmony_ci        d3dformat_to_string(DepthStencilFormat));
492bf215546Sopenharmony_ci
493bf215546Sopenharmony_ci    /* TODO: does it check AdapterFormat at all ?
494bf215546Sopenharmony_ci     * It seems to need to pass at least for A8R8G8B8:
495bf215546Sopenharmony_ci     * https://github.com/iXit/Mesa-3D/issues/317 */
496bf215546Sopenharmony_ci    user_assert(adapter_format(AdapterFormat), D3DERR_NOTAVAILABLE);
497bf215546Sopenharmony_ci    user_assert(depth_stencil_format(DepthStencilFormat), D3DERR_NOTAVAILABLE);
498bf215546Sopenharmony_ci
499bf215546Sopenharmony_ci    hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
500bf215546Sopenharmony_ci    if (FAILED(hr)) { return hr; }
501bf215546Sopenharmony_ci
502bf215546Sopenharmony_ci    dfmt = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D, 0,
503bf215546Sopenharmony_ci                                       NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
504bf215546Sopenharmony_ci    bfmt = d3d9_to_pipe_format_checked(screen, RenderTargetFormat,
505bf215546Sopenharmony_ci                                       PIPE_TEXTURE_2D, 0,
506bf215546Sopenharmony_ci                                       NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
507bf215546Sopenharmony_ci    if (RenderTargetFormat == D3DFMT_NULL)
508bf215546Sopenharmony_ci        bfmt = dfmt;
509bf215546Sopenharmony_ci    zsfmt = d3d9_to_pipe_format_checked(screen, DepthStencilFormat,
510bf215546Sopenharmony_ci                                        PIPE_TEXTURE_2D, 0,
511bf215546Sopenharmony_ci                                        d3d9_get_pipe_depth_format_bindings(DepthStencilFormat),
512bf215546Sopenharmony_ci                                        FALSE, FALSE);
513bf215546Sopenharmony_ci    if (dfmt == PIPE_FORMAT_NONE ||
514bf215546Sopenharmony_ci        bfmt == PIPE_FORMAT_NONE ||
515bf215546Sopenharmony_ci        zsfmt == PIPE_FORMAT_NONE) {
516bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
517bf215546Sopenharmony_ci    }
518bf215546Sopenharmony_ci
519bf215546Sopenharmony_ci    return D3D_OK;
520bf215546Sopenharmony_ci}
521bf215546Sopenharmony_ci
522bf215546Sopenharmony_ciHRESULT NINE_WINAPI
523bf215546Sopenharmony_ciNineAdapter9_CheckDeviceFormatConversion( struct NineAdapter9 *This,
524bf215546Sopenharmony_ci                                          D3DDEVTYPE DeviceType,
525bf215546Sopenharmony_ci                                          D3DFORMAT SourceFormat,
526bf215546Sopenharmony_ci                                          D3DFORMAT TargetFormat )
527bf215546Sopenharmony_ci{
528bf215546Sopenharmony_ci    /* MSDN says this tests whether a certain backbuffer format can be used in
529bf215546Sopenharmony_ci     * conjunction with a certain front buffer format. It's a little confusing
530bf215546Sopenharmony_ci     * but some one wiser might be able to figure this one out. XXX */
531bf215546Sopenharmony_ci    struct pipe_screen *screen;
532bf215546Sopenharmony_ci    enum pipe_format dfmt, bfmt;
533bf215546Sopenharmony_ci    HRESULT hr;
534bf215546Sopenharmony_ci
535bf215546Sopenharmony_ci    DBG("This=%p DeviceType=%s SourceFormat=%s TargetFormat=%s\n", This,
536bf215546Sopenharmony_ci        nine_D3DDEVTYPE_to_str(DeviceType),
537bf215546Sopenharmony_ci        d3dformat_to_string(SourceFormat), d3dformat_to_string(TargetFormat));
538bf215546Sopenharmony_ci
539bf215546Sopenharmony_ci    user_assert(backbuffer_format(TargetFormat, SourceFormat, FALSE),
540bf215546Sopenharmony_ci                D3DERR_NOTAVAILABLE);
541bf215546Sopenharmony_ci
542bf215546Sopenharmony_ci    hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
543bf215546Sopenharmony_ci    if (FAILED(hr)) { return hr; }
544bf215546Sopenharmony_ci
545bf215546Sopenharmony_ci    dfmt = d3d9_to_pipe_format_checked(screen, TargetFormat, PIPE_TEXTURE_2D, 1,
546bf215546Sopenharmony_ci                                       NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
547bf215546Sopenharmony_ci    bfmt = d3d9_to_pipe_format_checked(screen, SourceFormat, PIPE_TEXTURE_2D, 1,
548bf215546Sopenharmony_ci                                       NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
549bf215546Sopenharmony_ci
550bf215546Sopenharmony_ci    if (dfmt == PIPE_FORMAT_NONE || bfmt == PIPE_FORMAT_NONE) {
551bf215546Sopenharmony_ci        DBG("%s to %s not supported.\n",
552bf215546Sopenharmony_ci            d3dformat_to_string(SourceFormat),
553bf215546Sopenharmony_ci            d3dformat_to_string(TargetFormat));
554bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
555bf215546Sopenharmony_ci    }
556bf215546Sopenharmony_ci
557bf215546Sopenharmony_ci    return D3D_OK;
558bf215546Sopenharmony_ci}
559bf215546Sopenharmony_ci
560bf215546Sopenharmony_ciHRESULT NINE_WINAPI
561bf215546Sopenharmony_ciNineAdapter9_GetDeviceCaps( struct NineAdapter9 *This,
562bf215546Sopenharmony_ci                            D3DDEVTYPE DeviceType,
563bf215546Sopenharmony_ci                            D3DCAPS9 *pCaps )
564bf215546Sopenharmony_ci{
565bf215546Sopenharmony_ci    struct pipe_screen *screen;
566bf215546Sopenharmony_ci    HRESULT hr;
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_ci    DBG("This=%p DeviceType=%s pCaps=%p\n", This,
569bf215546Sopenharmony_ci        nine_D3DDEVTYPE_to_str(DeviceType), pCaps);
570bf215546Sopenharmony_ci
571bf215546Sopenharmony_ci    user_assert(pCaps, D3DERR_INVALIDCALL);
572bf215546Sopenharmony_ci
573bf215546Sopenharmony_ci    hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
574bf215546Sopenharmony_ci    if (FAILED(hr)) {
575bf215546Sopenharmony_ci       DBG("Failed to get pipe_screen.\n");
576bf215546Sopenharmony_ci       return hr;
577bf215546Sopenharmony_ci    }
578bf215546Sopenharmony_ci
579bf215546Sopenharmony_ci#define D3DPIPECAP(pcap, d3dcap) \
580bf215546Sopenharmony_ci    (screen->get_param(screen, PIPE_CAP_##pcap) ? (d3dcap) : 0)
581bf215546Sopenharmony_ci
582bf215546Sopenharmony_ci#define D3DNPIPECAP(pcap, d3dcap) \
583bf215546Sopenharmony_ci    (screen->get_param(screen, PIPE_CAP_##pcap) ? 0 : (d3dcap))
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_ci    pCaps->DeviceType = DeviceType;
586bf215546Sopenharmony_ci
587bf215546Sopenharmony_ci    pCaps->AdapterOrdinal = 0;
588bf215546Sopenharmony_ci
589bf215546Sopenharmony_ci    pCaps->Caps = D3DCAPS_READ_SCANLINE;
590bf215546Sopenharmony_ci
591bf215546Sopenharmony_ci    pCaps->Caps2 = /* D3DCAPS2_CANMANAGERESOURCE | */
592bf215546Sopenharmony_ci                /* D3DCAPS2_CANSHARERESOURCE | */
593bf215546Sopenharmony_ci                /* D3DCAPS2_CANCALIBRATEGAMMA | */
594bf215546Sopenharmony_ci                   D3DCAPS2_DYNAMICTEXTURES |
595bf215546Sopenharmony_ci                   D3DCAPS2_FULLSCREENGAMMA |
596bf215546Sopenharmony_ci                   D3DCAPS2_CANAUTOGENMIPMAP;
597bf215546Sopenharmony_ci
598bf215546Sopenharmony_ci    /* Note: D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD just means the
599bf215546Sopenharmony_ci     * backbuffer can be ARGB (instead of only XRGB) when we are fullscreen
600bf215546Sopenharmony_ci     * and in discard mode. */
601bf215546Sopenharmony_ci    pCaps->Caps3 = D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
602bf215546Sopenharmony_ci                   D3DCAPS3_COPY_TO_VIDMEM |
603bf215546Sopenharmony_ci                   D3DCAPS3_COPY_TO_SYSTEMMEM |
604bf215546Sopenharmony_ci                   D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION;
605bf215546Sopenharmony_ci
606bf215546Sopenharmony_ci    pCaps->PresentationIntervals = D3DPRESENT_INTERVAL_DEFAULT |
607bf215546Sopenharmony_ci                                   D3DPRESENT_INTERVAL_ONE |
608bf215546Sopenharmony_ci                                   D3DPRESENT_INTERVAL_TWO |
609bf215546Sopenharmony_ci                                   D3DPRESENT_INTERVAL_THREE |
610bf215546Sopenharmony_ci                                   D3DPRESENT_INTERVAL_FOUR |
611bf215546Sopenharmony_ci                                   D3DPRESENT_INTERVAL_IMMEDIATE;
612bf215546Sopenharmony_ci    pCaps->CursorCaps = D3DCURSORCAPS_COLOR /* | D3DCURSORCAPS_LOWRES*/;
613bf215546Sopenharmony_ci
614bf215546Sopenharmony_ci    pCaps->DevCaps = D3DDEVCAPS_CANBLTSYSTONONLOCAL |
615bf215546Sopenharmony_ci                     D3DDEVCAPS_CANRENDERAFTERFLIP |
616bf215546Sopenharmony_ci                     D3DDEVCAPS_DRAWPRIMITIVES2 |
617bf215546Sopenharmony_ci                     D3DDEVCAPS_DRAWPRIMITIVES2EX |
618bf215546Sopenharmony_ci                     D3DDEVCAPS_DRAWPRIMTLVERTEX |
619bf215546Sopenharmony_ci                     D3DDEVCAPS_EXECUTESYSTEMMEMORY |
620bf215546Sopenharmony_ci                     D3DDEVCAPS_EXECUTEVIDEOMEMORY |
621bf215546Sopenharmony_ci                     D3DDEVCAPS_HWRASTERIZATION |
622bf215546Sopenharmony_ci                     D3DDEVCAPS_HWTRANSFORMANDLIGHT |
623bf215546Sopenharmony_ci                     /*D3DDEVCAPS_NPATCHES |*/
624bf215546Sopenharmony_ci                     D3DDEVCAPS_PUREDEVICE |
625bf215546Sopenharmony_ci                     /*D3DDEVCAPS_QUINTICRTPATCHES |*/
626bf215546Sopenharmony_ci                     /*D3DDEVCAPS_RTPATCHES |*/
627bf215546Sopenharmony_ci                     /*D3DDEVCAPS_RTPATCHHANDLEZERO |*/
628bf215546Sopenharmony_ci                     /*D3DDEVCAPS_SEPARATETEXTUREMEMORIES |*/
629bf215546Sopenharmony_ci                     D3DDEVCAPS_TEXTURENONLOCALVIDMEM |
630bf215546Sopenharmony_ci                     /* D3DDEVCAPS_TEXTURESYSTEMMEMORY |*/
631bf215546Sopenharmony_ci                     D3DDEVCAPS_TEXTUREVIDEOMEMORY |
632bf215546Sopenharmony_ci                     D3DDEVCAPS_TLVERTEXSYSTEMMEMORY |
633bf215546Sopenharmony_ci                     D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
634bf215546Sopenharmony_ci
635bf215546Sopenharmony_ci    pCaps->PrimitiveMiscCaps = D3DPMISCCAPS_MASKZ |
636bf215546Sopenharmony_ci                               D3DPMISCCAPS_CULLNONE | /* XXX */
637bf215546Sopenharmony_ci                               D3DPMISCCAPS_CULLCW |
638bf215546Sopenharmony_ci                               D3DPMISCCAPS_CULLCCW |
639bf215546Sopenharmony_ci                               D3DPMISCCAPS_COLORWRITEENABLE |
640bf215546Sopenharmony_ci                               D3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
641bf215546Sopenharmony_ci                               /*D3DPMISCCAPS_CLIPTLVERTS |*/
642bf215546Sopenharmony_ci                               D3DPMISCCAPS_TSSARGTEMP |
643bf215546Sopenharmony_ci                               D3DPMISCCAPS_BLENDOP |
644bf215546Sopenharmony_ci                               D3DPIPECAP(INDEP_BLEND_ENABLE, D3DPMISCCAPS_INDEPENDENTWRITEMASKS) |
645bf215546Sopenharmony_ci                               D3DPMISCCAPS_PERSTAGECONSTANT |
646bf215546Sopenharmony_ci                               /*D3DPMISCCAPS_POSTBLENDSRGBCONVERT |*/ /* TODO: advertise if Ex and dx10 able card */
647bf215546Sopenharmony_ci                               D3DPMISCCAPS_FOGANDSPECULARALPHA | /* Note: documentation of the flag is wrong */
648bf215546Sopenharmony_ci                               D3DPIPECAP(BLEND_EQUATION_SEPARATE, D3DPMISCCAPS_SEPARATEALPHABLEND) |
649bf215546Sopenharmony_ci                               D3DPIPECAP(MIXED_COLORBUFFER_FORMATS, D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS) |
650bf215546Sopenharmony_ci                               D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING |
651bf215546Sopenharmony_ci                               D3DPMISCCAPS_FOGVERTEXCLAMPED;
652bf215546Sopenharmony_ci    if (!screen->get_param(screen, PIPE_CAP_VS_WINDOW_SPACE_POSITION))
653bf215546Sopenharmony_ci        pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_CLIPTLVERTS;
654bf215546Sopenharmony_ci
655bf215546Sopenharmony_ci    pCaps->RasterCaps =
656bf215546Sopenharmony_ci        D3DPIPECAP(ANISOTROPIC_FILTER, D3DPRASTERCAPS_ANISOTROPY) |
657bf215546Sopenharmony_ci        D3DPRASTERCAPS_COLORPERSPECTIVE |
658bf215546Sopenharmony_ci        D3DPRASTERCAPS_DITHER |
659bf215546Sopenharmony_ci        D3DPRASTERCAPS_DEPTHBIAS |
660bf215546Sopenharmony_ci        D3DPRASTERCAPS_FOGRANGE |
661bf215546Sopenharmony_ci        D3DPRASTERCAPS_FOGTABLE |
662bf215546Sopenharmony_ci        D3DPRASTERCAPS_FOGVERTEX |
663bf215546Sopenharmony_ci        D3DPRASTERCAPS_MIPMAPLODBIAS |
664bf215546Sopenharmony_ci        D3DPRASTERCAPS_MULTISAMPLE_TOGGLE |
665bf215546Sopenharmony_ci        D3DPRASTERCAPS_SCISSORTEST |
666bf215546Sopenharmony_ci        D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
667bf215546Sopenharmony_ci        /*D3DPRASTERCAPS_WBUFFER |*/
668bf215546Sopenharmony_ci        D3DPRASTERCAPS_WFOG |
669bf215546Sopenharmony_ci        /*D3DPRASTERCAPS_ZBUFFERLESSHSR |*/
670bf215546Sopenharmony_ci        D3DPRASTERCAPS_ZFOG |
671bf215546Sopenharmony_ci        D3DPRASTERCAPS_ZTEST;
672bf215546Sopenharmony_ci
673bf215546Sopenharmony_ci    pCaps->ZCmpCaps = D3DPCMPCAPS_NEVER |
674bf215546Sopenharmony_ci                      D3DPCMPCAPS_LESS |
675bf215546Sopenharmony_ci                      D3DPCMPCAPS_EQUAL |
676bf215546Sopenharmony_ci                      D3DPCMPCAPS_LESSEQUAL |
677bf215546Sopenharmony_ci                      D3DPCMPCAPS_GREATER |
678bf215546Sopenharmony_ci                      D3DPCMPCAPS_NOTEQUAL |
679bf215546Sopenharmony_ci                      D3DPCMPCAPS_GREATEREQUAL |
680bf215546Sopenharmony_ci                      D3DPCMPCAPS_ALWAYS;
681bf215546Sopenharmony_ci
682bf215546Sopenharmony_ci    pCaps->SrcBlendCaps = D3DPBLENDCAPS_ZERO |
683bf215546Sopenharmony_ci                          D3DPBLENDCAPS_ONE |
684bf215546Sopenharmony_ci                          D3DPBLENDCAPS_SRCCOLOR |
685bf215546Sopenharmony_ci                          D3DPBLENDCAPS_INVSRCCOLOR |
686bf215546Sopenharmony_ci                          D3DPBLENDCAPS_SRCALPHA |
687bf215546Sopenharmony_ci                          D3DPBLENDCAPS_INVSRCALPHA |
688bf215546Sopenharmony_ci                          D3DPBLENDCAPS_DESTALPHA |
689bf215546Sopenharmony_ci                          D3DPBLENDCAPS_INVDESTALPHA |
690bf215546Sopenharmony_ci                          D3DPBLENDCAPS_DESTCOLOR |
691bf215546Sopenharmony_ci                          D3DPBLENDCAPS_INVDESTCOLOR |
692bf215546Sopenharmony_ci                          D3DPBLENDCAPS_SRCALPHASAT |
693bf215546Sopenharmony_ci                          D3DPBLENDCAPS_BOTHSRCALPHA |
694bf215546Sopenharmony_ci                          D3DPBLENDCAPS_BOTHINVSRCALPHA |
695bf215546Sopenharmony_ci                          D3DPBLENDCAPS_BLENDFACTOR |
696bf215546Sopenharmony_ci                          D3DPIPECAP(MAX_DUAL_SOURCE_RENDER_TARGETS,
697bf215546Sopenharmony_ci                              D3DPBLENDCAPS_INVSRCCOLOR2 |
698bf215546Sopenharmony_ci                              D3DPBLENDCAPS_SRCCOLOR2);
699bf215546Sopenharmony_ci
700bf215546Sopenharmony_ci    pCaps->DestBlendCaps = pCaps->SrcBlendCaps;
701bf215546Sopenharmony_ci
702bf215546Sopenharmony_ci    pCaps->AlphaCmpCaps = D3DPCMPCAPS_NEVER |
703bf215546Sopenharmony_ci                          D3DPCMPCAPS_LESS |
704bf215546Sopenharmony_ci                          D3DPCMPCAPS_EQUAL |
705bf215546Sopenharmony_ci                          D3DPCMPCAPS_LESSEQUAL |
706bf215546Sopenharmony_ci                          D3DPCMPCAPS_GREATER |
707bf215546Sopenharmony_ci                          D3DPCMPCAPS_NOTEQUAL |
708bf215546Sopenharmony_ci                          D3DPCMPCAPS_GREATEREQUAL |
709bf215546Sopenharmony_ci                          D3DPCMPCAPS_ALWAYS;
710bf215546Sopenharmony_ci
711bf215546Sopenharmony_ci    /* FLAT caps not legal for D3D9. */
712bf215546Sopenharmony_ci    pCaps->ShadeCaps = D3DPSHADECAPS_COLORGOURAUDRGB |
713bf215546Sopenharmony_ci                       D3DPSHADECAPS_SPECULARGOURAUDRGB |
714bf215546Sopenharmony_ci                       D3DPSHADECAPS_ALPHAGOURAUDBLEND |
715bf215546Sopenharmony_ci                       D3DPSHADECAPS_FOGGOURAUD;
716bf215546Sopenharmony_ci
717bf215546Sopenharmony_ci    pCaps->TextureCaps =
718bf215546Sopenharmony_ci        D3DPTEXTURECAPS_ALPHA |
719bf215546Sopenharmony_ci        D3DPTEXTURECAPS_ALPHAPALETTE |
720bf215546Sopenharmony_ci        D3DPTEXTURECAPS_PERSPECTIVE |
721bf215546Sopenharmony_ci        D3DPTEXTURECAPS_PROJECTED |
722bf215546Sopenharmony_ci        D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE |
723bf215546Sopenharmony_ci        D3DPTEXTURECAPS_CUBEMAP |
724bf215546Sopenharmony_ci        D3DPTEXTURECAPS_VOLUMEMAP |
725bf215546Sopenharmony_ci        D3DNPIPECAP(NPOT_TEXTURES, D3DPTEXTURECAPS_POW2) |
726bf215546Sopenharmony_ci        D3DNPIPECAP(NPOT_TEXTURES, D3DPTEXTURECAPS_NONPOW2CONDITIONAL) |
727bf215546Sopenharmony_ci        D3DNPIPECAP(NPOT_TEXTURES, D3DPTEXTURECAPS_CUBEMAP_POW2) |
728bf215546Sopenharmony_ci        D3DNPIPECAP(NPOT_TEXTURES, D3DPTEXTURECAPS_VOLUMEMAP_POW2) |
729bf215546Sopenharmony_ci        D3DPIPECAP(MAX_TEXTURE_2D_SIZE, D3DPTEXTURECAPS_MIPMAP) |
730bf215546Sopenharmony_ci        D3DPIPECAP(MAX_TEXTURE_3D_LEVELS, D3DPTEXTURECAPS_MIPVOLUMEMAP) |
731bf215546Sopenharmony_ci        D3DPIPECAP(MAX_TEXTURE_CUBE_LEVELS, D3DPTEXTURECAPS_MIPCUBEMAP);
732bf215546Sopenharmony_ci
733bf215546Sopenharmony_ci    pCaps->TextureFilterCaps =
734bf215546Sopenharmony_ci        D3DPTFILTERCAPS_MINFPOINT |
735bf215546Sopenharmony_ci        D3DPTFILTERCAPS_MINFLINEAR |
736bf215546Sopenharmony_ci        D3DPIPECAP(ANISOTROPIC_FILTER, D3DPTFILTERCAPS_MINFANISOTROPIC) |
737bf215546Sopenharmony_ci        /*D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |*/
738bf215546Sopenharmony_ci        /*D3DPTFILTERCAPS_MINFGAUSSIANQUAD |*/
739bf215546Sopenharmony_ci        D3DPTFILTERCAPS_MIPFPOINT |
740bf215546Sopenharmony_ci        D3DPTFILTERCAPS_MIPFLINEAR |
741bf215546Sopenharmony_ci        D3DPTFILTERCAPS_MAGFPOINT |
742bf215546Sopenharmony_ci        D3DPTFILTERCAPS_MAGFLINEAR |
743bf215546Sopenharmony_ci        D3DPIPECAP(ANISOTROPIC_FILTER, D3DPTFILTERCAPS_MAGFANISOTROPIC) |
744bf215546Sopenharmony_ci        /*D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |*/
745bf215546Sopenharmony_ci        /*D3DPTFILTERCAPS_MAGFGAUSSIANQUAD*/0;
746bf215546Sopenharmony_ci
747bf215546Sopenharmony_ci    pCaps->CubeTextureFilterCaps = pCaps->TextureFilterCaps;
748bf215546Sopenharmony_ci    pCaps->VolumeTextureFilterCaps = pCaps->TextureFilterCaps;
749bf215546Sopenharmony_ci
750bf215546Sopenharmony_ci    pCaps->TextureAddressCaps =
751bf215546Sopenharmony_ci        D3DPTADDRESSCAPS_BORDER |
752bf215546Sopenharmony_ci        D3DPTADDRESSCAPS_INDEPENDENTUV |
753bf215546Sopenharmony_ci        D3DPTADDRESSCAPS_WRAP |
754bf215546Sopenharmony_ci        D3DPTADDRESSCAPS_MIRROR |
755bf215546Sopenharmony_ci        D3DPTADDRESSCAPS_CLAMP |
756bf215546Sopenharmony_ci        D3DPIPECAP(TEXTURE_MIRROR_CLAMP, D3DPTADDRESSCAPS_MIRRORONCE);
757bf215546Sopenharmony_ci
758bf215546Sopenharmony_ci    pCaps->VolumeTextureAddressCaps = pCaps->TextureAddressCaps;
759bf215546Sopenharmony_ci
760bf215546Sopenharmony_ci    pCaps->LineCaps =
761bf215546Sopenharmony_ci        D3DLINECAPS_ALPHACMP |
762bf215546Sopenharmony_ci        D3DLINECAPS_BLEND |
763bf215546Sopenharmony_ci        D3DLINECAPS_TEXTURE |
764bf215546Sopenharmony_ci        D3DLINECAPS_ZTEST |
765bf215546Sopenharmony_ci        D3DLINECAPS_FOG;
766bf215546Sopenharmony_ci    if (screen->get_paramf(screen, PIPE_CAPF_MAX_LINE_WIDTH_AA) > 0.0) {
767bf215546Sopenharmony_ci        pCaps->LineCaps |= D3DLINECAPS_ANTIALIAS;
768bf215546Sopenharmony_ci    }
769bf215546Sopenharmony_ci
770bf215546Sopenharmony_ci    pCaps->MaxTextureWidth =screen->get_param(screen,
771bf215546Sopenharmony_ci                                              PIPE_CAP_MAX_TEXTURE_2D_SIZE);
772bf215546Sopenharmony_ci    pCaps->MaxTextureHeight = pCaps->MaxTextureWidth;
773bf215546Sopenharmony_ci    pCaps->MaxVolumeExtent =
774bf215546Sopenharmony_ci        1 << (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS) - 1);
775bf215546Sopenharmony_ci    /* XXX values from wine */
776bf215546Sopenharmony_ci    pCaps->MaxTextureRepeat = 32768;
777bf215546Sopenharmony_ci    pCaps->MaxTextureAspectRatio = pCaps->MaxTextureWidth;
778bf215546Sopenharmony_ci
779bf215546Sopenharmony_ci    pCaps->MaxAnisotropy =
780bf215546Sopenharmony_ci        (DWORD)screen->get_paramf(screen, PIPE_CAPF_MAX_TEXTURE_ANISOTROPY);
781bf215546Sopenharmony_ci
782bf215546Sopenharmony_ci    /* Values for GeForce 9600 GT */
783bf215546Sopenharmony_ci    pCaps->MaxVertexW = 1e10f;
784bf215546Sopenharmony_ci    pCaps->GuardBandLeft = -1e9f;
785bf215546Sopenharmony_ci    pCaps->GuardBandTop = -1e9f;
786bf215546Sopenharmony_ci    pCaps->GuardBandRight = 1e9f;
787bf215546Sopenharmony_ci    pCaps->GuardBandBottom = 1e9f;
788bf215546Sopenharmony_ci    pCaps->ExtentsAdjust = 0.0f;
789bf215546Sopenharmony_ci
790bf215546Sopenharmony_ci    pCaps->StencilCaps =
791bf215546Sopenharmony_ci        D3DSTENCILCAPS_KEEP |
792bf215546Sopenharmony_ci        D3DSTENCILCAPS_ZERO |
793bf215546Sopenharmony_ci        D3DSTENCILCAPS_REPLACE |
794bf215546Sopenharmony_ci        D3DSTENCILCAPS_INCRSAT |
795bf215546Sopenharmony_ci        D3DSTENCILCAPS_DECRSAT |
796bf215546Sopenharmony_ci        D3DSTENCILCAPS_INVERT |
797bf215546Sopenharmony_ci        D3DSTENCILCAPS_INCR |
798bf215546Sopenharmony_ci        D3DSTENCILCAPS_DECR |
799bf215546Sopenharmony_ci        D3DSTENCILCAPS_TWOSIDED;
800bf215546Sopenharmony_ci
801bf215546Sopenharmony_ci    pCaps->FVFCaps =
802bf215546Sopenharmony_ci        8 | /* 8 textures max */
803bf215546Sopenharmony_ci        /*D3DFVFCAPS_DONOTSTRIPELEMENTS |*/
804bf215546Sopenharmony_ci        D3DFVFCAPS_PSIZE;
805bf215546Sopenharmony_ci
806bf215546Sopenharmony_ci    pCaps->TextureOpCaps = D3DTEXOPCAPS_DISABLE |
807bf215546Sopenharmony_ci                           D3DTEXOPCAPS_SELECTARG1 |
808bf215546Sopenharmony_ci                           D3DTEXOPCAPS_SELECTARG2 |
809bf215546Sopenharmony_ci                           D3DTEXOPCAPS_MODULATE |
810bf215546Sopenharmony_ci                           D3DTEXOPCAPS_MODULATE2X |
811bf215546Sopenharmony_ci                           D3DTEXOPCAPS_MODULATE4X |
812bf215546Sopenharmony_ci                           D3DTEXOPCAPS_ADD |
813bf215546Sopenharmony_ci                           D3DTEXOPCAPS_ADDSIGNED |
814bf215546Sopenharmony_ci                           D3DTEXOPCAPS_ADDSIGNED2X |
815bf215546Sopenharmony_ci                           D3DTEXOPCAPS_SUBTRACT |
816bf215546Sopenharmony_ci                           D3DTEXOPCAPS_ADDSMOOTH |
817bf215546Sopenharmony_ci                           D3DTEXOPCAPS_BLENDDIFFUSEALPHA |
818bf215546Sopenharmony_ci                           D3DTEXOPCAPS_BLENDTEXTUREALPHA |
819bf215546Sopenharmony_ci                           D3DTEXOPCAPS_BLENDFACTORALPHA |
820bf215546Sopenharmony_ci                           D3DTEXOPCAPS_BLENDTEXTUREALPHAPM |
821bf215546Sopenharmony_ci                           D3DTEXOPCAPS_BLENDCURRENTALPHA |
822bf215546Sopenharmony_ci                           D3DTEXOPCAPS_PREMODULATE |
823bf215546Sopenharmony_ci                           D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
824bf215546Sopenharmony_ci                           D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
825bf215546Sopenharmony_ci                           D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
826bf215546Sopenharmony_ci                           D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |
827bf215546Sopenharmony_ci                           D3DTEXOPCAPS_BUMPENVMAP |
828bf215546Sopenharmony_ci                           D3DTEXOPCAPS_BUMPENVMAPLUMINANCE |
829bf215546Sopenharmony_ci                           D3DTEXOPCAPS_DOTPRODUCT3 |
830bf215546Sopenharmony_ci                           D3DTEXOPCAPS_MULTIPLYADD |
831bf215546Sopenharmony_ci                           D3DTEXOPCAPS_LERP;
832bf215546Sopenharmony_ci
833bf215546Sopenharmony_ci    pCaps->MaxTextureBlendStages = 8; /* XXX wine */
834bf215546Sopenharmony_ci    pCaps->MaxSimultaneousTextures = 8;
835bf215546Sopenharmony_ci
836bf215546Sopenharmony_ci    pCaps->VertexProcessingCaps = D3DVTXPCAPS_TEXGEN |
837bf215546Sopenharmony_ci                                  D3DVTXPCAPS_TEXGEN_SPHEREMAP |
838bf215546Sopenharmony_ci                                  D3DVTXPCAPS_MATERIALSOURCE7 |
839bf215546Sopenharmony_ci                                  D3DVTXPCAPS_DIRECTIONALLIGHTS |
840bf215546Sopenharmony_ci                                  D3DVTXPCAPS_POSITIONALLIGHTS |
841bf215546Sopenharmony_ci                                  D3DVTXPCAPS_LOCALVIEWER |
842bf215546Sopenharmony_ci                                  D3DVTXPCAPS_TWEENING |
843bf215546Sopenharmony_ci                                  /*D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER*/0;
844bf215546Sopenharmony_ci
845bf215546Sopenharmony_ci    pCaps->MaxActiveLights = NINE_MAX_LIGHTS_ACTIVE; /* like GL_LIGHTi */
846bf215546Sopenharmony_ci    pCaps->MaxUserClipPlanes = PIPE_MAX_CLIP_PLANES;
847bf215546Sopenharmony_ci    pCaps->MaxVertexBlendMatrices = 4; /* 1 vec4 BLENDWEIGHT/INDICES input */
848bf215546Sopenharmony_ci    pCaps->MaxVertexBlendMatrixIndex = 8; /* D3DTS_WORLDMATRIX(0..8) */
849bf215546Sopenharmony_ci
850bf215546Sopenharmony_ci    pCaps->MaxPointSize = screen->get_paramf(screen, PIPE_CAPF_MAX_POINT_SIZE);
851bf215546Sopenharmony_ci
852bf215546Sopenharmony_ci    pCaps->MaxPrimitiveCount = 0x555555; /* <- wine, really 0xFFFFFFFF; */
853bf215546Sopenharmony_ci    pCaps->MaxVertexIndex = 0xFFFFFF; /* <- wine, really 0xFFFFFFFF */
854bf215546Sopenharmony_ci    pCaps->MaxStreams =
855bf215546Sopenharmony_ci        _min(screen->get_shader_param(screen,
856bf215546Sopenharmony_ci                 PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_MAX_INPUTS),
857bf215546Sopenharmony_ci             16);
858bf215546Sopenharmony_ci
859bf215546Sopenharmony_ci    pCaps->MaxStreamStride = screen->get_param(screen,
860bf215546Sopenharmony_ci            PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE);
861bf215546Sopenharmony_ci
862bf215546Sopenharmony_ci    pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
863bf215546Sopenharmony_ci
864bf215546Sopenharmony_ci    /* VS 2 as well as 3.0 supports a minimum of 256 consts.
865bf215546Sopenharmony_ci     * Wine and d3d9 drivers for dx1x hw advertise 256. Just as them,
866bf215546Sopenharmony_ci     * advertise 256. Problem is with hw that can only do 256, because
867bf215546Sopenharmony_ci     * we need take a few slots for boolean and integer constants. For these
868bf215546Sopenharmony_ci     * we'll have to fail later if they use complex shaders. */
869bf215546Sopenharmony_ci    pCaps->MaxVertexShaderConst = NINE_MAX_CONST_F;
870bf215546Sopenharmony_ci
871bf215546Sopenharmony_ci    pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
872bf215546Sopenharmony_ci    /* Value for GeForce 9600 GT */
873bf215546Sopenharmony_ci    pCaps->PixelShader1xMaxValue = 65504.f;
874bf215546Sopenharmony_ci
875bf215546Sopenharmony_ci    pCaps->DevCaps2 = D3DDEVCAPS2_STREAMOFFSET |
876bf215546Sopenharmony_ci                      D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET |
877bf215546Sopenharmony_ci                      D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES |
878bf215546Sopenharmony_ci                      /*D3DDEVCAPS2_DMAPNPATCH |*/
879bf215546Sopenharmony_ci                      /*D3DDEVCAPS2_ADAPTIVETESSRTPATCH |*/
880bf215546Sopenharmony_ci                      /*D3DDEVCAPS2_ADAPTIVETESSNPATCH |*/
881bf215546Sopenharmony_ci                      /*D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH*/0;
882bf215546Sopenharmony_ci
883bf215546Sopenharmony_ci    pCaps->MasterAdapterOrdinal = 0;
884bf215546Sopenharmony_ci    pCaps->AdapterOrdinalInGroup = 0;
885bf215546Sopenharmony_ci    pCaps->NumberOfAdaptersInGroup = 1;
886bf215546Sopenharmony_ci
887bf215546Sopenharmony_ci    /* Undocumented ? */
888bf215546Sopenharmony_ci    pCaps->MaxNpatchTessellationLevel = 0.0f;
889bf215546Sopenharmony_ci    pCaps->Reserved5 = 0;
890bf215546Sopenharmony_ci
891bf215546Sopenharmony_ci    /* XXX: use is_format_supported */
892bf215546Sopenharmony_ci    pCaps->DeclTypes = D3DDTCAPS_UBYTE4 |
893bf215546Sopenharmony_ci                       D3DDTCAPS_UBYTE4N |
894bf215546Sopenharmony_ci                       D3DDTCAPS_SHORT2N |
895bf215546Sopenharmony_ci                       D3DDTCAPS_SHORT4N |
896bf215546Sopenharmony_ci                       D3DDTCAPS_USHORT2N |
897bf215546Sopenharmony_ci                       D3DDTCAPS_USHORT4N |
898bf215546Sopenharmony_ci                       D3DDTCAPS_UDEC3 |
899bf215546Sopenharmony_ci                       D3DDTCAPS_DEC3N |
900bf215546Sopenharmony_ci                       D3DDTCAPS_FLOAT16_2 |
901bf215546Sopenharmony_ci                       D3DDTCAPS_FLOAT16_4;
902bf215546Sopenharmony_ci
903bf215546Sopenharmony_ci    pCaps->NumSimultaneousRTs =
904bf215546Sopenharmony_ci        screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS);
905bf215546Sopenharmony_ci    if (pCaps->NumSimultaneousRTs > NINE_MAX_SIMULTANEOUS_RENDERTARGETS)
906bf215546Sopenharmony_ci        pCaps->NumSimultaneousRTs = NINE_MAX_SIMULTANEOUS_RENDERTARGETS;
907bf215546Sopenharmony_ci
908bf215546Sopenharmony_ci    pCaps->StretchRectFilterCaps = D3DPTFILTERCAPS_MINFPOINT |
909bf215546Sopenharmony_ci                                   D3DPTFILTERCAPS_MINFLINEAR |
910bf215546Sopenharmony_ci                                   D3DPTFILTERCAPS_MAGFPOINT |
911bf215546Sopenharmony_ci                                   D3DPTFILTERCAPS_MAGFLINEAR;
912bf215546Sopenharmony_ci
913bf215546Sopenharmony_ci
914bf215546Sopenharmony_ci    pCaps->VS20Caps.Caps = D3DVS20CAPS_PREDICATION;
915bf215546Sopenharmony_ci    pCaps->VS20Caps.DynamicFlowControlDepth = /* XXX is this dynamic ? */
916bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
917bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
918bf215546Sopenharmony_ci    pCaps->VS20Caps.NumTemps =
919bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
920bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_TEMPS);
921bf215546Sopenharmony_ci    pCaps->VS20Caps.StaticFlowControlDepth = /* XXX is this static ? */
922bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
923bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
924bf215546Sopenharmony_ci
925bf215546Sopenharmony_ci    /* also check for values < 0, because get_shader_param may return unsigned */
926bf215546Sopenharmony_ci    if (pCaps->VS20Caps.DynamicFlowControlDepth > D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH
927bf215546Sopenharmony_ci        || pCaps->VS20Caps.DynamicFlowControlDepth < 0)
928bf215546Sopenharmony_ci        pCaps->VS20Caps.DynamicFlowControlDepth = D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH;
929bf215546Sopenharmony_ci    if (pCaps->VS20Caps.StaticFlowControlDepth > D3DVS20_MAX_STATICFLOWCONTROLDEPTH
930bf215546Sopenharmony_ci        || pCaps->VS20Caps.StaticFlowControlDepth < 0)
931bf215546Sopenharmony_ci        pCaps->VS20Caps.StaticFlowControlDepth = D3DVS20_MAX_STATICFLOWCONTROLDEPTH;
932bf215546Sopenharmony_ci    if (pCaps->VS20Caps.NumTemps > D3DVS20_MAX_NUMTEMPS)
933bf215546Sopenharmony_ci        pCaps->VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
934bf215546Sopenharmony_ci    assert(pCaps->VS20Caps.DynamicFlowControlDepth >= D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH);
935bf215546Sopenharmony_ci    assert(pCaps->VS20Caps.StaticFlowControlDepth >= D3DVS20_MIN_STATICFLOWCONTROLDEPTH);
936bf215546Sopenharmony_ci    assert(pCaps->VS20Caps.NumTemps >= D3DVS20_MIN_NUMTEMPS);
937bf215546Sopenharmony_ci
938bf215546Sopenharmony_ci
939bf215546Sopenharmony_ci    pCaps->PS20Caps.Caps = D3DPS20CAPS_ARBITRARYSWIZZLE |
940bf215546Sopenharmony_ci                           D3DPS20CAPS_GRADIENTINSTRUCTIONS |
941bf215546Sopenharmony_ci                           D3DPS20CAPS_PREDICATION;
942bf215546Sopenharmony_ci    if (screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
943bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS) ==
944bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
945bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS))
946bf215546Sopenharmony_ci        pCaps->PS20Caps.Caps |= D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
947bf215546Sopenharmony_ci    if (screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
948bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS) ==
949bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
950bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS))
951bf215546Sopenharmony_ci        pCaps->PS20Caps.Caps |= D3DPS20CAPS_NODEPENDENTREADLIMIT;
952bf215546Sopenharmony_ci    pCaps->PS20Caps.DynamicFlowControlDepth = /* XXX is this dynamic ? */
953bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
954bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
955bf215546Sopenharmony_ci    pCaps->PS20Caps.NumTemps =
956bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
957bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_TEMPS);
958bf215546Sopenharmony_ci    pCaps->PS20Caps.StaticFlowControlDepth =  /* XXX is this static ? */
959bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
960bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
961bf215546Sopenharmony_ci    pCaps->PS20Caps.NumInstructionSlots =
962bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
963bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
964bf215546Sopenharmony_ci
965bf215546Sopenharmony_ci    if (pCaps->PS20Caps.DynamicFlowControlDepth > D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH
966bf215546Sopenharmony_ci        || pCaps->PS20Caps.DynamicFlowControlDepth < 0)
967bf215546Sopenharmony_ci        pCaps->PS20Caps.DynamicFlowControlDepth = D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH;
968bf215546Sopenharmony_ci    if (pCaps->PS20Caps.StaticFlowControlDepth > D3DPS20_MAX_STATICFLOWCONTROLDEPTH
969bf215546Sopenharmony_ci        || pCaps->PS20Caps.StaticFlowControlDepth < 0)
970bf215546Sopenharmony_ci        pCaps->PS20Caps.StaticFlowControlDepth = D3DPS20_MAX_STATICFLOWCONTROLDEPTH;
971bf215546Sopenharmony_ci    if (pCaps->PS20Caps.NumTemps > D3DPS20_MAX_NUMTEMPS)
972bf215546Sopenharmony_ci        pCaps->PS20Caps.NumTemps = D3DPS20_MAX_NUMTEMPS;
973bf215546Sopenharmony_ci    if (pCaps->PS20Caps.NumInstructionSlots > D3DPS20_MAX_NUMINSTRUCTIONSLOTS)
974bf215546Sopenharmony_ci        pCaps->PS20Caps.NumInstructionSlots = D3DPS20_MAX_NUMINSTRUCTIONSLOTS;
975bf215546Sopenharmony_ci    assert(pCaps->PS20Caps.DynamicFlowControlDepth >= D3DPS20_MIN_DYNAMICFLOWCONTROLDEPTH);
976bf215546Sopenharmony_ci    assert(pCaps->PS20Caps.StaticFlowControlDepth >= D3DPS20_MIN_STATICFLOWCONTROLDEPTH);
977bf215546Sopenharmony_ci    assert(pCaps->PS20Caps.NumTemps >= D3DPS20_MIN_NUMTEMPS);
978bf215546Sopenharmony_ci    assert(pCaps->PS20Caps.NumInstructionSlots >= D3DPS20_MIN_NUMINSTRUCTIONSLOTS);
979bf215546Sopenharmony_ci
980bf215546Sopenharmony_ci
981bf215546Sopenharmony_ci    if (screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
982bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS))
983bf215546Sopenharmony_ci        pCaps->VertexTextureFilterCaps = pCaps->TextureFilterCaps &
984bf215546Sopenharmony_ci            ~(D3DPTFILTERCAPS_MIPFPOINT |
985bf215546Sopenharmony_ci              D3DPTFILTERCAPS_MIPFPOINT); /* XXX */
986bf215546Sopenharmony_ci    else
987bf215546Sopenharmony_ci        pCaps->VertexTextureFilterCaps = 0;
988bf215546Sopenharmony_ci
989bf215546Sopenharmony_ci    pCaps->MaxVertexShader30InstructionSlots =
990bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
991bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
992bf215546Sopenharmony_ci    pCaps->MaxPixelShader30InstructionSlots =
993bf215546Sopenharmony_ci        screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
994bf215546Sopenharmony_ci                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
995bf215546Sopenharmony_ci    if (pCaps->MaxVertexShader30InstructionSlots > D3DMAX30SHADERINSTRUCTIONS)
996bf215546Sopenharmony_ci        pCaps->MaxVertexShader30InstructionSlots = D3DMAX30SHADERINSTRUCTIONS;
997bf215546Sopenharmony_ci    if (pCaps->MaxPixelShader30InstructionSlots > D3DMAX30SHADERINSTRUCTIONS)
998bf215546Sopenharmony_ci        pCaps->MaxPixelShader30InstructionSlots = D3DMAX30SHADERINSTRUCTIONS;
999bf215546Sopenharmony_ci    assert(pCaps->MaxVertexShader30InstructionSlots >= D3DMIN30SHADERINSTRUCTIONS);
1000bf215546Sopenharmony_ci    assert(pCaps->MaxPixelShader30InstructionSlots >= D3DMIN30SHADERINSTRUCTIONS);
1001bf215546Sopenharmony_ci
1002bf215546Sopenharmony_ci    /* 65535 is required, advertise more for GPUs with >= 2048 instruction slots */
1003bf215546Sopenharmony_ci    pCaps->MaxVShaderInstructionsExecuted = MAX2(65535, pCaps->MaxVertexShader30InstructionSlots * 32);
1004bf215546Sopenharmony_ci    pCaps->MaxPShaderInstructionsExecuted = MAX2(65535, pCaps->MaxPixelShader30InstructionSlots * 32);
1005bf215546Sopenharmony_ci
1006bf215546Sopenharmony_ci    if (debug_get_bool_option("NINE_DUMP_CAPS", FALSE))
1007bf215546Sopenharmony_ci        nine_dump_D3DCAPS9(DBG_CHANNEL, pCaps);
1008bf215546Sopenharmony_ci
1009bf215546Sopenharmony_ci    return D3D_OK;
1010bf215546Sopenharmony_ci}
1011bf215546Sopenharmony_ci
1012bf215546Sopenharmony_ciHRESULT NINE_WINAPI
1013bf215546Sopenharmony_ciNineAdapter9_CreateDevice( struct NineAdapter9 *This,
1014bf215546Sopenharmony_ci                           UINT RealAdapter,
1015bf215546Sopenharmony_ci                           D3DDEVTYPE DeviceType,
1016bf215546Sopenharmony_ci                           HWND hFocusWindow,
1017bf215546Sopenharmony_ci                           DWORD BehaviorFlags,
1018bf215546Sopenharmony_ci                           D3DPRESENT_PARAMETERS *pPresentationParameters,
1019bf215546Sopenharmony_ci                           IDirect3D9 *pD3D9,
1020bf215546Sopenharmony_ci                           ID3DPresentGroup *pPresentationGroup,
1021bf215546Sopenharmony_ci                           IDirect3DDevice9 **ppReturnedDeviceInterface )
1022bf215546Sopenharmony_ci{
1023bf215546Sopenharmony_ci    struct pipe_screen *screen;
1024bf215546Sopenharmony_ci    D3DDEVICE_CREATION_PARAMETERS params;
1025bf215546Sopenharmony_ci    D3DCAPS9 caps;
1026bf215546Sopenharmony_ci    int major, minor;
1027bf215546Sopenharmony_ci    HRESULT hr;
1028bf215546Sopenharmony_ci
1029bf215546Sopenharmony_ci    DBG("This=%p RealAdapter=%u DeviceType=%s hFocusWindow=%p "
1030bf215546Sopenharmony_ci        "BehaviourFlags=%x " "pD3D9=%p pPresentationGroup=%p "
1031bf215546Sopenharmony_ci        "ppReturnedDeviceInterface=%p\n", This,
1032bf215546Sopenharmony_ci        RealAdapter, nine_D3DDEVTYPE_to_str(DeviceType), hFocusWindow,
1033bf215546Sopenharmony_ci        BehaviorFlags, pD3D9, pPresentationGroup, ppReturnedDeviceInterface);
1034bf215546Sopenharmony_ci
1035bf215546Sopenharmony_ci    ID3DPresentGroup_GetVersion(pPresentationGroup, &major, &minor);
1036bf215546Sopenharmony_ci    if (major != 1) {
1037bf215546Sopenharmony_ci        ERR("Doesn't support the ID3DPresentGroup version %d %d. Expected 1\n",
1038bf215546Sopenharmony_ci            major, minor);
1039bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
1040bf215546Sopenharmony_ci    }
1041bf215546Sopenharmony_ci
1042bf215546Sopenharmony_ci    hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
1043bf215546Sopenharmony_ci    if (FAILED(hr)) {
1044bf215546Sopenharmony_ci        DBG("Failed to get pipe_screen.\n");
1045bf215546Sopenharmony_ci        return hr;
1046bf215546Sopenharmony_ci    }
1047bf215546Sopenharmony_ci
1048bf215546Sopenharmony_ci    hr = NineAdapter9_GetDeviceCaps(This, DeviceType, &caps);
1049bf215546Sopenharmony_ci    if (FAILED(hr)) {
1050bf215546Sopenharmony_ci        DBG("Failed to get device caps.\n");
1051bf215546Sopenharmony_ci        return hr;
1052bf215546Sopenharmony_ci    }
1053bf215546Sopenharmony_ci
1054bf215546Sopenharmony_ci    params.AdapterOrdinal = RealAdapter;
1055bf215546Sopenharmony_ci    params.DeviceType = DeviceType;
1056bf215546Sopenharmony_ci    params.hFocusWindow = hFocusWindow;
1057bf215546Sopenharmony_ci    params.BehaviorFlags = BehaviorFlags;
1058bf215546Sopenharmony_ci
1059bf215546Sopenharmony_ci    hr = NineDevice9_new(screen, &params, &caps, pPresentationParameters,
1060bf215546Sopenharmony_ci                         pD3D9, pPresentationGroup, This->ctx, FALSE, NULL,
1061bf215546Sopenharmony_ci                         (struct NineDevice9 **)ppReturnedDeviceInterface,
1062bf215546Sopenharmony_ci                         minor);
1063bf215546Sopenharmony_ci    if (FAILED(hr)) {
1064bf215546Sopenharmony_ci        DBG("Failed to create device.\n");
1065bf215546Sopenharmony_ci        return hr;
1066bf215546Sopenharmony_ci    }
1067bf215546Sopenharmony_ci    DBG("NineDevice9 created successfully.\n");
1068bf215546Sopenharmony_ci
1069bf215546Sopenharmony_ci    return D3D_OK;
1070bf215546Sopenharmony_ci}
1071bf215546Sopenharmony_ci
1072bf215546Sopenharmony_ciHRESULT NINE_WINAPI
1073bf215546Sopenharmony_ciNineAdapter9_CreateDeviceEx( struct NineAdapter9 *This,
1074bf215546Sopenharmony_ci                             UINT RealAdapter,
1075bf215546Sopenharmony_ci                             D3DDEVTYPE DeviceType,
1076bf215546Sopenharmony_ci                             HWND hFocusWindow,
1077bf215546Sopenharmony_ci                             DWORD BehaviorFlags,
1078bf215546Sopenharmony_ci                             D3DPRESENT_PARAMETERS *pPresentationParameters,
1079bf215546Sopenharmony_ci                             D3DDISPLAYMODEEX *pFullscreenDisplayMode,
1080bf215546Sopenharmony_ci                             IDirect3D9Ex *pD3D9Ex,
1081bf215546Sopenharmony_ci                             ID3DPresentGroup *pPresentationGroup,
1082bf215546Sopenharmony_ci                             IDirect3DDevice9Ex **ppReturnedDeviceInterface )
1083bf215546Sopenharmony_ci{
1084bf215546Sopenharmony_ci    struct pipe_screen *screen;
1085bf215546Sopenharmony_ci    D3DDEVICE_CREATION_PARAMETERS params;
1086bf215546Sopenharmony_ci    D3DCAPS9 caps;
1087bf215546Sopenharmony_ci    int major, minor;
1088bf215546Sopenharmony_ci    HRESULT hr;
1089bf215546Sopenharmony_ci
1090bf215546Sopenharmony_ci    DBG("This=%p RealAdapter=%u DeviceType=%s hFocusWindow=%p "
1091bf215546Sopenharmony_ci        "BehaviourFlags=%x " "pD3D9Ex=%p pPresentationGroup=%p "
1092bf215546Sopenharmony_ci        "ppReturnedDeviceInterface=%p\n", This,
1093bf215546Sopenharmony_ci        RealAdapter, nine_D3DDEVTYPE_to_str(DeviceType), hFocusWindow,
1094bf215546Sopenharmony_ci        BehaviorFlags, pD3D9Ex, pPresentationGroup, ppReturnedDeviceInterface);
1095bf215546Sopenharmony_ci
1096bf215546Sopenharmony_ci    ID3DPresentGroup_GetVersion(pPresentationGroup, &major, &minor);
1097bf215546Sopenharmony_ci    if (major != 1) {
1098bf215546Sopenharmony_ci        ERR("Doesn't support the ID3DPresentGroup version %d %d. Expected 1\n",
1099bf215546Sopenharmony_ci            major, minor);
1100bf215546Sopenharmony_ci        return D3DERR_NOTAVAILABLE;
1101bf215546Sopenharmony_ci    }
1102bf215546Sopenharmony_ci
1103bf215546Sopenharmony_ci    hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
1104bf215546Sopenharmony_ci    if (FAILED(hr)) {
1105bf215546Sopenharmony_ci        DBG("Failed to get pipe_screen.\n");
1106bf215546Sopenharmony_ci        return hr;
1107bf215546Sopenharmony_ci    }
1108bf215546Sopenharmony_ci
1109bf215546Sopenharmony_ci    hr = NineAdapter9_GetDeviceCaps(This, DeviceType, &caps);
1110bf215546Sopenharmony_ci    if (FAILED(hr)) {
1111bf215546Sopenharmony_ci        DBG("Failed to get device caps.\n");
1112bf215546Sopenharmony_ci        return hr;
1113bf215546Sopenharmony_ci    }
1114bf215546Sopenharmony_ci
1115bf215546Sopenharmony_ci    params.AdapterOrdinal = RealAdapter;
1116bf215546Sopenharmony_ci    params.DeviceType = DeviceType;
1117bf215546Sopenharmony_ci    params.hFocusWindow = hFocusWindow;
1118bf215546Sopenharmony_ci    params.BehaviorFlags = BehaviorFlags;
1119bf215546Sopenharmony_ci
1120bf215546Sopenharmony_ci    hr = NineDevice9Ex_new(screen, &params, &caps, pPresentationParameters,
1121bf215546Sopenharmony_ci                           pFullscreenDisplayMode,
1122bf215546Sopenharmony_ci                           pD3D9Ex, pPresentationGroup, This->ctx,
1123bf215546Sopenharmony_ci                           (struct NineDevice9Ex **)ppReturnedDeviceInterface,
1124bf215546Sopenharmony_ci                           minor);
1125bf215546Sopenharmony_ci    if (FAILED(hr)) {
1126bf215546Sopenharmony_ci        DBG("Failed to create device.\n");
1127bf215546Sopenharmony_ci        return hr;
1128bf215546Sopenharmony_ci    }
1129bf215546Sopenharmony_ci    DBG("NineDevice9Ex created successfully.\n");
1130bf215546Sopenharmony_ci
1131bf215546Sopenharmony_ci    return D3D_OK;
1132bf215546Sopenharmony_ci}
1133bf215546Sopenharmony_ci
1134bf215546Sopenharmony_ciID3DAdapter9Vtbl NineAdapter9_vtable = {
1135bf215546Sopenharmony_ci    (void *)NineUnknown_QueryInterface,
1136bf215546Sopenharmony_ci    (void *)NineUnknown_AddRef,
1137bf215546Sopenharmony_ci    (void *)NineUnknown_Release,
1138bf215546Sopenharmony_ci    (void *)NineAdapter9_GetAdapterIdentifier,
1139bf215546Sopenharmony_ci    (void *)NineAdapter9_CheckDeviceType,
1140bf215546Sopenharmony_ci    (void *)NineAdapter9_CheckDeviceFormat,
1141bf215546Sopenharmony_ci    (void *)NineAdapter9_CheckDeviceMultiSampleType,
1142bf215546Sopenharmony_ci    (void *)NineAdapter9_CheckDepthStencilMatch,
1143bf215546Sopenharmony_ci    (void *)NineAdapter9_CheckDeviceFormatConversion,
1144bf215546Sopenharmony_ci    (void *)NineAdapter9_GetDeviceCaps,
1145bf215546Sopenharmony_ci    (void *)NineAdapter9_CreateDevice,
1146bf215546Sopenharmony_ci    (void *)NineAdapter9_CreateDeviceEx
1147bf215546Sopenharmony_ci};
1148bf215546Sopenharmony_ci
1149bf215546Sopenharmony_cistatic const GUID *NineAdapter9_IIDs[] = {
1150bf215546Sopenharmony_ci    &IID_ID3D9Adapter,
1151bf215546Sopenharmony_ci    &IID_IUnknown,
1152bf215546Sopenharmony_ci    NULL
1153bf215546Sopenharmony_ci};
1154bf215546Sopenharmony_ci
1155bf215546Sopenharmony_ciHRESULT
1156bf215546Sopenharmony_ciNineAdapter9_new( struct d3dadapter9_context *pCTX,
1157bf215546Sopenharmony_ci                  struct NineAdapter9 **ppOut )
1158bf215546Sopenharmony_ci{
1159bf215546Sopenharmony_ci    NINE_NEW(Adapter9, ppOut, FALSE, /* args */ pCTX);
1160bf215546Sopenharmony_ci}
1161