Henri Verbeet : wined3d: Send texture binding updates through the command stream.

Alexandre Julliard julliard at winehq.org
Thu Oct 3 15:18:01 CDT 2013


Module: wine
Branch: master
Commit: 052a86301080912e79b5316d69d30f0ab508a0f4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=052a86301080912e79b5316d69d30f0ab508a0f4

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Thu Oct  3 08:54:13 2013 +0200

wined3d: Send texture binding updates through the command stream.

---

 dlls/wined3d/cs.c              |   78 ++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/device.c          |   63 +-------------------------------
 dlls/wined3d/wined3d_private.h |    1 +
 3 files changed, 81 insertions(+), 61 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 0f060b4..176f36b 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -36,6 +36,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_SET_STREAM_SOURCE,
     WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ,
     WINED3D_CS_OP_SET_INDEX_BUFFER,
+    WINED3D_CS_OP_SET_TEXTURE,
 };
 
 struct wined3d_cs_present
@@ -125,6 +126,13 @@ struct wined3d_cs_set_index_buffer
     enum wined3d_format_id format_id;
 };
 
+struct wined3d_cs_set_texture
+{
+    enum wined3d_cs_op opcode;
+    UINT stage;
+    struct wined3d_texture *texture;
+};
+
 static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_present *op = data;
@@ -427,6 +435,75 @@ void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buff
     cs->ops->submit(cs);
 }
 
+static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info;
+    const struct wined3d_cs_set_texture *op = data;
+    struct wined3d_texture *prev;
+
+    prev = cs->state.textures[op->stage];
+    cs->state.textures[op->stage] = op->texture;
+
+    if (op->texture)
+    {
+        if (InterlockedIncrement(&op->texture->resource.bind_count) == 1)
+            op->texture->sampler = op->stage;
+
+        if (!prev || op->texture->target != prev->target)
+            device_invalidate_state(cs->device, STATE_PIXELSHADER);
+
+        if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
+        {
+            /* The source arguments for color and alpha ops have different
+             * meanings when a NULL texture is bound, so the COLOR_OP and
+             * ALPHA_OP have to be dirtified. */
+            device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
+            device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
+        }
+    }
+
+    if (prev)
+    {
+        if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage)
+        {
+            unsigned int i;
+
+            /* Search for other stages the texture is bound to. Shouldn't
+             * happen if applications bind textures to a single stage only. */
+            TRACE("Searching for other stages the texture is bound to.\n");
+            for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
+            {
+                if (cs->state.textures[i] == prev)
+                {
+                    TRACE("Texture is also bound to stage %u.\n", i);
+                    prev->sampler = i;
+                    break;
+                }
+            }
+        }
+
+        if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages)
+        {
+            device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
+            device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
+        }
+    }
+
+    device_invalidate_state(cs->device, STATE_SAMPLER(op->stage));
+}
+
+void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture)
+{
+    struct wined3d_cs_set_texture *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op));
+    op->opcode = WINED3D_CS_OP_SET_TEXTURE;
+    op->stage = stage;
+    op->texture = texture;
+
+    cs->ops->submit(cs);
+}
+
 static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
 {
     /* WINED3D_CS_OP_PRESENT                */ wined3d_cs_exec_present,
@@ -440,6 +517,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_SET_STREAM_SOURCE      */ wined3d_cs_exec_set_stream_source,
     /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq,
     /* WINED3D_CS_OP_SET_INDEX_BUFFER       */ wined3d_cs_exec_set_index_buffer,
+    /* WINED3D_CS_OP_SET_TEXTURE            */ wined3d_cs_exec_set_texture,
 };
 
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index acca498..0c2f3e8 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3164,7 +3164,6 @@ DWORD CDECL wined3d_device_get_texture_stage_state(const struct wined3d_device *
 HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device,
         UINT stage, struct wined3d_texture *texture)
 {
-    const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
     struct wined3d_texture *prev;
 
     TRACE("device %p, stage %u, texture %p.\n", device, stage, texture);
@@ -3200,70 +3199,12 @@ HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device,
     TRACE("Setting new texture to %p.\n", texture);
     device->update_state->textures[stage] = texture;
 
-    if (device->recording)
-    {
-        TRACE("Recording... not performing anything\n");
-
-        if (texture) wined3d_texture_incref(texture);
-        if (prev) wined3d_texture_decref(prev);
-
-        return WINED3D_OK;
-    }
-
     if (texture)
-    {
-        LONG bind_count = InterlockedIncrement(&texture->resource.bind_count);
-
         wined3d_texture_incref(texture);
-
-        if (!prev || texture->target != prev->target)
-            device_invalidate_state(device, STATE_PIXELSHADER);
-
-        if (!prev && stage < d3d_info->limits.ffp_blend_stages)
-        {
-            /* The source arguments for color and alpha ops have different
-             * meanings when a NULL texture is bound, so the COLOR_OP and
-             * ALPHA_OP have to be dirtified. */
-            device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP));
-            device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP));
-        }
-
-        if (bind_count == 1)
-            texture->sampler = stage;
-    }
-
+    if (!device->recording)
+        wined3d_cs_emit_set_texture(device->cs, stage, texture);
     if (prev)
-    {
-        LONG bind_count = InterlockedDecrement(&prev->resource.bind_count);
-
-        if (!texture && stage < d3d_info->limits.ffp_blend_stages)
-        {
-            device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP));
-            device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP));
-        }
-
-        if (bind_count && prev->sampler == stage)
-        {
-            unsigned int i;
-
-            /* Search for other stages the texture is bound to. Shouldn't
-             * happen if applications bind textures to a single stage only. */
-            TRACE("Searching for other stages the texture is bound to.\n");
-            for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
-            {
-                if (device->update_state->textures[i] == prev)
-                {
-                    TRACE("Texture is also bound to stage %u.\n", i);
-                    prev->sampler = i;
-                    break;
-                }
-            }
-        }
-
         wined3d_texture_decref(prev);
-    }
-
-    device_invalidate_state(device, STATE_SAMPLER(stage));
 
     return WINED3D_OK;
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 45ead88..6cde5b0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2496,6 +2496,7 @@ void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx,
         struct wined3d_buffer *buffer, UINT offset, UINT stride) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx,
         UINT frequency, UINT flags) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs,
         struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list