Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2018
- 68 participants
- 1149 messages
[PATCH vkd3d 03/12] libs/vkd3d-shader: Add initial support for typed registers.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 119 ++++++++++++++++++++++++-------
libs/vkd3d-shader/vkd3d_shader_private.h | 6 ++
2 files changed, 98 insertions(+), 27 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 8f6a833cd313..71db4be6b493 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1667,6 +1667,8 @@ struct vkd3d_symbol_register_data
{
SpvStorageClass storage_class;
uint32_t member_idx;
+ enum vkd3d_component_type component_type;
+ unsigned int write_mask;
unsigned int structure_stride;
};
@@ -2243,6 +2245,8 @@ struct vkd3d_shader_register_info
{
uint32_t id;
SpvStorageClass storage_class;
+ enum vkd3d_component_type component_type;
+ unsigned int write_mask;
uint32_t member_idx;
unsigned int structure_stride;
};
@@ -2260,6 +2264,8 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
assert(reg->idx[0].offset < compiler->temp_count);
register_info->id = compiler->temp_id + reg->idx[0].offset;
register_info->storage_class = SpvStorageClassFunction;
+ register_info->component_type = VKD3D_TYPE_FLOAT;
+ register_info->write_mask = VKD3DSP_WRITEMASK_ALL;
register_info->member_idx = 0;
return true;
}
@@ -2275,6 +2281,8 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
register_info->id = symbol->id;
register_info->storage_class = symbol->info.reg.storage_class;
+ register_info->component_type = symbol->info.reg.component_type;
+ register_info->write_mask = symbol->info.reg.write_mask;
register_info->structure_stride = symbol->info.reg.structure_stride;
register_info->member_idx = symbol->info.reg.member_idx;
@@ -2356,14 +2364,15 @@ static uint32_t vkd3d_dxbc_compiler_get_register_id(struct vkd3d_dxbc_compiler *
}
}
-static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *compiler,
- uint32_t val_id, enum vkd3d_component_type component_type, DWORD swizzle, DWORD write_mask)
+static uint32_t vkd3d_dxbc_compiler_emit_swizzle_ext(struct vkd3d_dxbc_compiler *compiler,
+ uint32_t val_id, unsigned int val_write_mask, enum vkd3d_component_type component_type,
+ unsigned int swizzle, unsigned int write_mask)
{
+ unsigned int i, component_idx, component_count, val_component_count;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- unsigned int i, component_idx, component_count;
uint32_t type_id, components[VKD3D_VEC4_SIZE];
- if (swizzle == VKD3D_NO_SWIZZLE && write_mask == VKD3DSP_WRITEMASK_ALL)
+ if (swizzle == VKD3D_NO_SWIZZLE && write_mask == val_write_mask)
return val_id;
component_count = vkd3d_write_mask_component_count(write_mask);
@@ -2376,6 +2385,20 @@ static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *com
return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx);
}
+ val_component_count = vkd3d_write_mask_component_count(val_write_mask);
+ if (val_component_count == 1)
+ {
+ for (i = 0, component_idx = 0; i < VKD3D_VEC4_SIZE; ++i)
+ {
+ if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
+ {
+ assert(VKD3DSP_WRITEMASK_0 << vkd3d_swizzle_get_component(swizzle, i) == val_write_mask);
+ components[component_idx++] = val_id;
+ }
+ }
+ return vkd3d_spirv_build_op_composite_construct(builder, type_id, components, component_count);
+ }
+
for (i = 0, component_idx = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
@@ -2385,6 +2408,13 @@ static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *com
type_id, val_id, val_id, components, component_count);
}
+static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *compiler,
+ uint32_t val_id, enum vkd3d_component_type component_type, DWORD swizzle, DWORD write_mask)
+{
+ return vkd3d_dxbc_compiler_emit_swizzle_ext(compiler,
+ val_id, VKD3DSP_WRITEMASK_ALL, component_type, swizzle, write_mask);
+}
+
static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
@@ -2416,36 +2446,44 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- uint32_t type_id, ptr_type_id, indexes[1], chain_id, val_id;
+ uint32_t type_id, ptr_type_id, indexes[1], reg_id, val_id;
+ unsigned int component_idx, reg_component_count;
struct vkd3d_shader_register_info reg_info;
- unsigned int component_idx;
+ enum vkd3d_component_type component_type;
assert(reg->type != VKD3DSPR_IMMCONST);
assert(vkd3d_write_mask_component_count(write_mask) == 1);
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
component_idx = vkd3d_swizzle_get_component(swizzle, component_idx);
+ component_type = vkd3d_component_type_from_data_type(reg->data_type);
if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info))
{
- type_id = vkd3d_spirv_get_type_id(builder,
- vkd3d_component_type_from_data_type(reg->data_type), 1);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
}
vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info);
+ reg_component_count = vkd3d_write_mask_component_count(reg_info.write_mask);
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
- indexes[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx);
- chain_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder,
- ptr_type_id, reg_info.id, indexes, ARRAY_SIZE(indexes));
+ if (component_idx > reg_component_count)
+ ERR("Invalid component_idx for register %#x, %u.\n", reg->type, reg->idx[0].offset);
- val_id = vkd3d_spirv_build_op_load(builder, type_id, chain_id, SpvMemoryAccessMaskNone);
+ type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, 1);
+ reg_id = reg_info.id;
+ if (reg_component_count != 1)
+ {
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
+ indexes[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx);
+ reg_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder,
+ ptr_type_id, reg_id, indexes, ARRAY_SIZE(indexes));
+ }
- if (reg->data_type != VKD3D_DATA_FLOAT)
+ val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_id, SpvMemoryAccessMaskNone);
+
+ if (component_type != reg_info.component_type)
{
- type_id = vkd3d_spirv_get_type_id(builder,
- vkd3d_component_type_from_data_type(reg->data_type), 1);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
@@ -2456,8 +2494,10 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- uint32_t src_id, type_id, val_id;
+ struct vkd3d_shader_register_info reg_info;
+ enum vkd3d_component_type component_type;
unsigned int component_count;
+ uint32_t type_id, val_id;
if (reg->type == VKD3DSPR_IMMCONST)
return vkd3d_dxbc_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
@@ -2466,17 +2506,24 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
if (component_count == 1)
return vkd3d_dxbc_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask);
- src_id = vkd3d_dxbc_compiler_get_register_id(compiler, reg);
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
- val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone);
+ component_type = vkd3d_component_type_from_data_type(reg->data_type);
+ if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info))
+ {
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
+ return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
+ }
+ vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info);
- val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
- val_id, VKD3D_TYPE_FLOAT, swizzle, write_mask);
+ type_id = vkd3d_spirv_get_type_id(builder,
+ reg_info.component_type, vkd3d_write_mask_component_count(reg_info.write_mask));
+ val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone);
- if (reg->data_type != VKD3D_DATA_FLOAT)
+ val_id = vkd3d_dxbc_compiler_emit_swizzle_ext(compiler,
+ val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask);
+
+ if (component_type != reg_info.component_type)
{
- type_id = vkd3d_spirv_get_type_id(builder,
- vkd3d_component_type_from_data_type(reg->data_type), component_count);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
@@ -2995,6 +3042,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
{
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@@ -3105,6 +3154,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp
{
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@@ -3221,6 +3272,8 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
reg_symbol.info.reg.member_idx = j;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
++j;
@@ -3281,6 +3334,8 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
reg_symbol.info.reg.member_idx = 0;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
}
@@ -3314,6 +3369,8 @@ static void vkd3d_dxbc_compiler_emit_dcl_immediate_constant_buffer(struct vkd3d_
vkd3d_symbol_make_register(®_symbol, ®);
reg_symbol.id = icb_id;
reg_symbol.info.reg.storage_class = SpvStorageClassPrivate;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
}
@@ -3566,6 +3623,8 @@ static void vkd3d_dxbc_compiler_emit_workgroup_memory(struct vkd3d_dxbc_compiler
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
reg_symbol.info.reg.member_idx = 0;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_UINT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_0;
reg_symbol.info.reg.structure_stride = structure_stride;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
}
@@ -3959,13 +4018,19 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
uint32_t val_id, dst_val_id, type_id, dst_id, src_id;
+ struct vkd3d_shader_register_info reg_info;
uint32_t components[VKD3D_VEC4_SIZE];
unsigned int i, component_count;
component_count = vkd3d_write_mask_component_count(dst->write_mask);
+ memset(®_info, 0, sizeof(reg_info));
+ if (src->reg.type != VKD3DSPR_IMMCONST)
+ vkd3d_dxbc_compiler_get_register_info(compiler, &src->reg, ®_info);
+
if (component_count == 1 || component_count == VKD3D_VEC4_SIZE
- || dst->modifiers || src->modifiers || src->reg.type == VKD3DSPR_IMMCONST)
+ || dst->modifiers || src->modifiers || src->reg.type == VKD3DSPR_IMMCONST
+ || reg_info.component_type != VKD3D_TYPE_FLOAT || reg_info.write_mask != VKD3DSP_WRITEMASK_ALL)
{
val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, dst->write_mask);
vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 7fc42627f820..9eb2c126332d 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -872,6 +872,12 @@ static inline unsigned int vkd3d_write_mask_component_count(DWORD write_mask)
return count;
}
+static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int component_count)
+{
+ assert(component_count <= 4);
+ return (VKD3DSP_WRITEMASK_0 << component_count) - 1;
+}
+
static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
unsigned int idx)
{
--
2.16.4
June 26, 2018
[PATCH vkd3d 02/12] libs/vkd3d-shader: Do not generate code in vkd3d_dxbc_compiler_get_register_info().
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 289797de9f01..8f6a833cd313 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2243,18 +2243,15 @@ struct vkd3d_shader_register_info
{
uint32_t id;
SpvStorageClass storage_class;
+ uint32_t member_idx;
unsigned int structure_stride;
};
static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, struct vkd3d_shader_register_info *register_info)
{
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
struct vkd3d_symbol reg_symbol, *symbol;
- uint32_t type_id, ptr_type_id;
- uint32_t index_count = 0;
struct rb_entry *entry;
- uint32_t indexes[2];
assert(reg->type != VKD3DSPR_IMMCONST);
@@ -2263,6 +2260,7 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
assert(reg->idx[0].offset < compiler->temp_count);
register_info->id = compiler->temp_id + reg->idx[0].offset;
register_info->storage_class = SpvStorageClassFunction;
+ register_info->member_idx = 0;
return true;
}
@@ -2278,11 +2276,23 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
register_info->id = symbol->id;
register_info->storage_class = symbol->info.reg.storage_class;
register_info->structure_stride = symbol->info.reg.structure_stride;
+ register_info->member_idx = symbol->info.reg.member_idx;
+
+ return true;
+}
+
+static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_compiler *compiler,
+ const struct vkd3d_shader_register *reg, struct vkd3d_shader_register_info *register_info)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ uint32_t type_id, ptr_type_id;
+ unsigned int index_count = 0;
+ uint32_t indexes[2];
if (reg->type == VKD3DSPR_CONSTBUFFER)
{
assert(!reg->idx[0].rel_addr);
- indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, symbol->info.reg.member_idx);
+ indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx);
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[1]);
}
else if (reg->type == VKD3DSPR_IMMCONSTBUFFER)
@@ -2306,8 +2316,6 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
register_info->id, indexes, index_count);
}
-
- return true;
}
static uint32_t vkd3d_dxbc_compiler_get_register_id(struct vkd3d_dxbc_compiler *compiler,
@@ -2331,7 +2339,10 @@ static uint32_t vkd3d_dxbc_compiler_get_register_id(struct vkd3d_dxbc_compiler *
case VKD3DSPR_LOCALTHREADINDEX:
case VKD3DSPR_THREADGROUPID:
if (vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®ister_info))
+ {
+ vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®ister_info);
return register_info.id;
+ }
return vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream,
SpvStorageClassPrivate, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
case VKD3DSPR_IMMCONST:
@@ -2421,6 +2432,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler
vkd3d_component_type_from_data_type(reg->data_type), 1);
return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
}
+ vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
@@ -2565,6 +2577,7 @@ static void vkd3d_dxbc_compiler_emit_store_scalar(struct vkd3d_dxbc_compiler *co
if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info))
return;
+ vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
--
2.16.4
June 26, 2018
[PATCH vkd3d 01/12] libs/vkd3d-shader: Split SPIR-V built-ins table into two tables.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 75 +++++++++++++++++++++++++++--------------------
1 file changed, 43 insertions(+), 32 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 10806a5a9a2f..289797de9f01 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2747,7 +2747,7 @@ typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct vkd3d_dxbc_compiler *co
uint32_t val_id);
/* Substitute "InstanceIndex - BaseInstance" for SV_InstanceID. */
-static uint32_t vkd3d_spirv_instance_id_fixup(struct vkd3d_dxbc_compiler *compiler,
+static uint32_t sv_instance_id_fixup(struct vkd3d_dxbc_compiler *compiler,
uint32_t instance_index_id)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@@ -2773,47 +2773,57 @@ static uint32_t vkd3d_spirv_instance_id_fixup(struct vkd3d_dxbc_compiler *compil
type_id, instance_index_id, base_instance_id);
}
-static uint32_t vkd3d_spirv_front_facing_fixup(struct vkd3d_dxbc_compiler *compiler,
+static uint32_t sv_front_face_fixup(struct vkd3d_dxbc_compiler *compiler,
uint32_t front_facing_id)
{
return vkd3d_dxbc_compiler_emit_bool_to_int(compiler, 1, front_facing_id);
}
-/*
- * The following table is based on the "14.6. Built-In Variables" section from
- * the Vulkan spec.
- */
-static const struct vkd3d_spirv_builtin
+struct vkd3d_spirv_builtin
{
- enum vkd3d_shader_input_sysval_semantic sysval;
- enum vkd3d_shader_register_type reg_type;
-
enum vkd3d_component_type component_type;
unsigned int component_count;
SpvBuiltIn spirv_builtin;
vkd3d_spirv_builtin_fixup_pfn fixup_pfn;
+};
+
+/*
+ * The following tables are based on the "14.6. Built-In Variables" section
+ * from the Vulkan spec.
+ */
+static const struct
+{
+ enum vkd3d_shader_input_sysval_semantic sysval;
+ struct vkd3d_spirv_builtin builtin;
}
-vkd3d_spirv_builtin_table[] =
+vkd3d_system_value_builtins[] =
{
- {VKD3D_SIV_NONE, VKD3DSPR_THREADID, VKD3D_TYPE_INT, 3, SpvBuiltInGlobalInvocationId},
- {VKD3D_SIV_NONE, VKD3DSPR_LOCALTHREADID, VKD3D_TYPE_INT, 3, SpvBuiltInLocalInvocationId},
- {VKD3D_SIV_NONE, VKD3DSPR_LOCALTHREADINDEX, VKD3D_TYPE_INT, 1, SpvBuiltInLocalInvocationIndex},
- {VKD3D_SIV_NONE, VKD3DSPR_THREADGROUPID, VKD3D_TYPE_INT, 3, SpvBuiltInWorkgroupId},
+ {VKD3D_SIV_POSITION, {VKD3D_TYPE_FLOAT, 4, SpvBuiltInPosition}},
+ {VKD3D_SIV_VERTEX_ID, {VKD3D_TYPE_INT, 1, SpvBuiltInVertexIndex}},
+ {VKD3D_SIV_INSTANCE_ID, {VKD3D_TYPE_INT, 1, SpvBuiltInInstanceIndex, sv_instance_id_fixup}},
- {VKD3D_SIV_NONE, VKD3DSPR_GSINSTID, VKD3D_TYPE_INT, 1, SpvBuiltInInvocationId},
- {VKD3D_SIV_NONE, VKD3DSPR_OUTPOINTID, VKD3D_TYPE_INT, 1, SpvBuiltInInvocationId},
+ {VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX, {VKD3D_TYPE_INT, 1, SpvBuiltInLayer}},
- {VKD3D_SIV_NONE, VKD3DSPR_TESSCOORD, VKD3D_TYPE_FLOAT, 3, SpvBuiltInTessCoord},
-
- {VKD3D_SIV_NONE, VKD3DSPR_DEPTHOUT, VKD3D_TYPE_FLOAT, 1, SpvBuiltInFragDepth},
+ {VKD3D_SIV_IS_FRONT_FACE, {VKD3D_TYPE_BOOL, 1, SpvBuiltInFrontFacing, sv_front_face_fixup}},
+};
+static const struct
+{
+ enum vkd3d_shader_register_type reg_type;
+ struct vkd3d_spirv_builtin builtin;
+}
+vkd3d_register_builtins[] =
+{
+ {VKD3DSPR_THREADID, {VKD3D_TYPE_INT, 3, SpvBuiltInGlobalInvocationId}},
+ {VKD3DSPR_LOCALTHREADID, {VKD3D_TYPE_INT, 3, SpvBuiltInLocalInvocationId}},
+ {VKD3DSPR_LOCALTHREADINDEX, {VKD3D_TYPE_INT, 1, SpvBuiltInLocalInvocationIndex}},
+ {VKD3DSPR_THREADGROUPID, {VKD3D_TYPE_INT, 3, SpvBuiltInWorkgroupId}},
- {VKD3D_SIV_POSITION, ~0u, VKD3D_TYPE_FLOAT, 4, SpvBuiltInPosition},
- {VKD3D_SIV_VERTEX_ID, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInVertexIndex},
- {VKD3D_SIV_INSTANCE_ID, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInInstanceIndex, vkd3d_spirv_instance_id_fixup},
+ {VKD3DSPR_GSINSTID, {VKD3D_TYPE_INT, 1, SpvBuiltInInvocationId}},
+ {VKD3DSPR_OUTPOINTID, {VKD3D_TYPE_INT, 1, SpvBuiltInInvocationId}},
- {VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInLayer},
+ {VKD3DSPR_TESSCOORD, {VKD3D_TYPE_FLOAT, 3, SpvBuiltInTessCoord}},
- {VKD3D_SIV_IS_FRONT_FACE, ~0u, VKD3D_TYPE_BOOL, 1, SpvBuiltInFrontFacing, vkd3d_spirv_front_facing_fixup},
+ {VKD3DSPR_DEPTHOUT, {VKD3D_TYPE_FLOAT, 1, SpvBuiltInFragDepth}},
};
static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shader_register_type reg_type,
@@ -2821,15 +2831,16 @@ static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shad
{
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(vkd3d_spirv_builtin_table); ++i)
+ for (i = 0; i < ARRAY_SIZE(vkd3d_system_value_builtins); ++i)
{
- const struct vkd3d_spirv_builtin* current = &vkd3d_spirv_builtin_table[i];
-
- if (current->sysval == VKD3D_SIV_NONE && current->reg_type == reg_type)
- return current;
+ if (vkd3d_system_value_builtins[i].sysval == sysval)
+ return &vkd3d_system_value_builtins[i].builtin;
+ }
- if (current->reg_type == ~0u && current->sysval == sysval)
- return current;
+ for (i = 0; i < ARRAY_SIZE(vkd3d_register_builtins); ++i)
+ {
+ if (vkd3d_register_builtins[i].reg_type == reg_type)
+ return &vkd3d_register_builtins[i].builtin;
}
if (sysval != VKD3D_SIV_NONE
--
2.16.4
June 26, 2018
[PATCH] testbot/web: Adjust the GetFile MIME type based on Step->FileType.
by Francois Gouget
This lets the browser offer to open the patches in a text editor instead
of systematically suggesting to save them to disk.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
Not an urgent or very important patch but I believe it will make some
people pretty happy.
testbot/web/GetFile.pl | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/testbot/web/GetFile.pl b/testbot/web/GetFile.pl
index 7e274a8bf..1fe140788 100644
--- a/testbot/web/GetFile.pl
+++ b/testbot/web/GetFile.pl
@@ -84,9 +84,11 @@ sub GetFile($$$)
# HTTP/1.0
$Request->headers_out->add("Pragma", "no-cache");
-
- # Binary file
- $Request->content_type("application/octet-stream");
+
+ # Text or binary file
+ my $MIME = $Step->FileType eq "patchdlls" ? "text/plain" :
+ "application/octet-stream";
+ $Request->content_type($MIME);
$Request->headers_out->add("Content-Disposition",
'attachment; filename="' . $Step->FileName . '"');
--
2.18.0
June 26, 2018
Re: [PATCH 3/5] devenum: Make some variables static.
by Alexandre Julliard
Zebediah Figura <z.figura12(a)gmail.com> writes:
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/devenum/createdevenum.c | 14 ++++++--------
> dlls/devenum/devenum_main.c | 13 ++++---------
> dlls/devenum/devenum_private.h | 4 +---
> dlls/devenum/mediacatenum.c | 4 +++-
> 4 files changed, 14 insertions(+), 21 deletions(-)
It doesn't work here:
../../../tools/runtest -q -P wine -T ../../.. -M devenum.dll -p devenum_test.exe.so devenum && touch devenum.ok
devenum.c:585: Test failed: filter should be registered
devenum.c:592: Test failed: Read failed: 0x80070002
devenum.c:595: Test failed: expected L"{DEADBEEF-CF51-43E6-B6C5-299EA8B6B591}", got L"\58e1\e0f1\cb04\11d0\4ebd\a000\11c9\86ce\2a92\37e9\d9aa\11d2\84bf\f28e\55b1\ed5a\29d1\e306\27e5\11ce\5d87\6000\b78c\6680\29d2\e306\27e5\11ce\5d87\6000\b78c\6680\9faf\0558\c356\11ce\01bf\aa00\5500\5a59\ca52\2ca8\3c3f\11d2\3db7\c000\b64f\3dbd\a762\33d9\90c8\11d0\43bd\a000\11c9\86ce\8d32\a5ea\253d\11d1\f1b3"...
devenum.c:600: Test failed: Read failed: 0x80070002
devenum.c:601: Test failed: expected L"{DEADBEEF-CF51-43E6-B6C5-299EA8B6B591}", got L"\58e1\e0f1\cb04\11d0\4ebd\a000\11c9\86ce\2a92\37e9\d9aa\11d2\84bf\f28e\55b1\ed5a\29d1\e306\27e5\11ce\5d87\6000\b78c\6680\29d2\e306\27e5\11ce\5d87\6000\b78c\6680\9faf\0558\c356\11ce\01bf\aa00\5500\5a59\ca52\2ca8\3c3f\11d2\3db7\c000\b64f\3dbd\a762\33d9\90c8\11d0\43bd\a000\11c9\86ce\8d32\a5ea\253d\11d1\f1b3"...
Makefile:183: recipe for target 'devenum.ok' failed
make: *** [devenum.ok] Error 5
--
Alexandre Julliard
julliard(a)winehq.org
June 26, 2018
[PATCH 7/7] testbot/WineSendLog: Fix detection of new errors.
by Francois Gouget
Comparing the compilation log with the reference WineTest report makes
no sense. So handle the WineTest reports and task logs separately.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 53b184cff..29da4a04d 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -439,13 +439,23 @@ EOF
my $TaskDir = $StepTask->GetTaskDir();
my ($BotFailure, $MessagesFromErr) = CheckErrLog("$TaskDir/err");
- if (! $BotFailure)
+ if ($BotFailure)
+ {
+ # TestBot errors are not the developer's fault and prevent us from doing
+ # any meaningful analysis. So skip.
+ Error "A TestBot error was found in $TaskDir/err\n";
+ next;
+ }
+
+ my $MessagesFromLog = "";
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
+ if ($LogName =~ /\.report$/)
{
$StepTask->FileName =~ m/^(.*)_test(64)?\.exe$/;
my ($BaseName, $Bits) = ($1, $2 || "32");
my $LatestName = "$DataDir/latest/" . $StepTask->VM->Name . "_$Bits";
my ($LatestBotFailure, $Dummy) = CheckErrLog("$LatestName.err");
- my $MessagesFromLog = "";
if (! $LatestBotFailure)
{
if (defined($StepTask->CmdLineArg))
@@ -463,15 +473,20 @@ EOF
{
Error "BotFailure found in ${LatestName}.err\n";
}
- if ($MessagesFromErr || $MessagesFromLog)
+ }
+ elsif (open(my $LogFile, "<", "$TaskDir/$LogName"))
+ {
+ foreach my $Line (<$LogFile>)
{
- $Messages .= "\n=== " . $StepTask->GetTitle() . " ===\n" .
- $MessagesFromLog . $MessagesFromErr;
+ my $Category = GetLogLineCategory($Line);
+ $MessagesFromLog .= $Line if ($Category eq "error");
}
+ close($LogFile);
}
- elsif ($BotFailure)
+ if ($MessagesFromErr || $MessagesFromLog)
{
- Error "BotFailure found in $TaskDir/err\n";
+ $Messages .= "\n=== " . $StepTask->GetTitle() . " ===\n" .
+ $MessagesFromLog . $MessagesFromErr;
}
}
--
2.18.0
June 26, 2018
[PATCH 6/7] testbot/WineSendLog: Use LogUtils to get the report / log filename.
by Francois Gouget
Currently we will either have a test report or a task log file so it's
ok to only take into account the first file returned by
GetLogFileNames().
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 33978095e..53b184cff 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -272,11 +272,13 @@ EOF
foreach my $Key (@SortedKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
+ my $TaskDir = $StepTask->GetTaskDir();
print SENDMAIL "\n=== ", $StepTask->GetTitle(), " ===\n";
- my $TaskDir = $StepTask->GetTaskDir();
- if (open LOGFILE, "<$TaskDir/log")
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
+ if (open LOGFILE, "<$TaskDir/$LogName")
{
my $HasLogEntries = !1;
my $PrintedSomething = !1;
@@ -376,6 +378,7 @@ EOF
foreach my $Key (@SortedKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
+ my $TaskDir = $StepTask->GetTaskDir();
print SENDMAIL <<"EOF";
--$PART_BOUNDARY
@@ -387,9 +390,10 @@ EOF
$StepTask->VM->Name, ".log\n\n";
print SENDMAIL "Not dumping logs in debug mode\n" if ($Debug);
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
my $PrintSeparator = !1;
- my $TaskDir = $StepTask->GetTaskDir();
- if (open LOGFILE, "<$TaskDir/log")
+ if (open LOGFILE, "<$TaskDir/$LogName")
{
my $Line;
while (defined($Line = <LOGFILE>))
@@ -432,8 +436,8 @@ EOF
foreach my $Key (@FailureKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
-
my $TaskDir = $StepTask->GetTaskDir();
+
my ($BotFailure, $MessagesFromErr) = CheckErrLog("$TaskDir/err");
if (! $BotFailure)
{
@@ -449,7 +453,9 @@ EOF
# Filter out failures that happened in the full test suite:
# the test suite is run against code which is already in Wine
# so any failure it reported is not caused by this patch.
- $MessagesFromLog = CompareLogs("$LatestName.log", "$TaskDir/log",
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
+ $MessagesFromLog = CompareLogs("$LatestName.log", "$TaskDir/$LogName",
$BaseName, $StepTask->CmdLineArg);
}
}
@@ -537,11 +543,14 @@ EOF
foreach my $Key (@SortedKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
+ my $TaskDir = $StepTask->GetTaskDir();
+
print $result "\n=== ", $StepTask->GetTitle(), " ===\n";
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
my $PrintSeparator = !1;
- my $TaskDir = $StepTask->GetTaskDir();
- if (open(my $logfile, "<", "$TaskDir/log"))
+ if (open(my $logfile, "<", "$TaskDir/$LogName"))
{
my $Line;
while (defined($Line = <$logfile>))
--
2.18.0
June 26, 2018
[PATCH 5/7] testbot/WineSendLog: Use LogUtils to identify errors in the log files.
by Francois Gouget
GetLogLineCategory()'s error detection is much more complete and this
avoids code duplication.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 2f097796e..33978095e 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -45,6 +45,7 @@ use Algorithm::Diff;
use WineTestBot::Config;
use WineTestBot::Jobs;
use WineTestBot::Log;
+use WineTestBot::LogUtils;
use WineTestBot::StepsTasks;
@@ -290,8 +291,8 @@ EOF
{
$CurrentDll = $1;
}
- if ($Line =~ m/: Test failed: / || $Line =~ m/ done \(258\)/ ||
- $Line =~ m/: unhandled exception [0-9a-fA-F]{8} at /)
+ my $Category = GetLogLineCategory($Line);
+ if ($Category eq "error")
{
if ($PrintedDll ne $CurrentDll)
{
--
2.18.0
June 26, 2018
[PATCH 4/7] testbot: Avoid duplicating the part boundary uuid.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index ed3453b80..2f097796e 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -48,6 +48,9 @@ use WineTestBot::Log;
use WineTestBot::StepsTasks;
+my $PART_BOUNDARY = "==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==";
+
+
#
# Logging and error handling helpers
#
@@ -241,9 +244,9 @@ sub SendLog($)
}
print SENDMAIL <<"EOF";
MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary="==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47=="
+Content-Type: multipart/mixed; boundary="$PART_BOUNDARY"
---==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==
+--$PART_BOUNDARY
Content-Type: text/plain; charset="UTF-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
@@ -374,7 +377,7 @@ EOF
my $StepTask = $StepsTasks->GetItem($Key);
print SENDMAIL <<"EOF";
---==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==
+--$PART_BOUNDARY
Content-Type: text/plain; charset="UTF-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
@@ -414,7 +417,7 @@ EOF
}
}
- print SENDMAIL "--==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==--\n";
+ print SENDMAIL "--$PART_BOUNDARY--\n";
close(SENDMAIL);
# This is all for jobs submitted from the website
--
2.18.0
June 26, 2018
[PATCH 3/7] testbot/WineSendLog: Add proper command line handling and options.
by Francois Gouget
When run in --debug mode WineSendLog prints the emails it would normally
send instead of piping them to sendmail.
Also the script now prints the error messages to stderr by default to
make it easier to figure things out when running it on the command
line. The --log-only option can be used when that's not desired.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/Engine.pl | 2 +-
testbot/bin/WineSendLog.pl | 193 +++++++++++++++++++++++++++++++------
2 files changed, 164 insertions(+), 31 deletions(-)
diff --git a/testbot/bin/Engine.pl b/testbot/bin/Engine.pl
index ce3509440..464b6db45 100755
--- a/testbot/bin/Engine.pl
+++ b/testbot/bin/Engine.pl
@@ -320,7 +320,7 @@ sub HandleJobStatusChange($$$)
CloseAllDBBackEnds();
WineTestBot::Log::SetupRedirects();
- exec("$BinDir/${ProjectName}SendLog.pl $JobKey") or
+ exec("$BinDir/${ProjectName}SendLog.pl --log-only $JobKey") or
LogMsg "Unable to exec ${ProjectName}SendLog.pl: $!\n";
exit(1);
}
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index e03395af1..ed3453b80 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -36,14 +36,47 @@ sub BEGIN
unshift @INC, "$::RootDir/lib";
}
}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
use Algorithm::Diff;
+
use WineTestBot::Config;
use WineTestBot::Jobs;
use WineTestBot::Log;
use WineTestBot::StepsTasks;
+#
+# Logging and error handling helpers
+#
+
+my $Debug;
+sub Debug(@)
+{
+ print STDERR @_ if ($Debug);
+}
+
+sub DebugTee($@)
+{
+ my ($File) = shift;
+ print $File @_;
+ Debug(@_);
+}
+
+my $LogOnly;
+sub Error(@)
+{
+ print STDERR "$Name0:error: ", @_ if (!$LogOnly);
+ LogMsg @_;
+}
+
+
+#
+# Log analysis
+#
+
sub IsBotFailure($)
{
my ($ErrLine) = @_;
@@ -121,7 +154,7 @@ sub ReadLog($$$)
}
else
{
- LogMsg "Unable to open '$LogName' for reading: $!\n";
+ Error "Unable to open '$LogName' for reading: $!\n";
}
return \@Messages;
@@ -179,7 +212,19 @@ sub SendLog($)
my $StepsTasks = CreateStepsTasks(undef, $Job);
my @SortedKeys = sort @{$StepsTasks->GetKeys()};
- open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+ #
+ # Send a job summary and all the logs as attachments to the developer
+ #
+
+ Debug("-------------------- Developer email --------------------\n");
+ if ($Debug)
+ {
+ open(SENDMAIL, ">>&=", 1);
+ }
+ else
+ {
+ open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+ }
print SENDMAIL "From: $RobotEMail\n";
print SENDMAIL "To: $To\n";
my $Subject = "TestBot job " . $Job->Id . " results";
@@ -218,6 +263,7 @@ EOF
$TestFailures;
}
+ # Print the job summary
my @FailureKeys;
foreach my $Key (@SortedKeys)
{
@@ -322,6 +368,7 @@ EOF
}
}
+ # Print the log attachments
foreach my $Key (@SortedKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
@@ -334,6 +381,7 @@ Content-Transfer-Encoding: 8bit
EOF
print SENDMAIL "Content-Disposition: attachment; filename=",
$StepTask->VM->Name, ".log\n\n";
+ print SENDMAIL "Not dumping logs in debug mode\n" if ($Debug);
my $PrintSeparator = !1;
my $TaskDir = $StepTask->GetTaskDir();
@@ -343,7 +391,7 @@ EOF
while (defined($Line = <LOGFILE>))
{
$Line =~ s/\s*$//;
- print SENDMAIL "$Line\n";
+ print SENDMAIL "$Line\n" if (!$Debug);
$PrintSeparator = 1;
}
close LOGFILE;
@@ -356,11 +404,11 @@ EOF
{
if ($PrintSeparator)
{
- print SENDMAIL "\n";
+ print SENDMAIL "\n" if (!$Debug);
$PrintSeparator = !1;
}
$Line =~ s/\s*$//;
- print SENDMAIL "$Line\n";
+ print SENDMAIL "$Line\n" if (!$Debug);
}
close ERRFILE;
}
@@ -369,10 +417,12 @@ EOF
print SENDMAIL "--==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==--\n";
close(SENDMAIL);
- if (! defined($Job->Patch))
- {
- return;
- }
+ # This is all for jobs submitted from the website
+ return if (!defined $Job->Patch);
+
+ #
+ # Build a job summary with only the new errors
+ #
my $Messages = "";
foreach my $Key (@FailureKeys)
@@ -401,7 +451,7 @@ EOF
}
else
{
- LogMsg "BotFailure found in ${LatestName}.err\n";
+ Error "BotFailure found in ${LatestName}.err\n";
}
if ($MessagesFromErr || $MessagesFromLog)
{
@@ -411,15 +461,28 @@ EOF
}
elsif ($BotFailure)
{
- LogMsg "BotFailure found in $TaskDir/err\n";
+ Error "BotFailure found in $TaskDir/err\n";
}
}
+ #
+ # Send a summary of the new errors to the mailing list
+ #
+
+ Debug("\n-------------------- Mailing list email --------------------\n");
+
my $WebSite = ($UseSSL ? "https://" : "http://") . $WebHostName;
if ($Messages)
{
- open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+ if ($Debug)
+ {
+ open(SENDMAIL, ">>&=", 1);
+ }
+ else
+ {
+ open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+ }
print SENDMAIL "From: $RobotEMail\n";
print SENDMAIL "To: $To\n";
print SENDMAIL "Cc: $WinePatchCc\n";
@@ -445,6 +508,14 @@ EOF
print SENDMAIL $Messages;
close SENDMAIL;
}
+ else
+ {
+ Debug("Found no error to report to the mailing list\n");
+ }
+
+ #
+ # Create a .testbot file for the patches website
+ #
my $Patch = $Job->Patch;
if (defined $Patch->WebPatchId and -d "$DataDir/webpatches")
@@ -452,9 +523,12 @@ EOF
my $BaseName = "$DataDir/webpatches/" . $Patch->WebPatchId;
if (open (my $result, ">", "$BaseName.testbot"))
{
- print $result "Status: " . ($Messages ? "Failed" : "OK") . "\n";
- print $result "Job-ID: " . $Job->Id . "\n";
- print $result "URL: $WebSite/JobDetails.pl?Key=" . $Job->GetKey() . "\n";
+ Debug("\n-------------------- WebPatches report --------------------\n");
+ # Only take into account new errors to decide whether the job was
+ # successful or not.
+ DebugTee($result, "Status: ". ($Messages ? "Failed" : "OK") ."\n");
+ DebugTee($result, "Job-ID: ". $Job->Id ."\n");
+ DebugTee($result, "URL: $WebSite/JobDetails.pl?Key=". $Job->GetKey() ."\n");
foreach my $Key (@SortedKeys)
{
@@ -496,7 +570,7 @@ EOF
}
else
{
- LogMsg "Job " . $Job->Id . ": Unable to open '$BaseName.testbot' for writing: $!";
+ Error "Job ". $Job->Id .": Unable to open '$BaseName.testbot' for writing: $!";
}
}
}
@@ -509,37 +583,96 @@ EOF
$ENV{PATH} = "/usr/bin:/bin";
delete $ENV{ENV};
-my $JobId = $ARGV[0];
-if (! $JobId)
+my $Usage;
+sub ValidateNumber($$)
+{
+ my ($Name, $Value) = @_;
+
+ # Validate and untaint the value
+ return $1 if ($Value =~ /^(\d+)$/);
+ Error "$Value is not a valid $Name\n";
+ $Usage = 2;
+ return undef;
+}
+
+my ($JobId);
+while (@ARGV)
{
- die "Usage: WineSendLog.pl JobId";
+ my $Arg = shift @ARGV;
+ if ($Arg eq "--debug")
+ {
+ $Debug = 1;
+ }
+ elsif ($Arg eq "--log-only")
+ {
+ $LogOnly = 1;
+ }
+ elsif ($Arg =~ /^(?:-\?|-h|--help)$/)
+ {
+ $Usage = 0;
+ last;
+ }
+ elsif ($Arg =~ /^-/)
+ {
+ Error "unknown option '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ elsif (!defined $JobId)
+ {
+ $JobId = ValidateNumber('job id', $Arg);
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
}
-# Untaint parameters
-if ($JobId =~ /^(\d+)$/)
+# Check parameters
+if (!defined $Usage)
{
- $JobId = $1;
+ if (!defined $JobId)
+ {
+ Error "you must specify the job id\n";
+ $Usage = 2;
+ }
}
-else
+if (defined $Usage)
{
- LogMsg "Invalid JobId $JobId\n";
- exit(1);
+ if ($Usage)
+ {
+ Error "try '$Name0 --help' for more information\n";
+ exit $Usage;
+ }
+ print "Usage: $Name0 [--debug] [--help] JOBID\n";
+ print "\n";
+ print "Analyze the job's logs and notifies the developer and the patches website.\n";
+ print "\n";
+ print "Where:\n";
+ print " JOBID Id of the job to report on.\n";
+ print " --debug More verbose messages for debugging.\n";
+ print " --log-only Only send error messages to the log instead of also printing them\n";
+ print " on stderr.\n";
+ print " --help Shows this usage message.\n";
+ exit 0;
}
my $Job = CreateJobs()->GetItem($JobId);
-if (! defined($Job))
+if (!defined $Job)
{
- LogMsg "Job $JobId doesn't exist\n";
- exit(1);
+ Error "Job $JobId doesn't exist\n";
+ exit 1;
}
#
-# Analyze the log and notify the developer
+# Analyze the log, notify the developer and the Patches website
#
SendLog($Job);
LogMsg "Log for job $JobId sent\n";
-exit(0);
+exit 0;
--
2.18.0
June 26, 2018