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 3/5] winmm/tests: Add more MIDI stream position tests.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/winmm/tests/midi.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
June 26, 2018
[PATCH 2/5] winmm: Preserve fractions in microseconds to compensate rounding errors.
by Akihiro Sagawa
Otherwise, a song is played faster than expected in some cases.
For instance, we assume that 40 pan control change (CC#10) messages are
expressed in 12.5ms each,
* Prior art omits fractions, i.e. 12ms + 12ms + ... = 480ms.
* Proposal technique saves fractions, i.e. 12ms + 13ms + ... = 500ms.
Ideal duration is 500ms. So, the proposed method is better than prior one.
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/winmm/winmm.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
June 26, 2018
[PATCH 1/5] winmm: Don't allow to set time division property while playing.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/winmm/tests/midi.c | 6 ++++++
dlls/winmm/winmm.c | 8 ++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
June 26, 2018
[PATCH] testbot/WineRunTask: Better detect standard Wine tests.
by Francois Gouget
It's better to take the step dependencies into account and to verify
that the previous step was dealing with a Wine patch.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index ff8aab9f4..9fa263eea 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -441,9 +441,10 @@ if ($Step->Type eq "single")
}
$Script .= "> $RptFileName\r\n";
- # If StepNo is 1 then the user gave us an executable. Then there is no
- # telling if it's going to follow the Wine test standards.
- $IsWineTest = ($StepNo != 1);
+ # If the user gave us an executable there is no telling
+ # if it is going going to follow the Wine test standards.
+ $IsWineTest = (defined $Step->PreviousNo and
+ $Job->Steps->GetItem($Step->PreviousNo)->FileType eq "patchdlls");
}
elsif ($Step->Type eq "suite")
{
--
2.18.0
June 26, 2018
[PATCH] testbot/WineRun*: Standardize a couple of TestBot error messages.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 2 +-
testbot/bin/WineRunTask.pl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index ff04ded0c..176ade6b6 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -458,7 +458,7 @@ foreach my $TestInfo (values %{$Impacts->{Tests}})
}
elsif ($TA->GetLastError() !~ /: No such file or directory/)
{
- FatalTAError($TA, "Could not retrieve '$Local'");
+ FatalTAError($TA, "An error occurred while retrieving '$Local'");
}
}
}
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 9fa263eea..9faae28c3 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -482,7 +482,7 @@ elsif ($Step->Type eq "suite")
Debug(Elapsed($Start), " Sending the script: [$Script]\n");
if (!$TA->SendFileFromString($Script, "script.bat", $TestAgent::SENDFILE_EXE))
{
- FatalTAError($TA, "Could not send the script to the VM");
+ FatalTAError($TA, "Could not send the task script to the VM");
}
--
2.18.0
June 26, 2018
[PATCH] testbot: Rename the Makefiles patch impact to MakeMakefiles.
by Francois Gouget
This makes it clearer that it does not mean a makefile was modified, but
that the make_makefiles script should be rerun.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 2 +-
testbot/bin/build/WineTest.pl | 2 +-
testbot/lib/WineTestBot/PatchUtils.pm | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index 4df107005..a3cb170a0 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -103,7 +103,7 @@ sub ApplyPatch($)
}
my $Impacts = GetPatchImpact($PatchFile, "nounits");
- if ($Impacts->{Makefiles})
+ if ($Impacts->{MakeMakefiles})
{
InfoMsg "\nRunning make_makefiles\n";
system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
diff --git a/testbot/bin/build/WineTest.pl b/testbot/bin/build/WineTest.pl
index 01396f9bf..032ee4640 100755
--- a/testbot/bin/build/WineTest.pl
+++ b/testbot/bin/build/WineTest.pl
@@ -100,7 +100,7 @@ sub ApplyPatch($)
}
my $Impacts = GetPatchImpact($PatchFile, "nounits");
- if ($Impacts->{Makefiles})
+ if ($Impacts->{MakeMakefiles})
{
InfoMsg "\nRunning make_makefiles\n";
system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index c37a1d3ab..b2bfe6a9a 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -178,7 +178,7 @@ sub _HandleFile($$$)
if ($Change eq "new" or $Change eq "rm")
{
# This adds / removes a directory
- $Impacts->{Makefiles} = 1;
+ $Impacts->{MakeMakefiles} = 1;
}
return;
}
@@ -216,7 +216,7 @@ sub _HandleFile($$$)
{
# This may or may not be a Wine patch but the new Makefile.in will be
# added to the build by make_makefiles.
- $Impacts->{WineBuild} = $Impacts->{Makefiles} = 1;
+ $Impacts->{WineBuild} = $Impacts->{MakeMakefiles} = 1;
}
}
}
@@ -289,7 +289,7 @@ sub GetPatchImpact($;$$)
}
elsif ($Line =~ m=^--- \w+/tools/make_makefiles$=)
{
- $Impacts->{WineBuild} = $Impacts->{Makefiles} = 1;
+ $Impacts->{WineBuild} = $Impacts->{MakeMakefiles} = 1;
$Impacts->{IsWinePatch} = 1;
}
elsif ($Line =~ m=^--- /dev/null$=)
--
2.18.0
June 26, 2018
[PATCH vkd3d 12/12] libs/vkd3d-shader: Fix returning multiple components from dot product instructions.
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 | 76 +++++++++++++++++++++++++----------------------
tests/d3d12.c | 23 ++++++++++++++
2 files changed, 64 insertions(+), 35 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index a5e51c9643cb..bfa2bc0dacf7 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2219,6 +2219,35 @@ static uint32_t vkd3d_dxbc_compiler_emit_array_variable(struct vkd3d_dxbc_compil
return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0);
}
+static uint32_t vkd3d_dxbc_compiler_emit_construct_vector(struct vkd3d_dxbc_compiler *compiler,
+ enum vkd3d_component_type component_type, unsigned int component_count,
+ uint32_t val_id, unsigned int val_component_idx, unsigned int val_component_count)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ uint32_t components[VKD3D_VEC4_SIZE];
+ uint32_t type_id, result_id;
+ unsigned int i;
+
+ assert(val_component_idx < val_component_count);
+
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
+ if (val_component_count == 1)
+ {
+ for (i = 0; i < component_count; ++i)
+ components[i] = val_id;
+ result_id = vkd3d_spirv_build_op_composite_construct(builder,
+ type_id, components, component_count);
+ }
+ else
+ {
+ for (i = 0; i < component_count; ++i)
+ components[i] = val_component_idx;
+ result_id = vkd3d_spirv_build_op_vector_shuffle(builder,
+ type_id, val_id, val_id, components, component_count);
+ }
+ return result_id;
+}
+
static uint32_t vkd3d_dxbc_compiler_emit_load_src(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_src_param *src, DWORD write_mask);
@@ -4202,11 +4231,13 @@ static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler,
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
+ enum vkd3d_component_type component_type;
uint32_t type_id, val_id, src_ids[2];
+ unsigned int component_count, i;
DWORD write_mask;
- unsigned int i;
- assert(vkd3d_write_mask_component_count(dst->write_mask) == 1);
+ component_count = vkd3d_write_mask_component_count(dst->write_mask);
+ component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
if (instruction->handler_idx == VKD3DSIH_DP4)
write_mask = VKD3DSP_WRITEMASK_ALL;
@@ -4219,11 +4250,15 @@ static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler,
for (i = 0; i < ARRAY_SIZE(src_ids); ++i)
src_ids[i] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[i], write_mask);
- type_id = vkd3d_spirv_get_type_id(builder,
- vkd3d_component_type_from_data_type(dst->reg.data_type), 1);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpDot, type_id, src_ids[0], src_ids[1]);
+ if (component_count > 1)
+ {
+ val_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler,
+ component_type, component_count, val_id, 0, 1);
+ }
vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id);
}
@@ -5270,35 +5305,6 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured(struct vkd3d_dxbc_compile
}
}
-static uint32_t vkd3d_dxbc_compiler_emit_construct_vec4(struct vkd3d_dxbc_compiler *compiler,
- uint32_t val_id, enum vkd3d_component_type component_type,
- unsigned int component_idx, unsigned int component_count)
-{
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- uint32_t components[VKD3D_VEC4_SIZE];
- uint32_t type_id, result_id;
- unsigned int i;
-
- assert(component_idx < component_count);
-
- type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE);
- if (component_count == 1)
- {
- for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
- components[i] = val_id;
- result_id = vkd3d_spirv_build_op_composite_construct(builder,
- type_id, components, VKD3D_VEC4_SIZE);
- }
- else
- {
- for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
- components[i] = component_idx;
- result_id = vkd3d_spirv_build_op_vector_shuffle(builder,
- type_id, val_id, val_id, components, VKD3D_VEC4_SIZE);
- }
- return result_id;
-}
-
static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
@@ -5325,8 +5331,8 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_
for (component_idx = 0; component_idx < component_count; ++component_idx)
{
/* Mesa Vulkan drivers require the texel parameter to be a vector. */
- texel_id = vkd3d_dxbc_compiler_emit_construct_vec4(compiler,
- val_id, VKD3D_TYPE_UINT, component_idx, component_count);
+ texel_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler,
+ VKD3D_TYPE_UINT, VKD3D_VEC4_SIZE, val_id, component_idx, component_count);
coordinate_id = base_coordinate_id;
if (component_idx)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index a761c0d3cad4..c6220aa0113d 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -4919,6 +4919,26 @@ static void test_shader_instructions(void)
0x00000000, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps_dot2 = {ps_dot2_code, sizeof(ps_dot2_code)};
+ static const DWORD ps_dot3_code[] =
+ {
+#if 0
+ float4 src0;
+ float3 src1;
+
+ float4 main() : SV_Target
+ {
+ return dot(src0, src1);
+ }
+#endif
+ 0x43425844, 0xa75a4a95, 0x5d09936e, 0xdc5c694f, 0x68b6b04f, 0x00000001, 0x000000c8, 0x00000003,
+ 0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
+ 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+ 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000050, 0x00000050, 0x00000014,
+ 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
+ 0x09000010, 0x001020f2, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x00208246, 0x00000000,
+ 0x00000001, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE ps_dot3 = {ps_dot3_code, sizeof(ps_dot3_code)};
static const DWORD ps_eq_code[] =
{
#if 0
@@ -6119,6 +6139,9 @@ static void test_shader_instructions(void)
{&ps_dot2, {{1.0f, 1.0f}, {1.0f, 1.0f}}, {{2.0f}}},
{&ps_dot2, {{1.0f, 1.0f}, {2.0f, 3.0f}}, {{5.0f}}},
+ {&ps_dot3, {{1.0f, 2.0f, 3.0f, 4.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, {{6.0f, 6.0f, 6.0f, 6.0f}}},
+ {&ps_dot3, {{1.0f, 2.0f, 3.0f}, {3.0f, 1.0f, 2.0f}}, {{11.0f, 11.0f, 11.0f, 11.0f}}},
+
{&ps_eq, {{0.0f}, {0.0f}}, {.u = {0xffffffff}}},
{&ps_eq, {{1.0f}, {0.0f}}, {.u = {0x00000000}}},
{&ps_eq, {{0.0f}, {1.0f}}, {.u = {0x00000000}}},
--
2.16.4
June 26, 2018
[PATCH vkd3d 11/12] tests: Add simple test for layered rendering.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
tests/d3d12.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++-
tests/vkd3d_d3d12_test.h | 6 +-
2 files changed, 211 insertions(+), 5 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 0e35fc866bbc..a761c0d3cad4 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -663,7 +663,7 @@ static void check_sub_resource_float_(unsigned int line, ID3D12Resource *texture
{
struct resource_readback rb;
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
check_readback_data_float_(line, &rb, NULL, expected, max_diff);
release_resource_readback(&rb);
}
@@ -745,7 +745,7 @@ static void check_sub_resource_uint16_(unsigned int line, ID3D12Resource *textur
{
struct resource_readback rb;
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
check_readback_data_uint16_(line, &rb, NULL, expected, max_diff);
release_resource_readback(&rb);
}
@@ -17034,6 +17034,211 @@ static void test_geometry_shader(void)
destroy_test_context(&context);
}
+static void test_layered_rendering(void)
+{
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
+ ID3D12GraphicsCommandList *command_list;
+ D3D12_INPUT_LAYOUT_DESC input_layout;
+ struct test_context_desc desc;
+ D3D12_VERTEX_BUFFER_VIEW vbv;
+ struct test_context context;
+ ID3D12CommandQueue *queue;
+ ID3D12PipelineState *pso;
+ ID3D12Device *device;
+ ID3D12Resource *vb;
+ HRESULT hr;
+
+ static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ static const struct
+ {
+ uint32_t color;
+ struct vec4 position;
+ uint32_t layer;
+ }
+ vertices[] =
+ {
+ {0x00000000, {-1.0f, -1.0f, 0.0f, 1.0f}, 2},
+ {0x00000000, {-1.0f, 1.0f, 0.0f, 1.0f}, 2},
+ {0x00000000, { 1.0f, -1.0f, 0.0f, 1.0f}, 2},
+ {0x00000000, { 1.0f, 1.0f, 0.0f, 1.0f}, 2},
+ {0xff00ff00, {-1.0f, -1.0f, 0.0f, 1.0f}, 0},
+ {0xff00ff00, {-1.0f, 1.0f, 0.0f, 1.0f}, 0},
+ {0xff00ff00, { 1.0f, -1.0f, 0.0f, 1.0f}, 0},
+ {0xff00ff00, { 1.0f, 1.0f, 0.0f, 1.0f}, 0},
+ {0xffffff00, {-1.0f, -1.0f, 0.0f, 1.0f}, 3},
+ {0xffffff00, {-1.0f, 1.0f, 0.0f, 1.0f}, 3},
+ {0xffffff00, { 1.0f, -1.0f, 0.0f, 1.0f}, 3},
+ {0xffffff00, { 1.0f, 1.0f, 0.0f, 1.0f}, 3},
+ };
+ static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
+ {
+ {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ {"SV_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 4, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ {"LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 20, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ };
+ static const DWORD vs_code[] =
+ {
+#if 0
+ struct vertex
+ {
+ float4 color : COLOR;
+ float4 position : SV_Position;
+ uint layer : LAYER;
+ };
+
+ struct vertex main(in vertex v)
+ {
+ return v;
+ }
+#endif
+ 0x43425844, 0x96d7f39a, 0x03d06cd5, 0x32c1fa04, 0xd509128f, 0x00000001, 0x000001ac, 0x00000003,
+ 0x0000002c, 0x0000009c, 0x0000010c, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000056, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000001, 0x00000f0f, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
+ 0x00000101, 0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x414c006e, 0x00524559, 0x4e47534f,
+ 0x00000068, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+ 0x0000000f, 0x00000056, 0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x0000000f, 0x00000062,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000e01, 0x4f4c4f43, 0x56530052, 0x736f505f,
+ 0x6f697469, 0x414c006e, 0x00524559, 0x58454853, 0x00000098, 0x00010050, 0x00000026, 0x0100086a,
+ 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x0300005f, 0x00101012,
+ 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000001, 0x00000001,
+ 0x03000065, 0x00102012, 0x00000002, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000,
+ 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001, 0x05000036, 0x00102012, 0x00000002,
+ 0x0010100a, 0x00000002, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
+ static const DWORD gs_code[] =
+ {
+#if 0
+ struct gs_in
+ {
+ float4 color : COLOR;
+ float4 position : SV_Position;
+ uint layer : LAYER;
+ };
+
+ struct gs_out
+ {
+ float4 color : COLOR;
+ float4 position : SV_Position;
+ uint layer : SV_RenderTargetArrayIndex;
+ };
+
+ [maxvertexcount(3)]
+ void main(triangle gs_in vin[3], inout TriangleStream<gs_out> vout)
+ {
+ gs_out o;
+
+ o.color = vin[0].color;
+ o.position = vin[0].position;
+ o.layer = vin[0].layer;
+ vout.Append(o);
+
+ o.color = vin[1].color;
+ o.position = vin[1].position;
+ o.layer = vin[1].layer;
+ vout.Append(o);
+
+ o.color = vin[2].color;
+ o.position = vin[2].position;
+ o.layer = vin[2].layer;
+ vout.Append(o);
+ }
+#endif
+ 0x43425844, 0x29d7c0a0, 0xcf146fd1, 0x5cd36ca7, 0xab2b10ff, 0x00000001, 0x000002bc, 0x00000003,
+ 0x0000002c, 0x0000009c, 0x0000012c, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000056, 0x00000000, 0x00000001,
+ 0x00000003, 0x00000001, 0x00000f0f, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
+ 0x00000101, 0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x414c006e, 0x00524559, 0x3547534f,
+ 0x00000088, 0x00000003, 0x00000008, 0x00000000, 0x0000005c, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x00000000, 0x00000062, 0x00000000, 0x00000001, 0x00000003, 0x00000001,
+ 0x0000000f, 0x00000000, 0x0000006e, 0x00000000, 0x00000004, 0x00000001, 0x00000002, 0x00000e01,
+ 0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x5653006e, 0x6e65525f, 0x54726564, 0x65677261,
+ 0x72724174, 0x6e497961, 0x00786564, 0x58454853, 0x00000188, 0x00020050, 0x00000062, 0x0100086a,
+ 0x0400005f, 0x002010f2, 0x00000003, 0x00000000, 0x05000061, 0x002010f2, 0x00000003, 0x00000001,
+ 0x00000001, 0x0400005f, 0x00201012, 0x00000003, 0x00000002, 0x0100185d, 0x0300008f, 0x00110000,
+ 0x00000000, 0x0100285c, 0x03000065, 0x001020f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000001,
+ 0x00000001, 0x04000067, 0x00102012, 0x00000002, 0x00000004, 0x0200005e, 0x00000003, 0x06000036,
+ 0x001020f2, 0x00000000, 0x00201e46, 0x00000000, 0x00000000, 0x06000036, 0x001020f2, 0x00000001,
+ 0x00201e46, 0x00000000, 0x00000001, 0x06000036, 0x00102012, 0x00000002, 0x0020100a, 0x00000000,
+ 0x00000002, 0x03000075, 0x00110000, 0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00201e46,
+ 0x00000001, 0x00000000, 0x06000036, 0x001020f2, 0x00000001, 0x00201e46, 0x00000001, 0x00000001,
+ 0x06000036, 0x00102012, 0x00000002, 0x0020100a, 0x00000001, 0x00000002, 0x03000075, 0x00110000,
+ 0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00201e46, 0x00000002, 0x00000000, 0x06000036,
+ 0x001020f2, 0x00000001, 0x00201e46, 0x00000002, 0x00000001, 0x06000036, 0x00102012, 0x00000002,
+ 0x0020100a, 0x00000002, 0x00000002, 0x03000075, 0x00110000, 0x00000000, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE gs = {gs_code, sizeof(gs_code)};
+ static const DWORD ps_code[] =
+ {
+#if 0
+ float4 main(float4 color : COLOR) : SV_Target0
+ {
+ return color;
+ }
+#endif
+ 0x43425844, 0xdccf00bf, 0xcc96375e, 0xba21f157, 0xe47b8b1c, 0x00000001, 0x000000d4, 0x00000003,
+ 0x0000002c, 0x0000005c, 0x00000090, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
+ 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+ 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, 0x0000000f,
+ 0x0100086a, 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
+ 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
+
+ memset(&desc, 0, sizeof(desc));
+ desc.rt_array_size = 4;
+ desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
+ desc.no_pipeline = true;
+ if (!init_test_context(&context, &desc))
+ return;
+ device = context.device;
+ command_list = context.list;
+ queue = context.queue;
+
+ input_layout.pInputElementDescs = layout_desc;
+ input_layout.NumElements = ARRAY_SIZE(layout_desc);
+
+ init_pipeline_state_desc(&pso_desc, context.root_signature,
+ context.render_target_desc.Format, &vs, &ps, &input_layout);
+ pso_desc.GS = gs;
+ hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
+ &IID_ID3D12PipelineState, (void **)&pso);
+ ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
+
+ vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
+ vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
+ vbv.StrideInBytes = sizeof(*vertices);
+ vbv.SizeInBytes = sizeof(vertices);
+
+ ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
+
+ ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL);
+ ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
+ ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
+ ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
+ ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
+ ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
+ ID3D12GraphicsCommandList_DrawInstanced(command_list, 12, 1, 0, 0);
+
+ transition_resource_state(command_list, context.render_target,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+
+ check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
+ reset_command_list(command_list, context.allocator);
+ check_sub_resource_uint(context.render_target, 1, queue, command_list, 0xffffffff, 0);
+ reset_command_list(command_list, context.allocator);
+ check_sub_resource_uint(context.render_target, 2, queue, command_list, 0x00000000, 0);
+ reset_command_list(command_list, context.allocator);
+ check_sub_resource_uint(context.render_target, 3, queue, command_list, 0xffffff00, 0);
+
+ ID3D12Resource_Release(vb);
+ ID3D12PipelineState_Release(pso);
+ destroy_test_context(&context);
+}
+
static void test_render_a8(void)
{
static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -17191,5 +17396,6 @@ START_TEST(d3d12)
run_test(test_face_culling);
run_test(test_multithread_command_queue_exec);
run_test(test_geometry_shader);
+ run_test(test_layered_rendering);
run_test(test_render_a8);
}
diff --git a/tests/vkd3d_d3d12_test.h b/tests/vkd3d_d3d12_test.h
index 538479e922c1..b4a9a442a5d2 100644
--- a/tests/vkd3d_d3d12_test.h
+++ b/tests/vkd3d_d3d12_test.h
@@ -313,7 +313,7 @@ static void check_sub_resource_uint_(unsigned int line, ID3D12Resource *texture,
{
struct resource_readback rb;
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
check_readback_data_uint_(line, &rb, NULL, expected, max_diff);
release_resource_readback(&rb);
}
@@ -492,7 +492,7 @@ static ID3D12PipelineState *create_pipeline_state_(unsigned int line, ID3D12Devi
struct test_context_desc
{
- unsigned int rt_width, rt_height;
+ unsigned int rt_width, rt_height, rt_array_size;
DXGI_FORMAT rt_format;
unsigned int rt_descriptor_count;
unsigned int root_signature_flags;
@@ -540,7 +540,7 @@ static void create_render_target_(unsigned int line, struct test_context *contex
resource_desc.Alignment = 0;
resource_desc.Width = desc && desc->rt_width ? desc->rt_width : 32;
resource_desc.Height = desc && desc->rt_height ? desc->rt_height : 32;
- resource_desc.DepthOrArraySize = 1;
+ resource_desc.DepthOrArraySize = desc && desc->rt_array_size ? desc->rt_array_size : 1;
resource_desc.MipLevels = 1;
resource_desc.Format = desc && desc->rt_format ? desc->rt_format : DXGI_FORMAT_R8G8B8A8_UNORM;
resource_desc.SampleDesc.Count = 1;
--
2.16.4
June 26, 2018
[PATCH vkd3d 10/12] libs/vkd3d: Add support for 2D array render target views.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d/command.c | 41 +++++++++++++++++++++++------------------
libs/vkd3d/resource.c | 8 ++++++--
libs/vkd3d/vkd3d_private.h | 2 ++
3 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 82a99fda2511..ee1d3f6e1018 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1583,7 +1583,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCom
}
static void d3d12_command_list_get_fb_extent(struct d3d12_command_list *list,
- uint32_t *width, uint32_t *height)
+ uint32_t *width, uint32_t *height, uint32_t *layer_count)
{
struct d3d12_device *device = list->device;
@@ -1591,11 +1591,15 @@ static void d3d12_command_list_get_fb_extent(struct d3d12_command_list *list,
{
*width = list->fb_width;
*height = list->fb_height;
+ if (layer_count)
+ *layer_count = list->fb_layer_count;
}
else
{
*width = device->vk_info.device_limits.maxFramebufferWidth;
*height = device->vk_info.device_limits.maxFramebufferHeight;
+ if (layer_count)
+ *layer_count = 1;
}
}
@@ -1620,8 +1624,7 @@ static bool d3d12_command_list_update_current_framebuffer(struct d3d12_command_l
fb_desc.renderPass = list->state->u.graphics.render_pass;
fb_desc.attachmentCount = list->state->u.graphics.attachment_count;
fb_desc.pAttachments = &list->views[start_idx];
- d3d12_command_list_get_fb_extent(list, &fb_desc.width, &fb_desc.height);
- fb_desc.layers = 1;
+ d3d12_command_list_get_fb_extent(list, &fb_desc.width, &fb_desc.height, &fb_desc.layers);
if ((vr = VK_CALL(vkCreateFramebuffer(device->vk_device, &fb_desc, NULL, &vk_framebuffer))) < 0)
{
WARN("Failed to create Vulkan framebuffer, vr %d.\n", vr);
@@ -2212,7 +2215,7 @@ static bool d3d12_command_list_begin_render_pass(struct d3d12_command_list *list
begin_desc.renderArea.offset.x = 0;
begin_desc.renderArea.offset.y = 0;
d3d12_command_list_get_fb_extent(list,
- &begin_desc.renderArea.extent.width, &begin_desc.renderArea.extent.height);
+ &begin_desc.renderArea.extent.width, &begin_desc.renderArea.extent.height, NULL);
begin_desc.clearValueCount = 0;
begin_desc.pClearValues = NULL;
VK_CALL(vkCmdBeginRenderPass(list->vk_command_buffer, &begin_desc, VK_SUBPASS_CONTENTS_INLINE));
@@ -3438,6 +3441,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
list->fb_width = 0;
list->fb_height = 0;
+ list->fb_layer_count = 0;
for (i = 0; i < render_target_descriptor_count; ++i)
{
if (single_descriptor_handle)
@@ -3448,10 +3452,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_track_resource_usage(list, rtv_desc->resource);
list->views[i + 1] = rtv_desc->vk_view;
- if (rtv_desc->width > list->fb_width)
- list->fb_width = rtv_desc->width;
- if (rtv_desc->height > list->fb_height)
- list->fb_height = rtv_desc->height;
+ list->fb_width = max(list->fb_width, rtv_desc->width);
+ list->fb_height = max(list->fb_height, rtv_desc->height);
+ list->fb_layer_count = max(list->fb_layer_count, rtv_desc->layer_count);
}
if (depth_stencil_descriptor)
@@ -3460,10 +3463,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_track_resource_usage(list, dsv_desc->resource);
- if (dsv_desc->width > list->fb_width)
- list->fb_width = dsv_desc->width;
- if (dsv_desc->height > list->fb_height)
- list->fb_height = dsv_desc->height;
+ list->fb_width = max(list->fb_width, dsv_desc->width);
+ list->fb_height = max(list->fb_height, dsv_desc->height);
+ list->fb_layer_count = max(list->fb_layer_count, 1);
list->views[0] = dsv_desc->vk_view;
}
@@ -3471,9 +3473,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_invalidate_current_framebuffer(list);
}
-static void d3d12_command_list_clear(struct d3d12_command_list *list, const struct vkd3d_vk_device_procs *vk_procs,
- const struct VkAttachmentDescription *attachment_desc, const struct VkAttachmentReference *color_reference,
- const struct VkAttachmentReference *ds_reference, VkImageView vk_view, size_t width, size_t height,
+static void d3d12_command_list_clear(struct d3d12_command_list *list,
+ const struct vkd3d_vk_device_procs *vk_procs, const struct VkAttachmentDescription *attachment_desc,
+ const struct VkAttachmentReference *color_reference, const struct VkAttachmentReference *ds_reference,
+ VkImageView vk_view, size_t width, size_t height, unsigned int layer_count,
const union VkClearValue *clear_value, unsigned int rect_count, const D3D12_RECT *rects)
{
struct VkSubpassDescription sub_pass_desc;
@@ -3538,7 +3541,7 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, const stru
fb_desc.pAttachments = &vk_view;
fb_desc.width = width;
fb_desc.height = height;
- fb_desc.layers = 1;
+ fb_desc.layers = layer_count;
if ((vr = VK_CALL(vkCreateFramebuffer(list->device->vk_device, &fb_desc, NULL, &vk_framebuffer))) < 0)
{
WARN("Failed to create Vulkan framebuffer, vr %d.\n", vr);
@@ -3615,7 +3618,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra
ds_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
d3d12_command_list_clear(list, &list->device->vk_procs, &attachment_desc, NULL, &ds_reference,
- dsv_desc->vk_view, dsv_desc->width, dsv_desc->height, &clear_value, rect_count, rects);
+ dsv_desc->vk_view, dsv_desc->width, dsv_desc->height, 1, &clear_value, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList *iface,
@@ -3646,7 +3649,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
d3d12_command_list_clear(list, &list->device->vk_procs, &attachment_desc, &color_reference, NULL,
- rtv_desc->vk_view, rtv_desc->width, rtv_desc->height, &clear_value, rect_count, rects);
+ rtv_desc->vk_view, rtv_desc->width, rtv_desc->height, rtv_desc->layer_count,
+ &clear_value, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList *iface,
@@ -4005,6 +4009,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d
memset(list->views, 0, sizeof(list->views));
list->fb_width = 0;
list->fb_height = 0;
+ list->fb_layer_count = 0;
list->current_framebuffer = VK_NULL_HANDLE;
list->current_pipeline = VK_NULL_HANDLE;
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 2ccb84797514..e45c90083229 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1534,6 +1534,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
struct d3d12_resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc)
{
const struct vkd3d_format *format;
+ VkImageViewType vk_view_type;
uint32_t miplevel_idx;
d3d12_rtv_desc_destroy(rtv_desc, device);
@@ -1566,13 +1567,16 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
FIXME("Ignoring plane slice %u.\n", desc->u.Texture2D.PlaneSlice);
miplevel_idx = desc ? desc->u.Texture2D.MipSlice : 0;
- if (vkd3d_create_texture_view(device, resource, format, VK_IMAGE_VIEW_TYPE_2D,
- miplevel_idx, 1, 0, 1, false, &rtv_desc->vk_view) < 0)
+ vk_view_type = resource->desc.DepthOrArraySize > 1
+ ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
+ if (vkd3d_create_texture_view(device, resource, format, vk_view_type,
+ miplevel_idx, 1, 0, VK_REMAINING_ARRAY_LAYERS, false, &rtv_desc->vk_view) < 0)
return;
rtv_desc->format = format->vk_format;
rtv_desc->width = d3d12_resource_desc_get_width(&resource->desc, miplevel_idx);
rtv_desc->height = d3d12_resource_desc_get_height(&resource->desc, miplevel_idx);
+ rtv_desc->layer_count = resource->desc.DepthOrArraySize;
rtv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_RTV;
rtv_desc->resource = resource;
}
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 7506471fbe6c..38f0bf38e215 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -287,6 +287,7 @@ struct d3d12_rtv_desc
VkFormat format;
uint64_t width;
unsigned int height;
+ unsigned int layer_count;
VkImageView vk_view;
struct d3d12_resource *resource;
};
@@ -587,6 +588,7 @@ struct d3d12_command_list
VkImageView views[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1];
unsigned int fb_width;
unsigned int fb_height;
+ unsigned int fb_layer_count;
VkFramebuffer current_framebuffer;
VkPipeline current_pipeline;
--
2.16.4
June 26, 2018
[PATCH vkd3d 09/12] libs/vkd3d-shader: Do not emit output setup for ret in geometry shaders.
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 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 1961ba62f202..a5e51c9643cb 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -4541,7 +4541,8 @@ static void vkd3d_dxbc_compiler_emit_return(struct vkd3d_dxbc_compiler *compiler
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- vkd3d_dxbc_compiler_emit_output_setup_invocation(compiler);
+ if (compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY)
+ vkd3d_dxbc_compiler_emit_output_setup_invocation(compiler);
vkd3d_spirv_build_op_return(builder);
}
--
2.16.4
June 26, 2018
[PATCH vkd3d 08/12] libs/vkd3d-shader: Generate correct SPIR-V code for arrayed shader inputs.
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 | 41 ++++++++++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 881f8109ea3d..1961ba62f202 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2983,16 +2983,17 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_signature_element *signature_element;
const struct vkd3d_shader_register *reg = &dst->reg;
+ uint32_t type_id, ptr_type_id, float_type_id;
const struct vkd3d_spirv_builtin *builtin;
enum vkd3d_component_type component_type;
uint32_t val_id, input_id, var_id;
- uint32_t type_id, float_type_id;
struct vkd3d_symbol reg_symbol;
SpvStorageClass storage_class;
struct rb_entry *entry = NULL;
bool use_private_var = false;
unsigned int array_size;
unsigned int reg_idx;
+ uint32_t i, index;
assert(!reg->idx[0].rel_addr);
assert(!reg->idx[1].rel_addr);
@@ -3071,22 +3072,36 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
if (use_private_var)
{
type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count);
- val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone);
+ for (i = 0; i < max(array_size, 1); ++i)
+ {
+ struct vkd3d_shader_register dst_reg = *reg;
- if (builtin && builtin->fixup_pfn)
- val_id = builtin->fixup_pfn(compiler, val_id);
+ val_id = input_id;
+ if (array_size)
+ {
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassInput, type_id);
+ index = vkd3d_dxbc_compiler_get_constant_uint(compiler, i);
+ val_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder,
+ ptr_type_id, input_id, &index, 1);
+ dst_reg.idx[0].offset = i;
+ }
+ val_id = vkd3d_spirv_build_op_load(builder, type_id, val_id, SpvMemoryAccessMaskNone);
- if (component_type != VKD3D_TYPE_FLOAT)
- {
- float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count);
- val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id);
- }
+ if (builtin && builtin->fixup_pfn)
+ val_id = builtin->fixup_pfn(compiler, val_id);
- if (input_component_count != component_count)
- val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
- val_id, VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
+ if (component_type != VKD3D_TYPE_FLOAT)
+ {
+ float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count);
+ val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id);
+ }
- vkd3d_dxbc_compiler_emit_store_reg(compiler, reg, dst->write_mask, val_id);
+ if (input_component_count != component_count)
+ val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
+ val_id, VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
+
+ vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst_reg, dst->write_mask, val_id);
+ }
}
return input_id;
--
2.16.4
June 26, 2018
[PATCH vkd3d 07/12] libs/vkd3d-shader: Pass register index to vkd3d_find_signature_element_for_reg().
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 | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 28cfb8977ea2..881f8109ea3d 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2949,13 +2949,13 @@ static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shad
static const struct vkd3d_shader_signature_element *vkd3d_find_signature_element_for_reg(
const struct vkd3d_shader_signature *signature, unsigned int *signature_element_index,
- const struct vkd3d_shader_register *reg, DWORD write_mask)
+ unsigned int reg_idx, DWORD write_mask)
{
unsigned int signature_idx;
for (signature_idx = 0; signature_idx < signature->element_count; ++signature_idx)
{
- if (signature->elements[signature_idx].register_index == reg->idx[0].offset
+ if (signature->elements[signature_idx].register_index == reg_idx
&& (signature->elements[signature_idx].mask & 0xff) == write_mask)
{
if (signature_element_index)
@@ -2965,7 +2965,7 @@ static const struct vkd3d_shader_signature_element *vkd3d_find_signature_element
}
FIXME("Could not find shader signature element (register %u, write mask %#x).\n",
- reg->idx[0].offset, write_mask);
+ reg_idx, write_mask);
if (signature_element_index)
*signature_element_index = ~0u;
return NULL;
@@ -3020,7 +3020,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
else
{
signature_element = vkd3d_find_signature_element_for_reg(compiler->input_signature,
- NULL, reg, dst->write_mask);
+ NULL, reg_idx, dst->write_mask);
component_type = signature_element ? signature_element->component_type : VKD3D_TYPE_FLOAT;
input_component_count = component_count;
}
@@ -3164,7 +3164,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp
uint32_t id, var_id;
signature_element = vkd3d_find_signature_element_for_reg(compiler->output_signature,
- &signature_idx, reg, dst->write_mask);
+ &signature_idx, reg->idx[0].offset, dst->write_mask);
builtin = vkd3d_get_spirv_builtin(dst->reg.type, sysval);
component_idx = vkd3d_write_mask_get_component_idx(dst->write_mask);
--
2.16.4
June 26, 2018
[PATCH vkd3d 06/12] libs/vkd3d-shader: Simplify vkd3d_dxbc_compiler_emit_input().
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 | 40 ++++++++++++++++++----------------------
1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index f2a1b1141e23..28cfb8977ea2 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2985,7 +2985,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
const struct vkd3d_shader_register *reg = &dst->reg;
const struct vkd3d_spirv_builtin *builtin;
enum vkd3d_component_type component_type;
- uint32_t val_id = 0, input_id, var_id;
+ uint32_t val_id, input_id, var_id;
uint32_t type_id, float_type_id;
struct vkd3d_symbol reg_symbol;
SpvStorageClass storage_class;
@@ -3043,26 +3043,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx);
}
- if (component_type != VKD3D_TYPE_FLOAT || component_count != VKD3D_VEC4_SIZE)
- {
- type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count);
- val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone);
-
- if (builtin && builtin->fixup_pfn)
- val_id = builtin->fixup_pfn(compiler, val_id);
-
- if (component_type != VKD3D_TYPE_FLOAT)
- {
- float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count);
- val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id);
- }
-
- use_private_var = true;
- }
-
- if (val_id && input_component_count != component_count)
- val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
- val_id, VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
+ use_private_var = component_type != VKD3D_TYPE_FLOAT || component_count != VKD3D_VEC4_SIZE;
vkd3d_symbol_make_register(®_symbol, reg);
@@ -3089,7 +3070,22 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
if (use_private_var)
{
- assert(val_id);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count);
+ val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone);
+
+ if (builtin && builtin->fixup_pfn)
+ val_id = builtin->fixup_pfn(compiler, val_id);
+
+ if (component_type != VKD3D_TYPE_FLOAT)
+ {
+ float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count);
+ val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id);
+ }
+
+ if (input_component_count != component_count)
+ val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
+ val_id, VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
+
vkd3d_dxbc_compiler_emit_store_reg(compiler, reg, dst->write_mask, val_id);
}
--
2.16.4
June 26, 2018
[PATCH vkd3d 05/12] libs/vkd3d-shader: Enable "geometry" capability for SpvBuiltInLayer.
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 | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index cf4fbf6d7a3a..f2a1b1141e23 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2770,8 +2770,21 @@ static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *com
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL && builtin == SpvBuiltInPosition)
- builtin = SpvBuiltInFragCoord;
+ switch (builtin)
+ {
+ case SpvBuiltInPosition:
+ if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL)
+ builtin = SpvBuiltInFragCoord;
+ break;
+ case SpvBuiltInFragDepth:
+ vkd3d_spirv_enable_depth_replacing(builder);
+ break;
+ case SpvBuiltInLayer:
+ vkd3d_spirv_enable_capability(builder, SpvCapabilityGeometry);
+ break;
+ default:
+ break;
+ }
vkd3d_spirv_build_op_decorate1(builder, target_id, SpvDecorationBuiltIn, builtin);
}
@@ -3228,9 +3241,6 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp
compiler->output_setup_function_id = vkd3d_spirv_alloc_id(builder);
}
- if (builtin && builtin->spirv_builtin == SpvBuiltInFragDepth)
- vkd3d_spirv_enable_depth_replacing(builder);
-
return id;
}
--
2.16.4
June 26, 2018
[PATCH vkd3d 04/12] libs/vkd3d-shader: Do not force input register type to float4.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Produces slightly smaller and cleaner SPIR-V code.
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 76 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 70 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 71db4be6b493..cf4fbf6d7a3a 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2886,26 +2886,51 @@ vkd3d_register_builtins[] =
{VKD3DSPR_DEPTHOUT, {VKD3D_TYPE_FLOAT, 1, SpvBuiltInFragDepth}},
};
-static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shader_register_type reg_type,
+static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_sysval(
enum vkd3d_shader_input_sysval_semantic sysval)
{
unsigned int i;
+ if (!sysval)
+ return NULL;
+
for (i = 0; i < ARRAY_SIZE(vkd3d_system_value_builtins); ++i)
{
if (vkd3d_system_value_builtins[i].sysval == sysval)
return &vkd3d_system_value_builtins[i].builtin;
}
+ FIXME("Unhandled builtin (sysval %#x).\n", sysval);
+
+ return NULL;
+}
+
+static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_register(
+ enum vkd3d_shader_register_type reg_type)
+{
+ unsigned int i;
+
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
- || (reg_type != VKD3DSPR_INPUT && reg_type != VKD3DSPR_OUTPUT && reg_type != VKD3DSPR_COLOROUT))
- FIXME("Unhandled builtin (register type %#x, semantic %#x).\n", reg_type, sysval);
+ return NULL;
+}
+
+static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shader_register_type reg_type,
+ enum vkd3d_shader_input_sysval_semantic sysval)
+{
+ const struct vkd3d_spirv_builtin *builtin;
+
+ if ((builtin = get_spirv_builtin_for_sysval(sysval)))
+ return builtin;
+ if ((builtin = get_spirv_builtin_for_register(reg_type)))
+ return builtin;
+
+ if (sysval != VKD3D_SIV_NONE || (reg_type != VKD3DSPR_OUTPUT && reg_type != VKD3DSPR_COLOROUT))
+ FIXME("Unhandled builtin (register type %#x, sysval %#x).\n", reg_type, sysval);
return NULL;
}
@@ -2970,7 +2995,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
reg_idx = reg->idx[0].offset;
}
- builtin = vkd3d_get_spirv_builtin(reg->type, sysval);
+ builtin = get_spirv_builtin_for_sysval(sysval);
component_idx = vkd3d_write_mask_get_component_idx(dst->write_mask);
component_count = vkd3d_write_mask_component_count(dst->write_mask);
@@ -3058,6 +3083,40 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
return input_id;
}
+static void vkd3d_dxbc_compiler_emit_input_register(struct vkd3d_dxbc_compiler *compiler,
+ const struct vkd3d_shader_dst_param *dst)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ const struct vkd3d_shader_register *reg = &dst->reg;
+ const struct vkd3d_spirv_builtin *builtin;
+ struct vkd3d_symbol reg_symbol;
+ uint32_t input_id;
+
+ assert(!reg->idx[0].rel_addr);
+ assert(!reg->idx[1].rel_addr);
+ assert(reg->idx[1].offset == ~0u);
+
+ if (!(builtin = get_spirv_builtin_for_register(reg->type)))
+ {
+ FIXME("Unhandled register %#x.\n", reg->type);
+ return;
+ }
+
+ input_id = vkd3d_dxbc_compiler_emit_variable(compiler,
+ &builder->global_stream, SpvStorageClassInput,
+ builtin->component_type, builtin->component_count);
+ vkd3d_spirv_add_iface_variable(builder, input_id);
+ vkd3d_dxbc_compiler_decorate_builtin(compiler, input_id, builtin->spirv_builtin);
+
+ vkd3d_symbol_make_register(®_symbol, reg);
+ reg_symbol.id = input_id;
+ reg_symbol.info.reg.storage_class = SpvStorageClassInput;
+ reg_symbol.info.reg.component_type = builtin->component_type;
+ reg_symbol.info.reg.write_mask = vkd3d_write_mask_from_component_count(builtin->component_count);
+ vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
+ vkd3d_dxbc_compiler_emit_register_debug_name(builder, input_id, reg);
+}
+
static unsigned int vkd3d_dxbc_compiler_get_output_variable_index(
struct vkd3d_dxbc_compiler *compiler, unsigned int register_idx)
{
@@ -3649,7 +3708,12 @@ static void vkd3d_dxbc_compiler_emit_dcl_tgsm_structured(struct vkd3d_dxbc_compi
static void vkd3d_dxbc_compiler_emit_dcl_input(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
- vkd3d_dxbc_compiler_emit_input(compiler, &instruction->declaration.dst, VKD3D_SIV_NONE);
+ const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst;
+
+ if (dst->reg.type != VKD3DSPR_INPUT)
+ vkd3d_dxbc_compiler_emit_input_register(compiler, dst);
+ else
+ vkd3d_dxbc_compiler_emit_input(compiler, dst, VKD3D_SIV_NONE);
}
static void vkd3d_dxbc_compiler_emit_interpolation_decorations(struct vkd3d_dxbc_compiler *compiler,
--
2.16.4
June 26, 2018
[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