diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index a4e29e241f7..ffc4e34a698 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -246,9 +246,12 @@ struct d3d10_sampler_state { ID3D10SamplerState ID3D10SamplerState_iface; LONG refcount; + + struct wined3d_sampler *wined3d_sampler; }; HRESULT d3d10_sampler_state_init(struct d3d10_sampler_state *state) DECLSPEC_HIDDEN; +struct d3d10_sampler_state *unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState *iface) DECLSPEC_HIDDEN; /* ID3D10Query */ struct d3d10_query diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 03c1e676084..1a75ee57fb1 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -327,8 +327,19 @@ static void STDMETHODCALLTYPE d3d10_device_VSSetShaderResources(ID3D10Device *if static void STDMETHODCALLTYPE d3d10_device_VSSetSamplers(ID3D10Device *iface, UINT start_slot, UINT sampler_count, ID3D10SamplerState *const *samplers) { - FIXME("iface %p, start_slot %u, sampler_count %u, samplers %p stub!\n", + struct d3d10_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers); + + for (i = 0; i < sampler_count; ++i) + { + struct d3d10_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]); + + wined3d_device_set_vs_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } } static void STDMETHODCALLTYPE d3d10_device_SetPredication(ID3D10Device *iface, ID3D10Predicate *predicate, BOOL value) diff --git a/dlls/d3d10core/state.c b/dlls/d3d10core/state.c index 9e64ea65b49..c1018f88419 100644 --- a/dlls/d3d10core/state.c +++ b/dlls/d3d10core/state.c @@ -445,6 +445,7 @@ static ULONG STDMETHODCALLTYPE d3d10_sampler_state_Release(ID3D10SamplerState *i if (!refcount) { + wined3d_sampler_decref(This->wined3d_sampler); HeapFree(GetProcessHeap(), 0, This); } @@ -509,8 +510,25 @@ static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl = HRESULT d3d10_sampler_state_init(struct d3d10_sampler_state *state) { + HRESULT hr; + state->ID3D10SamplerState_iface.lpVtbl = &d3d10_sampler_state_vtbl; state->refcount = 1; + if (FAILED(hr = wined3d_sampler_create(state, &state->wined3d_sampler))) + { + WARN("Failed to create wined3d sampler, hr %#x.\n", hr); + return hr; + } + return S_OK; } + +struct d3d10_sampler_state *unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_sampler_state_vtbl); + + return impl_from_ID3D10SamplerState(iface); +} diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in index f708913282f..b1051c27116 100644 --- a/dlls/wined3d/Makefile.in +++ b/dlls/wined3d/Makefile.in @@ -16,6 +16,7 @@ C_SRCS = \ palette.c \ query.c \ resource.c \ + sampler.c \ shader.c \ shader_sm1.c \ shader_sm4.c \ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index fd1de1b8af3..d0c36383877 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2584,6 +2584,27 @@ struct wined3d_buffer * CDECL wined3d_device_get_vs_cb(const struct wined3d_devi return device->stateBlock->state.vs_cb[idx]; } +void CDECL wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler) +{ + struct wined3d_sampler *prev; + + TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); + + if (idx >= MAX_SAMPLER_OBJECTS) + { + WARN("Invalid sampler index %u.\n", idx); + return; + } + + prev = device->updateStateBlock->state.vs_sampler[idx]; + device->updateStateBlock->state.vs_sampler[idx] = sampler; + + if (sampler) + wined3d_sampler_incref(sampler); + if (prev) + wined3d_sampler_decref(prev); +} + HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device, UINT start_register, const BOOL *constants, UINT bool_count) { diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c new file mode 100644 index 00000000000..1156d2ad0f9 --- /dev/null +++ b/dlls/wined3d/sampler.c @@ -0,0 +1,79 @@ +/* + * Copyright 2012 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" + +#include "wined3d_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d); + +ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler) +{ + ULONG refcount = InterlockedIncrement(&sampler->refcount); + + TRACE("%p increasing refcount to %u.\n", sampler, refcount); + + return refcount; +} + +ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) +{ + ULONG refcount = InterlockedDecrement(&sampler->refcount); + + TRACE("%p decreasing refcount to %u.\n", sampler, refcount); + + if (!refcount) + HeapFree(GetProcessHeap(), 0, sampler); + + return refcount; +} + +void * CDECL wined3d_sampler_get_parent(const struct wined3d_sampler *sampler) +{ + TRACE("sampler %p.\n", sampler); + + return sampler->parent; +} + +static void wined3d_sampler_init(struct wined3d_sampler *sampler, void *parent) +{ + sampler->refcount = 1; + sampler->parent = parent; +} + +HRESULT CDECL wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler) +{ + struct wined3d_sampler *object; + + TRACE("parent %p, sampler %p.\n", parent, sampler); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + { + ERR("Failed to allocate memory.\n"); + return E_OUTOFMEMORY; + } + + wined3d_sampler_init(object, parent); + + TRACE("Created sampler %p.\n", object); + *sampler = object; + + return WINED3D_OK; +} diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 518ae2a2bb9..0b55f181812 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -471,6 +471,7 @@ void stateblock_unbind_resources(struct wined3d_stateblock *stateblock) { struct wined3d_state *state = &stateblock->state; struct wined3d_vertex_declaration *decl; + struct wined3d_sampler *sampler; struct wined3d_texture *texture; struct wined3d_buffer *buffer; struct wined3d_shader *shader; @@ -530,6 +531,15 @@ void stateblock_unbind_resources(struct wined3d_stateblock *stateblock) } } + for (i = 0; i < MAX_SAMPLER_OBJECTS; ++i) + { + if ((sampler = state->vs_sampler[i])) + { + state->vs_sampler[i] = NULL; + wined3d_sampler_decref(sampler); + } + } + if ((shader = state->geometry_shader)) { state->geometry_shader = NULL; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index f94057db417..29d6740d405 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -149,6 +149,7 @@ @ cdecl wined3d_device_set_vs_consts_b(ptr long ptr long) @ cdecl wined3d_device_set_vs_consts_f(ptr long ptr long) @ cdecl wined3d_device_set_vs_consts_i(ptr long ptr long) +@ cdecl wined3d_device_set_vs_sampler(ptr long ptr); @ cdecl wined3d_device_setup_fullscreen_window(ptr ptr long long) @ cdecl wined3d_device_show_cursor(ptr long) @ cdecl wined3d_device_uninit_3d(ptr) @@ -185,6 +186,11 @@ @ cdecl wined3d_rendertarget_view_get_resource(ptr) @ cdecl wined3d_rendertarget_view_incref(ptr) +@ cdecl wined3d_sampler_create(ptr ptr) +@ cdecl wined3d_sampler_decref(ptr) +@ cdecl wined3d_sampler_get_parent(ptr) +@ cdecl wined3d_sampler_incref(ptr) + @ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr ptr long) @ cdecl wined3d_shader_create_ps(ptr ptr ptr ptr ptr ptr long) @ cdecl wined3d_shader_create_vs(ptr ptr ptr ptr ptr ptr long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f0c44eb5d6e..c3470687482 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -163,6 +163,7 @@ void wined3d_rb_free(void *ptr) DECLSPEC_HIDDEN; #define MAX_ACTIVE_LIGHTS 8 #define MAX_CLIPPLANES WINED3DMAXUSERCLIPPLANES #define MAX_CONSTANT_BUFFERS 15 +#define MAX_SAMPLER_OBJECTS 16 struct min_lookup { @@ -2210,6 +2211,12 @@ enum wined3d_conversion_type void d3dfmt_p8_init_palette(const struct wined3d_surface *surface, BYTE table[256][4], BOOL colorkey) DECLSPEC_HIDDEN; +struct wined3d_sampler +{ + LONG refcount; + void *parent; +}; + struct wined3d_vertex_declaration_element { const struct wined3d_format *format; @@ -2301,6 +2308,7 @@ struct wined3d_state struct wined3d_shader *vertex_shader; struct wined3d_buffer *vs_cb[MAX_CONSTANT_BUFFERS]; + struct wined3d_sampler *vs_sampler[MAX_SAMPLER_OBJECTS]; BOOL vs_consts_b[MAX_CONST_B]; INT vs_consts_i[MAX_CONST_I * 4]; float *vs_consts_f; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 258c926814b..90fb8de9241 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1981,6 +1981,7 @@ struct wined3d_palette; struct wined3d_query; struct wined3d_rendertarget_view; struct wined3d_resource; +struct wined3d_sampler; struct wined3d_shader; struct wined3d_stateblock; struct wined3d_surface; @@ -2256,6 +2257,7 @@ HRESULT __cdecl wined3d_device_set_vs_consts_f(struct wined3d_device *device, UINT start_register, const float *constants, UINT vector4f_count); HRESULT __cdecl wined3d_device_set_vs_consts_i(struct wined3d_device *device, UINT start_register, const int *constants, UINT vector4i_count); +void __cdecl wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler); void __cdecl wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, UINT w, UINT h); BOOL __cdecl wined3d_device_show_cursor(struct wined3d_device *device, BOOL show); HRESULT __cdecl wined3d_device_uninit_3d(struct wined3d_device *device); @@ -2302,6 +2304,11 @@ void * __cdecl wined3d_rendertarget_view_get_parent(const struct wined3d_rendert struct wined3d_resource * __cdecl wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view); ULONG __cdecl wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view); +HRESULT __cdecl wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler); +ULONG __cdecl wined3d_sampler_decref(struct wined3d_sampler *sampler); +void * __cdecl wined3d_sampler_get_parent(const struct wined3d_sampler *sampler); +ULONG __cdecl wined3d_sampler_incref(struct wined3d_sampler *sampler); + HRESULT __cdecl wined3d_shader_create_gs(struct wined3d_device *device, const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);