[PATCH 2/2] wined3d: Check map queue when executing command lists.
Jan Sikorski
jsikorski at codeweavers.com
Wed Mar 23 11:31:59 CDT 2022
Increases performance of The Evil Within, and possibly other games that
render using command lists and map resources in the meantime.
Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
---
dlls/wined3d/cs.c | 109 +++++++++++++++++++++++++++-------------------
1 file changed, 63 insertions(+), 46 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 9edb002ec9e..63d6ed4c123 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -2872,27 +2872,6 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
/* WINED3D_CS_OP_EXECUTE_COMMAND_LIST */ wined3d_cs_exec_execute_command_list,
};
-static void wined3d_cs_exec_execute_command_list(struct wined3d_cs *cs, const void *data)
-{
- const struct wined3d_cs_execute_command_list *op = data;
- SIZE_T start = 0, end = op->list->data_size;
- const BYTE *cs_data = op->list->data;
-
- TRACE("Executing command list %p.\n", op->list);
-
- while (start < end)
- {
- const struct wined3d_cs_packet *packet = wined3d_next_cs_packet(cs_data, &start, WINED3D_CS_QUEUE_MASK);
- enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)packet->data;
-
- if (opcode >= WINED3D_CS_OP_STOP)
- ERR("Invalid opcode %#x.\n", opcode);
- else
- wined3d_cs_op_handlers[opcode](cs, packet->data);
- TRACE("%s executed.\n", debug_cs_op(opcode));
- }
-}
-
void wined3d_device_context_emit_execute_command_list(struct wined3d_device_context *context,
struct wined3d_command_list *list, bool restore_state)
{
@@ -3303,16 +3282,74 @@ static void wined3d_cs_command_unlock(const struct wined3d_cs *cs)
LeaveCriticalSection(&wined3d_command_cs);
}
-static DWORD WINAPI wined3d_cs_run(void *ctx)
+static inline bool wined3d_cs_execute_next(struct wined3d_cs *cs, struct wined3d_cs_queue *queue)
{
struct wined3d_cs_packet *packet;
+ enum wined3d_cs_op opcode;
+ SIZE_T tail;
+
+ tail = queue->tail;
+ packet = wined3d_next_cs_packet(queue->data, &tail, WINED3D_CS_QUEUE_MASK);
+
+ if (packet->size)
+ {
+ opcode = *(const enum wined3d_cs_op *)packet->data;
+
+ TRACE("Executing %s at %p.\n", debug_cs_op(opcode), packet);
+ if (opcode >= WINED3D_CS_OP_STOP)
+ {
+ if (opcode > WINED3D_CS_OP_STOP)
+ ERR("Invalid opcode %#x.\n", opcode);
+ return false;
+ }
+
+ wined3d_cs_command_lock(cs);
+ wined3d_cs_op_handlers[opcode](cs, packet->data);
+ wined3d_cs_command_unlock(cs);
+ TRACE("%s at %p executed.\n", debug_cs_op(opcode), packet);
+ }
+
+ InterlockedExchange((LONG *)&queue->tail, tail);
+ return true;
+}
+
+static void wined3d_cs_exec_execute_command_list(struct wined3d_cs *cs, const void *data)
+{
+ const struct wined3d_cs_execute_command_list *op = data;
+ SIZE_T start = 0, end = op->list->data_size;
+ const BYTE *cs_data = op->list->data;
+ struct wined3d_cs_queue *queue;
+
+ TRACE("Executing command list %p.\n", op->list);
+
+ queue = &cs->queue[WINED3D_CS_QUEUE_MAP];
+ while (start < end)
+ {
+ const struct wined3d_cs_packet *packet;
+ enum wined3d_cs_op opcode;
+
+ while (!wined3d_cs_queue_is_empty(cs, queue))
+ wined3d_cs_execute_next(cs, queue);
+
+ packet = wined3d_next_cs_packet(cs_data, &start, WINED3D_CS_QUEUE_MASK);
+ opcode = *(const enum wined3d_cs_op *)packet->data;
+
+ if (opcode >= WINED3D_CS_OP_STOP)
+ ERR("Invalid opcode %#x.\n", opcode);
+ else
+ wined3d_cs_op_handlers[opcode](cs, packet->data);
+ TRACE("%s executed.\n", debug_cs_op(opcode));
+ }
+}
+
+static DWORD WINAPI wined3d_cs_run(void *ctx)
+{
struct wined3d_cs_queue *queue;
unsigned int spin_count = 0;
struct wined3d_cs *cs = ctx;
- enum wined3d_cs_op opcode;
HMODULE wined3d_module;
unsigned int poll = 0;
- SIZE_T tail;
+ bool run = true;
TRACE("Started.\n");
@@ -3322,7 +3359,7 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
list_init(&cs->query_poll_list);
cs->thread_id = GetCurrentThreadId();
- for (;;)
+ while (run)
{
if (++poll == WINED3D_CS_QUERY_POLL_INTERVAL)
{
@@ -3345,27 +3382,7 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
}
spin_count = 0;
- tail = queue->tail;
- packet = wined3d_next_cs_packet(queue->data, &tail, WINED3D_CS_QUEUE_MASK);
- if (packet->size)
- {
- opcode = *(const enum wined3d_cs_op *)packet->data;
-
- TRACE("Executing %s at %p.\n", debug_cs_op(opcode), packet);
- if (opcode >= WINED3D_CS_OP_STOP)
- {
- if (opcode > WINED3D_CS_OP_STOP)
- ERR("Invalid opcode %#x.\n", opcode);
- break;
- }
-
- wined3d_cs_command_lock(cs);
- wined3d_cs_op_handlers[opcode](cs, packet->data);
- wined3d_cs_command_unlock(cs);
- TRACE("%s at %p executed.\n", debug_cs_op(opcode), packet);
- }
-
- InterlockedExchange((LONG *)&queue->tail, tail);
+ run = wined3d_cs_execute_next(cs, queue);
}
cs->queue[WINED3D_CS_QUEUE_MAP].tail = cs->queue[WINED3D_CS_QUEUE_MAP].head;
--
2.32.0
More information about the wine-devel
mailing list