[PATCH 4/5] d3d10core: Implement d3d10_device_VSSetSamplers().

Henri Verbeet hverbeet at codeweavers.com
Wed Dec 5 14:01:47 CST 2012


---
 dlls/d3d10core/d3d10core_private.h |    3 +
 dlls/d3d10core/device.c            |   13 +++++-
 dlls/d3d10core/state.c             |   19 +++++++++
 dlls/wined3d/Makefile.in           |    1 +
 dlls/wined3d/device.c              |   21 +++++++++
 dlls/wined3d/sampler.c             |   79 ++++++++++++++++++++++++++++++++++++
 dlls/wined3d/stateblock.c          |   10 +++++
 dlls/wined3d/wined3d.spec          |    6 +++
 dlls/wined3d/wined3d_private.h     |    8 ++++
 include/wine/wined3d.h             |    7 +++
 10 files changed, 166 insertions(+), 1 deletions(-)
 create mode 100644 dlls/wined3d/sampler.c

diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h
index a4e29e2..ffc4e34 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 03c1e67..1a75ee5 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 9e64ea6..a7f903f 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,26 @@ 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 f708913..b1051c2 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 fd1de1b..d0c3638 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 0000000..1156d2a
--- /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 518ae2a..0b55f18 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 f94057d..29d6740 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 f0c44eb..c347068 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 258c926..90fb8de 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);
-- 
1.7.8.6




More information about the wine-patches mailing list