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
January 2022
- 86 participants
- 2418 messages
Re: [PATCH v5 vkd3d 12/13] vkd3d-shader/hlsl: Implement texture gather methods.
by Matteo Bruni
On Wed, Jan 26, 2022 at 11:00 PM Zebediah Figura (she/her)
<zfigura(a)codeweavers.com> wrote:
>
> On 1/26/22 15:48, Matteo Bruni wrote:
> > On Wed, Jan 26, 2022 at 10:33 PM Zebediah Figura (she/her)
> > <zfigura(a)codeweavers.com> wrote:
> >>
> >> On 1/26/22 08:52, Matteo Bruni wrote:
> >>> On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
> >>>>
> >>>> On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura
> >>>> <zfigura(a)codeweavers.com> wrote:
> >>>>>
> >>>>> From: Francisco Casas <fcasas(a)codeweavers.com>
> >>>>>
> >>>>> Signed-off-by: Francisco Casas <fcasas(a)codeweavers.com>
> >>>>> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
> >>>>> ---
> >>>>> v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused
> >>>>> status_out_arg variable, expand the srcs[] array to have size 4, use sm4
> >>>>> register helpers, minor stylistic tweaks.
> >>>>>
> >>>>> libs/vkd3d-shader/hlsl.c | 4 ++
> >>>>> libs/vkd3d-shader/hlsl.h | 4 ++
> >>>>> libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++
> >>>>> libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++-
> >>>>> 4 files changed, 163 insertions(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
> >>>>> index 26175008d..856fb0f9d 100644
> >>>>> --- a/libs/vkd3d-shader/hlsl.c
> >>>>> +++ b/libs/vkd3d-shader/hlsl.c
> >>>>> @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
> >>>>> {
> >>>>> [HLSL_RESOURCE_LOAD] = "load_resource",
> >>>>> [HLSL_RESOURCE_SAMPLE] = "sample",
> >>>>> + [HLSL_RESOURCE_GATHER_RED] = "gather_red",
> >>>>> + [HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
> >>>>> + [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
> >>>>> + [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha",
> >>>>> };
> >>>>>
> >>>>> vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
> >>>>> diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
> >>>>> index 2396adb40..49fa8d9d3 100644
> >>>>> --- a/libs/vkd3d-shader/hlsl.h
> >>>>> +++ b/libs/vkd3d-shader/hlsl.h
> >>>>> @@ -378,6 +378,10 @@ enum hlsl_resource_load_type
> >>>>> {
> >>>>> HLSL_RESOURCE_LOAD,
> >>>>> HLSL_RESOURCE_SAMPLE,
> >>>>> + HLSL_RESOURCE_GATHER_RED,
> >>>>> + HLSL_RESOURCE_GATHER_GREEN,
> >>>>> + HLSL_RESOURCE_GATHER_BLUE,
> >>>>> + HLSL_RESOURCE_GATHER_ALPHA,
> >>>>> };
> >>>>>
> >>>>> struct hlsl_ir_resource_load
> >>>>> diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
> >>>>> index 9b1e5c071..460ba44bb 100644
> >>>>> --- a/libs/vkd3d-shader/hlsl.y
> >>>>> +++ b/libs/vkd3d-shader/hlsl.y
> >>>>> @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
> >>>>> list_add_tail(instrs, &load->node.entry);
> >>>>> return true;
> >>>>> }
> >>>>> + else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
> >>>>> + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
> >>>>> + {
> >>>>> + const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
> >>>>> + enum hlsl_resource_load_type load_type;
> >>>>> + const struct hlsl_type *sampler_type;
> >>>>> + struct hlsl_ir_resource_load *load;
> >>>>> + struct hlsl_ir_node *offset = NULL;
> >>>>> + struct hlsl_ir_load *sampler_load;
> >>>>> + struct hlsl_type *result_type;
> >>>>> + struct hlsl_ir_node *coords;
> >>>>> + unsigned int read_channel;
> >>>>> +
> >>>>> + if (!strcmp(name, "GatherGreen"))
> >>>>> + {
> >>>
> >>> At some point we probably want to introduce an enum for intrinsics and
> >>> e.g. table-driven intrinsic_from_{function,method}() helpers to find
> >>> out which intrinsic a call is supposed to match, if any. Repeatedly
> >>> string-matching the function name like this is a bit ugly and it's
> >>> only going to get worse as we introduce more intrinsics.
> >>> The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the
> >>> problem but that's only going to apply to those that can be inlined
> >>> straight away.
> >>
> >> I agree that a table would help here. I'm not sure I understand the
> >> concern about intrinsics that can't be inlined, though; can you please
> >> elaborate?
> >
> > I'm referring to those intrinsics that shouldn't become expressions
> > but stay as function calls, to make sure they aren't reordered or
> > otherwise optimized (e.g. barriers). As we discussed earlier, they
> > could also be represented by a separate instruction type, in which
> > case they are sort of inlined anyway and, I guess, the existing
> > intrinsic_functions[] table could be a good place for the
> > string-to-enum conversion I'm proposing.
>
> That seems like an orthogonal problem; there's nothing about the way
> intrinsic functions are currently handled that is tied to EXPR types.
> I.e. there's no reason an handler from the intrinsic_functions table has
> to emit an HLSL_IR_EXPR; it could just as easily emit HLSL_IR_INTRINSIC
> or HLSL_IR_BARRIER or whatever it'd end up being called.
Yeah. Just saying that that's what I meant with "intrinsics that can't
be inlined".
Jan. 26, 2022
Re: [PATCH v5 vkd3d 12/13] vkd3d-shader/hlsl: Implement texture gather methods.
by Zebediah Figura (she/her)
On 1/26/22 15:48, Matteo Bruni wrote:
> On Wed, Jan 26, 2022 at 10:33 PM Zebediah Figura (she/her)
> <zfigura(a)codeweavers.com> wrote:
>>
>> On 1/26/22 08:52, Matteo Bruni wrote:
>>> On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
>>>>
>>>> On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura
>>>> <zfigura(a)codeweavers.com> wrote:
>>>>>
>>>>> From: Francisco Casas <fcasas(a)codeweavers.com>
>>>>>
>>>>> Signed-off-by: Francisco Casas <fcasas(a)codeweavers.com>
>>>>> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
>>>>> ---
>>>>> v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused
>>>>> status_out_arg variable, expand the srcs[] array to have size 4, use sm4
>>>>> register helpers, minor stylistic tweaks.
>>>>>
>>>>> libs/vkd3d-shader/hlsl.c | 4 ++
>>>>> libs/vkd3d-shader/hlsl.h | 4 ++
>>>>> libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++
>>>>> libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++-
>>>>> 4 files changed, 163 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
>>>>> index 26175008d..856fb0f9d 100644
>>>>> --- a/libs/vkd3d-shader/hlsl.c
>>>>> +++ b/libs/vkd3d-shader/hlsl.c
>>>>> @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
>>>>> {
>>>>> [HLSL_RESOURCE_LOAD] = "load_resource",
>>>>> [HLSL_RESOURCE_SAMPLE] = "sample",
>>>>> + [HLSL_RESOURCE_GATHER_RED] = "gather_red",
>>>>> + [HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
>>>>> + [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
>>>>> + [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha",
>>>>> };
>>>>>
>>>>> vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
>>>>> diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
>>>>> index 2396adb40..49fa8d9d3 100644
>>>>> --- a/libs/vkd3d-shader/hlsl.h
>>>>> +++ b/libs/vkd3d-shader/hlsl.h
>>>>> @@ -378,6 +378,10 @@ enum hlsl_resource_load_type
>>>>> {
>>>>> HLSL_RESOURCE_LOAD,
>>>>> HLSL_RESOURCE_SAMPLE,
>>>>> + HLSL_RESOURCE_GATHER_RED,
>>>>> + HLSL_RESOURCE_GATHER_GREEN,
>>>>> + HLSL_RESOURCE_GATHER_BLUE,
>>>>> + HLSL_RESOURCE_GATHER_ALPHA,
>>>>> };
>>>>>
>>>>> struct hlsl_ir_resource_load
>>>>> diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
>>>>> index 9b1e5c071..460ba44bb 100644
>>>>> --- a/libs/vkd3d-shader/hlsl.y
>>>>> +++ b/libs/vkd3d-shader/hlsl.y
>>>>> @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
>>>>> list_add_tail(instrs, &load->node.entry);
>>>>> return true;
>>>>> }
>>>>> + else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
>>>>> + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
>>>>> + {
>>>>> + const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
>>>>> + enum hlsl_resource_load_type load_type;
>>>>> + const struct hlsl_type *sampler_type;
>>>>> + struct hlsl_ir_resource_load *load;
>>>>> + struct hlsl_ir_node *offset = NULL;
>>>>> + struct hlsl_ir_load *sampler_load;
>>>>> + struct hlsl_type *result_type;
>>>>> + struct hlsl_ir_node *coords;
>>>>> + unsigned int read_channel;
>>>>> +
>>>>> + if (!strcmp(name, "GatherGreen"))
>>>>> + {
>>>
>>> At some point we probably want to introduce an enum for intrinsics and
>>> e.g. table-driven intrinsic_from_{function,method}() helpers to find
>>> out which intrinsic a call is supposed to match, if any. Repeatedly
>>> string-matching the function name like this is a bit ugly and it's
>>> only going to get worse as we introduce more intrinsics.
>>> The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the
>>> problem but that's only going to apply to those that can be inlined
>>> straight away.
>>
>> I agree that a table would help here. I'm not sure I understand the
>> concern about intrinsics that can't be inlined, though; can you please
>> elaborate?
>
> I'm referring to those intrinsics that shouldn't become expressions
> but stay as function calls, to make sure they aren't reordered or
> otherwise optimized (e.g. barriers). As we discussed earlier, they
> could also be represented by a separate instruction type, in which
> case they are sort of inlined anyway and, I guess, the existing
> intrinsic_functions[] table could be a good place for the
> string-to-enum conversion I'm proposing.
That seems like an orthogonal problem; there's nothing about the way
intrinsic functions are currently handled that is tied to EXPR types.
I.e. there's no reason an handler from the intrinsic_functions table has
to emit an HLSL_IR_EXPR; it could just as easily emit HLSL_IR_INTRINSIC
or HLSL_IR_BARRIER or whatever it'd end up being called.
Jan. 26, 2022
Re: [PATCH vkd3d 3/6] vkd3d-shader/hlsl: Write SM4 unsigned multiplication instructions.
by Zebediah Figura (she/her)
On 1/26/22 02:31, Giovanni Mascellani wrote:
> Hi,
>
> Il 25/01/22 20:06, Zebediah Figura (she/her) ha scritto:
>> I'd also suggest specifying both dsts as optional hlsl_ir_node
>> pointers, where NULL translates to SM4_RT_NULL. That would allow you
>> to use this helper even if both dsts are used.
>
> Actually, a difficulty with this approach is that then, if both
> destinations are specified, we don't know which one is to be used to map
> the sources' writemasks. The ways out I see are to add another argument
> to specify it, to assume that they are identical so either can be used
> or to keep the current interface with which exactly one destination is
> non-NULL (it's true that it is more constraining, but my, admittedly
> probably poor, understanding of Matteo's intentions is that
> optimizations like the one you say are going to happen at a lower level,
> so I wouldn't bother for the time being).
>
> Which one do you prefer?
I guess that optimization would probably have to happen at a lower
level, as you say, and probably even after register allocation.
In that case I'm not sure I have a preference for design.
Jan. 26, 2022
Re: [PATCH v5 vkd3d 12/13] vkd3d-shader/hlsl: Implement texture gather methods.
by Matteo Bruni
On Wed, Jan 26, 2022 at 10:33 PM Zebediah Figura (she/her)
<zfigura(a)codeweavers.com> wrote:
>
> On 1/26/22 08:52, Matteo Bruni wrote:
> > On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
> >>
> >> On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura
> >> <zfigura(a)codeweavers.com> wrote:
> >>>
> >>> From: Francisco Casas <fcasas(a)codeweavers.com>
> >>>
> >>> Signed-off-by: Francisco Casas <fcasas(a)codeweavers.com>
> >>> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
> >>> ---
> >>> v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused
> >>> status_out_arg variable, expand the srcs[] array to have size 4, use sm4
> >>> register helpers, minor stylistic tweaks.
> >>>
> >>> libs/vkd3d-shader/hlsl.c | 4 ++
> >>> libs/vkd3d-shader/hlsl.h | 4 ++
> >>> libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++
> >>> libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++-
> >>> 4 files changed, 163 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
> >>> index 26175008d..856fb0f9d 100644
> >>> --- a/libs/vkd3d-shader/hlsl.c
> >>> +++ b/libs/vkd3d-shader/hlsl.c
> >>> @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
> >>> {
> >>> [HLSL_RESOURCE_LOAD] = "load_resource",
> >>> [HLSL_RESOURCE_SAMPLE] = "sample",
> >>> + [HLSL_RESOURCE_GATHER_RED] = "gather_red",
> >>> + [HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
> >>> + [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
> >>> + [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha",
> >>> };
> >>>
> >>> vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
> >>> diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
> >>> index 2396adb40..49fa8d9d3 100644
> >>> --- a/libs/vkd3d-shader/hlsl.h
> >>> +++ b/libs/vkd3d-shader/hlsl.h
> >>> @@ -378,6 +378,10 @@ enum hlsl_resource_load_type
> >>> {
> >>> HLSL_RESOURCE_LOAD,
> >>> HLSL_RESOURCE_SAMPLE,
> >>> + HLSL_RESOURCE_GATHER_RED,
> >>> + HLSL_RESOURCE_GATHER_GREEN,
> >>> + HLSL_RESOURCE_GATHER_BLUE,
> >>> + HLSL_RESOURCE_GATHER_ALPHA,
> >>> };
> >>>
> >>> struct hlsl_ir_resource_load
> >>> diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
> >>> index 9b1e5c071..460ba44bb 100644
> >>> --- a/libs/vkd3d-shader/hlsl.y
> >>> +++ b/libs/vkd3d-shader/hlsl.y
> >>> @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
> >>> list_add_tail(instrs, &load->node.entry);
> >>> return true;
> >>> }
> >>> + else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
> >>> + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
> >>> + {
> >>> + const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
> >>> + enum hlsl_resource_load_type load_type;
> >>> + const struct hlsl_type *sampler_type;
> >>> + struct hlsl_ir_resource_load *load;
> >>> + struct hlsl_ir_node *offset = NULL;
> >>> + struct hlsl_ir_load *sampler_load;
> >>> + struct hlsl_type *result_type;
> >>> + struct hlsl_ir_node *coords;
> >>> + unsigned int read_channel;
> >>> +
> >>> + if (!strcmp(name, "GatherGreen"))
> >>> + {
> >
> > At some point we probably want to introduce an enum for intrinsics and
> > e.g. table-driven intrinsic_from_{function,method}() helpers to find
> > out which intrinsic a call is supposed to match, if any. Repeatedly
> > string-matching the function name like this is a bit ugly and it's
> > only going to get worse as we introduce more intrinsics.
> > The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the
> > problem but that's only going to apply to those that can be inlined
> > straight away.
>
> I agree that a table would help here. I'm not sure I understand the
> concern about intrinsics that can't be inlined, though; can you please
> elaborate?
I'm referring to those intrinsics that shouldn't become expressions
but stay as function calls, to make sure they aren't reordered or
otherwise optimized (e.g. barriers). As we discussed earlier, they
could also be represented by a separate instruction type, in which
case they are sort of inlined anyway and, I guess, the existing
intrinsic_functions[] table could be a good place for the
string-to-enum conversion I'm proposing.
Jan. 26, 2022
Re: [PATCH 2/2] user32: Reject invalid length in SetWindowPlacement.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=106114
Your paranoid android.
=== w10pro64 (32 bit report) ===
user32:
win.c:2392: Test failed: style 0x200000: expected !100
win.c:2392: Test failed: style 0x300000: expected !100
=== w10pro64 (64 bit report) ===
user32:
win.c:2392: Test failed: style 0x200000: expected !100
win.c:2392: Test failed: style 0x300000: expected !100
=== w10pro64_zh_CN (64 bit report) ===
user32:
win.c:10385: Test failed: pos = 00fa00fa
win.c:10389: Test failed: pos = 00fa00fa
win.c:10393: Test failed: pos = 00fa00fa
=== debian11 (32 bit French report) ===
user32:
win.c:10554: Test failed: Expected foreground window 0, got 01130074
win.c:10560: Test failed: Expected foreground window 00020052, got 01130074
win.c:10577: Test failed: Expected foreground window 00020052, got 01130074
win.c:10579: Test failed: GetActiveWindow() = 00000000
win.c:10579: Test failed: GetFocus() = 00000000
win.c:10581: Test failed: Received WM_ACTIVATEAPP(0), did not expect it.
win.c:10589: Test failed: Expected foreground window 00020052, got 00000000
win.c:10591: Test failed: GetActiveWindow() = 00000000
win.c:10591: Test failed: GetFocus() = 00000000
win.c:10599: Test failed: Received WM_ACTIVATEAPP(1), did not expect it.
=== debian11 (64 bit WoW report) ===
user32:
menu.c:2337: Test failed: test 25
win.c:10577: Test failed: Expected foreground window 0000000000550126, got 00000000011600EC
win.c:10579: Test failed: GetActiveWindow() = 0000000000000000
win.c:10579: Test failed: GetFocus() = 0000000000000000
win.c:10580: Test failed: Received WM_ACTIVATEAPP(1), did not expect it.
win.c:10581: Test failed: Received WM_ACTIVATEAPP(0), did not expect it.
win.c:10589: Test failed: Expected foreground window 0000000000550126, got 0000000000000000
win.c:10591: Test failed: GetActiveWindow() = 0000000000000000
win.c:10591: Test failed: GetFocus() = 0000000000000000
win.c:10599: Test failed: Received WM_ACTIVATEAPP(1), did not expect it.
Jan. 26, 2022
Re: [PATCH] d3d10/tests: Add a test with fx_4_1 binary.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
Jan. 26, 2022
[PATCH v2 2/2] d3dcompiler: Implement D3DWriteBlobToFile().
by Matteo Bruni
From: Nikolay Sivov <nsivov(a)codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2: Rebase on top of the previous patch, tweak TRACE().
dlls/d3dcompiler_43/blob.c | 25 ++++++++++++++++++++++---
dlls/d3dcompiler_43/tests/blob.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dcompiler_43/blob.c b/dlls/d3dcompiler_43/blob.c
index 5cc49fe5699..ee23893576d 100644
--- a/dlls/d3dcompiler_43/blob.c
+++ b/dlls/d3dcompiler_43/blob.c
@@ -514,9 +514,28 @@ HRESULT WINAPI D3DReadFileToBlob(const WCHAR *filename, ID3DBlob **contents)
return S_OK;
}
-HRESULT WINAPI D3DWriteBlobToFile(ID3DBlob* blob, const WCHAR *filename, BOOL overwrite)
+HRESULT WINAPI D3DWriteBlobToFile(ID3DBlob *blob, const WCHAR *filename, BOOL overwrite)
{
- FIXME("blob %p, filename %s, overwrite %d\n", blob, debugstr_w(filename), overwrite);
+ DWORD written_size;
+ SIZE_T data_size;
+ HANDLE file;
+ BOOL ret;
+
+ TRACE("blob %p, filename %s, overwrite %#x.\n", blob, debugstr_w(filename), overwrite);
+
+ file = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, overwrite ? CREATE_ALWAYS : CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ return HRESULT_FROM_WIN32(GetLastError());
- return E_NOTIMPL;
+ data_size = ID3D10Blob_GetBufferSize(blob);
+ ret = WriteFile(file, ID3D10Blob_GetBufferPointer(blob), data_size, &written_size, NULL);
+ CloseHandle(file);
+ if (!ret || data_size != written_size)
+ {
+ WARN("Failed to write blob contents.\n");
+ return E_FAIL;
+ }
+
+ return S_OK;
}
diff --git a/dlls/d3dcompiler_43/tests/blob.c b/dlls/d3dcompiler_43/tests/blob.c
index 9369fcd97f5..400d5940bf7 100644
--- a/dlls/d3dcompiler_43/tests/blob.c
+++ b/dlls/d3dcompiler_43/tests/blob.c
@@ -859,6 +859,37 @@ static void test_D3DReadFileToBlob(void)
DeleteFileW(filename);
ID3D10Blob_Release(blob);
}
+
+static void test_D3DWriteBlobToFile(void)
+{
+ WCHAR temp_dir[MAX_PATH], filename[MAX_PATH];
+ ID3DBlob *blob;
+ HRESULT hr;
+
+ GetTempPathW(ARRAY_SIZE(temp_dir), temp_dir);
+ GetTempFileNameW(temp_dir, NULL, 0, filename);
+
+ hr = D3DCreateBlob(16, &blob);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = D3DWriteBlobToFile(blob, filename, FALSE);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "Unexpected hr %#x.\n", hr);
+
+ hr = D3DWriteBlobToFile(blob, filename, TRUE);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ DeleteFileW(filename);
+
+ hr = D3DWriteBlobToFile(blob, filename, FALSE);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = D3DWriteBlobToFile(blob, filename, FALSE);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "Unexpected hr %#x.\n", hr);
+
+ DeleteFileW(filename);
+
+ ID3D10Blob_Release(blob);
+}
#endif
#endif
@@ -870,6 +901,7 @@ START_TEST(blob)
test_get_blob_part2();
#if D3D_COMPILER_VERSION >= 46
test_D3DReadFileToBlob();
+ test_D3DWriteBlobToFile();
#endif
#endif
}
--
2.34.1
Jan. 26, 2022
[PATCH 1/2] d3dcompiler/tests: Use the relevant d3dcompiler version in blob tests.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
Sort of a missing piece from
910a398b729c61db8e803709368d011fd9b8ce33. Annoyingly some HRESULT on
error changed starting with d3dcompiler_46.
dlls/d3dcompiler_43/tests/blob.c | 205 +++++++++++++++----------------
1 file changed, 97 insertions(+), 108 deletions(-)
diff --git a/dlls/d3dcompiler_43/tests/blob.c b/dlls/d3dcompiler_43/tests/blob.c
index 3e1a3aa3da3..9369fcd97f5 100644
--- a/dlls/d3dcompiler_43/tests/blob.c
+++ b/dlls/d3dcompiler_43/tests/blob.c
@@ -33,11 +33,6 @@
*/
#define D3DERR_INVALIDCALL 0x8876086c
-static HRESULT (WINAPI *pD3DCreateBlob)(SIZE_T, ID3DBlob **);
-static HRESULT (WINAPI *pD3DGetBlobPart)(const void *, SIZE_T, D3D_BLOB_PART, UINT, ID3DBlob **);
-static HRESULT (WINAPI *pD3DReadFileToBlob)(const WCHAR *, ID3DBlob **);
-static HRESULT (WINAPI *pD3DStripShader)(const void *, SIZE_T, UINT, ID3DBlob **);
-
#define MAKE_TAG(ch0, ch1, ch2, ch3) \
((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \
((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 ))
@@ -54,19 +49,20 @@ static HRESULT (WINAPI *pD3DStripShader)(const void *, SIZE_T, UINT, ID3DBlob **
#define TAG_XNAP MAKE_TAG('X', 'N', 'A', 'P')
#define TAG_XNAS MAKE_TAG('X', 'N', 'A', 'S')
+#if D3D_COMPILER_VERSION >= 43
static void test_create_blob(void)
{
ID3D10Blob *blob;
HRESULT hr;
ULONG refcount;
- hr = pD3DCreateBlob(1, NULL);
+ hr = D3DCreateBlob(1, NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DCreateBlob failed with %x\n", hr);
- hr = pD3DCreateBlob(0, NULL);
+ hr = D3DCreateBlob(0, NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DCreateBlob failed with %x\n", hr);
- hr = pD3DCreateBlob(0, &blob);
+ hr = D3DCreateBlob(0, &blob);
ok(hr == S_OK, "D3DCreateBlob failed with %x\n", hr);
refcount = ID3D10Blob_Release(blob);
@@ -119,46 +115,52 @@ static DWORD test_blob_part[] = {
static void test_get_blob_part(void)
{
ID3DBlob *blob, *blob2;
- HRESULT hr;
+ HRESULT hr, expected;
ULONG refcount;
DWORD *dword;
SIZE_T size;
UINT i;
- hr = pD3DCreateBlob(1, &blob2);
+#if D3D_COMPILER_VERSION >= 46
+ expected = D3DERR_INVALIDCALL;
+#else
+ expected = E_FAIL;
+#endif
+
+ hr = D3DCreateBlob(1, &blob2);
ok(hr == S_OK, "D3DCreateBlob failed with %x\n", hr);
blob = blob2;
/* invalid cases */
- hr = pD3DGetBlobPart(NULL, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(NULL, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2);
- hr = pD3DGetBlobPart(NULL, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(NULL, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2);
- hr = pD3DGetBlobPart(NULL, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL);
+ hr = D3DGetBlobPart(NULL, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
- hr = pD3DGetBlobPart(NULL, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL);
+ hr = D3DGetBlobPart(NULL, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
- hr = pD3DGetBlobPart(test_blob_part, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2);
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
- hr = pD3DGetBlobPart(test_blob_part, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL);
+ hr = D3DGetBlobPart(test_blob_part, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 1, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 1, &blob);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2);
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], 0xffffffff, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], 0xffffffff, 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr);
ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2);
@@ -166,7 +168,7 @@ static void test_get_blob_part(void)
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_INPUT_SIGNATURE_BLOB */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -178,7 +180,7 @@ static void test_get_blob_part(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
if (parts[i] == D3D_BLOB_INPUT_SIGNATURE_BLOB)
{
@@ -197,7 +199,7 @@ static void test_get_blob_part(void)
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_OUTPUT_SIGNATURE_BLOB */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_OUTPUT_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_OUTPUT_SIGNATURE_BLOB, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -209,7 +211,7 @@ static void test_get_blob_part(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
if (parts[i] == D3D_BLOB_OUTPUT_SIGNATURE_BLOB)
{
@@ -228,7 +230,7 @@ static void test_get_blob_part(void)
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -241,7 +243,7 @@ static void test_get_blob_part(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
if (parts[i] == D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB
|| parts[i] == D3D_BLOB_INPUT_SIGNATURE_BLOB
@@ -262,19 +264,19 @@ static void test_get_blob_part(void)
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, 0, &blob);
ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
/* D3D_BLOB_ALL_SIGNATURE_BLOB */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_ALL_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_ALL_SIGNATURE_BLOB, 0, &blob);
ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
/* D3D_BLOB_DEBUG_INFO */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_DEBUG_INFO, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_DEBUG_INFO, 0, &blob);
ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
/* D3D_BLOB_LEGACY_SHADER */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_LEGACY_SHADER, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_LEGACY_SHADER, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -286,15 +288,18 @@ static void test_get_blob_part(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
/* There isn't a full DXBC blob returned for D3D_BLOB_LEGACY_SHADER */
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
- ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+#if D3D_COMPILER_VERSION >= 46
+ todo_wine
+#endif
+ ok(hr == expected, "D3DGetBlobPart failed, got %x, expected %x\n", hr, expected);
}
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_XNA_PREPASS_SHADER */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_XNA_PREPASS_SHADER, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_XNA_PREPASS_SHADER, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -306,15 +311,18 @@ static void test_get_blob_part(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
/* There isn't a full DXBC blob returned for D3D_BLOB_XNA_PREPASS_SHADER */
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
- ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+#if D3D_COMPILER_VERSION >= 46
+ todo_wine
+#endif
+ ok(hr == expected, "D3DGetBlobPart failed, got %x, expected %x\n", hr, expected);
}
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_XNA_SHADER */
- hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_XNA_SHADER, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_XNA_SHADER, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -326,43 +334,46 @@ static void test_get_blob_part(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
/* There isn't a full DXBC blob returned for D3D_BLOB_XNA_SHADER */
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
- ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+#if D3D_COMPILER_VERSION >= 46
+ todo_wine
+#endif
+ ok(hr == expected, "D3DGetBlobPart failed, got %x, expected %x\n", hr, expected);
}
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* check corner cases for D3DStripShader */
- hr = pD3DStripShader(test_blob_part, test_blob_part[6], 0xffffffff, &blob);
+ hr = D3DStripShader(test_blob_part, test_blob_part[6], 0xffffffff, &blob);
ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
- hr = pD3DStripShader(test_blob_part, test_blob_part[6], 0, &blob);
+ hr = D3DStripShader(test_blob_part, test_blob_part[6], 0, &blob);
ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
- hr = pD3DStripShader(NULL, test_blob_part[6], 0, &blob);
+ hr = D3DStripShader(NULL, test_blob_part[6], 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "D3DStripShader failed, got %x, expected %x\n", hr, D3DERR_INVALIDCALL);
- hr = pD3DStripShader(test_blob_part, 2, 0, &blob);
+ hr = D3DStripShader(test_blob_part, 2, 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "D3DStripShader failed, got %x, expected %x\n", hr, D3DERR_INVALIDCALL);
- hr = pD3DStripShader(test_blob_part, test_blob_part[6], 0, NULL);
+ hr = D3DStripShader(test_blob_part, test_blob_part[6], 0, NULL);
ok(hr == E_FAIL, "D3DStripShader failed, got %x, expected %x\n", hr, E_FAIL);
- hr = pD3DStripShader(NULL, test_blob_part[6], 0, NULL);
+ hr = D3DStripShader(NULL, test_blob_part[6], 0, NULL);
ok(hr == E_FAIL, "D3DStripShader failed, got %x, expected %x\n", hr, E_FAIL);
- hr = pD3DStripShader(test_blob_part, 0, 0, NULL);
+ hr = D3DStripShader(test_blob_part, 0, 0, NULL);
ok(hr == E_FAIL, "D3DStripShader failed, got %x, expected %x\n", hr, E_FAIL);
/* D3DCOMPILER_STRIP_DEBUG_INFO */
- hr = pD3DStripShader(test_blob_part, test_blob_part[6], D3DCOMPILER_STRIP_DEBUG_INFO, &blob);
+ hr = D3DStripShader(test_blob_part, test_blob_part[6], D3DCOMPILER_STRIP_DEBUG_INFO, &blob);
ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -379,14 +390,14 @@ static void test_get_blob_part(void)
ok(TAG_ISGN == *(dword+149), "ISGN got %#x, expected %#x.\n", *(dword+149), TAG_ISGN);
ok(TAG_OSGN == *(dword+171), "OSGN got %#x, expected %#x.\n", *(dword+171), TAG_OSGN);
- hr = pD3DGetBlobPart(dword, size, D3D_BLOB_DEBUG_INFO, 0, &blob2);
+ hr = D3DGetBlobPart(dword, size, D3D_BLOB_DEBUG_INFO, 0, &blob2);
ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3DCOMPILER_STRIP_REFLECTION_DATA */
- hr = pD3DStripShader(test_blob_part, test_blob_part[6], D3DCOMPILER_STRIP_REFLECTION_DATA, &blob);
+ hr = D3DStripShader(test_blob_part, test_blob_part[6], D3DCOMPILER_STRIP_REFLECTION_DATA, &blob);
ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -594,14 +605,20 @@ static DWORD test_blob_part2[] = {
static void test_get_blob_part2(void)
{
ID3DBlob *blob, *blob2;
- HRESULT hr;
+ HRESULT hr, expected;
ULONG refcount;
DWORD *dword;
SIZE_T size;
UINT i;
+#if D3D_COMPILER_VERSION >= 46
+ expected = D3DERR_INVALIDCALL;
+#else
+ expected = E_FAIL;
+#endif
+
/* D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB */
- hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -613,7 +630,7 @@ static void test_get_blob_part2(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
if (parts[i] == D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB)
{
@@ -632,7 +649,7 @@ static void test_get_blob_part2(void)
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_ALL_SIGNATURE_BLOB */
- hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_ALL_SIGNATURE_BLOB, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_ALL_SIGNATURE_BLOB, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -646,7 +663,7 @@ static void test_get_blob_part2(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
if (parts[i] == D3D_BLOB_ALL_SIGNATURE_BLOB
|| parts[i] == D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB
@@ -669,7 +686,7 @@ static void test_get_blob_part2(void)
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_DEBUG_INFO */
- hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_DEBUG_INFO, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_DEBUG_INFO, 0, &blob);
ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -681,27 +698,30 @@ static void test_get_blob_part2(void)
for (i = 0; i < ARRAY_SIZE(parts); i++)
{
/* There isn't a full DXBC blob returned for D3D_BLOB_DEBUG_INFO */
- hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2);
- ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
+ hr = D3DGetBlobPart(dword, size, parts[i], 0, &blob2);
+#if D3D_COMPILER_VERSION >= 46
+ todo_wine
+#endif
+ ok(hr == expected, "D3DGetBlobPart failed, got %x, expected %x\n", hr, expected);
}
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3D_BLOB_LEGACY_SHADER */
- hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_LEGACY_SHADER, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_LEGACY_SHADER, 0, &blob);
ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
/* D3D_BLOB_XNA_PREPASS_SHADER */
- hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_XNA_PREPASS_SHADER, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_XNA_PREPASS_SHADER, 0, &blob);
ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
/* D3D_BLOB_XNA_SHADER */
- hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_XNA_SHADER, 0, &blob);
+ hr = D3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_XNA_SHADER, 0, &blob);
ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
/* D3DCOMPILER_STRIP_DEBUG_INFO */
- hr = pD3DStripShader(test_blob_part2, test_blob_part2[6], D3DCOMPILER_STRIP_DEBUG_INFO, &blob);
+ hr = D3DStripShader(test_blob_part2, test_blob_part2[6], D3DCOMPILER_STRIP_DEBUG_INFO, &blob);
ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -716,14 +736,14 @@ static void test_get_blob_part2(void)
ok(TAG_SHEX == *(dword+119), "SHEX got %#x, expected %#x.\n", *(dword+119), TAG_SHEX);
ok(TAG_STAT == *(dword+199), "STAT got %#x, expected %#x.\n", *(dword+199), TAG_STAT);
- hr = pD3DGetBlobPart(dword, size, D3D_BLOB_DEBUG_INFO, 0, &blob2);
+ hr = D3DGetBlobPart(dword, size, D3D_BLOB_DEBUG_INFO, 0, &blob2);
ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
/* D3DCOMPILER_STRIP_REFLECTION_DATA */
- hr = pD3DStripShader(test_blob_part2, test_blob_part2[6], D3DCOMPILER_STRIP_REFLECTION_DATA, &blob);
+ hr = D3DStripShader(test_blob_part2, test_blob_part2[6], D3DCOMPILER_STRIP_REFLECTION_DATA, &blob);
ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK);
size = ID3D10Blob_GetBufferSize(blob);
@@ -741,29 +761,7 @@ static void test_get_blob_part2(void)
ok(!refcount, "ID3DBlob has %u references left\n", refcount);
}
-static BOOL load_d3dcompiler_43(void)
-{
- HMODULE module;
-
- if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE;
-
- pD3DCreateBlob = (void*)GetProcAddress(module, "D3DCreateBlob");
- pD3DGetBlobPart = (void*)GetProcAddress(module, "D3DGetBlobPart");
- pD3DStripShader = (void*)GetProcAddress(module, "D3DStripShader");
- return TRUE;
-}
-
-static BOOL load_d3dcompiler_47(void)
-{
- HMODULE module;
-
- if (!(module = LoadLibraryA("d3dcompiler_47.dll")))
- return FALSE;
-
- pD3DReadFileToBlob = (void *)GetProcAddress(module, "D3DReadFileToBlob");
- return TRUE;
-}
-
+#if D3D_COMPILER_VERSION >= 46
static BOOL create_file(WCHAR *filename, const DWORD *data, DWORD data_size)
{
static WCHAR temp_dir[MAX_PATH];
@@ -821,17 +819,17 @@ static void test_D3DReadFileToBlob(void)
DWORD *data;
HRESULT hr;
- hr = pD3DReadFileToBlob(filename, NULL);
+ hr = D3DReadFileToBlob(filename, NULL);
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got unexpected hr %#x.\n", hr);
- hr = pD3DReadFileToBlob(filename, &blob);
+ hr = D3DReadFileToBlob(filename, &blob);
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got unexpected hr %#x.\n", hr);
if (0)
{
/* Crashes on Windows. */
create_file(filename, test_cso_data, ARRAY_SIZE(test_cso_data));
- pD3DReadFileToBlob(filename, NULL);
+ D3DReadFileToBlob(filename, NULL);
DeleteFileW(filename);
}
@@ -840,7 +838,7 @@ static void test_D3DReadFileToBlob(void)
win_skip("File creation failed.\n");
return;
}
- hr = pD3DReadFileToBlob(filename, &blob);
+ hr = D3DReadFileToBlob(filename, &blob);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
data_size = ID3D10Blob_GetBufferSize(blob);
ok(!data_size, "Got unexpected data size.\n");
@@ -852,7 +850,7 @@ static void test_D3DReadFileToBlob(void)
win_skip("File creation failed.\n");
return;
}
- hr = pD3DReadFileToBlob(filename, &blob);
+ hr = D3DReadFileToBlob(filename, &blob);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
data_size = ID3D10Blob_GetBufferSize(blob);
ok(data_size == ARRAY_SIZE(test_cso_data), "Got unexpected data size.\n");
@@ -861,26 +859,17 @@ static void test_D3DReadFileToBlob(void)
DeleteFileW(filename);
ID3D10Blob_Release(blob);
}
+#endif
+#endif
START_TEST(blob)
{
- if (load_d3dcompiler_43())
- {
- test_create_blob();
- test_get_blob_part();
- test_get_blob_part2();
- }
- else
- {
- win_skip("Could not load d3dcompiler_43.dll\n");
- }
-
- if (load_d3dcompiler_47())
- {
- test_D3DReadFileToBlob();
- }
- else
- {
- win_skip("Could not load d3dcompiler_47.dll.\n");
- }
+#if D3D_COMPILER_VERSION >= 43
+ test_create_blob();
+ test_get_blob_part();
+ test_get_blob_part2();
+#if D3D_COMPILER_VERSION >= 46
+ test_D3DReadFileToBlob();
+#endif
+#endif
}
--
2.34.1
Jan. 26, 2022
Re: [PATCH v5 vkd3d 12/13] vkd3d-shader/hlsl: Implement texture gather methods.
by Zebediah Figura (she/her)
On 1/26/22 08:52, Matteo Bruni wrote:
> On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
>>
>> On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura
>> <zfigura(a)codeweavers.com> wrote:
>>>
>>> From: Francisco Casas <fcasas(a)codeweavers.com>
>>>
>>> Signed-off-by: Francisco Casas <fcasas(a)codeweavers.com>
>>> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
>>> ---
>>> v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused
>>> status_out_arg variable, expand the srcs[] array to have size 4, use sm4
>>> register helpers, minor stylistic tweaks.
>>>
>>> libs/vkd3d-shader/hlsl.c | 4 ++
>>> libs/vkd3d-shader/hlsl.h | 4 ++
>>> libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++
>>> libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++-
>>> 4 files changed, 163 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
>>> index 26175008d..856fb0f9d 100644
>>> --- a/libs/vkd3d-shader/hlsl.c
>>> +++ b/libs/vkd3d-shader/hlsl.c
>>> @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
>>> {
>>> [HLSL_RESOURCE_LOAD] = "load_resource",
>>> [HLSL_RESOURCE_SAMPLE] = "sample",
>>> + [HLSL_RESOURCE_GATHER_RED] = "gather_red",
>>> + [HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
>>> + [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
>>> + [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha",
>>> };
>>>
>>> vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
>>> diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
>>> index 2396adb40..49fa8d9d3 100644
>>> --- a/libs/vkd3d-shader/hlsl.h
>>> +++ b/libs/vkd3d-shader/hlsl.h
>>> @@ -378,6 +378,10 @@ enum hlsl_resource_load_type
>>> {
>>> HLSL_RESOURCE_LOAD,
>>> HLSL_RESOURCE_SAMPLE,
>>> + HLSL_RESOURCE_GATHER_RED,
>>> + HLSL_RESOURCE_GATHER_GREEN,
>>> + HLSL_RESOURCE_GATHER_BLUE,
>>> + HLSL_RESOURCE_GATHER_ALPHA,
>>> };
>>>
>>> struct hlsl_ir_resource_load
>>> diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
>>> index 9b1e5c071..460ba44bb 100644
>>> --- a/libs/vkd3d-shader/hlsl.y
>>> +++ b/libs/vkd3d-shader/hlsl.y
>>> @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
>>> list_add_tail(instrs, &load->node.entry);
>>> return true;
>>> }
>>> + else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
>>> + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
>>> + {
>>> + const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
>>> + enum hlsl_resource_load_type load_type;
>>> + const struct hlsl_type *sampler_type;
>>> + struct hlsl_ir_resource_load *load;
>>> + struct hlsl_ir_node *offset = NULL;
>>> + struct hlsl_ir_load *sampler_load;
>>> + struct hlsl_type *result_type;
>>> + struct hlsl_ir_node *coords;
>>> + unsigned int read_channel;
>>> +
>>> + if (!strcmp(name, "GatherGreen"))
>>> + {
>
> At some point we probably want to introduce an enum for intrinsics and
> e.g. table-driven intrinsic_from_{function,method}() helpers to find
> out which intrinsic a call is supposed to match, if any. Repeatedly
> string-matching the function name like this is a bit ugly and it's
> only going to get worse as we introduce more intrinsics.
> The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the
> problem but that's only going to apply to those that can be inlined
> straight away.
I agree that a table would help here. I'm not sure I understand the
concern about intrinsics that can't be inlined, though; can you please
elaborate?
Jan. 26, 2022
[PATCH] server: Use a free list for unallocated object handles.
by Zebediah Figura
The Legend of Heroes: Trails of Cold Steel III suffers from an application bug,
where it tries to wait on a handle after closing it. Because of the usage
patterns of the game and the way Wine allocates handles, the handle is usually
reused by a separate object, which is effectively never signaled, resulting in a
hang.
This patch changes our handle allocation strategy to resemble Windows, and in
the process makes the race much less likely, although still theoretically
possible.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52461
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
A more detailed explanation of the bug can be found in the linked bug report.
server/handle.c | 125 +++++++++++++++++++++++++-----------------------
1 file changed, 65 insertions(+), 60 deletions(-)
diff --git a/server/handle.c b/server/handle.c
index bc692b8ebeb..75b1f7969df 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -41,8 +41,13 @@
struct handle_entry
{
- struct object *ptr; /* object */
- unsigned int access; /* access rights */
+ union
+ {
+ struct object *ptr; /* object */
+ struct handle_entry *next; /* next free entry */
+ } u;
+ unsigned int access; /* access rights */
+ int used; /* is the entry currently in use? */
};
struct handle_table
@@ -51,8 +56,8 @@ struct handle_table
struct process *process; /* process owning this table */
int count; /* number of allocated entries */
int last; /* last used entry */
- int free; /* first entry that may be free */
struct handle_entry *entries; /* handle entries */
+ struct handle_entry *freelist; /* head of free list */
};
static struct handle_table *global_table;
@@ -157,11 +162,11 @@ static void handle_table_dump( struct object *obj, int verbose )
entry = table->entries;
for (i = 0; i <= table->last; i++, entry++)
{
- if (!entry->ptr) continue;
+ if (!entry->used) continue;
fprintf( stderr, " %04x: %p %08x ",
- index_to_handle(i), entry->ptr, entry->access );
- dump_object_name( entry->ptr );
- entry->ptr->ops->dump( entry->ptr, 0 );
+ index_to_handle(i), entry->u.ptr, entry->access );
+ dump_object_name( entry->u.ptr );
+ entry->u.ptr->ops->dump( entry->u.ptr, 0 );
}
}
@@ -176,12 +181,14 @@ static void handle_table_destroy( struct object *obj )
for (i = 0, entry = table->entries; i <= table->last; i++, entry++)
{
- struct object *obj = entry->ptr;
- entry->ptr = NULL;
- if (obj)
+ if (entry->used)
{
+ struct object *obj = entry->u.ptr;
if (table->process)
obj->ops->close_handle( obj, table->process, index_to_handle(i) );
+ entry->used = 0;
+ entry->u.next = table->freelist;
+ table->freelist = entry;
release_object_from_handle( obj );
}
}
@@ -208,7 +215,7 @@ struct handle_table *alloc_handle_table( struct process *process, int count )
table->process = process;
table->count = count;
table->last = -1;
- table->free = 0;
+ table->freelist = NULL;
if ((table->entries = mem_alloc( count * sizeof(*table->entries) ))) return table;
release_object( table );
return NULL;
@@ -234,21 +241,23 @@ static int grow_handle_table( struct handle_table *table )
/* allocate the first free entry in the handle table */
static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned int access )
{
- struct handle_entry *entry = table->entries + table->free;
- int i;
+ struct handle_entry *entry;
- for (i = table->free; i <= table->last; i++, entry++) if (!entry->ptr) goto found;
- if (i >= table->count)
+ if (table->freelist)
{
- if (!grow_handle_table( table )) return 0;
- entry = table->entries + i; /* the entries may have moved */
+ entry = table->freelist;
+ table->freelist = entry->u.next;
}
- table->last = i;
- found:
- table->free = i + 1;
- entry->ptr = grab_object_for_handle( obj );
+ else
+ {
+ if (table->last + 1 >= table->count && !grow_handle_table( table )) return 0;
+ entry = &table->entries[++table->last];
+ }
+
+ entry->used = 1;
+ entry->u.ptr = grab_object_for_handle( obj );
entry->access = access;
- return index_to_handle(i);
+ return index_to_handle( entry - table->entries );
}
/* allocate a handle for an object, incrementing its refcount */
@@ -327,31 +336,10 @@ static struct handle_entry *get_handle( struct process *process, obj_handle_t ha
if (index < 0) return NULL;
if (index > table->last) return NULL;
entry = table->entries + index;
- if (!entry->ptr) return NULL;
+ if (!entry->used) return NULL;
return entry;
}
-/* attempt to shrink a table */
-static void shrink_handle_table( struct handle_table *table )
-{
- struct handle_entry *entry = table->entries + table->last;
- struct handle_entry *new_entries;
- int count = table->count;
-
- while (table->last >= 0)
- {
- if (entry->ptr) break;
- table->last--;
- entry--;
- }
- if (table->last >= count / 4) return; /* no need to shrink */
- if (count < MIN_HANDLE_ENTRIES * 2) return; /* too small to shrink */
- count /= 2;
- if (!(new_entries = realloc( table->entries, count * sizeof(*new_entries) ))) return;
- table->count = count;
- table->entries = new_entries;
-}
-
static void inherit_handle( struct process *parent, const obj_handle_t handle, struct handle_table *table )
{
struct handle_entry *dst, *src;
@@ -362,8 +350,9 @@ static void inherit_handle( struct process *parent, const obj_handle_t handle, s
src = get_handle( parent, handle );
if (!src || !(src->access & RESERVED_INHERIT)) return;
index = handle_to_index( handle );
- if (dst[index].ptr) return;
- grab_object_for_handle( src->ptr );
+ if (dst[index].used) return;
+
+ grab_object_for_handle( src->u.ptr );
dst[index] = *src;
table->last = max( table->last, index );
}
@@ -397,6 +386,18 @@ struct handle_table *copy_handle_table( struct process *process, struct process
{
inherit_handle( parent, std_handles[i], table );
}
+
+ /* iterate in reverse so that low values are allocated first */
+ for (i = table->last; i >= 0; --i)
+ {
+ struct handle_entry *entry = &table->entries[i];
+
+ if (!entry->used)
+ {
+ entry->u.next = table->freelist;
+ table->freelist = entry;
+ }
+ }
}
else
{
@@ -406,14 +407,16 @@ struct handle_table *copy_handle_table( struct process *process, struct process
memcpy( ptr, parent_table->entries, (table->last + 1) * sizeof(struct handle_entry) );
for (i = 0; i <= table->last; i++, ptr++)
{
- if (!ptr->ptr) continue;
- if (ptr->access & RESERVED_INHERIT) grab_object_for_handle( ptr->ptr );
- else ptr->ptr = NULL; /* don't inherit this entry */
+ if (ptr->used && (ptr->access & RESERVED_INHERIT)) grab_object_for_handle( ptr->u.ptr );
+ else
+ {
+ ptr->used = 0;
+ ptr->u.next = table->freelist;
+ table->freelist = ptr;
+ }
}
}
}
- /* attempt to shrink the table */
- shrink_handle_table( table );
return table;
}
@@ -426,12 +429,14 @@ unsigned int close_handle( struct process *process, obj_handle_t handle )
if (!(entry = get_handle( process, handle ))) return STATUS_INVALID_HANDLE;
if (entry->access & RESERVED_CLOSE_PROTECT) return STATUS_HANDLE_NOT_CLOSABLE;
- obj = entry->ptr;
+ obj = entry->u.ptr;
if (!obj->ops->close_handle( obj, process, handle )) return STATUS_HANDLE_NOT_CLOSABLE;
- entry->ptr = NULL;
+
table = handle_is_global(handle) ? global_table : process->handles;
- if (entry < table->entries + table->free) table->free = entry - table->entries;
- if (entry == table->entries + table->last) shrink_handle_table( table );
+ entry->used = 0;
+ entry->u.next = table->freelist;
+ table->freelist = entry;
+
release_object_from_handle( obj );
return STATUS_SUCCESS;
}
@@ -471,7 +476,7 @@ struct object *get_handle_obj( struct process *process, obj_handle_t handle,
set_error( STATUS_INVALID_HANDLE );
return NULL;
}
- obj = entry->ptr;
+ obj = entry->u.ptr;
if (ops && (obj->ops != ops))
{
set_error( STATUS_OBJECT_TYPE_MISMATCH ); /* not the right type */
@@ -513,8 +518,8 @@ obj_handle_t find_inherited_handle( struct process *process, const struct object
for (i = 0, ptr = table->entries; i <= table->last; i++, ptr++)
{
- if (!ptr->ptr) continue;
- if (ptr->ptr->ops != ops) continue;
+ if (!ptr->used) continue;
+ if (ptr->u.ptr->ops != ops) continue;
if (ptr->access & RESERVED_INHERIT) return index_to_handle(i);
}
return 0;
@@ -825,7 +830,7 @@ static int enum_handles( struct process *process, void *user )
for (i = 0, entry = table->entries; i <= table->last; i++, entry++)
{
- if (!entry->ptr) continue;
+ if (!entry->used) continue;
if (!info->handle)
{
info->count++;
@@ -836,7 +841,7 @@ static int enum_handles( struct process *process, void *user )
handle->owner = process->id;
handle->handle = index_to_handle(i);
handle->access = entry->access & ~RESERVED_ALL;
- handle->type = entry->ptr->ops->type->index;
+ handle->type = entry->u.ptr->ops->type->index;
handle->attributes = 0;
if (entry->access & RESERVED_INHERIT) handle->attributes |= OBJ_INHERIT;
if (entry->access & RESERVED_CLOSE_PROTECT) handle->attributes |= OBJ_PROTECT_CLOSE;
--
2.34.1
Jan. 26, 2022