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