[PATCH vkd3d v2 3/5] vkd3d-shader: Move the bytecode buffer helpers to vkd3d_shader_main.c.

Zebediah Figura zfigura at codeweavers.com
Wed Jun 30 21:54:22 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
v3: Get rid of the "vkd3d_" prefix from put_* and set_* functions; replace it
with "bytecode_" in remaining functions. Because these functions are called
often it's nice for their names to be terse, and I'd like to try to avoid
polluting the "vkd3d" namespace for functions that aren't library exports.

 libs/vkd3d-shader/hlsl_codegen.c         | 168 ++++++++---------------
 libs/vkd3d-shader/vkd3d_shader_main.c    |  28 ++++
 libs/vkd3d-shader/vkd3d_shader_private.h |  36 +++++
 3 files changed, 119 insertions(+), 113 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 8e842bd1..ef6beadf 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -1325,67 +1325,6 @@ static struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const
     return ret;
 }
 
-struct bytecode_buffer
-{
-    struct hlsl_ctx *ctx;
-    uint8_t *data;
-    size_t size, capacity;
-    int status;
-};
-
-static size_t put_bytes(struct bytecode_buffer *buffer, const void *bytes, size_t size, size_t alignment)
-{
-    size_t prev_size = buffer->size;
-    size_t offset = align(prev_size, alignment);
-
-    if (buffer->status)
-        return offset;
-
-    if (!hlsl_array_reserve(buffer->ctx, (void **)&buffer->data, &buffer->capacity, offset + size, 1))
-    {
-        buffer->status = VKD3D_ERROR_OUT_OF_MEMORY;
-        return offset;
-    }
-    memset(buffer->data + prev_size, 0xab, offset - prev_size);
-    memcpy(buffer->data + offset, bytes, size);
-    buffer->size = offset + size;
-    return offset;
-}
-
-static size_t put_dword(struct bytecode_buffer *buffer, uint32_t value)
-{
-    return put_bytes(buffer, &value, sizeof(value), sizeof(value));
-}
-
-static size_t put_float(struct bytecode_buffer *buffer, float value)
-{
-    return put_bytes(buffer, &value, sizeof(value), sizeof(value));
-}
-
-static void set_dword(struct bytecode_buffer *buffer, size_t offset, uint32_t value)
-{
-    if (buffer->status)
-        return;
-
-    assert(offset + sizeof(value) <= buffer->size);
-    memcpy(buffer->data + offset, &value, sizeof(value));
-}
-
-static size_t put_string(struct bytecode_buffer *buffer, const char *string)
-{
-    return put_bytes(buffer, string, strlen(string) + 1, 1);
-}
-
-static size_t align_buffer(struct bytecode_buffer *buffer, uint32_t alignment)
-{
-    return put_bytes(buffer, NULL, 0, alignment);
-}
-
-static size_t get_buffer_size(struct bytecode_buffer *buffer)
-{
-    return buffer->size;
-}
-
 static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, unsigned int minor)
 {
     if (type == VKD3D_SHADER_TYPE_VERTEX)
@@ -1496,7 +1435,7 @@ static unsigned int get_array_size(const struct hlsl_type *type)
     return 1;
 }
 
-static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *type, unsigned int ctab_start)
+static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type, unsigned int ctab_start)
 {
     const struct hlsl_type *array_type = get_array_type(type);
     unsigned int array_size = get_array_size(type);
@@ -1515,20 +1454,20 @@ static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *typ
             write_sm1_type(buffer, field->type, ctab_start);
         }
 
-        fields_offset = get_buffer_size(buffer) - ctab_start;
+        fields_offset = bytecode_get_size(buffer) - ctab_start;
 
         LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry)
         {
-            put_dword(buffer, field->name_bytecode_offset - ctab_start);
-            put_dword(buffer, field->type->bytecode_offset - ctab_start);
+            put_u32(buffer, field->name_bytecode_offset - ctab_start);
+            put_u32(buffer, field->type->bytecode_offset - ctab_start);
             ++field_count;
         }
     }
 
-    type->bytecode_offset = put_dword(buffer, sm1_class(type) | (sm1_base_type(type) << 16));
-    put_dword(buffer, type->dimy | (type->dimx << 16));
-    put_dword(buffer, array_size | (field_count << 16));
-    put_dword(buffer, fields_offset);
+    type->bytecode_offset = put_u32(buffer, sm1_class(type) | (sm1_base_type(type) << 16));
+    put_u32(buffer, type->dimy | (type->dimx << 16));
+    put_u32(buffer, array_size | (field_count << 16));
+    put_u32(buffer, fields_offset);
 }
 
 static void sm1_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort)
@@ -1559,7 +1498,7 @@ static void sm1_sort_externs(struct hlsl_ctx *ctx)
     list_move_tail(&ctx->extern_vars, &sorted);
 }
 
-static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
+static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
         struct hlsl_ir_function_decl *entry_func)
 {
     size_t ctab_offset, ctab_start, ctab_end, vars_start, size_offset, creator_offset, offset;
@@ -1591,28 +1530,28 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
 
     sm1_sort_externs(ctx);
 
-    size_offset = put_dword(buffer, 0);
-    ctab_offset = put_dword(buffer, MAKEFOURCC('C','T','A','B'));
+    size_offset = put_u32(buffer, 0);
+    ctab_offset = put_u32(buffer, MAKEFOURCC('C','T','A','B'));
 
-    ctab_start = put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE));
-    creator_offset = put_dword(buffer, 0);
-    put_dword(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
-    put_dword(buffer, uniform_count);
-    put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* offset of constants */
-    put_dword(buffer, 0); /* FIXME: flags */
-    put_dword(buffer, 0); /* FIXME: target string */
+    ctab_start = put_u32(buffer, sizeof(D3DXSHADER_CONSTANTTABLE));
+    creator_offset = put_u32(buffer, 0);
+    put_u32(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
+    put_u32(buffer, uniform_count);
+    put_u32(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* offset of constants */
+    put_u32(buffer, 0); /* FIXME: flags */
+    put_u32(buffer, 0); /* FIXME: target string */
 
-    vars_start = get_buffer_size(buffer);
+    vars_start = bytecode_get_size(buffer);
 
     LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
     {
         if (!var->semantic.name && var->reg.allocated)
         {
-            put_dword(buffer, 0); /* name */
-            put_dword(buffer, D3DXRS_FLOAT4 | (var->reg.id << 16));
-            put_dword(buffer, var->data_type->reg_size / 4);
-            put_dword(buffer, 0); /* type */
-            put_dword(buffer, 0); /* FIXME: default value */
+            put_u32(buffer, 0); /* name */
+            put_u32(buffer, D3DXRS_FLOAT4 | (var->reg.id << 16));
+            put_u32(buffer, var->data_type->reg_size / 4);
+            put_u32(buffer, 0); /* type */
+            put_u32(buffer, 0); /* FIXME: default value */
         }
     }
 
@@ -1626,19 +1565,19 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
             size_t name_offset;
 
             name_offset = put_string(buffer, var->name);
-            set_dword(buffer, var_offset, name_offset - ctab_start);
+            set_u32(buffer, var_offset, name_offset - ctab_start);
 
             write_sm1_type(buffer, var->data_type, ctab_start);
-            set_dword(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start);
+            set_u32(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start);
             ++uniform_count;
         }
     }
 
     offset = put_string(buffer, vkd3d_shader_get_version(NULL, NULL));
-    set_dword(buffer, creator_offset, offset - ctab_start);
+    set_u32(buffer, creator_offset, offset - ctab_start);
 
-    ctab_end = align_buffer(buffer, sizeof(uint32_t));
-    set_dword(buffer, size_offset, D3DSIO_COMMENT | (((ctab_end - ctab_offset) / sizeof(uint32_t)) << 16));
+    ctab_end = bytecode_align(buffer, sizeof(uint32_t));
+    set_u32(buffer, size_offset, D3DSIO_COMMENT | (((ctab_end - ctab_offset) / sizeof(uint32_t)) << 16));
 }
 
 static uint32_t sm1_encode_register_type(D3DSHADER_PARAM_REGISTER_TYPE type)
@@ -1671,21 +1610,21 @@ struct sm1_instruction
     unsigned int has_dst;
 };
 
-static void write_sm1_dst_register(struct bytecode_buffer *buffer, const struct sm1_dst_register *reg)
+static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const struct sm1_dst_register *reg)
 {
     assert(reg->writemask);
-    put_dword(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->writemask << 16) | reg->reg);
+    put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->writemask << 16) | reg->reg);
 }
 
-static void write_sm1_src_register(struct bytecode_buffer *buffer,
+static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer,
         const struct sm1_src_register *reg, unsigned int dst_writemask)
 {
     unsigned int swizzle = map_swizzle(reg->swizzle, dst_writemask);
 
-    put_dword(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (swizzle << 16) | reg->reg);
+    put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (swizzle << 16) | reg->reg);
 }
 
-static void write_sm1_instruction(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
+static void write_sm1_instruction(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
         const struct sm1_instruction *instr)
 {
     uint32_t token = instr->opcode;
@@ -1693,7 +1632,7 @@ static void write_sm1_instruction(struct hlsl_ctx *ctx, struct bytecode_buffer *
 
     if (ctx->profile->major_version > 1)
         token |= (instr->has_dst + instr->src_count) << D3DSI_INSTLENGTH_SHIFT;
-    put_dword(buffer, token);
+    put_u32(buffer, token);
 
     if (instr->has_dst)
         write_sm1_dst_register(buffer, &instr->dst);
@@ -1702,7 +1641,7 @@ static void write_sm1_instruction(struct hlsl_ctx *ctx, struct bytecode_buffer *
         write_sm1_src_register(buffer, &instr->srcs[i], instr->dst.writemask);
 };
 
-static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
+static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
         D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst,
         const struct hlsl_reg *src1, const struct hlsl_reg *src2)
 {
@@ -1726,7 +1665,7 @@ static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct bytecode_buffer *bu
     write_sm1_instruction(ctx, buffer, &instr);
 }
 
-static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
+static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
         D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst,
         const struct hlsl_reg *src, D3DSHADER_PARAM_SRCMOD_TYPE src_mod)
 {
@@ -1748,7 +1687,7 @@ static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
     write_sm1_instruction(ctx, buffer, &instr);
 }
 
-static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer)
+static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer)
 {
     unsigned int i, x;
 
@@ -1764,7 +1703,7 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct bytecode_buffer
 
         if (ctx->profile->major_version > 1)
             token |= 5 << D3DSI_INSTLENGTH_SHIFT;
-        put_dword(buffer, token);
+        put_u32(buffer, token);
 
         write_sm1_dst_register(buffer, &reg);
         for (x = 0; x < 4; ++x)
@@ -1772,7 +1711,7 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct bytecode_buffer
     }
 }
 
-static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
+static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
         const struct hlsl_ir_var *var, bool output)
 {
     struct sm1_dst_register reg = {0};
@@ -1796,18 +1735,18 @@ static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct bytecode_buffer
     token = D3DSIO_DCL;
     if (ctx->profile->major_version > 1)
         token |= 2 << D3DSI_INSTLENGTH_SHIFT;
-    put_dword(buffer, token);
+    put_u32(buffer, token);
 
     token = (1u << 31);
     token |= usage << D3DSP_DCL_USAGE_SHIFT;
     token |= usage_idx << D3DSP_DCL_USAGEINDEX_SHIFT;
-    put_dword(buffer, token);
+    put_u32(buffer, token);
 
     reg.writemask = (1 << var->data_type->dimx) - 1;
     write_sm1_dst_register(buffer, &reg);
 }
 
-static void write_sm1_semantic_dcls(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer)
+static void write_sm1_semantic_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer)
 {
     bool write_in = false, write_out = false;
     struct hlsl_ir_var *var;
@@ -1828,7 +1767,8 @@ static void write_sm1_semantic_dcls(struct hlsl_ctx *ctx, struct bytecode_buffer
     }
 }
 
-static void write_sm1_constant(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
+static void write_sm1_constant(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
+        const struct hlsl_ir_node *instr)
 {
     const struct hlsl_ir_constant *constant = hlsl_ir_constant(instr);
     struct sm1_instruction sm1_instr =
@@ -1851,7 +1791,7 @@ static void write_sm1_constant(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
     write_sm1_instruction(ctx, buffer, &sm1_instr);
 }
 
-static void write_sm1_expr(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
+static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
 {
     struct hlsl_ir_expr *expr = hlsl_ir_expr(instr);
     struct hlsl_ir_node *arg1 = expr->operands[0].node;
@@ -1901,7 +1841,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
     }
 }
 
-static void write_sm1_load(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
+static void write_sm1_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
 {
     const struct hlsl_ir_load *load = hlsl_ir_load(instr);
     const struct hlsl_reg reg = hlsl_reg_from_deref(&load->src, instr->data_type);
@@ -1943,7 +1883,8 @@ static void write_sm1_load(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
     write_sm1_instruction(ctx, buffer, &sm1_instr);
 }
 
-static void write_sm1_store(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
+static void write_sm1_store(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
+        const struct hlsl_ir_node *instr)
 {
     const struct hlsl_ir_store *store = hlsl_ir_store(instr);
     const struct hlsl_ir_node *rhs = store->rhs.node;
@@ -1986,7 +1927,8 @@ static void write_sm1_store(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer
     write_sm1_instruction(ctx, buffer, &sm1_instr);
 }
 
-static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
+static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
+        const struct hlsl_ir_node *instr)
 {
     const struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(instr);
     const struct hlsl_ir_node *val = swizzle->val.node;
@@ -2011,7 +1953,7 @@ static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct bytecode_buffer *buff
     write_sm1_instruction(ctx, buffer, &sm1_instr);
 }
 
-static void write_sm1_instructions(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
+static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
         const struct hlsl_ir_function_decl *entry_func)
 {
     const struct hlsl_ir_node *instr;
@@ -2060,10 +2002,10 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct bytecode_buffer
 static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
         struct vkd3d_shader_code *out)
 {
-    struct bytecode_buffer buffer = {.ctx = ctx};
+    struct vkd3d_bytecode_buffer buffer = {0};
     int ret;
 
-    put_dword(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
+    put_u32(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
 
     write_sm1_uniforms(ctx, &buffer, entry_func);
 
@@ -2071,7 +2013,7 @@ static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *
     write_sm1_semantic_dcls(ctx, &buffer);
     write_sm1_instructions(ctx, &buffer, entry_func);
 
-    put_dword(&buffer, D3DSIO_END);
+    put_u32(&buffer, D3DSIO_END);
 
     if (!(ret = buffer.status))
     {
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 40d55b70..8b4f3533 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -282,6 +282,34 @@ void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const stru
     va_end(args);
 }
 
+size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size, size_t alignment)
+{
+    size_t prev_size = buffer->size;
+    size_t offset = align(prev_size, alignment);
+
+    if (buffer->status)
+        return offset;
+
+    if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->capacity, offset + size, 1))
+    {
+        buffer->status = VKD3D_ERROR_OUT_OF_MEMORY;
+        return offset;
+    }
+    memset(buffer->data + prev_size, 0xab, offset - prev_size);
+    memcpy(buffer->data + offset, bytes, size);
+    buffer->size = offset + size;
+    return offset;
+}
+
+void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value)
+{
+    if (buffer->status)
+        return;
+
+    assert(offset + sizeof(value) <= buffer->size);
+    memcpy(buffer->data + offset, &value, sizeof(value));
+}
+
 static void vkd3d_shader_dump_blob(const char *path, const char *prefix, const void *data, size_t size)
 {
     static int shader_id = 0;
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index c61b3773..87e5801a 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -899,6 +899,42 @@ void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *list,
 void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function) DECLSPEC_HIDDEN;
 int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args) DECLSPEC_HIDDEN;
 
+struct vkd3d_bytecode_buffer
+{
+    char *data;
+    size_t size, capacity;
+    int status;
+};
+
+size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes,
+        size_t size, size_t alignment) DECLSPEC_HIDDEN;
+void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value) DECLSPEC_HIDDEN;
+
+static inline size_t put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value)
+{
+    return bytecode_put_bytes(buffer, &value, sizeof(value), sizeof(value));
+}
+
+static inline size_t put_float(struct vkd3d_bytecode_buffer *buffer, float value)
+{
+    return bytecode_put_bytes(buffer, &value, sizeof(value), sizeof(value));
+}
+
+static inline size_t put_string(struct vkd3d_bytecode_buffer *buffer, const char *string)
+{
+    return bytecode_put_bytes(buffer, string, strlen(string) + 1, 1);
+}
+
+static inline size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer, uint32_t alignment)
+{
+    return bytecode_put_bytes(buffer, NULL, 0, alignment);
+}
+
+static inline size_t bytecode_get_size(struct vkd3d_bytecode_buffer *buffer)
+{
+    return buffer->size;
+}
+
 struct vkd3d_shader_location
 {
     const char *source_name;
-- 
2.32.0




More information about the wine-devel mailing list