state.c 42 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * Copyright 2009 Henri Verbeet for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 */

#include "config.h"
#include "wine/port.h"

23
#include "d3d11_private.h"
24

25
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
26

27 28 29
/* ID3D11BlendState methods */

static HRESULT STDMETHODCALLTYPE d3d11_blend_state_QueryInterface(ID3D11BlendState *iface,
30 31
        REFIID riid, void **object)
{
32 33
    struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface);

34 35
    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);

36 37
    if (IsEqualGUID(riid, &IID_ID3D11BlendState)
            || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
38 39
            || IsEqualGUID(riid, &IID_IUnknown))
    {
40
        ID3D11BlendState_AddRef(iface);
41 42 43 44
        *object = iface;
        return S_OK;
    }

45 46
    if (IsEqualGUID(riid, &IID_ID3D10BlendState1)
            || IsEqualGUID(riid, &IID_ID3D10BlendState)
47 48
            || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
    {
49 50
        ID3D10BlendState1_AddRef(&state->ID3D10BlendState1_iface);
        *object = &state->ID3D10BlendState1_iface;
51 52 53
        return S_OK;
    }

54 55 56 57 58 59
    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));

    *object = NULL;
    return E_NOINTERFACE;
}

60
static ULONG STDMETHODCALLTYPE d3d11_blend_state_AddRef(ID3D11BlendState *iface)
61
{
62 63
    struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface);
    ULONG refcount = InterlockedIncrement(&state->refcount);
64

65
    TRACE("%p increasing refcount to %u.\n", state, refcount);
66 67 68 69

    return refcount;
}

70
static ULONG STDMETHODCALLTYPE d3d11_blend_state_Release(ID3D11BlendState *iface)
71
{
72
    struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface);
73
    ULONG refcount = InterlockedDecrement(&state->refcount);
74

75
    TRACE("%p decreasing refcount to %u.\n", state, refcount);
76 77 78

    if (!refcount)
    {
79
        struct d3d_device *device = impl_from_ID3D11Device(state->device);
80
        wined3d_mutex_lock();
81
        wine_rb_remove(&device->blend_states, &state->entry);
82
        ID3D11Device_Release(state->device);
83
        wined3d_private_store_cleanup(&state->private_store);
84
        wined3d_mutex_unlock();
85
        HeapFree(GetProcessHeap(), 0, state);
86 87 88 89 90
    }

    return refcount;
}

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
static void STDMETHODCALLTYPE d3d11_blend_state_GetDevice(ID3D11BlendState *iface,
        ID3D11Device **device)
{
    struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface);

    TRACE("iface %p, device %p.\n", iface, device);

    *device = state->device;
    ID3D11Device_AddRef(*device);
}

static HRESULT STDMETHODCALLTYPE d3d11_blend_state_GetPrivateData(ID3D11BlendState *iface,
        REFGUID guid, UINT *data_size, void *data)
{
    struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface);

    TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);

    return d3d_get_private_data(&state->private_store, guid, data_size, data);
}

static HRESULT STDMETHODCALLTYPE d3d11_blend_state_SetPrivateData(ID3D11BlendState *iface,
        REFGUID guid, UINT data_size, const void *data)
{
    struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface);

    TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);

    return d3d_set_private_data(&state->private_store, guid, data_size, data);
}

static HRESULT STDMETHODCALLTYPE d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState *iface,
        REFGUID guid, const IUnknown *data)
{
    struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface);

    TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);

    return d3d_set_private_data_interface(&state->private_store, guid, data);
}

static void STDMETHODCALLTYPE d3d11_blend_state_GetDesc(ID3D11BlendState *iface, D3D11_BLEND_DESC *desc)
{
134 135 136 137 138
    struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface);

    TRACE("iface %p, desc %p.\n", iface, desc);

    *desc = state->desc;
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
}

static const struct ID3D11BlendStateVtbl d3d11_blend_state_vtbl =
{
    /* IUnknown methods */
    d3d11_blend_state_QueryInterface,
    d3d11_blend_state_AddRef,
    d3d11_blend_state_Release,
    /* ID3D11DeviceChild methods */
    d3d11_blend_state_GetDevice,
    d3d11_blend_state_GetPrivateData,
    d3d11_blend_state_SetPrivateData,
    d3d11_blend_state_SetPrivateDataInterface,
    /* ID3D11BlendState methods */
    d3d11_blend_state_GetDesc,
};

/* ID3D10BlendState methods */

158
static inline struct d3d_blend_state *impl_from_ID3D10BlendState(ID3D10BlendState1 *iface)
159
{
160
    return CONTAINING_RECORD(iface, struct d3d_blend_state, ID3D10BlendState1_iface);
161 162 163 164
}

/* IUnknown methods */

165
static HRESULT STDMETHODCALLTYPE d3d10_blend_state_QueryInterface(ID3D10BlendState1 *iface,
166 167 168 169 170 171 172 173 174
        REFIID riid, void **object)
{
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);

    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);

    return d3d11_blend_state_QueryInterface(&state->ID3D11BlendState_iface, riid, object);
}

175
static ULONG STDMETHODCALLTYPE d3d10_blend_state_AddRef(ID3D10BlendState1 *iface)
176 177 178 179 180 181 182 183
{
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);

    TRACE("iface %p.\n", iface);

    return d3d11_blend_state_AddRef(&state->ID3D11BlendState_iface);
}

184
static ULONG STDMETHODCALLTYPE d3d10_blend_state_Release(ID3D10BlendState1 *iface)
185 186 187 188 189 190 191 192
{
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);

    TRACE("iface %p.\n", iface);

    return d3d11_blend_state_Release(&state->ID3D11BlendState_iface);
}

193 194
/* ID3D10DeviceChild methods */

195
static void STDMETHODCALLTYPE d3d10_blend_state_GetDevice(ID3D10BlendState1 *iface, ID3D10Device **device)
196
{
197
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);
198 199 200

    TRACE("iface %p, device %p.\n", iface, device);

201
    ID3D11Device_QueryInterface(state->device, &IID_ID3D10Device, (void **)device);
202 203
}

204
static HRESULT STDMETHODCALLTYPE d3d10_blend_state_GetPrivateData(ID3D10BlendState1 *iface,
205 206
        REFGUID guid, UINT *data_size, void *data)
{
207
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);
208 209

    TRACE("iface %p, guid %s, data_size %p, data %p.\n",
210 211
            iface, debugstr_guid(guid), data_size, data);

212
    return d3d_get_private_data(&state->private_store, guid, data_size, data);
213 214
}

215
static HRESULT STDMETHODCALLTYPE d3d10_blend_state_SetPrivateData(ID3D10BlendState1 *iface,
216 217
        REFGUID guid, UINT data_size, const void *data)
{
218
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);
219 220

    TRACE("iface %p, guid %s, data_size %u, data %p.\n",
221 222
            iface, debugstr_guid(guid), data_size, data);

223
    return d3d_set_private_data(&state->private_store, guid, data_size, data);
224 225
}

226
static HRESULT STDMETHODCALLTYPE d3d10_blend_state_SetPrivateDataInterface(ID3D10BlendState1 *iface,
227 228
        REFGUID guid, const IUnknown *data)
{
229
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);
230

231 232
    TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);

233
    return d3d_set_private_data_interface(&state->private_store, guid, data);
234 235 236 237
}

/* ID3D10BlendState methods */

238
static void STDMETHODCALLTYPE d3d10_blend_state_GetDesc(ID3D10BlendState1 *iface, D3D10_BLEND_DESC *desc)
239
{
240
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);
241 242
    const D3D11_BLEND_DESC *d3d11_desc = &state->desc;
    unsigned int i;
243 244 245

    TRACE("iface %p, desc %p.\n", iface, desc);

246 247 248 249 250 251 252 253 254 255 256 257
    desc->AlphaToCoverageEnable = d3d11_desc->AlphaToCoverageEnable;
    desc->SrcBlend = d3d11_desc->RenderTarget[0].SrcBlend;
    desc->DestBlend = d3d11_desc->RenderTarget[0].DestBlend;
    desc->BlendOp = d3d11_desc->RenderTarget[0].BlendOp;
    desc->SrcBlendAlpha = d3d11_desc->RenderTarget[0].SrcBlendAlpha;
    desc->DestBlendAlpha = d3d11_desc->RenderTarget[0].DestBlendAlpha;
    desc->BlendOpAlpha = d3d11_desc->RenderTarget[0].BlendOpAlpha;
    for (i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
    {
        desc->BlendEnable[i] = d3d11_desc->RenderTarget[i].BlendEnable;
        desc->RenderTargetWriteMask[i] = d3d11_desc->RenderTarget[i].RenderTargetWriteMask;
    }
258 259
}

260 261 262 263 264 265 266 267 268 269
static void STDMETHODCALLTYPE d3d10_blend_state_GetDesc1(ID3D10BlendState1 *iface, D3D10_BLEND_DESC1 *desc)
{
    struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface);

    TRACE("iface %p, desc %p.\n", iface, desc);

    memcpy(desc, &state->desc, sizeof(*desc));
}

static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl =
270 271 272 273 274 275 276 277 278 279 280 281
{
    /* IUnknown methods */
    d3d10_blend_state_QueryInterface,
    d3d10_blend_state_AddRef,
    d3d10_blend_state_Release,
    /* ID3D10DeviceChild methods */
    d3d10_blend_state_GetDevice,
    d3d10_blend_state_GetPrivateData,
    d3d10_blend_state_SetPrivateData,
    d3d10_blend_state_SetPrivateDataInterface,
    /* ID3D10BlendState methods */
    d3d10_blend_state_GetDesc,
282 283
    /* ID3D10BlendState1 methods */
    d3d10_blend_state_GetDesc1,
284 285
};

286
HRESULT d3d_blend_state_init(struct d3d_blend_state *state, struct d3d_device *device,
287
        const D3D11_BLEND_DESC *desc)
288
{
289
    state->ID3D11BlendState_iface.lpVtbl = &d3d11_blend_state_vtbl;
290
    state->ID3D10BlendState1_iface.lpVtbl = &d3d10_blend_state_vtbl;
291
    state->refcount = 1;
292
    wined3d_mutex_lock();
293
    wined3d_private_store_init(&state->private_store);
294
    state->desc = *desc;
295

296 297 298
    if (wine_rb_put(&device->blend_states, desc, &state->entry) == -1)
    {
        ERR("Failed to insert blend state entry.\n");
299
        wined3d_private_store_cleanup(&state->private_store);
300
        wined3d_mutex_unlock();
301 302
        return E_FAIL;
    }
303
    wined3d_mutex_unlock();
304

305 306
    state->device = &device->ID3D11Device_iface;
    ID3D11Device_AddRef(state->device);
307

308 309 310
    return S_OK;
}

311 312 313 314 315 316 317 318 319
struct d3d_blend_state *unsafe_impl_from_ID3D11BlendState(ID3D11BlendState *iface)
{
    if (!iface)
        return NULL;
    assert(iface->lpVtbl == &d3d11_blend_state_vtbl);

    return impl_from_ID3D11BlendState(iface);
}

320
struct d3d_blend_state *unsafe_impl_from_ID3D10BlendState(ID3D10BlendState *iface)
321 322 323
{
    if (!iface)
        return NULL;
324
    assert(iface->lpVtbl == (ID3D10BlendStateVtbl *)&d3d10_blend_state_vtbl);
325

326
    return impl_from_ID3D10BlendState((ID3D10BlendState1 *)iface);
327 328
}

329 330 331
/* ID3D11DepthStencilState methods */

static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState *iface,
332 333
        REFIID riid, void **object)
{
334 335
    struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface);

336 337
    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);

338 339
    if (IsEqualGUID(riid, &IID_ID3D11DepthStencilState)
            || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
340 341
            || IsEqualGUID(riid, &IID_IUnknown))
    {
342
        ID3D11DepthStencilState_AddRef(iface);
343 344 345 346
        *object = iface;
        return S_OK;
    }

347 348 349 350 351 352 353 354
    if (IsEqualGUID(riid, &IID_ID3D10DepthStencilState)
            || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
    {
        ID3D10DepthStencilState_AddRef(&state->ID3D10DepthStencilState_iface);
        *object = &state->ID3D10DepthStencilState_iface;
        return S_OK;
    }

355 356 357 358 359 360
    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));

    *object = NULL;
    return E_NOINTERFACE;
}

361
static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState *iface)
362
{
363 364
    struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface);
    ULONG refcount = InterlockedIncrement(&state->refcount);
365

366
    TRACE("%p increasing refcount to %u.\n", state, refcount);
367 368 369 370

    return refcount;
}

371
static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_Release(ID3D11DepthStencilState *iface)
372
{
373
    struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface);
374
    ULONG refcount = InterlockedDecrement(&state->refcount);
375

376
    TRACE("%p decreasing refcount to %u.\n", state, refcount);
377 378 379

    if (!refcount)
    {
380
        struct d3d_device *device = impl_from_ID3D11Device(state->device);
381
        wined3d_mutex_lock();
382
        wine_rb_remove(&device->depthstencil_states, &state->entry);
383
        ID3D11Device_Release(state->device);
384
        wined3d_private_store_cleanup(&state->private_store);
385
        wined3d_mutex_unlock();
386
        HeapFree(GetProcessHeap(), 0, state);
387 388 389 390 391
    }

    return refcount;
}

392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
static void STDMETHODCALLTYPE d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState *iface,
        ID3D11Device **device)
{
    struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface);

    TRACE("iface %p, device %p.\n", iface, device);

    *device = state->device;
    ID3D11Device_AddRef(*device);
}

static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState *iface,
        REFGUID guid, UINT *data_size, void *data)
{
    struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface);

    TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);

    return d3d_get_private_data(&state->private_store, guid, data_size, data);
}

static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState *iface,
        REFGUID guid, UINT data_size, const void *data)
{
    struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface);

    TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);

    return d3d_set_private_data(&state->private_store, guid, data_size, data);
}

static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState *iface,
        REFGUID guid, const IUnknown *data)
{
    struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface);

    TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);

    return d3d_set_private_data_interface(&state->private_store, guid, data);
}

static void STDMETHODCALLTYPE d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState *iface,
        D3D11_DEPTH_STENCIL_DESC *desc)
{
436 437 438 439 440
    struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface);

    TRACE("iface %p, desc %p.\n", iface, desc);

    *desc = state->desc;
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
}

static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl =
{
    /* IUnknown methods */
    d3d11_depthstencil_state_QueryInterface,
    d3d11_depthstencil_state_AddRef,
    d3d11_depthstencil_state_Release,
    /* ID3D11DeviceChild methods */
    d3d11_depthstencil_state_GetDevice,
    d3d11_depthstencil_state_GetPrivateData,
    d3d11_depthstencil_state_SetPrivateData,
    d3d11_depthstencil_state_SetPrivateDataInterface,
    /* ID3D11DepthStencilState methods */
    d3d11_depthstencil_state_GetDesc,
};

/* ID3D10DepthStencilState methods */

static inline struct d3d_depthstencil_state *impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState *iface)
{
    return CONTAINING_RECORD(iface, struct d3d_depthstencil_state, ID3D10DepthStencilState_iface);
}

/* IUnknown methods */

static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState *iface,
        REFIID riid, void **object)
{
    struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);

    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);

    return d3d11_depthstencil_state_QueryInterface(&state->ID3D11DepthStencilState_iface, riid, object);
}

static ULONG STDMETHODCALLTYPE d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState *iface)
{
    struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);

    TRACE("iface %p.\n", iface);

    return d3d11_depthstencil_state_AddRef(&state->ID3D11DepthStencilState_iface);
}

static ULONG STDMETHODCALLTYPE d3d10_depthstencil_state_Release(ID3D10DepthStencilState *iface)
{
    struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);

    TRACE("iface %p.\n", iface);

    return d3d11_depthstencil_state_Release(&state->ID3D11DepthStencilState_iface);
}

495 496 497 498
/* ID3D10DeviceChild methods */

static void STDMETHODCALLTYPE d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState *iface, ID3D10Device **device)
{
499
    struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);
500 501 502

    TRACE("iface %p, device %p.\n", iface, device);

503
    ID3D11Device_QueryInterface(state->device, &IID_ID3D10Device, (void **)device);
504 505 506 507 508
}

static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState *iface,
        REFGUID guid, UINT *data_size, void *data)
{
509
    struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);
510 511

    TRACE("iface %p, guid %s, data_size %p, data %p.\n",
512 513
            iface, debugstr_guid(guid), data_size, data);

514
    return d3d_get_private_data(&state->private_store, guid, data_size, data);
515 516 517 518 519
}

static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState *iface,
        REFGUID guid, UINT data_size, const void *data)
{
520
    struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);
521 522

    TRACE("iface %p, guid %s, data_size %u, data %p.\n",
523 524
            iface, debugstr_guid(guid), data_size, data);

525
    return d3d_set_private_data(&state->private_store, guid, data_size, data);
526 527 528 529 530
}

static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState *iface,
        REFGUID guid, const IUnknown *data)
{
531
    struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);
532

533 534
    TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);

535
    return d3d_set_private_data_interface(&state->private_store, guid, data);
536 537 538 539 540 541 542
}

/* ID3D10DepthStencilState methods */

static void STDMETHODCALLTYPE d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState *iface,
        D3D10_DEPTH_STENCIL_DESC *desc)
{
543
    struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);
544 545 546

    TRACE("iface %p, desc %p.\n", iface, desc);

547
    memcpy(desc, &state->desc, sizeof(*desc));
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
}

static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl =
{
    /* IUnknown methods */
    d3d10_depthstencil_state_QueryInterface,
    d3d10_depthstencil_state_AddRef,
    d3d10_depthstencil_state_Release,
    /* ID3D10DeviceChild methods */
    d3d10_depthstencil_state_GetDevice,
    d3d10_depthstencil_state_GetPrivateData,
    d3d10_depthstencil_state_SetPrivateData,
    d3d10_depthstencil_state_SetPrivateDataInterface,
    /* ID3D10DepthStencilState methods */
    d3d10_depthstencil_state_GetDesc,
};

565
HRESULT d3d_depthstencil_state_init(struct d3d_depthstencil_state *state, struct d3d_device *device,
566
        const D3D11_DEPTH_STENCIL_DESC *desc)
567
{
568
    state->ID3D11DepthStencilState_iface.lpVtbl = &d3d11_depthstencil_state_vtbl;
569
    state->ID3D10DepthStencilState_iface.lpVtbl = &d3d10_depthstencil_state_vtbl;
570
    state->refcount = 1;
571
    wined3d_mutex_lock();
572
    wined3d_private_store_init(&state->private_store);
573
    state->desc = *desc;
574

575 576 577
    if (wine_rb_put(&device->depthstencil_states, desc, &state->entry) == -1)
    {
        ERR("Failed to insert depthstencil state entry.\n");
578
        wined3d_private_store_cleanup(&state->private_store);
579
        wined3d_mutex_unlock();
580 581
        return E_FAIL;
    }
582
    wined3d_mutex_unlock();
583

584 585
    state->device = &device->ID3D11Device_iface;
    ID3D11Device_AddRef(state->device);
586

587 588
    return S_OK;
}
589

590 591 592 593 594 595 596 597 598
struct d3d_depthstencil_state *unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState *iface)
{
    if (!iface)
        return NULL;
    assert(iface->lpVtbl == &d3d11_depthstencil_state_vtbl);

    return impl_from_ID3D11DepthStencilState(iface);
}

599
struct d3d_depthstencil_state *unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState *iface)
600 601 602 603 604 605 606 607
{
    if (!iface)
        return NULL;
    assert(iface->lpVtbl == &d3d10_depthstencil_state_vtbl);

    return impl_from_ID3D10DepthStencilState(iface);
}

608 609 610
/* ID3D11RasterizerState methods */

static inline struct d3d_rasterizer_state *impl_from_ID3D11RasterizerState(ID3D11RasterizerState *iface)
611
{
612
    return CONTAINING_RECORD(iface, struct d3d_rasterizer_state, ID3D11RasterizerState_iface);
613 614
}

615
static HRESULT STDMETHODCALLTYPE d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState *iface,
616 617
        REFIID riid, void **object)
{
618 619
    struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface);

620 621
    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);

622 623
    if (IsEqualGUID(riid, &IID_ID3D11RasterizerState)
            || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
624 625
            || IsEqualGUID(riid, &IID_IUnknown))
    {
626
        ID3D11RasterizerState_AddRef(iface);
627 628 629 630
        *object = iface;
        return S_OK;
    }

631 632 633 634 635 636 637 638
    if (IsEqualGUID(riid, &IID_ID3D10RasterizerState)
            || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
    {
        ID3D10RasterizerState_AddRef(&state->ID3D10RasterizerState_iface);
        *object = &state->ID3D10RasterizerState_iface;
        return S_OK;
    }

639 640 641 642 643 644
    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));

    *object = NULL;
    return E_NOINTERFACE;
}

645
static ULONG STDMETHODCALLTYPE d3d11_rasterizer_state_AddRef(ID3D11RasterizerState *iface)
646
{
647 648
    struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface);
    ULONG refcount = InterlockedIncrement(&state->refcount);
649

650
    TRACE("%p increasing refcount to %u.\n", state, refcount);
651 652 653 654

    return refcount;
}

655
static ULONG STDMETHODCALLTYPE d3d11_rasterizer_state_Release(ID3D11RasterizerState *iface)
656
{
657
    struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface);
658
    ULONG refcount = InterlockedDecrement(&state->refcount);
659

660
    TRACE("%p decreasing refcount to %u.\n", state, refcount);
661 662 663

    if (!refcount)
    {
664
        struct d3d_device *device = impl_from_ID3D11Device(state->device);
665
        wined3d_mutex_lock();
666
        wine_rb_remove(&device->rasterizer_states, &state->entry);
667
        wined3d_rasterizer_state_decref(state->wined3d_state);
668
        wined3d_private_store_cleanup(&state->private_store);
669
        wined3d_mutex_unlock();
670
        ID3D11Device_Release(state->device);
671
        HeapFree(GetProcessHeap(), 0, state);
672 673 674 675 676
    }

    return refcount;
}

677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
static void STDMETHODCALLTYPE d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState *iface,
        ID3D11Device **device)
{
    struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface);

    TRACE("iface %p, device %p.\n", iface, device);

    *device = state->device;
    ID3D11Device_AddRef(*device);
}

static HRESULT STDMETHODCALLTYPE d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState *iface,
        REFGUID guid, UINT *data_size, void *data)
{
    struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface);

    TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);

    return d3d_get_private_data(&state->private_store, guid, data_size, data);
}

static HRESULT STDMETHODCALLTYPE d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState *iface,
        REFGUID guid, UINT data_size, const void *data)
{
    struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface);

    TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);

    return d3d_set_private_data(&state->private_store, guid, data_size, data);
}

static HRESULT STDMETHODCALLTYPE d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState *iface,
        REFGUID guid, const IUnknown *data)
{
    struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface);

    TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);

    return d3d_set_private_data_interface(&state->private_store, guid, data);
}

static void STDMETHODCALLTYPE d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState *iface,
        D3D11_RASTERIZER_DESC *desc)
{
721 722 723 724 725
    struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface);

    TRACE("iface %p, desc %p.\n", iface, desc);

    *desc = state->desc;
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779
}

static const struct ID3D11RasterizerStateVtbl d3d11_rasterizer_state_vtbl =
{
    /* IUnknown methods */
    d3d11_rasterizer_state_QueryInterface,
    d3d11_rasterizer_state_AddRef,
    d3d11_rasterizer_state_Release,
    /* ID3D11DeviceChild methods */
    d3d11_rasterizer_state_GetDevice,
    d3d11_rasterizer_state_GetPrivateData,
    d3d11_rasterizer_state_SetPrivateData,
    d3d11_rasterizer_state_SetPrivateDataInterface,
    /* ID3D11RasterizerState methods */
    d3d11_rasterizer_state_GetDesc,
};

/* ID3D10RasterizerState methods */

static inline struct d3d_rasterizer_state *impl_from_ID3D10RasterizerState(ID3D10RasterizerState *iface)
{
    return CONTAINING_RECORD(iface, struct d3d_rasterizer_state, ID3D10RasterizerState_iface);
}

/* IUnknown methods */

static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState *iface,
        REFIID riid, void **object)
{
    struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);

    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);

    return d3d11_rasterizer_state_QueryInterface(&state->ID3D11RasterizerState_iface, riid, object);
}

static ULONG STDMETHODCALLTYPE d3d10_rasterizer_state_AddRef(ID3D10RasterizerState *iface)
{
    struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);

    TRACE("iface %p.\n", iface);

    return d3d11_rasterizer_state_AddRef(&state->ID3D11RasterizerState_iface);
}

static ULONG STDMETHODCALLTYPE d3d10_rasterizer_state_Release(ID3D10RasterizerState *iface)
{
    struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);

    TRACE("iface %p.\n", state);

    return d3d11_rasterizer_state_Release(&state->ID3D11RasterizerState_iface);
}

780 781 782 783
/* ID3D10DeviceChild methods */

static void STDMETHODCALLTYPE d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState *iface, ID3D10Device **device)
{
784
    struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);
785 786 787

    TRACE("iface %p, device %p.\n", iface, device);

788
    ID3D11Device_QueryInterface(state->device, &IID_ID3D10Device, (void **)device);
789 790 791 792 793
}

static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState *iface,
        REFGUID guid, UINT *data_size, void *data)
{
794
    struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);
795 796

    TRACE("iface %p, guid %s, data_size %p, data %p.\n",
797 798
            iface, debugstr_guid(guid), data_size, data);

799
    return d3d_get_private_data(&state->private_store, guid, data_size, data);
800 801 802 803 804
}

static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState *iface,
        REFGUID guid, UINT data_size, const void *data)
{
805
    struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);
806 807

    TRACE("iface %p, guid %s, data_size %u, data %p.\n",
808 809
            iface, debugstr_guid(guid), data_size, data);

810
    return d3d_set_private_data(&state->private_store, guid, data_size, data);
811 812 813 814 815
}

static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState *iface,
        REFGUID guid, const IUnknown *data)
{
816
    struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);
817

818 819
    TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);

820
    return d3d_set_private_data_interface(&state->private_store, guid, data);
821 822 823 824 825 826 827
}

/* ID3D10RasterizerState methods */

static void STDMETHODCALLTYPE d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState *iface,
        D3D10_RASTERIZER_DESC *desc)
{
828
    struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);
829 830 831

    TRACE("iface %p, desc %p.\n", iface, desc);

832
    memcpy(desc, &state->desc, sizeof(*desc));
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
}

static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl =
{
    /* IUnknown methods */
    d3d10_rasterizer_state_QueryInterface,
    d3d10_rasterizer_state_AddRef,
    d3d10_rasterizer_state_Release,
    /* ID3D10DeviceChild methods */
    d3d10_rasterizer_state_GetDevice,
    d3d10_rasterizer_state_GetPrivateData,
    d3d10_rasterizer_state_SetPrivateData,
    d3d10_rasterizer_state_SetPrivateDataInterface,
    /* ID3D10RasterizerState methods */
    d3d10_rasterizer_state_GetDesc,
};

850
HRESULT d3d_rasterizer_state_init(struct d3d_rasterizer_state *state, struct d3d_device *device,
851
        const D3D11_RASTERIZER_DESC *desc)
852
{
853 854 855
    struct wined3d_rasterizer_state_desc wined3d_desc;
    HRESULT hr;

856
    state->ID3D11RasterizerState_iface.lpVtbl = &d3d11_rasterizer_state_vtbl;
857
    state->ID3D10RasterizerState_iface.lpVtbl = &d3d10_rasterizer_state_vtbl;
858
    state->refcount = 1;
859
    wined3d_mutex_lock();
860
    wined3d_private_store_init(&state->private_store);
861
    state->desc = *desc;
862

863 864 865 866 867 868 869 870 871 872
    wined3d_desc.front_ccw = desc->FrontCounterClockwise;
    if (FAILED(hr = wined3d_rasterizer_state_create(device->wined3d_device,
            &wined3d_desc, &state->wined3d_state)))
    {
        WARN("Failed to create wined3d rasterizer state, hr %#x.\n", hr);
        wined3d_private_store_cleanup(&state->private_store);
        wined3d_mutex_unlock();
        return hr;
    }

873 874 875
    if (wine_rb_put(&device->rasterizer_states, desc, &state->entry) == -1)
    {
        ERR("Failed to insert rasterizer state entry.\n");
876
        wined3d_private_store_cleanup(&state->private_store);
877
        wined3d_rasterizer_state_decref(state->wined3d_state);
878
        wined3d_mutex_unlock();
879 880
        return E_FAIL;
    }
881
    wined3d_mutex_unlock();
882

883
    ID3D11Device_AddRef(state->device = &device->ID3D11Device_iface);
884

885 886
    return S_OK;
}
887

888 889 890 891 892 893 894 895 896
struct d3d_rasterizer_state *unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState *iface)
{
    if (!iface)
        return NULL;
    assert(iface->lpVtbl == &d3d11_rasterizer_state_vtbl);

    return impl_from_ID3D11RasterizerState(iface);
}

897
struct d3d_rasterizer_state *unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState *iface)
898 899 900 901 902 903 904 905
{
    if (!iface)
        return NULL;
    assert(iface->lpVtbl == &d3d10_rasterizer_state_vtbl);

    return impl_from_ID3D10RasterizerState(iface);
}

906 907 908
/* ID3D11SampleState methods */

static inline struct d3d_sampler_state *impl_from_ID3D11SamplerState(ID3D11SamplerState *iface)
909
{
910
    return CONTAINING_RECORD(iface, struct d3d_sampler_state, ID3D11SamplerState_iface);
911 912
}

913
static HRESULT STDMETHODCALLTYPE d3d11_sampler_state_QueryInterface(ID3D11SamplerState *iface,
914 915
        REFIID riid, void **object)
{
916 917
    struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface);

918 919
    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);

920 921
    if (IsEqualGUID(riid, &IID_ID3D11SamplerState)
            || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
922 923
            || IsEqualGUID(riid, &IID_IUnknown))
    {
924
        ID3D11SamplerState_AddRef(iface);
925 926 927 928
        *object = iface;
        return S_OK;
    }

929 930 931 932 933 934 935 936
    if (IsEqualGUID(riid, &IID_ID3D10SamplerState)
            || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
    {
        ID3D10SamplerState_AddRef(&state->ID3D10SamplerState_iface);
        *object = &state->ID3D10SamplerState_iface;
        return S_OK;
    }

937 938 939 940 941 942
    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));

    *object = NULL;
    return E_NOINTERFACE;
}

943
static ULONG STDMETHODCALLTYPE d3d11_sampler_state_AddRef(ID3D11SamplerState *iface)
944
{
945 946
    struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface);
    ULONG refcount = InterlockedIncrement(&state->refcount);
947

948
    TRACE("%p increasing refcount to %u.\n", state, refcount);
949 950 951 952

    return refcount;
}

953
static ULONG STDMETHODCALLTYPE d3d11_sampler_state_Release(ID3D11SamplerState *iface)
954
{
955
    struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface);
956
    ULONG refcount = InterlockedDecrement(&state->refcount);
957

958
    TRACE("%p decreasing refcount to %u.\n", state, refcount);
959 960 961

    if (!refcount)
    {
962
        struct d3d_device *device = impl_from_ID3D11Device(state->device);
963

964
        wined3d_mutex_lock();
965
        wined3d_sampler_decref(state->wined3d_sampler);
966
        wine_rb_remove(&device->sampler_states, &state->entry);
967
        ID3D11Device_Release(state->device);
968
        wined3d_private_store_cleanup(&state->private_store);
969
        wined3d_mutex_unlock();
970
        HeapFree(GetProcessHeap(), 0, state);
971 972 973 974 975
    }

    return refcount;
}

976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
static void STDMETHODCALLTYPE d3d11_sampler_state_GetDevice(ID3D11SamplerState *iface,
        ID3D11Device **device)
{
    struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface);

    TRACE("iface %p, device %p.\n", iface, device);

    *device = state->device;
    ID3D11Device_AddRef(*device);
}

static HRESULT STDMETHODCALLTYPE d3d11_sampler_state_GetPrivateData(ID3D11SamplerState *iface,
        REFGUID guid, UINT *data_size, void *data)
{
    struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface);

    TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);

    return d3d_get_private_data(&state->private_store, guid, data_size, data);
}

static HRESULT STDMETHODCALLTYPE d3d11_sampler_state_SetPrivateData(ID3D11SamplerState *iface,
        REFGUID guid, UINT data_size, const void *data)
{
    struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface);

    TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);

    return d3d_set_private_data(&state->private_store, guid, data_size, data);
}

static HRESULT STDMETHODCALLTYPE d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState *iface,
        REFGUID guid, const IUnknown *data)
{
    struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface);

    TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);

    return d3d_set_private_data_interface(&state->private_store, guid, data);
}

static void STDMETHODCALLTYPE d3d11_sampler_state_GetDesc(ID3D11SamplerState *iface,
        D3D11_SAMPLER_DESC *desc)
{
1020 1021 1022 1023 1024
    struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface);

    TRACE("iface %p, desc %p.\n", iface, desc);

    *desc = state->desc;
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
}

static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl =
{
    /* IUnknown methods */
    d3d11_sampler_state_QueryInterface,
    d3d11_sampler_state_AddRef,
    d3d11_sampler_state_Release,
    /* ID3D11DeviceChild methods */
    d3d11_sampler_state_GetDevice,
    d3d11_sampler_state_GetPrivateData,
    d3d11_sampler_state_SetPrivateData,
    d3d11_sampler_state_SetPrivateDataInterface,
    /* ID3D11SamplerState methods */
    d3d11_sampler_state_GetDesc,
};

/* ID3D10SamplerState methods */

static inline struct d3d_sampler_state *impl_from_ID3D10SamplerState(ID3D10SamplerState *iface)
{
    return CONTAINING_RECORD(iface, struct d3d_sampler_state, ID3D10SamplerState_iface);
}

/* IUnknown methods */

static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_QueryInterface(ID3D10SamplerState *iface,
        REFIID riid, void **object)
{
    struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface);

    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);

    return d3d11_sampler_state_QueryInterface(&state->ID3D11SamplerState_iface, riid, object);
}

static ULONG STDMETHODCALLTYPE d3d10_sampler_state_AddRef(ID3D10SamplerState *iface)
{
    struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface);

    TRACE("iface %p.\n", iface);

    return d3d11_sampler_state_AddRef(&state->ID3D11SamplerState_iface);
}

static ULONG STDMETHODCALLTYPE d3d10_sampler_state_Release(ID3D10SamplerState *iface)
{
    struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface);

    TRACE("iface %p.\n", iface);

    return d3d11_sampler_state_Release(&state->ID3D11SamplerState_iface);
}

1079 1080 1081 1082
/* ID3D10DeviceChild methods */

static void STDMETHODCALLTYPE d3d10_sampler_state_GetDevice(ID3D10SamplerState *iface, ID3D10Device **device)
{
1083
    struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface);
1084 1085 1086

    TRACE("iface %p, device %p.\n", iface, device);

1087
    ID3D11Device_QueryInterface(state->device, &IID_ID3D10Device, (void **)device);
1088 1089 1090 1091 1092
}

static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_GetPrivateData(ID3D10SamplerState *iface,
        REFGUID guid, UINT *data_size, void *data)
{
1093
    struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface);
1094 1095

    TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1096 1097
            iface, debugstr_guid(guid), data_size, data);

1098
    return d3d_get_private_data(&state->private_store, guid, data_size, data);
1099 1100 1101 1102 1103
}

static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_SetPrivateData(ID3D10SamplerState *iface,
        REFGUID guid, UINT data_size, const void *data)
{
1104
    struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface);
1105 1106

    TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1107 1108
            iface, debugstr_guid(guid), data_size, data);

1109
    return d3d_set_private_data(&state->private_store, guid, data_size, data);
1110 1111 1112 1113 1114
}

static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState *iface,
        REFGUID guid, const IUnknown *data)
{
1115
    struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface);
1116

1117 1118
    TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);

1119
    return d3d_set_private_data_interface(&state->private_store, guid, data);
1120 1121 1122 1123 1124 1125 1126
}

/* ID3D10SamplerState methods */

static void STDMETHODCALLTYPE d3d10_sampler_state_GetDesc(ID3D10SamplerState *iface,
        D3D10_SAMPLER_DESC *desc)
{
1127
    struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface);
1128 1129 1130

    TRACE("iface %p, desc %p.\n", iface, desc);

1131
    memcpy(desc, &state->desc, sizeof(*desc));
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
}

static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl =
{
    /* IUnknown methods */
    d3d10_sampler_state_QueryInterface,
    d3d10_sampler_state_AddRef,
    d3d10_sampler_state_Release,
    /* ID3D10DeviceChild methods */
    d3d10_sampler_state_GetDevice,
    d3d10_sampler_state_GetPrivateData,
    d3d10_sampler_state_SetPrivateData,
    d3d10_sampler_state_SetPrivateDataInterface,
    /* ID3D10SamplerState methods */
    d3d10_sampler_state_GetDesc,
};

1149
static enum wined3d_texture_address wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t)
1150 1151 1152 1153
{
    return (enum wined3d_texture_address)t;
}

1154
static enum wined3d_texture_filter_type wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f)
1155
{
1156
    if (D3D11_DECODE_MIP_FILTER(f) == D3D11_FILTER_TYPE_LINEAR)
1157 1158 1159 1160
        return WINED3D_TEXF_LINEAR;
    return WINED3D_TEXF_POINT;
}

1161
static enum wined3d_texture_filter_type wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f)
1162
{
1163
    if (D3D11_DECODE_MAG_FILTER(f) == D3D11_FILTER_TYPE_LINEAR)
1164 1165 1166 1167
        return WINED3D_TEXF_LINEAR;
    return WINED3D_TEXF_POINT;
}

1168
static enum wined3d_texture_filter_type wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f)
1169
{
1170
    if (D3D11_DECODE_MIN_FILTER(f) == D3D11_FILTER_TYPE_LINEAR)
1171 1172 1173 1174
        return WINED3D_TEXF_LINEAR;
    return WINED3D_TEXF_POINT;
}

1175
static BOOL wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f)
1176
{
1177
    return D3D11_DECODE_IS_COMPARISON_FILTER(f);
1178 1179
}

1180
static enum wined3d_cmp_func wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC f)
1181 1182 1183 1184
{
    return (enum wined3d_cmp_func)f;
}

1185
HRESULT d3d_sampler_state_init(struct d3d_sampler_state *state, struct d3d_device *device,
1186
        const D3D11_SAMPLER_DESC *desc)
1187
{
1188
    struct wined3d_sampler_desc wined3d_desc;
1189 1190
    HRESULT hr;

1191
    state->ID3D11SamplerState_iface.lpVtbl = &d3d11_sampler_state_vtbl;
1192
    state->ID3D10SamplerState_iface.lpVtbl = &d3d10_sampler_state_vtbl;
1193
    state->refcount = 1;
1194
    wined3d_mutex_lock();
1195
    wined3d_private_store_init(&state->private_store);
1196
    state->desc = *desc;
1197

1198 1199 1200
    wined3d_desc.address_u = wined3d_texture_address_from_d3d11(desc->AddressU);
    wined3d_desc.address_v = wined3d_texture_address_from_d3d11(desc->AddressV);
    wined3d_desc.address_w = wined3d_texture_address_from_d3d11(desc->AddressW);
1201
    memcpy(wined3d_desc.border_color, desc->BorderColor, sizeof(wined3d_desc.border_color));
1202 1203 1204
    wined3d_desc.mag_filter = wined3d_texture_filter_mag_from_d3d11(desc->Filter);
    wined3d_desc.min_filter = wined3d_texture_filter_min_from_d3d11(desc->Filter);
    wined3d_desc.mip_filter = wined3d_texture_filter_mip_from_d3d11(desc->Filter);
1205 1206 1207
    wined3d_desc.lod_bias = desc->MipLODBias;
    wined3d_desc.min_lod = desc->MinLOD;
    wined3d_desc.max_lod = desc->MaxLOD;
1208 1209 1210
    wined3d_desc.max_anisotropy = D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc->Filter) ? desc->MaxAnisotropy : 1;
    wined3d_desc.compare = wined3d_texture_compare_from_d3d11(desc->Filter);
    wined3d_desc.comparison_func = wined3d_cmp_func_from_d3d11(desc->ComparisonFunc);
1211
    wined3d_desc.srgb_decode = TRUE;
1212

1213
    if (FAILED(hr = wined3d_sampler_create(device->wined3d_device, &wined3d_desc, state, &state->wined3d_sampler)))
1214 1215
    {
        WARN("Failed to create wined3d sampler, hr %#x.\n", hr);
1216
        wined3d_private_store_cleanup(&state->private_store);
1217
        wined3d_mutex_unlock();
1218 1219 1220
        return hr;
    }

1221 1222 1223 1224
    if (wine_rb_put(&device->sampler_states, desc, &state->entry) == -1)
    {
        ERR("Failed to insert sampler state entry.\n");
        wined3d_sampler_decref(state->wined3d_sampler);
1225
        wined3d_private_store_cleanup(&state->private_store);
1226
        wined3d_mutex_unlock();
1227 1228
        return E_FAIL;
    }
1229
    wined3d_mutex_unlock();
1230

1231 1232
    state->device = &device->ID3D11Device_iface;
    ID3D11Device_AddRef(state->device);
1233

1234 1235
    return S_OK;
}
1236

1237 1238 1239 1240 1241 1242 1243 1244 1245
struct d3d_sampler_state *unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState *iface)
{
    if (!iface)
        return NULL;
    assert(iface->lpVtbl == &d3d11_sampler_state_vtbl);

    return impl_from_ID3D11SamplerState(iface);
}

1246
struct d3d_sampler_state *unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState *iface)
1247 1248 1249 1250 1251 1252 1253
{
    if (!iface)
        return NULL;
    assert(iface->lpVtbl == &d3d10_sampler_state_vtbl);

    return impl_from_ID3D10SamplerState(iface);
}