From: Francisco Casas <fcasas@codeweavers.com> Command stream queues are implemented using a fixed size array. This implementation requires NOP packets to be inserted at the end sometimes, so that these packets can be skipped and the head pointer can be properly move back to the beginning. Furthermore, sometimes it is necessary to insert padding packets that contain zero data (besides the size field), so they don't even have space for the NOP opcode. Their opcode shouldn't be read. Currently it is possible to get trace messages such as this: 0484:trace:d3d:wined3d_cs_queue_submit Queuing op UNKNOWN_OP(0x34) at 06EF1C8C. for these padding packets. In this case the packet was from cs->queue[0] but 0x34 was actually cs->queue[1].size. Depending of the out-of-bounds data, spurious yet valid opcodes could be reported, so we fix that. --- dlls/wined3d/cs.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index add8f8f174e..7b17b1d3557 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -641,6 +641,13 @@ static const char *debug_cs_op(enum wined3d_cs_op op) return wine_dbg_sprintf("UNKNOWN_OP(%#x)", op); } +static const char *debug_cs_packet(const struct wined3d_cs_packet *packet) +{ + if (!packet->size) + return wine_dbg_sprintf("padding at %p", packet); + return wine_dbg_sprintf("op %s at %p", debug_cs_op(*(const enum wined3d_cs_op *)packet->data), packet); +} + static struct wined3d_cs_packet *wined3d_next_cs_packet(const uint8_t *data, SIZE_T *offset, SIZE_T mask) { struct wined3d_cs_packet *packet = (struct wined3d_cs_packet *)&data[*offset & mask]; @@ -3310,7 +3317,7 @@ static void wined3d_cs_queue_submit(struct wined3d_cs_queue *queue, struct wined size_t packet_size; packet = (struct wined3d_cs_packet *)&queue->data[queue->head & WINED3D_CS_QUEUE_MASK]; - TRACE("Queuing op %s at %p.\n", debug_cs_op(*(const enum wined3d_cs_op *)packet->data), packet); + TRACE("Queuing %s.\n", debug_cs_packet(packet)); packet_size = FIELD_OFFSET(struct wined3d_cs_packet, data[packet->size]); InterlockedExchange((LONG *)&queue->head, queue->head + packet_size); @@ -3500,7 +3507,7 @@ static inline bool wined3d_cs_execute_next(struct wined3d_cs *cs, struct wined3d { opcode = *(const enum wined3d_cs_op *)packet->data; - TRACE("Executing %s at %p.\n", debug_cs_op(opcode), packet); + TRACE("Executing %s.\n", debug_cs_packet(packet)); if (opcode >= WINED3D_CS_OP_STOP) { if (opcode > WINED3D_CS_OP_STOP) @@ -3511,7 +3518,7 @@ static inline bool wined3d_cs_execute_next(struct wined3d_cs *cs, struct wined3d 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); + TRACE("%s executed.\n", debug_cs_packet(packet)); } InterlockedExchange((LONG *)&queue->tail, tail); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9903