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
December 2019
- 73 participants
- 1394 messages
[PATCH 02/10] d3d10: Implement scalar effect variable set methods.
by Connor McAdams
Implement SetFloat/SetFloatArray, SetInt/SetIntArray, and
SetBool/SetBoolArray methods for the scalar effect variable interface.
Signed-off-by: Connor McAdams <conmanx360(a)gmail.com>
---
dlls/d3d10/effect.c | 83 ++++++++++++++++++++++++++++++++++++++-------
1 file changed, 71 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index f0932409b1..4ecc0753de 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -4212,6 +4212,43 @@ static const struct ID3D10EffectConstantBufferVtbl d3d10_effect_constant_buffer_
d3d10_effect_constant_buffer_GetTextureBuffer,
};
+static inline void write_variable_to_cbuffer(struct d3d10_effect_variable *variable, void *data)
+{
+ memcpy(variable->buffer->u.buffer.local_buffer + variable->buffer_offset, data, variable->type->size_packed);
+
+ variable->buffer->u.buffer.changed = 1;
+}
+
+static void write_variable_array_to_cbuffer(struct d3d10_effect_variable *variable, void *data, UINT count)
+{
+ char *cbuf = variable->buffer->u.buffer.local_buffer + variable->buffer_offset;
+ char *cur_element = data;
+ DWORD element_size;
+ UINT i;
+
+ /*
+ * If for some reason we try to use an array write on a variable that
+ * isn't an array, just default back to the normal variable write.
+ */
+ if (!variable->type->element_count)
+ {
+ write_variable_to_cbuffer(variable, data);
+ return;
+ }
+
+ element_size = variable->type->elementtype->size_packed;
+
+ for (i = 0; i < count; i++)
+ {
+ memcpy(cbuf, cur_element, element_size);
+
+ cur_element += element_size;
+ cbuf += variable->type->stride;
+ }
+
+ variable->buffer->u.buffer.changed = 1;
+}
+
/* ID3D10EffectVariable methods */
static BOOL STDMETHODCALLTYPE d3d10_effect_scalar_variable_IsValid(ID3D10EffectScalarVariable *iface)
@@ -4370,9 +4407,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetRawValue(ID3D10
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetFloat(ID3D10EffectScalarVariable *iface,
float value)
{
- FIXME("iface %p, value %.8e stub!\n", iface, value);
+ struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface);
- return E_NOTIMPL;
+ TRACE("iface %p, value %.8e.\n", iface, value);
+ write_variable_to_cbuffer(effect_var, &value);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloat(ID3D10EffectScalarVariable *iface,
@@ -4383,12 +4423,19 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloat(ID3D10Eff
return E_NOTIMPL;
}
+/*
+ * According to MSDN, array writing functions for Scalar/Vector effect
+ * variables have offset go unused.
+ */
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetFloatArray(ID3D10EffectScalarVariable *iface,
float *values, UINT offset, UINT count)
{
- FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count);
+ struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface);
- return E_NOTIMPL;
+ TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count);
+ write_variable_array_to_cbuffer(effect_var, values, count);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloatArray(ID3D10EffectScalarVariable *iface,
@@ -4402,9 +4449,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloatArray(ID3D
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetInt(ID3D10EffectScalarVariable *iface,
int value)
{
- FIXME("iface %p, value %d stub!\n", iface, value);
+ struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface);
- return E_NOTIMPL;
+ TRACE("iface %p, value %d.\n", iface, value);
+ write_variable_to_cbuffer(effect_var, &value);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetInt(ID3D10EffectScalarVariable *iface,
@@ -4418,9 +4468,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetInt(ID3D10Effec
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetIntArray(ID3D10EffectScalarVariable *iface,
int *values, UINT offset, UINT count)
{
- FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count);
+ struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface);
- return E_NOTIMPL;
+ TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count);
+ write_variable_array_to_cbuffer(effect_var, values, count);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetIntArray(ID3D10EffectScalarVariable *iface,
@@ -4434,9 +4487,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetIntArray(ID3D10
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBool(ID3D10EffectScalarVariable *iface,
BOOL value)
{
- FIXME("iface %p, value %d stub!\n", iface, value);
+ struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface);
- return E_NOTIMPL;
+ TRACE("iface %p, value %d.\n", iface, value);
+ write_variable_to_cbuffer(effect_var, &value);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBool(ID3D10EffectScalarVariable *iface,
@@ -4450,9 +4506,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBool(ID3D10Effe
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBoolArray(ID3D10EffectScalarVariable *iface,
BOOL *values, UINT offset, UINT count)
{
- FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count);
+ struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface);
- return E_NOTIMPL;
+ TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count);
+ write_variable_array_to_cbuffer(effect_var, values, count);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBoolArray(ID3D10EffectScalarVariable *iface,
--
2.20.1
Dec. 7, 2019
[PATCH 01/10] d3d10: Allocate buffers for effect interface local_buffers.
by Connor McAdams
Create ID3D10Buffer interfaces for the constant buffers within the
effect shader.
Signed-off-by: Connor McAdams <conmanx360(a)gmail.com>
---
dlls/d3d10/d3d10_private.h | 10 ++++++
dlls/d3d10/effect.c | 62 ++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index 96020cd4a0..5c6c7a2d72 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -114,6 +114,15 @@ struct d3d10_effect_state_object_variable
} object;
};
+struct d3d10_effect_buffer_variable
+{
+ ID3D10Buffer *buffer;
+ ID3D10ShaderResourceView *resource_view;
+
+ UINT changed;
+ char *local_buffer;
+};
+
/* ID3D10EffectType */
struct d3d10_effect_type
{
@@ -169,6 +178,7 @@ struct d3d10_effect_variable
{
struct d3d10_effect_state_object_variable state;
struct d3d10_effect_shader_variable shader;
+ struct d3d10_effect_buffer_variable buffer;
} u;
};
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 91e713bdf5..f0932409b1 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -2096,6 +2096,53 @@ static HRESULT parse_fx10_local_variable(const char *data, size_t data_size,
return S_OK;
}
+static HRESULT create_variable_buffer(struct d3d10_effect_variable *l, D3D10_CBUFFER_TYPE d3d10_cbuffer_type)
+{
+ D3D10_BUFFER_DESC buffer_desc;
+ D3D10_SUBRESOURCE_DATA subresource_data;
+ D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
+ ID3D10Device *device = l->effect->device;
+ HRESULT hr;
+
+ if (!(l->u.buffer.local_buffer = heap_calloc(l->type->size_unpacked, sizeof(unsigned char))))
+ {
+ ERR("Failed to allocate local constant buffer memory.\n");
+ return E_OUTOFMEMORY;
+ }
+
+ buffer_desc.ByteWidth = l->type->size_unpacked;
+ buffer_desc.Usage = D3D10_USAGE_DEFAULT;
+ buffer_desc.CPUAccessFlags = 0;
+ buffer_desc.MiscFlags = 0;
+ if (d3d10_cbuffer_type == D3D10_CT_CBUFFER)
+ buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
+ else if (d3d10_cbuffer_type == D3D10_CT_TBUFFER)
+ buffer_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
+
+ subresource_data.pSysMem = (const void *)l->u.buffer.local_buffer;
+ subresource_data.SysMemPitch = 0;
+ subresource_data.SysMemSlicePitch = 0;
+
+ if (FAILED(hr = ID3D10Device_CreateBuffer(device, &buffer_desc, &subresource_data, &l->u.buffer.buffer)))
+ return hr;
+
+ if (d3d10_cbuffer_type == D3D10_CT_TBUFFER)
+ {
+ srv_desc.Format = DXGI_FORMAT_R32G32B32A32_UINT;
+ srv_desc.ViewDimension = D3D_SRV_DIMENSION_BUFFER;
+ srv_desc.Buffer.ElementOffset = 0;
+ srv_desc.Buffer.ElementWidth = l->type->size_unpacked / 16;
+
+ if (FAILED(hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)l->u.buffer.buffer,
+ (const D3D10_SHADER_RESOURCE_VIEW_DESC *)&srv_desc, &l->u.buffer.resource_view)))
+ return hr;
+ }
+ else
+ l->u.buffer.resource_view = NULL;
+
+ return S_OK;
+}
+
static HRESULT parse_fx10_local_buffer(const char *data, size_t data_size,
const char **ptr, struct d3d10_effect_variable *l)
{
@@ -2282,6 +2329,12 @@ static HRESULT parse_fx10_local_buffer(const char *data, size_t data_size,
TRACE("\tBasetype: %s.\n", debug_d3d10_shader_variable_type(l->type->basetype));
TRACE("\tTypeclass: %s.\n", debug_d3d10_shader_variable_class(l->type->type_class));
+ if (l->type->size_unpacked && l->type->size_packed)
+ {
+ if (FAILED(hr = create_variable_buffer(l, d3d10_cbuffer_type)))
+ return hr;
+ }
+
return S_OK;
}
@@ -2760,6 +2813,15 @@ static void d3d10_effect_local_buffer_destroy(struct d3d10_effect_variable *l)
}
heap_free(l->annotations);
}
+
+ if (l->u.buffer.buffer)
+ ID3D10Buffer_Release(l->u.buffer.buffer);
+
+ if (l->u.buffer.local_buffer)
+ heap_free(l->u.buffer.local_buffer);
+
+ if (l->u.buffer.resource_view)
+ ID3D10ShaderResourceView_Release(l->u.buffer.resource_view);
}
/* IUnknown methods */
--
2.20.1
Dec. 7, 2019
[PATCH 00/10] Implement d3d10 effect framework functionality
by Connor McAdams
Patch series to implement the functions that are used by steam big
picture mode. Submitting for feedback/ideas on how to improve/change
things.
Connor McAdams (10):
d3d10: Allocate buffers for effect interface local_buffers.
d3d10: Implement scalar effect variable set methods.
d3d10: Implement scalar effect variable get methods.
d3d10: Implement vector effect variable set methods.
d3d10: Implement vector effect variable get methods.
d3d10: Implement matrix effect variable set methods.
d3d10: Implement matrix effect variable get methods.
d3d10: Implement ShaderResource effect variable set method.
d3d10: Get resources used by effect shaders.
d3d10: Apply shader resources for shaders used in pass.
dlls/d3d10/d3d10_private.h | 28 ++
dlls/d3d10/effect.c | 758 +++++++++++++++++++++++++++++++++----
2 files changed, 718 insertions(+), 68 deletions(-)
--
2.20.1
Dec. 7, 2019
Re: [wine-devel] Wine staging 4.21 release
by Olivier F. R. Dierick
Le samedi 07 décembre 2019 à 00:48 -0800, Alan W. Irwin a écrit :
> On 2019-12-05 14:03+0100 Olivier F. R. Dierick wrote:
>
> > Le mercredi 04 décembre 2019 à 14:56 -0800, Alan W. Irwin a écrit :
> > > On 2019-11-30 04:56-0000 Alistair Leslie-Hughes wrote:
> > >
> > > > Added:
> > > > * [47668] kernelbase: Improve stub for ReOpenFile and add small
> > >
> > > [...]
> > >
> > > Could you explain how these patch numbers in your report are
> > > related
> > > with each other?
> > >
> >
> > Hello,
> >
> > The numbers between brackets are winehq.org bugzilla bug numbers.
> >
>
> Hi Olivier:
>
> Thanks for trying to be helpful, but your answer did not respond to
> the question which was about how to account for the total number of
> patches in each category mentioned in these reports.
>
Hello,
Yes it did. The whole point is that you assume patch numbers where it
is in fact patch sets referred to with bug numbers. That's why they
don't account for the total number of patches.
That is enough information for you to know that your assumptions are
wrong and do a bit of research.
You could have found that yourself had you put more effort into looking
at the wine-staging code than into thinking out an over-complicated
pointless formula.
> Could you let me know what the correct formula is for predicting the
> rebased patch number from report to report (which helps to evaluate
> the reliability of the staging patch number statistics that you
> present), and if that formula depends on information (my guess is it
> is the number of patches in staging that have just been deleted by
> thestaging maintainers because they judge those patches to not be
> worthwhile) that you currently do not include in your reports, could
> you include that important information in your following reports?
What makes you think that the information in the report is not
reliable? Have you anything against the staging maintainers?
You're the only one that want to make a formula out of the reports. We
don't have to provide you the formula you seek or provide the
"important" (to you; What makes it important?) information that formula
would need.
Your whole 'predicting to evaluate the reliability of the report' thing
is nonsense. Predicting the future number of patch from report
statistics is pointless as the number of patches is determined by
specific issues and development and there is no way to predict what
will be done next, and it certainly doesn't depend on the previous
changes.
To me, you're just making ground for an argument in a convoluted way.
Regards.
--
        Olivier F. R. Dierick
        o.dierick(a)piezo-forte.be
Dec. 7, 2019
Re: [PATCH 5/5] d3d9: Stop setting the device state when setting the default ZENABLE state.
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=61574
Your paranoid android.
=== debian10 (32 bit report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e8611a4).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7ead8738).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (32 bit WoW report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e85e738).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (64 bit WoW report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e85e738).
Report errors:
d3d9:visual crashed (c0000005)
Dec. 7, 2019
Re: [PATCH 4/5] d3d9: Stop setting the device state in d3d9_device_SetRenderState().
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=61573
Your paranoid android.
=== debian10 (32 bit report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e85e738).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7ead8738).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (32 bit WoW report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e85e738).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (64 bit WoW report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e8e4c70).
Report errors:
d3d9:visual crashed (c0000005)
Dec. 7, 2019
Re: [PATCH 3/5] d3d9: Handle multisample depth resolve in d3d9_device_SetRenderState().
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=61572
Your paranoid android.
=== debian10 (32 bit report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e8611a4).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7ead8738).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (32 bit WoW report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e8611a4).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (64 bit WoW report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e85e738).
Report errors:
d3d9:visual crashed (c0000005)
Dec. 7, 2019
Re: [PATCH 2/5] d3d9: Apply the device state before executing a draw call.
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=61571
Your paranoid android.
=== debian10 (32 bit report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e8611a4).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7eadb1a4).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (32 bit WoW report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e8611a4).
Report errors:
d3d9:visual crashed (c0000005)
=== debian10 (64 bit WoW report) ===
d3d9:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e85e738).
Report errors:
d3d9:visual crashed (c0000005)
Dec. 7, 2019
[PATCH 5/5] d3d9: Stop setting the device state when setting the default ZENABLE state.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/d3d9/device.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 54271240e11..a45f4baa21b 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -1020,8 +1020,6 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
device->auto_mipmaps = 0;
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
!!swapchain_desc.enable_auto_depth_stencil);
- wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE,
- !!swapchain_desc.enable_auto_depth_stencil);
device_reset_viewport_state(device);
}
@@ -4673,8 +4671,6 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
!!swapchain_desc->enable_auto_depth_stencil);
- wined3d_device_set_render_state(device->wined3d_device,
- WINED3D_RS_ZENABLE, !!swapchain_desc->enable_auto_depth_stencil);
device_reset_viewport_state(device);
if (FAILED(hr = d3d9_device_get_swapchains(device)))
--
2.23.0
Dec. 7, 2019
[PATCH 4/5] d3d9: Stop setting the device state in d3d9_device_SetRenderState().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/d3d9/device.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 35364046936..54271240e11 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -2331,22 +2331,11 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_SetRenderState(IDirect3DDevi
D3DRENDERSTATETYPE state, DWORD value)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
- struct wined3d_color factor;
TRACE("iface %p, state %#x, value %#x.\n", iface, state, value);
wined3d_mutex_lock();
wined3d_stateblock_set_render_state(device->update_state, state, value);
- if (!device->recording)
- {
- if (state == D3DRS_BLENDFACTOR)
- {
- wined3d_color_from_d3dcolor(&factor, value);
- wined3d_device_set_blend_state(device->wined3d_device, NULL, &factor);
- }
- else
- wined3d_device_set_render_state(device->wined3d_device, state, value);
- }
if (state == D3DRS_POINTSIZE && value == WINED3D_RESZ_CODE)
resolve_depth_buffer(device);
wined3d_mutex_unlock();
--
2.23.0
Dec. 7, 2019
[PATCH 3/5] d3d9: Handle multisample depth resolve in d3d9_device_SetRenderState().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/d3d9/device.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index be9c2a9d5a1..35364046936 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -2299,6 +2299,34 @@ static HRESULT WINAPI d3d9_device_GetClipPlane(IDirect3DDevice9Ex *iface, DWORD
return hr;
}
+static void resolve_depth_buffer(struct d3d9_device *device)
+{
+ const struct wined3d_stateblock_state *state = wined3d_stateblock_get_state(device->state);
+ struct wined3d_rendertarget_view *wined3d_dsv;
+ struct wined3d_resource *dst_resource;
+ struct wined3d_texture *dst_texture;
+ struct wined3d_resource_desc desc;
+ struct d3d9_surface *d3d9_dsv;
+
+ if (!(dst_texture = state->textures[0]))
+ return;
+ dst_resource = wined3d_texture_get_resource(dst_texture);
+ wined3d_resource_get_desc(dst_resource, &desc);
+ if (desc.format != WINED3DFMT_D24_UNORM_S8_UINT
+ && desc.format != WINED3DFMT_X8D24_UNORM
+ && desc.format != MAKEFOURCC('D','F','1','6')
+ && desc.format != MAKEFOURCC('D','F','2','4')
+ && desc.format != WINED3DFMT_INTZ)
+ return;
+
+ if (!(wined3d_dsv = wined3d_device_get_depth_stencil_view(device->wined3d_device)))
+ return;
+ d3d9_dsv = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_dsv);
+
+ wined3d_device_resolve_sub_resource(device->wined3d_device, dst_resource, 0,
+ wined3d_rendertarget_view_get_resource(wined3d_dsv), d3d9_dsv->sub_resource_idx, desc.format);
+}
+
static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_SetRenderState(IDirect3DDevice9Ex *iface,
D3DRENDERSTATETYPE state, DWORD value)
{
@@ -2319,6 +2347,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_SetRenderState(IDirect3DDevi
else
wined3d_device_set_render_state(device->wined3d_device, state, value);
}
+ if (state == D3DRS_POINTSIZE && value == WINED3D_RESZ_CODE)
+ resolve_depth_buffer(device);
wined3d_mutex_unlock();
return D3D_OK;
--
2.23.0
Dec. 7, 2019
[PATCH 2/5] d3d9: Apply the device state before executing a draw call.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/d3d9/device.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 82fba25ce73..be9c2a9d5a1 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -1821,6 +1821,7 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface,
return D3DERR_INVALIDCALL;
}
+ wined3d_device_apply_stateblock(device->wined3d_device, device->state);
rtv = d3d9_surface_acquire_rendertarget_view(surface_impl);
hr = wined3d_device_clear_rendertarget_view(device->wined3d_device,
rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0);
@@ -2071,6 +2072,7 @@ static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_co
wined3d_color_from_d3dcolor(&c, color);
wined3d_mutex_lock();
+ wined3d_device_apply_stateblock(device->wined3d_device, device->state);
hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
if (SUCCEEDED(hr))
d3d9_rts_flag_auto_gen_mipmap(device);
@@ -2654,6 +2656,7 @@ static HRESULT WINAPI d3d9_device_ValidateDevice(IDirect3DDevice9Ex *iface, DWOR
TRACE("iface %p, pass_count %p.\n", iface, pass_count);
wined3d_mutex_lock();
+ wined3d_device_apply_stateblock(device->wined3d_device, device->state);
hr = wined3d_device_validate_device(device->wined3d_device, pass_count);
wined3d_mutex_unlock();
@@ -2885,6 +2888,7 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
WARN("Called without a valid vertex declaration set.\n");
return D3DERR_INVALIDCALL;
}
+ wined3d_device_apply_stateblock(device->wined3d_device, device->state);
vertex_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
d3d9_device_upload_sysmem_vertex_buffers(device, 0, start_vertex, vertex_count);
d3d9_generate_auto_mipmaps(device);
@@ -2917,6 +2921,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
WARN("Called without a valid vertex declaration set.\n");
return D3DERR_INVALIDCALL;
}
+ wined3d_device_apply_stateblock(device->wined3d_device, device->state);
index_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
d3d9_device_upload_sysmem_vertex_buffers(device, base_vertex_idx, min_vertex_idx, vertex_count);
d3d9_device_upload_sysmem_index_buffer(device, start_idx, index_count);
@@ -3003,6 +3008,7 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface,
return D3DERR_INVALIDCALL;
}
+ wined3d_device_apply_stateblock(device->wined3d_device, device->state);
hr = d3d9_device_prepare_vertex_buffer(device, size);
if (FAILED(hr))
goto done;
@@ -3119,6 +3125,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa
return D3DERR_INVALIDCALL;
}
+ wined3d_device_apply_stateblock(device->wined3d_device, device->state);
hr = d3d9_device_prepare_vertex_buffer(device, vtx_size);
if (FAILED(hr))
goto done;
@@ -3203,6 +3210,8 @@ static HRESULT WINAPI d3d9_device_ProcessVertices(IDirect3DDevice9Ex *iface,
wined3d_mutex_lock();
+ wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+
/* Note that an alternative approach would be to simply create these
* buffers with WINED3D_RESOURCE_ACCESS_MAP_R and update them here like we
* do for draws. In some regards that would be easier, but it seems less
--
2.23.0
Dec. 7, 2019
[PATCH 1/5] wined3d: Introduce wined3d_device_apply_stateblock().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/wined3d/device.c | 93 +++++++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d.spec | 1 +
include/wine/wined3d.h | 1 +
3 files changed, 95 insertions(+)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 0ae841d4e35..50029dfbec2 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3829,6 +3829,99 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d
return device->state.textures[stage];
}
+void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
+ struct wined3d_stateblock *stateblock)
+{
+ const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info;
+ const struct wined3d_stateblock_state *state = &stateblock->stateblock_state;
+ unsigned int i, j;
+
+ TRACE("device %p, stateblock %p.\n", device, stateblock);
+
+ wined3d_stateblock_init_contained_states(stateblock);
+
+ wined3d_device_set_vertex_shader(device, state->vs);
+ wined3d_device_set_pixel_shader(device, state->ps);
+
+ for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i)
+ wined3d_device_set_vs_consts_f(device, i, 1, &state->vs_consts_f[i]);
+ for (i = 0; i < ARRAY_SIZE(state->vs_consts_i); ++i)
+ wined3d_device_set_vs_consts_i(device, i, 1, &state->vs_consts_i[i]);
+ for (i = 0; i < ARRAY_SIZE(state->vs_consts_b); ++i)
+ wined3d_device_set_vs_consts_b(device, i, 1, &state->vs_consts_b[i]);
+
+ for (i = 0; i < ARRAY_SIZE(state->ps_consts_f); ++i)
+ wined3d_device_set_ps_consts_f(device, i, 1, &state->ps_consts_f[i]);
+ for (i = 0; i < ARRAY_SIZE(state->ps_consts_i); ++i)
+ wined3d_device_set_ps_consts_i(device, i, 1, &state->ps_consts_i[i]);
+ for (i = 0; i < ARRAY_SIZE(state->ps_consts_b); ++i)
+ wined3d_device_set_ps_consts_b(device, i, 1, &state->ps_consts_b[i]);
+
+ for (i = 0; i < ARRAY_SIZE(state->light_state->light_map); ++i)
+ {
+ const struct wined3d_light_info *light;
+
+ LIST_FOR_EACH_ENTRY(light, &state->light_state->light_map[i], struct wined3d_light_info, entry)
+ {
+ wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms);
+ wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1);
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(state->rs); ++i)
+ {
+ if (i == WINED3D_RS_BLENDFACTOR)
+ {
+ struct wined3d_color color;
+ wined3d_color_from_d3dcolor(&color, state->rs[i]);
+ wined3d_device_set_blend_state(device, NULL, &color);
+ }
+ else
+ wined3d_device_set_render_state(device, i, state->rs[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(state->texture_states); ++i)
+ {
+ for (j = 0; j < ARRAY_SIZE(state->texture_states[i]); ++j)
+ wined3d_device_set_texture_stage_state(device, i, j, state->texture_states[i][j]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(state->sampler_states); ++i)
+ {
+ DWORD stage = i;
+ if (stage >= WINED3D_MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - WINED3D_MAX_FRAGMENT_SAMPLERS;
+ for (j = 0; j < ARRAY_SIZE(state->sampler_states[j]); ++j)
+ wined3d_device_set_sampler_state(device, stage, j, state->sampler_states[i][j]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(state->transforms); ++i)
+ wined3d_device_set_transform(device, i, &state->transforms[i]);
+
+ wined3d_device_set_index_buffer(device, state->index_buffer, state->index_format, 0);
+ wined3d_device_set_base_vertex_index(device, state->base_vertex_index);
+ wined3d_device_set_vertex_declaration(device, state->vertex_declaration);
+ wined3d_device_set_material(device, &state->material);
+ wined3d_device_set_viewports(device, 1, &state->viewport);
+ wined3d_device_set_scissor_rects(device, 1, &state->scissor_rect);
+
+ for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
+ {
+ wined3d_device_set_stream_source(device, i, state->streams[i].buffer,
+ state->streams[i].offset, state->streams[i].stride);
+ wined3d_device_set_stream_source_freq(device, i,
+ state->streams[i].frequency | state->streams[i].flags);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
+ wined3d_device_set_texture(device, i < WINED3D_MAX_FRAGMENT_SAMPLERS ? i
+ : WINED3DVERTEXTEXTURESAMPLER0 + i - WINED3D_MAX_FRAGMENT_SAMPLERS, state->textures[i]);
+
+ for (i = 0; i < ARRAY_SIZE(state->clip_planes); ++i)
+ wined3d_device_set_clip_plane(device, i, &state->clip_planes[i]);
+
+ TRACE("Applied stateblock %p.\n", stateblock);
+}
+
HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps)
{
TRACE("device %p, caps %p.\n", device, caps);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index e03c57055b7..c8ef442c72d 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -37,6 +37,7 @@
@ cdecl wined3d_buffer_incref(ptr)
@ cdecl wined3d_device_acquire_focus_window(ptr ptr)
+@ cdecl wined3d_device_apply_stateblock(ptr ptr)
@ cdecl wined3d_device_begin_scene(ptr)
@ cdecl wined3d_device_clear(ptr long ptr long ptr float long)
@ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr long ptr float long)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 4b5d4e02f9b..a6eaaca468c 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2287,6 +2287,7 @@ struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buf
ULONG __cdecl wined3d_buffer_incref(struct wined3d_buffer *buffer);
HRESULT __cdecl wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window);
+void __cdecl wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_stateblock *stateblock);
HRESULT __cdecl wined3d_device_begin_scene(struct wined3d_device *device);
HRESULT __cdecl wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, const RECT *rects, DWORD flags,
const struct wined3d_color *color, float z, DWORD stencil);
--
2.23.0
Dec. 7, 2019
Re: [PATCH] wineqtdecoder: Fix macos compile error
by Zebediah Figura
On 12/7/19 12:03 AM, Alistair Leslie-Hughes wrote:
> Regression of 498179b4482026091bf7376c0d2ac9a036e7ca0e
>
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
> ---
> dlls/wineqtdecoder/qtsplitter.c | 10 ++++------
> 1 file changed, 4 insertions(+), 6 deletions(-)
>
Hello Alistair, thanks for catching these errors.
> diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
> index 5b1e82ebc9b..956dd0a7d0d 100644
> --- a/dlls/wineqtdecoder/qtsplitter.c
> +++ b/dlls/wineqtdecoder/qtsplitter.c
> @@ -285,7 +285,7 @@ static HRESULT qt_splitter_start_stream(struct strmbase_filter *iface, REFERENCE
> QTSplitter *filter = impl_from_strmbase_filter(iface);
> HRESULT hr = VFW_E_NOT_CONNECTED, pin_hr;
>
> - EnterCriticalSection(&This->csReceive);
> + EnterCriticalSection(&filter->csReceive);
>
> if (filter->pVideo_Pin)
> pin_hr = BaseOutputPinImpl_Active(&filter->pVideo_Pin->pin);
> @@ -297,7 +297,7 @@ static HRESULT qt_splitter_start_stream(struct strmbase_filter *iface, REFERENCE
> hr = pin_hr;
> SetEvent(filter->runEvent);
>
> - LeaveCriticalSection(&This->csReceive);
> + LeaveCriticalSection(&filter->csReceive);
>
> return hr;
> }
> @@ -306,10 +306,10 @@ static HRESULT qt_splitter_cleanup_stream(struct strmbase_filter *iface)
> {
> QTSplitter *filter = impl_from_strmbase_filter(iface);
>
> - EnterCriticalSection(&This->csReceive);
> + EnterCriticalSection(&filter->csReceive);
> IAsyncReader_BeginFlush(filter->pInputPin.pReader);
> IAsyncReader_EndFlush(filter->pInputPin.pReader);
> - LeaveCriticalSection(&This->csReceive);
> + LeaveCriticalSection(&filter->csReceive);
>
> return S_OK;
> }
> @@ -1170,8 +1170,6 @@ static HRESULT WINAPI QTOutPin_QueryInterface(IPin *iface, REFIID riid, void **p
> *ppv = iface;
> else if (IsEqualIID(riid, &IID_IPin))
> *ppv = iface;
> - else if (IsEqualIID(riid, &IID_IMediaSeeking))
> - *ppv = &This->sourceSeeking.IMediaSeeking_iface;
> else if (IsEqualIID(riid, &IID_IQualityControl))
> *ppv = &This->IQualityControl_iface;
>
>
Did you mean to do this?
Dec. 7, 2019
Re: Winter is coming
by Sveinar Søpler
All i want for christmas is... for someone to make a huge push towards
releasing vkd3d_1.2, so that it would not pass yet another year to
actually have working D3D12 out-of-the-box with a release version of wine :)
Yeah, i know its a huge wish in the likes of "world peace" and the
likes, but well.. one can always wish :)
Sveinar
On 06.12.2019 20:25, Alexandre Julliard wrote:
> Folks,
>
> As you are probably aware, we are now entering the code freeze season.
> The plan is to start the code freeze after the next release, i.e. one
> week from today. So if there are things you want to see in Wine 5.0, now
> is the last moment to submit them...
>
Dec. 7, 2019
[PATCH vkd3d v4] Support RS 1.0 VOLATILE descriptors
by Sveinar Søpler
This fixes bug: https://bugs.winehq.org/show_bug.cgi?id=46410
v4: Rebase and resubmit patch.
Original commit message:
From: post(a)arntzen-software.no
Use EXT_descriptor_indexing's UPDATE_AFTER_BIND feature to support
semantics required by RS 1.0 VOLATILE descriptors. We implement this by
deferring all updates of desciptor sets until Submit time.
This is fine, as command buffers cannot be executed simultaneously on
D3D12, so at Submit time, we know that the command buffer is not being
executed on the GPU, and updating descriptors for multiple submissions
is correct.
If EXT_descriptor_indexing is not available, the fallback is the older
method, which matches RS 1.1 STATIC descriptor model.
Signed-off-by: Sveinar Søpler <cybermax(a)dexter.no>
Dec. 7, 2019
[PATCH vkd3d v4] Allocate one large buffer for a heap and offset into it.
by Hans-Kristian Arntzen
Greatly reduce VA allocations we have to make and makes returned VA more
sensible, and better matches returned VAs we see on native drivers.
D3D12 usage flags for buffers seem generic enough that there is no
obvious benefit to place smaller VkBuffers on top of VkDeviceMemory.
Ideally, physical_buffer_address is used here, but this works as a good
fallback if that path is added later.
With this patch and previous VA optimization, I'm observing a 2.0-2.5%
FPS uplift on SOTTR when CPU bound.
Signed-off-by: Hans-Kristian Arntzen <post(a)arntzen-software.no>
---
libs/vkd3d/command.c | 14 ++--
libs/vkd3d/resource.c | 133 ++++++++++++++++++++++++++++++++-----
libs/vkd3d/vkd3d_private.h | 2 +
3 files changed, 128 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 8a7ff66..8bff7ea 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -3081,8 +3081,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12Graphics
d3d12_command_list_end_current_render_pass(list);
- buffer_copy.srcOffset = src_offset;
- buffer_copy.dstOffset = dst_offset;
+ buffer_copy.srcOffset = src_offset + src_resource->heap_offset;
+ buffer_copy.dstOffset = dst_offset + dst_resource->heap_offset;
buffer_copy.size = byte_count;
VK_CALL(vkCmdCopyBuffer(list->vk_command_buffer,
@@ -3395,6 +3395,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
vk_image_buffer_copy_from_d3d12(&buffer_image_copy, &dst->u.PlacedFootprint,
src->u.SubresourceIndex, &src_resource->desc, dst_format, src_box, dst_x, dst_y, dst_z);
+ buffer_image_copy.bufferOffset += dst_resource->heap_offset;
VK_CALL(vkCmdCopyImageToBuffer(list->vk_command_buffer,
src_resource->u.vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
dst_resource->u.vk_buffer, 1, &buffer_image_copy));
@@ -3424,6 +3425,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
vk_buffer_image_copy_from_d3d12(&buffer_image_copy, &src->u.PlacedFootprint,
dst->u.SubresourceIndex, &dst_resource->desc, src_format, src_box, dst_x, dst_y, dst_z);
+ buffer_image_copy.bufferOffset += src_resource->heap_offset;
VK_CALL(vkCmdCopyBufferToImage(list->vk_command_buffer,
src_resource->u.vk_buffer, dst_resource->u.vk_image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &buffer_image_copy));
@@ -3504,8 +3506,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm
assert(d3d12_resource_is_buffer(src_resource));
assert(src_resource->desc.Width == dst_resource->desc.Width);
- vk_buffer_copy.srcOffset = 0;
- vk_buffer_copy.dstOffset = 0;
+ vk_buffer_copy.srcOffset = src_resource->heap_offset;
+ vk_buffer_copy.dstOffset = dst_resource->heap_offset;
vk_buffer_copy.size = dst_resource->desc.Width;
VK_CALL(vkCmdCopyBuffer(list->vk_command_buffer,
src_resource->u.vk_buffer, dst_resource->u.vk_buffer, 1, &vk_buffer_copy));
@@ -3962,8 +3964,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC
vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.buffer = resource->u.vk_buffer;
- vk_barrier.offset = 0;
- vk_barrier.size = VK_WHOLE_SIZE;
+ vk_barrier.offset = resource->heap_offset;
+ vk_barrier.size = resource->desc.Width;
VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer, src_stage_mask, dst_stage_mask, 0,
0, NULL, 1, &vk_barrier, 0, NULL));
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index f40d986..ed2b18f 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -315,6 +315,8 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
return refcount;
}
+static ULONG d3d12_resource_decref(struct d3d12_resource *resource);
+
static void d3d12_heap_destroy(struct d3d12_heap *heap)
{
struct d3d12_device *device = heap->device;
@@ -322,6 +324,9 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap)
TRACE("Destroying heap %p.\n", heap);
+ if (heap->buffer_resource)
+ d3d12_resource_decref(heap->buffer_resource);
+
vkd3d_private_store_destroy(&heap->private_store);
VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
@@ -562,6 +567,12 @@ static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc, const struct d3d1
return S_OK;
}
+static HRESULT d3d12_resource_create(struct d3d12_device *device,
+ const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
+ const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
+ const D3D12_CLEAR_VALUE *optimized_clear_value, bool placed,
+ struct d3d12_resource **resource);
+
static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
struct d3d12_device *device, const D3D12_HEAP_DESC *desc, const struct d3d12_resource *resource)
{
@@ -569,6 +580,9 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
VkDeviceSize vk_memory_size;
HRESULT hr;
int rc;
+ bool buffers_allowed;
+ D3D12_RESOURCE_DESC resource_desc;
+ D3D12_RESOURCE_STATES initial_resource_state;
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
heap->refcount = 1;
@@ -579,6 +593,7 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
heap->map_ptr = NULL;
heap->map_count = 0;
+ heap->buffer_resource = NULL;
if (!heap->desc.Properties.CreationNodeMask)
heap->desc.Properties.CreationNodeMask = 1;
@@ -606,6 +621,53 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
return hr;
}
+ buffers_allowed = !(heap->desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS);
+ if (buffers_allowed && !resource)
+ {
+ /* Create a single omnipotent buffer which fills the entire heap.
+ * Whenever we place buffer resources on this heap, we'll just offset this VkBuffer.
+ * This allows us to keep VA space somewhat sane, and keeps number of (limited) VA allocations down.
+ * One possible downside is that the buffer might be slightly slower to access,
+ * but D3D12 has very lenient usage flags for buffers. */
+
+ memset(&resource_desc, 0, sizeof(resource_desc));
+ resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ resource_desc.Width = desc->SizeInBytes;
+ resource_desc.Height = 1;
+ resource_desc.DepthOrArraySize = 1;
+ resource_desc.MipLevels = 1;
+ resource_desc.SampleDesc.Count = 1;
+ resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+
+ switch (desc->Properties.Type)
+ {
+ case D3D12_HEAP_TYPE_UPLOAD:
+ initial_resource_state = D3D12_RESOURCE_STATE_GENERIC_READ;
+ break;
+
+ case D3D12_HEAP_TYPE_READBACK:
+ initial_resource_state = D3D12_RESOURCE_STATE_COPY_DEST;
+ break;
+
+ default:
+ /* Upload and readback heaps do not allow UAV access, only enable this flag for other heaps. */
+ resource_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
+ initial_resource_state = D3D12_RESOURCE_STATE_COMMON;
+ break;
+ }
+
+ if (FAILED(hr = d3d12_resource_create(device, &desc->Properties, desc->Flags,
+ &resource_desc, initial_resource_state,
+ NULL, false, &heap->buffer_resource)))
+ {
+ heap->buffer_resource = NULL;
+ return hr;
+ }
+ /* This internal resource should not own a reference on the device.
+ * d3d12_resource_create takes a reference on the device. */
+ d3d12_device_release(device);
+ }
+
if (resource)
{
if (d3d12_resource_is_buffer(resource))
@@ -623,8 +685,16 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
heap->desc.SizeInBytes = vk_memory_size;
}
+ else if (heap->buffer_resource)
+ {
+ hr = vkd3d_allocate_buffer_memory(device, heap->buffer_resource->u.vk_buffer,
+ &heap->desc.Properties, heap->desc.Flags,
+ &heap->vk_memory, &heap->vk_memory_type, &vk_memory_size);
+ }
else
{
+ /* Allocate generic memory which should hopefully match up with whatever resources
+ * we want to place here. */
memory_requirements.size = heap->desc.SizeInBytes;
memory_requirements.alignment = heap->desc.Alignment;
memory_requirements.memoryTypeBits = ~(uint32_t)0;
@@ -637,6 +707,11 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
{
vkd3d_private_store_destroy(&heap->private_store);
pthread_mutex_destroy(&heap->mutex);
+ if (heap->buffer_resource)
+ {
+ d3d12_resource_decref(heap->buffer_resource);
+ heap->buffer_resource = NULL;
+ }
return hr;
}
@@ -1030,13 +1105,16 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12
if (resource->flags & VKD3D_RESOURCE_EXTERNAL)
return;
- if (resource->gpu_address)
- vkd3d_gpu_va_allocator_free(&device->gpu_va_allocator, resource->gpu_address);
+ if (!(resource->flags & VKD3D_RESOURCE_PLACED_BUFFER))
+ {
+ if (resource->gpu_address)
+ vkd3d_gpu_va_allocator_free(&device->gpu_va_allocator, resource->gpu_address);
- if (d3d12_resource_is_buffer(resource))
- VK_CALL(vkDestroyBuffer(device->vk_device, resource->u.vk_buffer, NULL));
- else
- VK_CALL(vkDestroyImage(device->vk_device, resource->u.vk_image, NULL));
+ if (d3d12_resource_is_buffer(resource))
+ VK_CALL(vkDestroyBuffer(device->vk_device, resource->u.vk_buffer, NULL));
+ else
+ VK_CALL(vkDestroyImage(device->vk_device, resource->u.vk_image, NULL));
+ }
if (resource->flags & VKD3D_RESOURCE_DEDICATED_HEAP)
d3d12_heap_destroy(resource->heap);
@@ -1738,7 +1816,7 @@ static bool d3d12_resource_validate_heap_properties(const struct d3d12_resource
static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
- const D3D12_CLEAR_VALUE *optimized_clear_value)
+ const D3D12_CLEAR_VALUE *optimized_clear_value, bool placed)
{
HRESULT hr;
@@ -1768,6 +1846,8 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
resource->gpu_address = 0;
resource->flags = 0;
+ if (placed && d3d12_resource_is_buffer(resource))
+ resource->flags |= VKD3D_RESOURCE_PLACED_BUFFER;
if (FAILED(hr = d3d12_resource_validate_desc(&resource->desc, device)))
return hr;
@@ -1775,6 +1855,13 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
switch (desc->Dimension)
{
case D3D12_RESOURCE_DIMENSION_BUFFER:
+ /* We'll inherit a VkBuffer reference from the heap with an implied offset. */
+ if (placed)
+ {
+ resource->u.vk_buffer = VK_NULL_HANDLE;
+ break;
+ }
+
if (FAILED(hr = vkd3d_create_buffer(device, heap_properties, heap_flags,
&resource->desc, &resource->u.vk_buffer)))
return hr;
@@ -1825,7 +1912,7 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
static HRESULT d3d12_resource_create(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
- const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource)
+ const D3D12_CLEAR_VALUE *optimized_clear_value, bool placed, struct d3d12_resource **resource)
{
struct d3d12_resource *object;
HRESULT hr;
@@ -1834,7 +1921,7 @@ static HRESULT d3d12_resource_create(struct d3d12_device *device,
return E_OUTOFMEMORY;
if (FAILED(hr = d3d12_resource_init(object, device, heap_properties, heap_flags,
- desc, initial_state, optimized_clear_value)))
+ desc, initial_state, optimized_clear_value, placed)))
{
vkd3d_free(object);
return hr;
@@ -1876,7 +1963,7 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
}
if (FAILED(hr = d3d12_resource_create(device, heap_properties, heap_flags,
- desc, initial_state, optimized_clear_value, &object)))
+ desc, initial_state, optimized_clear_value, false, &object)))
return hr;
if (FAILED(hr = vkd3d_allocate_resource_memory(device, object, heap_properties, heap_flags)))
@@ -1900,6 +1987,16 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device,
VkMemoryRequirements requirements;
VkResult vr;
+ if (resource->flags & VKD3D_RESOURCE_PLACED_BUFFER)
+ {
+ /* Just inherit the buffer from the heap. */
+ resource->u.vk_buffer = heap->buffer_resource->u.vk_buffer;
+ resource->heap = heap;
+ resource->heap_offset = heap_offset;
+ resource->gpu_address = heap->buffer_resource->gpu_address + heap_offset;
+ return S_OK;
+ }
+
if (d3d12_resource_is_buffer(resource))
VK_CALL(vkGetBufferMemoryRequirements(vk_device, resource->u.vk_buffer, &requirements));
else
@@ -1949,7 +2046,7 @@ HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_h
HRESULT hr;
if (FAILED(hr = d3d12_resource_create(device, &heap->desc.Properties, heap->desc.Flags,
- desc, initial_state, optimized_clear_value, &object)))
+ desc, initial_state, optimized_clear_value, true, &object)))
return hr;
if (FAILED(hr = vkd3d_bind_heap_memory(device, object, heap, heap_offset)))
@@ -1973,7 +2070,7 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
HRESULT hr;
if (FAILED(hr = d3d12_resource_create(device, NULL, 0,
- desc, initial_state, optimized_clear_value, &object)))
+ desc, initial_state, optimized_clear_value, false, &object)))
return hr;
TRACE("Created reserved resource %p.\n", object);
@@ -2275,7 +2372,7 @@ static bool vkd3d_create_buffer_view_for_resource(struct d3d12_device *device,
assert(d3d12_resource_is_buffer(resource));
return vkd3d_create_buffer_view(device, resource->u.vk_buffer,
- format, offset * element_size, size * element_size, view);
+ format, resource->heap_offset + offset * element_size, size * element_size, view);
}
static void vkd3d_set_view_swizzle_for_format(VkComponentMapping *components,
@@ -2869,7 +2966,7 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_
format = vkd3d_get_format(device, DXGI_FORMAT_R32_UINT, false);
if (!vkd3d_create_vk_buffer_view(device, counter_resource->u.vk_buffer, format,
- desc->u.Buffer.CounterOffsetInBytes, sizeof(uint32_t), &view->vk_counter_view))
+ desc->u.Buffer.CounterOffsetInBytes + resource->heap_offset, sizeof(uint32_t), &view->vk_counter_view))
{
WARN("Failed to create counter buffer view.\n");
view->vk_counter_view = VK_NULL_HANDLE;
@@ -2960,12 +3057,18 @@ bool vkd3d_create_raw_buffer_view(struct d3d12_device *device,
{
const struct vkd3d_format *format;
struct d3d12_resource *resource;
+ uint64_t range;
+ uint64_t offset;
format = vkd3d_get_format(device, DXGI_FORMAT_R32_UINT, false);
resource = vkd3d_gpu_va_allocator_dereference(&device->gpu_va_allocator, gpu_address);
assert(d3d12_resource_is_buffer(resource));
+
+ offset = gpu_address - resource->gpu_address;
+ range = min(resource->desc.Width - offset, device->vk_info.device_limits.maxStorageBufferRange);
+
return vkd3d_create_vk_buffer_view(device, resource->u.vk_buffer, format,
- gpu_address - resource->gpu_address, VK_WHOLE_SIZE, vk_buffer_view);
+ offset, range, vk_buffer_view);
}
/* samplers */
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 0c031d2..206e550 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -379,6 +379,7 @@ struct d3d12_heap
unsigned int map_count;
uint32_t vk_memory_type;
+ struct d3d12_resource *buffer_resource;
struct d3d12_device *device;
struct vkd3d_private_store private_store;
@@ -393,6 +394,7 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface) DECLSPEC_HIDDE
#define VKD3D_RESOURCE_EXTERNAL 0x00000004
#define VKD3D_RESOURCE_DEDICATED_HEAP 0x00000008
#define VKD3D_RESOURCE_LINEAR_TILING 0x00000010
+#define VKD3D_RESOURCE_PLACED_BUFFER 0x00000020
/* ID3D12Resource */
struct d3d12_resource
--
2.24.0
Dec. 7, 2019
Re: [PATCH] kernel32/tests: Trace the mapped string when FoldStringW fails.
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=61569
Your paranoid android.
=== wxppro (32 bit report) ===
kernel32:
locale.c:3586: Test failed: Got unexpected string L"Wine\0348\0551\1323\280dWine\03c5\0308j\030c\00a0\00aa".
=== w2003std (32 bit report) ===
kernel32:
locale.c:3586: Test failed: Got unexpected string L"Wine\0348\0551\1323\280dWine\03c5\0308j\030c\00a0\00aa".
Dec. 7, 2019
[PATCH] kernel32/tests: Trace the mapped string when FoldStringW fails.
by Mathew Hodson
Signed-off-by: Mathew Hodson <mathew.hodson(a)gmail.com>
---
dlls/kernel32/tests/locale.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index e43eee2..9328666 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -3585,7 +3585,7 @@ static void test_FoldStringW(void)
ok(ret == ARRAY_SIZE(foldczone_dst), "Got %d, error %d\n", ret, GetLastError());
ok(!memcmp(dst, foldczone_dst, sizeof(foldczone_dst))
|| broken(!memcmp(dst, foldczone_broken_dst, sizeof(foldczone_broken_dst))),
- "MAP_FOLDCZONE: Expanded incorrectly\n");
+ "Got unexpected string %s.\n", wine_dbgstr_w(dst));
/* MAP_EXPAND_LIGATURES */
SetLastError(0);
@@ -3594,7 +3594,7 @@ static void test_FoldStringW(void)
if (!(ret == 0 && GetLastError() == ERROR_INVALID_FLAGS)) {
ok(ret == ARRAY_SIZE(ligatures_dst), "Got %d, error %d\n", ret, GetLastError());
ok(!memcmp(dst, ligatures_dst, sizeof(ligatures_dst)),
- "MAP_EXPAND_LIGATURES: Expanded incorrectly\n");
+ "Got unexpected string %s.\n", wine_dbgstr_w(dst));
}
/* FIXME: MAP_PRECOMPOSED : MAP_COMPOSITE */
--
2.7.4
Dec. 7, 2019
[PATCH 4/4] d3d8: Support texture dirty regions.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d8/tests/visual.c | 12 ++++++------
dlls/d3d8/texture.c | 12 +++++++++++-
2 files changed, 17 insertions(+), 7 deletions(-)
Dec. 7, 2019
[PATCH 3/4] wined3d: Update a part of the texture if dirty regions is tracked.
by Akihiro Sagawa
Wine-Bugs: https://bugs.winehq.org/show_bug.cgi?id=35205
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d9/tests/visual.c | 12 ++++++------
dlls/wined3d/device.c | 49 +++++++++++++++++++++++++++++++++++++++++-------
dlls/wined3d/texture.c | 11 ++++-------
3 files changed, 52 insertions(+), 20 deletions(-)
Dec. 7, 2019
[PATCH 2/4] wined3d: Record texture dirty regions.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/wined3d/device.c | 2 ++
dlls/wined3d/texture.c | 66 ++++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 3 ++
3 files changed, 71 insertions(+)
Dec. 7, 2019
[PATCH 1/4] wined3d: Add dirty region members for d3d9 textures.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d9/texture.c | 9 ++++++++-
dlls/wined3d/texture.c | 13 +++++++++++++
dlls/wined3d/wined3d_private.h | 7 +++++++
include/wine/wined3d.h | 1 +
4 files changed, 29 insertions(+), 1 deletion(-)
Dec. 7, 2019
Re: [wine-devel] Wine staging 4.21 release
by Alistair Leslie-Hughes
Hi Alan,
On 7/12/19 7:48 pm, Alan W. Irwin wrote:
> On 2019-12-05 14:03+0100 Olivier F. R. Dierick wrote:
>
> Version rebased upstreamed added updated predicted predicted-rebased
>     T   U      A    u    P       D
>
> 4.17   855   5      9    7    n/a       n/a
> 4.18Â Â Â 850Â Â Â 1Â Â Â Â Â Â 1Â Â Â Â 3Â Â Â Â 855Â Â Â Â Â Â Â 5
> 4.19Â Â Â 840Â Â Â 8Â Â Â Â Â Â 1Â Â Â Â 1Â Â Â Â 843Â Â Â Â Â Â Â 3
> 4.20Â Â Â 832Â Â Â 8Â Â Â Â Â Â 1Â Â Â Â 3Â Â Â Â 833Â Â Â Â Â Â Â 1
> 4.21Â Â Â 833Â Â Â 0Â Â Â Â Â Â 6Â Â Â Â 2Â Â Â Â 838Â Â Â Â Â Â Â 5
>
These rebased number is the total number of patches applied to the
current wine. The numbers aren't always going to add up as you expect,
For example: we might disable a patchset from one version to another
while we workout a regression or drop a patch(s) because they aren't
correct or add patches to a patchset to increase functionally.
This release will have two patches listed as upstreamed but were
actually part of the previous release since I initial disabled the
patchset until I could verify that these patches were no longer
required. Likewise we might drop/disable the remaining wusa patch since
we are unable to verify whether is actually required anymore, which wont
be listed in the release notes.
Regards
Alistair.
Dec. 7, 2019
Re: [wine-devel] Wine staging 4.21 release
by Alan W. Irwin
On 2019-12-05 14:03+0100 Olivier F. R. Dierick wrote:
> Le mercredi 04 décembre 2019 à 14:56 -0800, Alan W. Irwin a écrit :
>> On 2019-11-30 04:56-0000 Alistair Leslie-Hughes wrote:
>>
>>> Added:
>>> * [47668] kernelbase: Improve stub for ReOpenFile and add small
>> [...]
>>
>> Could you explain how these patch numbers in your report are related
>> with each other?
>>
>
> Hello,
>
> The numbers between brackets are winehq.org bugzilla bug numbers.
>
Hi Olivier:
Thanks for trying to be helpful, but your answer did not respond to
the question which was about how to account for the total number of
patches in each category mentioned in these reports.
To explain further, my curiosity about this question was stimulated by
these staging "accounting" numbers from recent reports:
Version rebased upstreamed added updated predicted predicted-rebased
T U A u P D
4.17 855 5 9 7 n/a n/a
4.18 850 1 1 3 855 5
4.19 840 8 1 1 843 3
4.20 832 8 1 3 833 1
4.21 833 0 6 2 838 5
I assume the "T" column is the total number of patches in staging,
i.e., the report is only sent out when the rebasing work is completed,
but could someone confirm that? I also assume U reduces the total
number in staging by that number, A increases the total number in
staging by that number, and u leaves the total number in staging
unchanged. And I have used
P = T' - U - A
to calculate the predicted number of patches from one report to the next
and
D = P - T
to calculate the discrepancy between predicted and actual values where
T' is taken from the previous report and T, U and A are taken from the
current report.
In every case D is positive (P always greater than T) so I hypothesize
there is another kind of patch category not currently mentioned in the
report that explains this discrepancy (e.g., patches which the staging
developers have removed from staging). Could someone please describe
the true reason why D is always positive?
Furthermore, my view is it would be helpful if patch categories
(deletions from staging or whatever) that are currently not mentioned
in these reports should be mentioned in future reports.
Alan
__________________________
Alan W. Irwin
Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net) the Time
Ephemerides project (timeephem.sf.net) PLplot scientific plotting
software package (plplot.org) the libLASi project
(unifont.org/lasi) the Loads of Linux Links project (loll.sf.net)
and the Linux Brochure Project (lbproject.sf.net)
__________________________
Linux-powered Science
__________________________
Dec. 7, 2019
[PATCH] wtsapi32: Make WTSRegisterSessionNotificationEx's return consistant with WTSRegisterSessionNotification.
by Patrick Hibbs
No point in these returning different values, considering one is a superset of the other.
Fix as per Zebediah Figura's bug comment (#12).
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47433
Signed-off-by: Patrick Hibbs <hibbsncc1701(a)gmail.com>
---
dlls/wtsapi32/wtsapi32.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wtsapi32/wtsapi32.c b/dlls/wtsapi32/wtsapi32.c
index c2b817a6ed..026e7f4369 100644
--- a/dlls/wtsapi32/wtsapi32.c
+++ b/dlls/wtsapi32/wtsapi32.c
@@ -385,7 +385,7 @@ BOOL WINAPI WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
BOOL WINAPI WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags)
{
FIXME("Stub %p %p 0x%08x\n", hServer, hWnd, dwFlags);
- return FALSE;
+ return TRUE;
}
--
2.24.0
Dec. 7, 2019
Re: [PATCH v3 3/3] xmllite: Expand test for any unparsed data at end of XML.
by Jeff Smith
On Fri, Dec 6, 2019 at 4:19 PM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> On 12/7/19 12:24 AM, Jeff Smith wrote:
> > On Fri, Dec 6, 2019 at 11:16 AM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
> >> On 12/5/19 10:53 PM, Jeff Smith wrote:
> >>> @@ -2662,7 +2663,7 @@ static HRESULT reader_parse_nextnode(xmlreader *reader)
> >>> hr = reader_parse_misc(reader);
> >>> if (hr != S_FALSE) return hr;
> >>>
> >>> - if (*reader_get_ptr(reader))
> >>> + if (buffer->cur*sizeof(WCHAR) < buffer->written)
> >>> {
> >>> WARN("found garbage in the end of XML\n");
> >>> return WC_E_SYNTAX;
> > Hi Nikolay,
> >
> >> That means we don't have enough data,
> > How do you figure that?
> >
> >> it's another change not backed by tests
> > This fixes two tests, and does not break any others.
> >
> >> and potentially depending on current read-ahead buffer size/filled level.
> > I'm pretty sure reader_parse_misc would have read at least one byte
> > ahead, which is all that is required for this to trigger, though I
> > could double-check that.
> > However, to your point made in the patch 2 of the set about not
> > exposing the buffer at this level, I will also consider this something
> > that potentially needs to be handled elsewhere.
> My point is that we should always hit this single invalid syntax/garbage
> at the end condition that we already have,
That garbage-at-the-end condition, as it exists, is explicitly NOT
triggered by a null character, but it should.
So what we have here currently is not sufficient.
While there may be cases that my patch does not cover, based on
existing test cases, it is an improvement.
> instead of doing fixups for specific node types.
On Windows, the context in which the null character is encountered is
significant.
For instance, if any character other than '<' is encountered at the
end of a whitespace sequence, it raises the syntax error without
returning a Whitespace node.
So we need to catch the invalid character and interrupt before a
Whitespace node is returned.
Dec. 7, 2019
[PATCH] wineqtdecoder: Fix macos compile error
by Alistair Leslie-Hughes
Regression of 498179b4482026091bf7376c0d2ac9a036e7ca0e
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/wineqtdecoder/qtsplitter.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 5b1e82ebc9b..956dd0a7d0d 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -285,7 +285,7 @@ static HRESULT qt_splitter_start_stream(struct strmbase_filter *iface, REFERENCE
QTSplitter *filter = impl_from_strmbase_filter(iface);
HRESULT hr = VFW_E_NOT_CONNECTED, pin_hr;
- EnterCriticalSection(&This->csReceive);
+ EnterCriticalSection(&filter->csReceive);
if (filter->pVideo_Pin)
pin_hr = BaseOutputPinImpl_Active(&filter->pVideo_Pin->pin);
@@ -297,7 +297,7 @@ static HRESULT qt_splitter_start_stream(struct strmbase_filter *iface, REFERENCE
hr = pin_hr;
SetEvent(filter->runEvent);
- LeaveCriticalSection(&This->csReceive);
+ LeaveCriticalSection(&filter->csReceive);
return hr;
}
@@ -306,10 +306,10 @@ static HRESULT qt_splitter_cleanup_stream(struct strmbase_filter *iface)
{
QTSplitter *filter = impl_from_strmbase_filter(iface);
- EnterCriticalSection(&This->csReceive);
+ EnterCriticalSection(&filter->csReceive);
IAsyncReader_BeginFlush(filter->pInputPin.pReader);
IAsyncReader_EndFlush(filter->pInputPin.pReader);
- LeaveCriticalSection(&This->csReceive);
+ LeaveCriticalSection(&filter->csReceive);
return S_OK;
}
@@ -1170,8 +1170,6 @@ static HRESULT WINAPI QTOutPin_QueryInterface(IPin *iface, REFIID riid, void **p
*ppv = iface;
else if (IsEqualIID(riid, &IID_IPin))
*ppv = iface;
- else if (IsEqualIID(riid, &IID_IMediaSeeking))
- *ppv = &This->sourceSeeking.IMediaSeeking_iface;
else if (IsEqualIID(riid, &IID_IQualityControl))
*ppv = &This->IQualityControl_iface;
--
2.24.0
Dec. 7, 2019
Re: [PATCH 6/6] strmbase: Get rid of the "vtbl" argument to strmbase_source_init().
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=61549
Your paranoid android.
=== w1064v1809_he (32 bit report) ===
quartz:
videorenderer.c:928: Test failed: Thread should block in Receive().
Dec. 7, 2019
[PATCH] bcrypt: Add fallback when gnutls_decode_rs_value isn't present.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
I overlooked the fact that wine won't compile on systems where gnutls headers are too old.
---
dlls/bcrypt/gnutls.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 1c31b5625f..868f898bbb 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -86,13 +86,15 @@ static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *,
gnutls_datum_t *);
static int (*pgnutls_privkey_generate)(gnutls_privkey_t, gnutls_pk_algorithm_t, unsigned int, unsigned int);
+/* Not present in gnutls version < 3.6.0 */
+static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
+
static void *libgnutls_handle;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(gnutls_cipher_decrypt2);
MAKE_FUNCPTR(gnutls_cipher_deinit);
MAKE_FUNCPTR(gnutls_cipher_encrypt2);
MAKE_FUNCPTR(gnutls_cipher_init);
-MAKE_FUNCPTR(gnutls_decode_rs_value);
MAKE_FUNCPTR(gnutls_global_deinit);
MAKE_FUNCPTR(gnutls_global_init);
MAKE_FUNCPTR(gnutls_global_set_log_function);
@@ -164,6 +166,11 @@ static int compat_gnutls_privkey_generate(gnutls_privkey_t key, gnutls_pk_algori
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
}
+static int compat_gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
+{
+ return GNUTLS_E_INTERNAL_ERROR;
+}
+
static void gnutls_log( int level, const char *msg )
{
TRACE( "<%d> %s", level, msg );
@@ -190,7 +197,6 @@ BOOL gnutls_initialize(void)
LOAD_FUNCPTR(gnutls_cipher_deinit)
LOAD_FUNCPTR(gnutls_cipher_encrypt2)
LOAD_FUNCPTR(gnutls_cipher_init)
- LOAD_FUNCPTR(gnutls_decode_rs_value)
LOAD_FUNCPTR(gnutls_global_deinit)
LOAD_FUNCPTR(gnutls_global_init)
LOAD_FUNCPTR(gnutls_global_set_log_function)
@@ -259,6 +265,11 @@ BOOL gnutls_initialize(void)
WARN("gnutls_privkey_generate not found\n");
pgnutls_privkey_generate = compat_gnutls_privkey_generate;
}
+ if (!(pgnutls_decode_rs_value = wine_dlsym( libgnutls_handle, "gnutls_decode_rs_value", NULL, 0 )))
+ {
+ WARN("gnutls_decode_rs_value not found\n");
+ pgnutls_decode_rs_value = compat_gnutls_decode_rs_value;
+ }
if (TRACE_ON( bcrypt ))
{
--
2.24.0
Dec. 7, 2019
[PATCH 6/6] strmbase: Get rid of the "vtbl" argument to strmbase_source_init().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avico.c | 24 +---------------
dlls/qcap/avimux.c | 24 +---------------
dlls/qcap/smartteefilter.c | 48 ++-----------------------------
dlls/qcap/vfwcapture.c | 25 +---------------
dlls/qedit/samplegrabber.c | 24 +---------------
dlls/quartz/filesource.c | 26 +----------------
dlls/quartz/tests/videorenderer.c | 24 +---------------
dlls/quartz/tests/vmr7.c | 24 +---------------
dlls/quartz/tests/vmr9.c | 24 +---------------
dlls/strmbase/pin.c | 38 ++++++++++++++++++------
dlls/strmbase/transform.c | 26 +----------------
dlls/winegstreamer/gstdemux.c | 25 +---------------
dlls/wineqtdecoder/qtsplitter.c | 25 +---------------
include/wine/strmbase.h | 10 +------
14 files changed, 44 insertions(+), 323 deletions(-)
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index 9365c437b4f..debe6bca386 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -473,27 +473,6 @@ static const struct strmbase_sink_ops sink_ops =
.pfnReceive = AVICompressorIn_Receive,
};
-static const IPinVtbl AVICompressorOutputPinVtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static HRESULT source_get_media_type(struct strmbase_pin *base, unsigned int iPosition, AM_MEDIA_TYPE *amt)
{
AVICompressor *This = impl_from_strmbase_filter(base->filter);
@@ -564,8 +543,7 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
strmbase_sink_init(&compressor->sink, &AVICompressorInputPinVtbl,
&compressor->filter, sink_name, &sink_ops, NULL);
- strmbase_source_init(&compressor->source, &AVICompressorOutputPinVtbl,
- &compressor->filter, source_name, &source_ops);
+ strmbase_source_init(&compressor->source, &compressor->filter, source_name, &source_ops);
*phr = S_OK;
return &compressor->filter.IUnknown_inner;
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index 677e79ef68f..c344ab47266 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1217,27 +1217,6 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = AviMuxOut_DecideAllocator,
};
-static const IPinVtbl AviMuxOut_PinVtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static inline AviMux* impl_from_out_IQualityControl(IQualityControl *iface)
{
return CONTAINING_RECORD(iface, AviMux, IQualityControl_iface);
@@ -1923,8 +1902,7 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr)
info.dir = PINDIR_OUTPUT;
info.pFilter = &avimux->filter.IBaseFilter_iface;
lstrcpyW(info.achName, output_name);
- strmbase_source_init(&avimux->source, &AviMuxOut_PinVtbl, &avimux->filter,
- output_name, &source_ops);
+ strmbase_source_init(&avimux->source, &avimux->filter, output_name, &source_ops);
avimux->IQualityControl_iface.lpVtbl = &AviMuxOut_QualityControlVtbl;
avimux->cur_stream = 0;
avimux->cur_time = 0;
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index 7762ec1e500..929929632f1 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -275,27 +275,6 @@ static const struct strmbase_sink_ops sink_ops =
.pfnReceive = SmartTeeFilterInput_Receive,
};
-static const IPinVtbl SmartTeeFilterCaptureVtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static HRESULT capture_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
{
FIXME("(%p) stub\n", base);
@@ -339,27 +318,6 @@ static const struct strmbase_source_ops capture_ops =
.pfnDecideAllocator = SmartTeeFilterCapture_DecideAllocator,
};
-static const IPinVtbl SmartTeeFilterPreviewVtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static HRESULT preview_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
{
FIXME("(%p) stub\n", base);
@@ -410,10 +368,8 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_source_init(&object->capture, &SmartTeeFilterCaptureVtbl,
- &object->filter, captureW, &capture_ops);
- strmbase_source_init(&object->preview, &SmartTeeFilterPreviewVtbl,
- &object->filter, previewW, &preview_ops);
+ strmbase_source_init(&object->capture, &object->filter, captureW, &capture_ops);
+ strmbase_source_init(&object->preview, &object->filter, previewW, &preview_ops);
*phr = S_OK;
return &object->filter.IUnknown_inner;
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c
index e7522ea9b36..2185053ecd0 100644
--- a/dlls/qcap/vfwcapture.c
+++ b/dlls/qcap/vfwcapture.c
@@ -559,28 +559,6 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
};
-static const IPinVtbl VfwPin_Vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
{
static const WCHAR source_name[] = {'O','u','t','p','u','t',0};
@@ -599,8 +577,7 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
object->IPersistPropertyBag_iface.lpVtbl = &IPersistPropertyBag_VTable;
object->init = FALSE;
- strmbase_source_init(&object->source, &VfwPin_Vtbl, &object->filter,
- source_name, &source_ops);
+ strmbase_source_init(&object->source, &object->filter, source_name, &source_ops);
object->IKsPropertySet_iface.lpVtbl = &IKsPropertySet_VTable;
diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c
index 019af5c35de..f8d90a5c0df 100644
--- a/dlls/qedit/samplegrabber.c
+++ b/dlls/qedit/samplegrabber.c
@@ -660,28 +660,6 @@ static const struct strmbase_source_ops source_ops =
.pfnAttemptConnection = sample_grabber_source_AttemptConnection,
};
-static const IPinVtbl source_vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment,
-};
-
HRESULT SampleGrabber_create(IUnknown *outer, void **out)
{
SG_Impl* obj = NULL;
@@ -700,7 +678,7 @@ HRESULT SampleGrabber_create(IUnknown *outer, void **out)
obj->IMemInputPin_iface.lpVtbl = &IMemInputPin_VTable;
strmbase_sink_init(&obj->sink, &sink_vtbl, &obj->filter, L"In", &sink_ops, NULL);
- strmbase_source_init(&obj->source, &source_vtbl, &obj->filter, L"Out", &source_ops);
+ strmbase_source_init(&obj->source, &obj->filter, L"Out", &source_ops);
obj->mtype.majortype = GUID_NULL;
obj->mtype.subtype = MEDIASUBTYPE_None;
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index e841391e83a..fb8adb4a3fb 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -77,7 +77,6 @@ typedef struct AsyncReader
HANDLE *handle_list;
} AsyncReader;
-static const IPinVtbl FileAsyncReaderPin_Vtbl;
static const struct strmbase_source_ops source_ops;
static inline AsyncReader *impl_from_strmbase_filter(struct strmbase_filter *iface)
@@ -468,8 +467,7 @@ static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFi
return HRESULT_FROM_WIN32(GetLastError());
}
- strmbase_source_init(&This->source, &FileAsyncReaderPin_Vtbl, &This->filter,
- wszOutputPinName, &source_ops);
+ strmbase_source_init(&This->source, &This->filter, wszOutputPinName, &source_ops);
BaseFilterImpl_IncrementPinVersion(&This->filter);
This->file = hFile;
@@ -594,28 +592,6 @@ static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, vo
return S_OK;
}
-static const IPinVtbl FileAsyncReaderPin_Vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
/* Function called as a helper to IPin_Connect */
/* specific AM_MEDIA_TYPE - it cannot be NULL */
/* this differs from standard OutputPin_AttemptConnection only in that it
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index d4d9622b415..00a9041a8b4 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -521,28 +521,6 @@ static const struct strmbase_filter_ops testfilter_ops =
.filter_destroy = testfilter_destroy,
};
-static const IPinVtbl testsource_vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment,
-};
-
static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
{
return S_OK;
@@ -579,7 +557,7 @@ static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
- strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
+ strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
}
static void test_allocator(IMemInputPin *input)
diff --git a/dlls/quartz/tests/vmr7.c b/dlls/quartz/tests/vmr7.c
index 008c84ab30f..dae86bd3fa9 100644
--- a/dlls/quartz/tests/vmr7.c
+++ b/dlls/quartz/tests/vmr7.c
@@ -881,28 +881,6 @@ static const struct strmbase_filter_ops testfilter_ops =
.filter_destroy = testfilter_destroy,
};
-static const IPinVtbl testsource_vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment,
-};
-
static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
{
return S_OK;
@@ -939,7 +917,7 @@ static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
- strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
+ strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
}
static void test_allocator(IMemInputPin *input)
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c
index fd6901d2117..5ece5c6f7bb 100644
--- a/dlls/quartz/tests/vmr9.c
+++ b/dlls/quartz/tests/vmr9.c
@@ -885,28 +885,6 @@ static const struct strmbase_filter_ops testfilter_ops =
.filter_destroy = testfilter_destroy,
};
-static const IPinVtbl testsource_vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment,
-};
-
static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
{
return S_OK;
@@ -943,7 +921,7 @@ static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
- strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
+ strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
}
static void test_allocator(IMemInputPin *input)
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c
index bdc827c6f60..bcac22eb3c4 100644
--- a/dlls/strmbase/pin.c
+++ b/dlls/strmbase/pin.c
@@ -284,7 +284,7 @@ static inline struct strmbase_source *impl_source_from_IPin( IPin *iface )
return CONTAINING_RECORD(iface, struct strmbase_source, pin.IPin_iface);
}
-HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
+static HRESULT WINAPI source_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
HRESULT hr;
struct strmbase_source *This = impl_source_from_IPin(iface);
@@ -375,13 +375,13 @@ HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const
return hr;
}
-HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin *iface, IPin *pin, const AM_MEDIA_TYPE *pmt)
+static HRESULT WINAPI source_ReceiveConnection(IPin *iface, IPin *pin, const AM_MEDIA_TYPE *pmt)
{
ERR("(%p)->(%p, %p) incoming connection on an output pin!\n", iface, pin, pmt);
return E_UNEXPECTED;
}
-HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin * iface)
+static HRESULT WINAPI source_Disconnect(IPin *iface)
{
HRESULT hr;
struct strmbase_source *This = impl_source_from_IPin(iface);
@@ -418,7 +418,7 @@ HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin * iface)
return hr;
}
-HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin * iface)
+static HRESULT WINAPI source_EndOfStream(IPin *iface)
{
TRACE("(%p)->()\n", iface);
@@ -427,7 +427,7 @@ HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin * iface)
return E_UNEXPECTED;
}
-HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin * iface)
+static HRESULT WINAPI source_BeginFlush(IPin *iface)
{
TRACE("(%p)->()\n", iface);
@@ -436,7 +436,7 @@ HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin * iface)
return E_UNEXPECTED;
}
-HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface)
+static HRESULT WINAPI source_EndFlush(IPin *iface)
{
TRACE("(%p)->()\n", iface);
@@ -445,6 +445,28 @@ HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface)
return E_UNEXPECTED;
}
+static const IPinVtbl source_vtbl =
+{
+ BasePinImpl_QueryInterface,
+ BasePinImpl_AddRef,
+ BasePinImpl_Release,
+ source_Connect,
+ source_ReceiveConnection,
+ source_Disconnect,
+ BasePinImpl_ConnectedTo,
+ BasePinImpl_ConnectionMediaType,
+ BasePinImpl_QueryPinInfo,
+ BasePinImpl_QueryDirection,
+ BasePinImpl_QueryId,
+ BasePinImpl_QueryAccept,
+ BasePinImpl_EnumMediaTypes,
+ BasePinImpl_QueryInternalConnections,
+ source_EndOfStream,
+ source_BeginFlush,
+ source_EndFlush,
+ BasePinImpl_NewSegment,
+};
+
HRESULT WINAPI BaseOutputPinImpl_GetDeliveryBuffer(struct strmbase_source *This,
IMediaSample **ppSample, REFERENCE_TIME *tStart, REFERENCE_TIME *tStop, DWORD dwFlags)
{
@@ -595,11 +617,11 @@ HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *This,
return hr;
}
-void strmbase_source_init(struct strmbase_source *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter,
+void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter,
const WCHAR *name, const struct strmbase_source_ops *func_table)
{
memset(pin, 0, sizeof(*pin));
- pin->pin.IPin_iface.lpVtbl = vtbl;
+ pin->pin.IPin_iface.lpVtbl = &source_vtbl;
pin->pin.filter = filter;
pin->pin.dir = PINDIR_OUTPUT;
lstrcpyW(pin->pin.name, name);
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 5c079d38e76..7a79f709055 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -27,7 +27,6 @@ static const WCHAR wcsInputPinName[] = {'I','n',0};
static const WCHAR wcsOutputPinName[] = {'O','u','t',0};
static const IPinVtbl TransformFilter_InputPin_Vtbl;
-static const IPinVtbl TransformFilter_OutputPin_Vtbl;
static inline TransformFilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
@@ -338,8 +337,7 @@ static HRESULT strmbase_transform_init(IUnknown *outer, const CLSID *clsid,
strmbase_sink_init(&filter->sink, &TransformFilter_InputPin_Vtbl, &filter->filter,
wcsInputPinName, &sink_ops, NULL);
- strmbase_source_init(&filter->source, &TransformFilter_OutputPin_Vtbl, &filter->filter,
- wcsOutputPinName, &source_ops);
+ strmbase_source_init(&filter->source, &filter->filter, wcsOutputPinName, &source_ops);
filter->source_IQualityControl_iface.lpVtbl = &source_qc_vtbl;
filter->seekthru_unk = NULL;
@@ -503,25 +501,3 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
TransformFilter_InputPin_EndFlush,
TransformFilter_InputPin_NewSegment
};
-
-static const IPinVtbl TransformFilter_OutputPin_Vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 04fb54915c6..e7d0313d7ce 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -97,7 +97,6 @@ const char* media_quark_string = "media-sample";
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
static const IMediaSeekingVtbl GST_Seeking_Vtbl;
-static const IPinVtbl GST_OutputPin_Vtbl;
static const IPinVtbl GST_InputPin_Vtbl;
static const IQualityControlVtbl GSTOutPin_QualityControl_Vtbl;
@@ -1836,27 +1835,6 @@ static void free_source_pin(struct gstdemux_source *pin)
heap_free(pin);
}
-static const IPinVtbl GST_OutputPin_Vtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static const struct strmbase_source_ops source_ops =
{
.base.pin_query_interface = source_query_interface,
@@ -1879,8 +1857,7 @@ static struct gstdemux_source *create_pin(struct gstdemux *filter, const WCHAR *
if (!(pin = heap_alloc_zero(sizeof(*pin))))
return NULL;
- strmbase_source_init(&pin->pin, &GST_OutputPin_Vtbl, &filter->filter, name,
- &source_ops);
+ strmbase_source_init(&pin->pin, &filter->filter, name, &source_ops);
pin->caps_event = CreateEventW(NULL, FALSE, FALSE, NULL);
pin->segment = gst_segment_new();
gst_segment_init(pin->segment, GST_FORMAT_TIME);
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 2b05eefa8f4..03100c7a93e 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -171,7 +171,6 @@ typedef struct QTSplitter {
HANDLE splitterThread;
} QTSplitter;
-static const IPinVtbl QT_OutputPin_Vtbl;
static const IPinVtbl QT_InputPin_Vtbl;
static const IBaseFilterVtbl QT_Vtbl;
static const IMediaSeekingVtbl QT_Seeking_Vtbl;
@@ -1211,27 +1210,6 @@ static HRESULT WINAPI QTOutPin_DecideAllocator(struct strmbase_source *iface,
return hr;
}
-static const IPinVtbl QT_OutputPin_Vtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static inline QTOutPin *impl_from_IQualityControl( IQualityControl *iface )
{
return CONTAINING_RECORD(iface, QTOutPin, IQualityControl_iface);
@@ -1304,8 +1282,7 @@ static HRESULT QT_AddPin(QTSplitter *filter, const WCHAR *name,
else
filter->pAudio_Pin = pin;
- strmbase_source_init(&pin->pin, &QT_OutputPin_Vtbl, &filter->filter, name,
- &source_ops);
+ strmbase_source_init(&pin->pin, &filter->filter, name, &source_ops);
pin->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
CopyMediaType(pin->pmt, mt);
pin->IQualityControl_iface.lpVtbl = &QTOutPin_QualityControl_Vtbl;
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 75eac504209..c3699f19253 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -113,14 +113,6 @@ HRESULT WINAPI BasePinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnu
HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin);
HRESULT WINAPI BasePinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
-/* Base Output Pin */
-HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin * iface);
-HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin * iface);
-HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin * iface);
-HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface);
-
HRESULT WINAPI BaseOutputPinImpl_GetDeliveryBuffer(struct strmbase_source *pin,
IMediaSample **sample, REFERENCE_TIME *start, REFERENCE_TIME *stop, DWORD flags);
HRESULT WINAPI BaseOutputPinImpl_Active(struct strmbase_source *pin);
@@ -130,7 +122,7 @@ HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(struct strmbase_source *pin, IM
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *pin, IPin *peer, const AM_MEDIA_TYPE *mt);
void strmbase_source_cleanup(struct strmbase_source *pin);
-void strmbase_source_init(struct strmbase_source *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter,
+void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter,
const WCHAR *name, const struct strmbase_source_ops *func_table);
/* Base Input Pin */
--
2.23.0
Dec. 7, 2019
[PATCH 5/6] qcap/avimux: Use BaseOutputPinImpl_Connect().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avimux.c | 58 +++++++++++++++++-----------------------------
1 file changed, 21 insertions(+), 37 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index d2f29dbbeb0..677e79ef68f 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1132,19 +1132,35 @@ static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYP
return S_OK;
}
-static HRESULT WINAPI AviMuxOut_AttemptConnection(struct strmbase_source *base,
+static HRESULT WINAPI AviMuxOut_AttemptConnection(struct strmbase_source *iface,
IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
+ AviMux *filter = impl_from_source_pin(&iface->pin);
PIN_DIRECTION dir;
+ unsigned int i;
HRESULT hr;
- TRACE("(%p)->(%p AM_MEDIA_TYPE(%p))\n", base, pReceivePin, pmt);
-
hr = IPin_QueryDirection(pReceivePin, &dir);
if(hr==S_OK && dir!=PINDIR_INPUT)
return VFW_E_INVALID_DIRECTION;
- return BaseOutputPinImpl_AttemptConnection(base, pReceivePin, pmt);
+ if (FAILED(hr = BaseOutputPinImpl_AttemptConnection(iface, pReceivePin, pmt)))
+ return hr;
+
+ for (i = 0; i < filter->input_pin_no; ++i)
+ {
+ if (!filter->in[i]->pin.pin.peer)
+ continue;
+
+ hr = IFilterGraph_Reconnect(filter->filter.filterInfo.pGraph, &filter->in[i]->pin.pin.IPin_iface);
+ if (FAILED(hr))
+ {
+ IPin_Disconnect(&iface->pin.IPin_iface);
+ break;
+ }
+ }
+
+ return hr;
}
static HRESULT source_get_media_type(struct strmbase_pin *base, unsigned int iPosition, AM_MEDIA_TYPE *amt)
@@ -1201,43 +1217,11 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = AviMuxOut_DecideAllocator,
};
-static inline AviMux *impl_from_out_IPin(IPin *iface)
-{
- return CONTAINING_RECORD(iface, AviMux, source.pin.IPin_iface);
-}
-
-static HRESULT WINAPI AviMuxOut_Connect(IPin *iface,
- IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
-{
- AviMux *This = impl_from_out_IPin(iface);
- HRESULT hr;
- int i;
-
- TRACE("(%p)->(%p AM_MEDIA_TYPE(%p))\n", This, pReceivePin, pmt);
-
- hr = BaseOutputPinImpl_Connect(iface, pReceivePin, pmt);
- if(FAILED(hr))
- return hr;
-
- for(i=0; i<This->input_pin_no; i++) {
- if(!This->in[i]->pin.pin.peer)
- continue;
-
- hr = IFilterGraph_Reconnect(This->filter.filterInfo.pGraph, &This->in[i]->pin.pin.IPin_iface);
- if(FAILED(hr)) {
- BaseOutputPinImpl_Disconnect(iface);
- break;
- }
- }
-
- return hr;
-}
-
static const IPinVtbl AviMuxOut_PinVtbl = {
BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
- AviMuxOut_Connect,
+ BaseOutputPinImpl_Connect,
BaseOutputPinImpl_ReceiveConnection,
BaseOutputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
--
2.23.0
Dec. 7, 2019
[PATCH 4/6] qcap/avimux: Use BaseOutputPinImpl_Disconnect().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avimux.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index 645f0b7d5e4..d2f29dbbeb0 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1230,21 +1230,6 @@ static HRESULT WINAPI AviMuxOut_Connect(IPin *iface,
}
}
- if(hr == S_OK)
- IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
- return hr;
-}
-
-static HRESULT WINAPI AviMuxOut_Disconnect(IPin *iface)
-{
- AviMux *This = impl_from_out_IPin(iface);
- HRESULT hr;
-
- TRACE("(%p)\n", This);
-
- hr = BaseOutputPinImpl_Disconnect(iface);
- if(hr == S_OK)
- IBaseFilter_Release(&This->filter.IBaseFilter_iface);
return hr;
}
@@ -1254,7 +1239,7 @@ static const IPinVtbl AviMuxOut_PinVtbl = {
BasePinImpl_Release,
AviMuxOut_Connect,
BaseOutputPinImpl_ReceiveConnection,
- AviMuxOut_Disconnect,
+ BaseOutputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
--
2.23.0
Dec. 7, 2019
[PATCH 3/6] qcap/avimux: Use BasePinImpl_QueryInterface().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avimux.c | 94 +++++++++++++++++++++++-----------------------
1 file changed, 46 insertions(+), 48 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index dc28104c80a..645f0b7d5e4 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1108,6 +1108,24 @@ static const ISpecifyPropertyPagesVtbl SpecifyPropertyPagesVtbl = {
SpecifyPropertyPages_GetPages
};
+static inline AviMux *impl_from_source_pin(struct strmbase_pin *iface)
+{
+ return CONTAINING_RECORD(iface, AviMux, source.pin);
+}
+
+static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
+{
+ AviMux *filter = impl_from_source_pin(iface);
+
+ if (IsEqualGUID(iid, &IID_IQualityControl))
+ *out = &filter->IQualityControl_iface;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
+}
+
static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
{
FIXME("(%p) stub\n", base);
@@ -1176,6 +1194,7 @@ static HRESULT WINAPI AviMuxOut_DecideAllocator(struct strmbase_source *base,
static const struct strmbase_source_ops source_ops =
{
+ .base.pin_query_interface = source_query_interface,
.base.pin_query_accept = source_query_accept,
.base.pin_get_media_type = source_get_media_type,
.pfnAttemptConnection = AviMuxOut_AttemptConnection,
@@ -1187,26 +1206,6 @@ static inline AviMux *impl_from_out_IPin(IPin *iface)
return CONTAINING_RECORD(iface, AviMux, source.pin.IPin_iface);
}
-static HRESULT WINAPI AviMuxOut_QueryInterface(IPin *iface, REFIID riid, void **ppv)
-{
- AviMux *This = impl_from_out_IPin(iface);
-
- TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
-
- if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin))
- *ppv = iface;
- else if(IsEqualIID(riid, &IID_IQualityControl))
- *ppv = &This->IQualityControl_iface;
- else {
- FIXME("no interface for %s\n", debugstr_guid(riid));
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef((IUnknown*)*ppv);
- return S_OK;
-}
-
static HRESULT WINAPI AviMuxOut_Connect(IPin *iface,
IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
@@ -1250,7 +1249,7 @@ static HRESULT WINAPI AviMuxOut_Disconnect(IPin *iface)
}
static const IPinVtbl AviMuxOut_PinVtbl = {
- AviMuxOut_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
AviMuxOut_Connect,
@@ -1321,6 +1320,30 @@ static const IQualityControlVtbl AviMuxOut_QualityControlVtbl = {
AviMuxOut_QualityControl_SetSink
};
+static inline AviMuxIn *impl_sink_from_strmbase_pin(struct strmbase_pin *iface)
+{
+ return CONTAINING_RECORD(iface, AviMuxIn, pin.pin.IPin_iface);
+}
+
+static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
+{
+ AviMuxIn *pin = impl_sink_from_strmbase_pin(iface);
+
+ if (IsEqualGUID(iid, &IID_IAMStreamControl))
+ *out = &pin->IAMStreamControl_iface;
+ else if (IsEqualGUID(iid, &IID_IMemInputPin))
+ *out = &pin->pin.IMemInputPin_iface;
+ else if (IsEqualGUID(iid, &IID_IPropertyBag))
+ *out = &pin->IPropertyBag_iface;
+ else if (IsEqualGUID(iid, &IID_IQualityControl))
+ *out = &pin->IQualityControl_iface;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
+}
+
static HRESULT sink_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *pmt)
{
if(IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio) &&
@@ -1441,6 +1464,7 @@ static HRESULT WINAPI AviMuxIn_Receive(struct strmbase_sink *base, IMediaSample
static const struct strmbase_sink_ops sink_ops =
{
+ .base.pin_query_interface = sink_query_interface,
.base.pin_query_accept = sink_query_accept,
.base.pin_get_media_type = strmbase_pin_get_media_type,
.pfnReceive = AviMuxIn_Receive,
@@ -1457,32 +1481,6 @@ static inline AviMuxIn* AviMuxIn_from_IPin(IPin *iface)
return CONTAINING_RECORD(iface, AviMuxIn, pin.pin.IPin_iface);
}
-static HRESULT WINAPI AviMuxIn_QueryInterface(IPin *iface, REFIID riid, void **ppv)
-{
- AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
-
- TRACE("pin %p, riid %s, ppv %p.\n", avimuxin, debugstr_guid(riid), ppv);
-
- if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin))
- *ppv = &avimuxin->pin.pin.IPin_iface;
- else if(IsEqualIID(riid, &IID_IAMStreamControl))
- *ppv = &avimuxin->IAMStreamControl_iface;
- else if(IsEqualIID(riid, &IID_IMemInputPin))
- *ppv = &avimuxin->pin.IMemInputPin_iface;
- else if(IsEqualIID(riid, &IID_IPropertyBag))
- *ppv = &avimuxin->IPropertyBag_iface;
- else if(IsEqualIID(riid, &IID_IQualityControl))
- *ppv = &avimuxin->IQualityControl_iface;
- else {
- FIXME("no interface for %s\n", debugstr_guid(riid));
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef((IUnknown*)*ppv);
- return S_OK;
-}
-
static HRESULT WINAPI AviMuxIn_ReceiveConnection(IPin *iface,
IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
@@ -1576,7 +1574,7 @@ static HRESULT WINAPI AviMuxIn_Disconnect(IPin *iface)
}
static const IPinVtbl AviMuxIn_PinVtbl = {
- AviMuxIn_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
--
2.23.0
Dec. 7, 2019
[PATCH 2/6] wineqtdecoder: Use BasePinImpl_QueryInterface().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/wineqtdecoder/qtsplitter.c | 45 ++++++++++-----------------------
1 file changed, 13 insertions(+), 32 deletions(-)
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 5b1e82ebc9b..2b05eefa8f4 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -1140,15 +1140,7 @@ static const IPinVtbl QT_InputPin_Vtbl = {
QTInPin_NewSegment
};
-/*
- * Output Pin
- */
-static inline QTOutPin *impl_QTOutPin_from_IPin( IPin *iface )
-{
- return CONTAINING_RECORD(iface, QTOutPin, pin.pin.IPin_iface);
-}
-
-static inline QTOutPin *impl_sink_from_strmbase_pin(struct strmbase_pin *iface)
+static inline QTOutPin *impl_source_from_strmbase_pin(struct strmbase_pin *iface)
{
return CONTAINING_RECORD(iface, QTOutPin, pin.pin);
}
@@ -1158,30 +1150,19 @@ static inline QTOutPin *impl_QTOutPin_from_BaseOutputPin(struct strmbase_source
return CONTAINING_RECORD(iface, QTOutPin, pin);
}
-static HRESULT WINAPI QTOutPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)
+static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
{
- QTOutPin *This = impl_QTOutPin_from_IPin(iface);
-
- TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
-
- *ppv = NULL;
+ QTOutPin *pin = impl_source_from_strmbase_pin(&iface->IPin_iface);
- if (IsEqualIID(riid, &IID_IUnknown))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IPin))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IMediaSeeking))
- *ppv = &This->sourceSeeking.IMediaSeeking_iface;
- else if (IsEqualIID(riid, &IID_IQualityControl))
- *ppv = &This->IQualityControl_iface;
+ if (IsEqualGUID(iid, &IID_IMediaSeeking))
+ *out = &pin->sourceSeeking.IMediaSeeking_iface;
+ else if (IsEqualGUID(iid, &IID_IQualityControl))
+ *out = &pin->IQualityControl_iface;
+ else
+ return E_NOINTERFACE;
- if (*ppv)
- {
- IUnknown_AddRef((IUnknown *)(*ppv));
- return S_OK;
- }
- FIXME("No interface for %s!\n", debugstr_guid(riid));
- return E_NOINTERFACE;
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
}
static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
@@ -1192,7 +1173,7 @@ static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYP
static HRESULT source_get_media_type(struct strmbase_pin *iface, unsigned int iPosition, AM_MEDIA_TYPE *pmt)
{
- QTOutPin *This = impl_sink_from_strmbase_pin(iface);
+ QTOutPin *This = impl_source_from_strmbase_pin(iface);
if (iPosition > 0)
return VFW_S_NO_MORE_ITEMS;
@@ -1231,7 +1212,7 @@ static HRESULT WINAPI QTOutPin_DecideAllocator(struct strmbase_source *iface,
}
static const IPinVtbl QT_OutputPin_Vtbl = {
- QTOutPin_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseOutputPinImpl_Connect,
--
2.23.0
Dec. 7, 2019
[PATCH 1/6] winegstreamer: Use BasePinImpl_QueryInterface().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gstdemux.c | 63 ++++++++---------------------------
1 file changed, 13 insertions(+), 50 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 78c8e38701a..04fb54915c6 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -1735,29 +1735,19 @@ static inline struct gstdemux_source *impl_source_from_IPin(IPin *iface)
return CONTAINING_RECORD(iface, struct gstdemux_source, pin.pin.IPin_iface);
}
-static HRESULT WINAPI GSTOutPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)
+static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
{
- struct gstdemux_source *This = impl_source_from_IPin(iface);
+ struct gstdemux_source *pin = impl_source_from_IPin(&iface->IPin_iface);
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
-
- *ppv = NULL;
-
- if (IsEqualIID(riid, &IID_IUnknown))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IPin))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IMediaSeeking))
- *ppv = &This->seek;
- else if (IsEqualIID(riid, &IID_IQualityControl))
- *ppv = &This->IQualityControl_iface;
+ if (IsEqualGUID(iid, &IID_IMediaSeeking))
+ *out = &pin->seek.IMediaSeeking_iface;
+ else if (IsEqualGUID(iid, &IID_IQualityControl))
+ *out = &pin->IQualityControl_iface;
+ else
+ return E_NOINTERFACE;
- if (*ppv) {
- IUnknown_AddRef((IUnknown *)(*ppv));
- return S_OK;
- }
- FIXME("No interface for %s!\n", debugstr_guid(riid));
- return E_NOINTERFACE;
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
}
static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
@@ -1847,7 +1837,7 @@ static void free_source_pin(struct gstdemux_source *pin)
}
static const IPinVtbl GST_OutputPin_Vtbl = {
- GSTOutPin_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseOutputPinImpl_Connect,
@@ -1869,6 +1859,7 @@ static const IPinVtbl GST_OutputPin_Vtbl = {
static const struct strmbase_source_ops source_ops =
{
+ .base.pin_query_interface = source_query_interface,
.base.pin_query_accept = source_query_accept,
.base.pin_get_media_type = source_get_media_type,
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
@@ -2071,36 +2062,8 @@ static HRESULT WINAPI GSTInPin_NewSegment(IPin *iface, REFERENCE_TIME start,
return S_OK;
}
-static HRESULT WINAPI GSTInPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
-{
- struct gstdemux *filter = impl_from_sink_IPin(iface);
-
- TRACE("filter %p, riid %s, ppv %p.\n", filter, debugstr_guid(riid), ppv);
-
- *ppv = NULL;
-
- if (IsEqualIID(riid, &IID_IUnknown))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IPin))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IMediaSeeking))
- {
- return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, &IID_IMediaSeeking, ppv);
- }
-
- if (*ppv)
- {
- IUnknown_AddRef((IUnknown *)(*ppv));
- return S_OK;
- }
-
- FIXME("No interface for %s!\n", debugstr_guid(riid));
-
- return E_NOINTERFACE;
-}
-
static const IPinVtbl GST_InputPin_Vtbl = {
- GSTInPin_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
--
2.23.0
Dec. 7, 2019
Re: [PATCH v3 3/3] xmllite: Expand test for any unparsed data at end of XML.
by Nikolay Sivov
On 12/7/19 12:24 AM, Jeff Smith wrote:
> On Fri, Dec 6, 2019 at 11:16 AM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>> On 12/5/19 10:53 PM, Jeff Smith wrote:
>>> @@ -2662,7 +2663,7 @@ static HRESULT reader_parse_nextnode(xmlreader *reader)
>>> hr = reader_parse_misc(reader);
>>> if (hr != S_FALSE) return hr;
>>>
>>> - if (*reader_get_ptr(reader))
>>> + if (buffer->cur*sizeof(WCHAR) < buffer->written)
>>> {
>>> WARN("found garbage in the end of XML\n");
>>> return WC_E_SYNTAX;
> Hi Nikolay,
>
>> That means we don't have enough data,
> How do you figure that?
>
>> it's another change not backed by tests
> This fixes two tests, and does not break any others.
>
>> and potentially depending on current read-ahead buffer size/filled level.
> I'm pretty sure reader_parse_misc would have read at least one byte
> ahead, which is all that is required for this to trigger, though I
> could double-check that.
> However, to your point made in the patch 2 of the set about not
> exposing the buffer at this level, I will also consider this something
> that potentially needs to be handled elsewhere.
My point is that we should always hit this single invalid syntax/garbage
at the end condition that we already have,
instead of doing fixups for specific node types.
>
> Regards,
> Jeff
Dec. 6, 2019
[PATCH 3/3] kernel32/tests: Test invalid parent handle in test_parent_process_attribute().
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
dlls/kernel32/tests/process.c | 87 ++++++++++++++++++++++++++++++++++-
1 file changed, 86 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 6d7a9a74c3..b8df8b8dce 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3825,7 +3825,8 @@ static void test_ProcThreadAttributeList(void)
/* level 0: Main test process
* level 1: Process created by level 0 process without handle inheritance
* level 2: Process created by level 1 process with handle inheritance and level 0
- * process parent substitute. */
+ * process parent substitute.
+ * level 255: Process created by level 1 process during invalid parent handles testing. */
void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
{
PROCESS_BASIC_INFORMATION pbi;
@@ -3848,6 +3849,9 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
}
parent_data;
+ if (level == 255)
+ return;
+
if (!pInitializeProcThreadAttributeList)
{
win_skip("No support for ProcThreadAttributeList.\n");
@@ -3891,11 +3895,92 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
if (level)
{
+ HANDLE handle;
SIZE_T size;
ret = pInitializeProcThreadAttributeList(NULL, 1, 0, &size);
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+ sprintf(buffer, "\"%s\" tests/process.c parent %u %p %p", selfname, 255, read_pipe, NULL);
+
+#if 0
+ /* Crashes on some Windows installations, otherwise successfully creates process. */
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+#endif
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = INVALID_HANDLE_VALUE;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ /* Broken on w7u/w8. */
+ ok((!ret && GetLastError() == ERROR_INVALID_HANDLE) || broken(ret),
+ "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ if (ret)
+ {
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+ }
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = (HANDLE)0xdeadbeef;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = NULL;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = GetCurrentProcess();
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ /* Broken on w7u/w8. */
+ ok((!ret && GetLastError() == ERROR_INVALID_HANDLE) || broken(ret),
+ "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ if (ret)
+ {
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+ }
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
si.lpAttributeList = heap_alloc(size);
ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
--
2.23.0
Dec. 6, 2019
[PATCH 2/3] ntdll: Support creating processes with specified parent.
by Paul Gofman
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47817
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
dlls/kernel32/tests/process.c | 4 ++--
dlls/ntdll/process.c | 11 +++++++++--
include/wine/server_protocol.h | 4 +++-
server/process.c | 30 ++++++++++++++++++++++++------
server/protocol.def | 1 +
server/request.h | 17 +++++++++--------
server/trace.c | 3 ++-
7 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 3efbfa2402..6d7a9a74c3 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3874,14 +3874,14 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
memset(&parent_data, 0, sizeof(parent_data));
ret = ReadFile(read_pipe, &parent_data, sizeof(parent_data), &size, NULL);
- todo_wine_if(level == 2) ok((level == 2 && ret) || (level == 1 && !ret && GetLastError() == ERROR_INVALID_HANDLE),
+ ok((level == 2 && ret) || (level == 1 && !ret && GetLastError() == ERROR_INVALID_HANDLE),
"Got unexpected ret %#x, level %u, GetLastError() %u.\n",
ret, level, GetLastError());
}
if (level == 2)
{
- todo_wine ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
+ ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
parent_id, parent_data.parent_id);
return;
}
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 52d7ea429e..5d75a27e97 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -1667,8 +1667,14 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
RtlNormalizeProcessParams( params );
- TRACE( "%s image %s cmdline %s\n", debugstr_us( path ),
- debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine ));
+ TRACE( "%s image %s cmdline %s, parent %p.\n", debugstr_us( path ),
+ debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine ), parent);
+
+ if (parent == INVALID_HANDLE_VALUE)
+ {
+ memset(info, 0, sizeof(*info));
+ return STATUS_INVALID_HANDLE;
+ }
if ((status = get_pe_file_info( path, attributes, &file_handle, &pe_info )))
{
@@ -1709,6 +1715,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
SERVER_START_REQ( new_process )
{
+ req->parent_process = wine_server_obj_handle(parent);
req->inherit_all = inherit;
req->create_flags = params->DebugFlags; /* hack: creation flags stored in DebugFlags for now */
req->socket_fd = socketfd[1];
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index aaa5fd2e33..98ecd98b08 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -769,6 +769,7 @@ struct rawinput_device
struct new_process_request
{
struct request_header __header;
+ obj_handle_t parent_process;
int inherit_all;
unsigned int create_flags;
int socket_fd;
@@ -779,6 +780,7 @@ struct new_process_request
/* VARARG(objattr,object_attributes); */
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */
+ char __pad_44[4];
};
struct new_process_reply
{
@@ -6702,6 +6704,6 @@ union generic_reply
struct resume_process_reply resume_process_reply;
};
-#define SERVER_PROTOCOL_VERSION 593
+#define SERVER_PROTOCOL_VERSION 594
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/process.c b/server/process.c
index 16bb5d57e7..195f54fa79 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1117,6 +1117,7 @@ DECL_HANDLER(new_process)
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
struct process *process = NULL;
struct process *parent = current->process;
+ struct thread *parent_thread = current;
int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
if (socket_fd == -1)
@@ -1148,11 +1149,26 @@ DECL_HANDLER(new_process)
return;
}
+ if (req->parent_process)
+ {
+ if (!(parent = get_process_from_handle( req->parent_process, PROCESS_CREATE_PROCESS)))
+ {
+ set_error(STATUS_INVALID_HANDLE);
+ close(socket_fd);
+ return;
+ }
+ parent_thread = get_process_first_thread(parent);
+ }
+
if (parent->job && (req->create_flags & CREATE_BREAKAWAY_FROM_JOB) &&
!(parent->job->limit_flags & (JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)))
{
set_error( STATUS_ACCESS_DENIED );
close( socket_fd );
+
+ if (req->parent_process)
+ release_object(parent);
+
return;
}
@@ -1222,7 +1238,7 @@ DECL_HANDLER(new_process)
}
/* connect to the window station */
- connect_process_winstation( process, current );
+ connect_process_winstation( process, parent_thread );
/* set the process console */
if (!(req->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)))
@@ -1231,7 +1247,7 @@ DECL_HANDLER(new_process)
* like if hConOut and hConIn are console handles, then they should be on the same
* physical console
*/
- inherit_console( current, process, req->inherit_all ? info->data->hstdin : 0 );
+ inherit_console( parent_thread, process, req->inherit_all ? info->data->hstdin : 0 );
}
if (!req->inherit_all && !(req->create_flags & CREATE_NEW_CONSOLE))
@@ -1246,16 +1262,15 @@ DECL_HANDLER(new_process)
if (get_error() == STATUS_INVALID_HANDLE ||
get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error();
}
-
/* attach to the debugger if requested */
if (req->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
{
set_process_debugger( process, current );
process->debug_children = !(req->create_flags & DEBUG_ONLY_THIS_PROCESS);
}
- else if (parent->debugger && parent->debug_children)
+ else if (current->process->debugger && current->process->debug_children)
{
- set_process_debugger( process, parent->debugger );
+ set_process_debugger( process, current->process->debugger );
/* debug_children is set to 1 by default */
}
@@ -1265,9 +1280,12 @@ DECL_HANDLER(new_process)
info->process = (struct process *)grab_object( process );
reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
reply->pid = get_process_id( process );
- reply->handle = alloc_handle_no_access_check( parent, process, req->access, objattr->attributes );
+ reply->handle = alloc_handle_no_access_check( current->process, process, req->access, objattr->attributes );
done:
+ if (req->parent_process)
+ release_object(parent);
+
if (process) release_object( process );
release_object( info );
}
diff --git a/server/protocol.def b/server/protocol.def
index 1cb1fea602..7f9ec3a149 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -783,6 +783,7 @@ struct rawinput_device
/* Create a new process from the context of the parent */
@REQ(new_process)
+ obj_handle_t parent_process; /* parent process */
int inherit_all; /* inherit all handles from parent */
unsigned int create_flags; /* creation flags */
int socket_fd; /* file descriptor for process socket */
diff --git a/server/request.h b/server/request.h
index 90a3180a6c..9f36bcb711 100644
--- a/server/request.h
+++ b/server/request.h
@@ -745,14 +745,15 @@ C_ASSERT( sizeof(unsigned char) == 1 );
C_ASSERT( sizeof(unsigned int) == 4 );
C_ASSERT( sizeof(unsigned short) == 2 );
C_ASSERT( sizeof(user_handle_t) == 4 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 12 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 16 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 20 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 24 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 28 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 32 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 36 );
-C_ASSERT( sizeof(struct new_process_request) == 40 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, parent_process) == 12 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 16 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 20 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 24 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 28 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 32 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 36 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 40 );
+C_ASSERT( sizeof(struct new_process_request) == 48 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, pid) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 );
diff --git a/server/trace.c b/server/trace.c
index 411369a4f6..026aba9c50 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1243,7 +1243,8 @@ typedef void (*dump_func)( const void *req );
static void dump_new_process_request( const struct new_process_request *req )
{
- fprintf( stderr, " inherit_all=%d", req->inherit_all );
+ fprintf( stderr, " parent_process=%04x", req->parent_process );
+ fprintf( stderr, ", inherit_all=%d", req->inherit_all );
fprintf( stderr, ", create_flags=%08x", req->create_flags );
fprintf( stderr, ", socket_fd=%d", req->socket_fd );
fprintf( stderr, ", exe_file=%04x", req->exe_file );
--
2.23.0
Dec. 6, 2019
[PATCH 1/3] kernelbase: Support PROC_THREAD_ATTRIBUTE_PARENT_PROCESS in CreateProcessInternalW().
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
dlls/kernelbase/process.c | 85 ++++++++++++++++++++++++++-------------
1 file changed, 56 insertions(+), 29 deletions(-)
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
index 90ea299416..ec034aa75d 100644
--- a/dlls/kernelbase/process.c
+++ b/dlls/kernelbase/process.c
@@ -244,7 +244,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename
*/
static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa,
BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params,
- RTL_USER_PROCESS_INFORMATION *info )
+ RTL_USER_PROCESS_INFORMATION *info, HANDLE parent )
{
NTSTATUS status;
UNICODE_STRING nameW;
@@ -257,7 +257,7 @@ static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES
status = RtlCreateUserProcess( &nameW, OBJ_CASE_INSENSITIVE, params,
psa ? psa->lpSecurityDescriptor : NULL,
tsa ? tsa->lpSecurityDescriptor : NULL,
- 0, inherit, 0, 0, info );
+ parent, inherit, 0, 0, info );
RtlFreeUnicodeString( &nameW );
}
return status;
@@ -288,7 +288,7 @@ static NTSTATUS create_vdm_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE
winevdm, params->ImagePathName.Buffer, params->CommandLine.Buffer );
RtlInitUnicodeString( ¶ms->ImagePathName, winevdm );
RtlInitUnicodeString( ¶ms->CommandLine, newcmdline );
- status = create_nt_process( psa, tsa, inherit, flags, params, info );
+ status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL );
HeapFree( GetProcessHeap(), 0, newcmdline );
return status;
}
@@ -316,7 +316,7 @@ static NTSTATUS create_cmd_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE
swprintf( newcmdline, len, L"%s /s/c \"%s\"", comspec, params->CommandLine.Buffer );
RtlInitUnicodeString( ¶ms->ImagePathName, comspec );
RtlInitUnicodeString( ¶ms->CommandLine, newcmdline );
- status = create_nt_process( psa, tsa, inherit, flags, params, info );
+ status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL );
RtlFreeHeap( GetProcessHeap(), 0, newcmdline );
return status;
}
@@ -368,7 +368,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW( HANDLE token, const WCHAR *a
inherit, flags, env, cur_dir, startup_info, info, NULL );
}
-
/**********************************************************************
* CreateProcessInternalA (kernelbase.@)
*/
@@ -382,7 +381,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalA( HANDLE token, const char *
BOOL ret = FALSE;
WCHAR *app_nameW = NULL, *cmd_lineW = NULL, *cur_dirW = NULL;
UNICODE_STRING desktopW, titleW;
- STARTUPINFOW infoW;
+ STARTUPINFOEXW infoW;
desktopW.Buffer = NULL;
titleW.Buffer = NULL;
@@ -393,12 +392,15 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalA( HANDLE token, const char *
if (startup_info->lpDesktop) RtlCreateUnicodeStringFromAsciiz( &desktopW, startup_info->lpDesktop );
if (startup_info->lpTitle) RtlCreateUnicodeStringFromAsciiz( &titleW, startup_info->lpTitle );
- memcpy( &infoW, startup_info, sizeof(infoW) );
- infoW.lpDesktop = desktopW.Buffer;
- infoW.lpTitle = titleW.Buffer;
+ memcpy( &infoW.StartupInfo, startup_info, sizeof(infoW.StartupInfo) );
+ infoW.StartupInfo.lpDesktop = desktopW.Buffer;
+ infoW.StartupInfo.lpTitle = titleW.Buffer;
+
+ if (flags & EXTENDED_STARTUPINFO_PRESENT)
+ infoW.lpAttributeList = ((STARTUPINFOEXW *)startup_info)->lpAttributeList;
ret = CreateProcessInternalW( token, app_nameW, cmd_lineW, process_attr, thread_attr,
- inherit, flags, env, cur_dirW, &infoW, info, new_token );
+ inherit, flags, env, cur_dirW, (STARTUPINFOW *)&infoW, info, new_token );
done:
RtlFreeHeap( GetProcessHeap(), 0, app_nameW );
RtlFreeHeap( GetProcessHeap(), 0, cmd_lineW );
@@ -408,6 +410,22 @@ done:
return ret;
}
+struct proc_thread_attr
+{
+ DWORD_PTR attr;
+ SIZE_T size;
+ void *value;
+};
+
+struct _PROC_THREAD_ATTRIBUTE_LIST
+{
+ DWORD mask; /* bitmask of items in list */
+ DWORD size; /* max number of items in list */
+ DWORD count; /* number of items in list */
+ DWORD pad;
+ DWORD_PTR unk;
+ struct proc_thread_attr attrs[1];
+};
/**********************************************************************
* CreateProcessInternalW (kernelbase.@)
@@ -423,6 +441,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
WCHAR *p, *tidy_cmdline = cmd_line;
RTL_USER_PROCESS_PARAMETERS *params = NULL;
RTL_USER_PROCESS_INFORMATION rtl_info;
+ HANDLE parent = NULL;
NTSTATUS status;
/* Process the AppName and/or CmdLine to get module name and path */
@@ -473,7 +492,33 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
goto done;
}
- status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info );
+ if (flags & EXTENDED_STARTUPINFO_PRESENT)
+ {
+ struct _PROC_THREAD_ATTRIBUTE_LIST *attrs =
+ (struct _PROC_THREAD_ATTRIBUTE_LIST *)((STARTUPINFOEXW *)startup_info)->lpAttributeList;
+ unsigned int i;
+
+ if (attrs)
+ {
+ for (i = 0; i < attrs->count; ++i)
+ {
+ switch(attrs->attrs[i].attr)
+ {
+ case PROC_THREAD_ATTRIBUTE_PARENT_PROCESS:
+ parent = *(HANDLE *)attrs->attrs[i].value;
+ TRACE("PROC_THREAD_ATTRIBUTE_PARENT_PROCESS parent %p.\n", parent);
+ if (!parent)
+ parent = INVALID_HANDLE_VALUE;
+ break;
+ default:
+ FIXME("Unsupported attribute %#lx.\n", attrs->attrs[i].attr);
+ break;
+ }
+ }
+ }
+ }
+
+ status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info, parent );
switch (status)
{
case STATUS_SUCCESS:
@@ -1301,24 +1346,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW( LPCWSTR name, LPCWSTR val
* Process/thread attribute lists
***********************************************************************/
-
-struct proc_thread_attr
-{
- DWORD_PTR attr;
- SIZE_T size;
- void *value;
-};
-
-struct _PROC_THREAD_ATTRIBUTE_LIST
-{
- DWORD mask; /* bitmask of items in list */
- DWORD size; /* max number of items in list */
- DWORD count; /* number of items in list */
- DWORD pad;
- DWORD_PTR unk;
- struct proc_thread_attr attrs[1];
-};
-
/***********************************************************************
* InitializeProcThreadAttributeList (kernelbase.@)
*/
--
2.23.0
Dec. 6, 2019
Re: [PATCH v3 3/3] xmllite: Expand test for any unparsed data at end of XML.
by Jeff Smith
On Fri, Dec 6, 2019 at 11:16 AM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> On 12/5/19 10:53 PM, Jeff Smith wrote:
> > @@ -2662,7 +2663,7 @@ static HRESULT reader_parse_nextnode(xmlreader *reader)
> > hr = reader_parse_misc(reader);
> > if (hr != S_FALSE) return hr;
> >
> > - if (*reader_get_ptr(reader))
> > + if (buffer->cur*sizeof(WCHAR) < buffer->written)
> > {
> > WARN("found garbage in the end of XML\n");
> > return WC_E_SYNTAX;
Hi Nikolay,
> That means we don't have enough data,
How do you figure that?
> it's another change not backed by tests
This fixes two tests, and does not break any others.
> and potentially depending on current read-ahead buffer size/filled level.
I'm pretty sure reader_parse_misc would have read at least one byte
ahead, which is all that is required for this to trigger, though I
could double-check that.
However, to your point made in the patch 2 of the set about not
exposing the buffer at this level, I will also consider this something
that potentially needs to be handled elsewhere.
Regards,
Jeff
Dec. 6, 2019
Re: [PATCH v3 2/3] xmllite: Whitespace node not returned when followed by invalid character.
by Jeff Smith
On Fri, Dec 6, 2019 at 11:13 AM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> On 12/5/19 10:53 PM, Jeff Smith wrote:
> > Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
> > ---
> > dlls/xmllite/reader.c | 12 ++++++++++--
> > dlls/xmllite/tests/reader.c | 2 --
> > 2 files changed, 10 insertions(+), 4 deletions(-)
> >
> > diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
> > index eddc4d8eec..79e5c2253a 100644
> > --- a/dlls/xmllite/reader.c
> > +++ b/dlls/xmllite/reader.c
> > @@ -1113,8 +1113,8 @@ static inline UINT reader_get_cur(xmlreader *reader)
> > static inline WCHAR *reader_get_ptr(xmlreader *reader)
> > {
> > encoded_buffer *buffer = &reader->input->buffer->utf16;
> > - WCHAR *ptr = (WCHAR*)buffer->data + buffer->cur;
> > - if (!*ptr) reader_more(reader);
> > + if (buffer->cur*sizeof(WCHAR) >= buffer->written)
> > + reader_more(reader);
> > return (WCHAR*)buffer->data + buffer->cur;
> > }
Hi Nikolay,
> Why do you need to change that? It's used everywhere.
Since the test is fixed even without this, I will probably take this
chunk out of this patch set.
> >
> > @@ -1714,8 +1714,16 @@ static HRESULT reader_parse_whitespace(xmlreader *reader)
> > {
> > strval value;
> > UINT start;
> > + const encoded_buffer *buffer = &reader->input->buffer->utf16;
> >
> > reader_skipspaces(reader);
> > +
> > + /* Do NOT return Whitespace node if followed by a character other than '<'.
> > + * The reader_skipspaces call should have already read in the character. */
> > + if (buffer->cur*sizeof(WCHAR) < buffer->written &&
> > + *reader_get_ptr2(reader, buffer->cur) != '<')
> > + return WC_E_SYNTAX;
> > +
> Buffer access should not be exposed like that.
OK, I will try to improve where that is handled. Though that could
potentially entail changing more things that are used everywhere.
Regards,
Jeff
Dec. 6, 2019
Winter is coming
by Alexandre Julliard
Folks,
As you are probably aware, we are now entering the code freeze season.
The plan is to start the code freeze after the next release, i.e. one
week from today. So if there are things you want to see in Wine 5.0, now
is the last moment to submit them...
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 6, 2019
[PATCH 3/3] wined3d: Unload resources in wined3d_device_uninit_3d().
by Henri Verbeet
Instead of in wined3d_device_delete_opengl_contexts_cs(), which is specific to
the GL backend.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/device.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 90c08876505..0ae841d4e35 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -939,7 +939,6 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi
void wined3d_device_delete_opengl_contexts_cs(void *object)
{
- struct wined3d_resource *resource, *cursor;
struct wined3d_swapchain_gl *swapchain_gl;
struct wined3d_device *device = object;
struct wined3d_context_gl *context_gl;
@@ -949,12 +948,6 @@ void wined3d_device_delete_opengl_contexts_cs(void *object)
device_gl = wined3d_device_gl(device);
- LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
- {
- TRACE("Unloading resource %p.\n", resource);
- wined3d_cs_emit_unload_resource(device->cs, resource);
- }
-
LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry)
{
device->shader_backend->shader_destroy(shader);
@@ -1106,6 +1099,7 @@ static void device_free_sampler(struct wine_rb_entry *entry, void *context)
void wined3d_device_uninit_3d(struct wined3d_device *device)
{
BOOL no3d = device->wined3d->flags & WINED3D_NO3D;
+ struct wined3d_resource *resource, *cursor;
struct wined3d_rendertarget_view *view;
struct wined3d_texture *texture;
unsigned int i;
@@ -1145,6 +1139,12 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
wine_rb_clear(&device->samplers, device_free_sampler, NULL);
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ TRACE("Unloading resource %p.\n", resource);
+ wined3d_cs_emit_unload_resource(device->cs, resource);
+ }
+
device->adapter->adapter_ops->adapter_uninit_3d(device);
device->d3d_initialized = FALSE;
@@ -5298,6 +5298,12 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
wined3d_cs_emit_reset_state(device->cs);
state_cleanup(&device->state);
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ TRACE("Unloading resource %p.\n", resource);
+ wined3d_cs_emit_unload_resource(device->cs, resource);
+ }
+
if (device->d3d_initialized)
device->adapter->adapter_ops->adapter_uninit_3d(device);
--
2.11.0
Dec. 6, 2019
[PATCH 2/3] wined3d: Unload texture resources through texture ops.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 57 +-----------
dlls/wined3d/device.c | 3 +-
dlls/wined3d/texture.c | 200 +++++++++++++++++++++++++----------------
dlls/wined3d/wined3d_private.h | 3 +-
4 files changed, 125 insertions(+), 138 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 3408439660f..a8a8e93c0b2 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4746,61 +4746,6 @@ static HRESULT adapter_gl_create_texture(struct wined3d_device *device,
return hr;
}
-static void wined3d_texture_gl_destroy_object(void *object)
-{
- struct wined3d_renderbuffer_entry *entry, *entry2;
- struct wined3d_texture_gl *texture_gl = object;
- struct wined3d_context *context = NULL;
- const struct wined3d_gl_info *gl_info;
- struct wined3d_device *device;
- unsigned int sub_count, i;
- GLuint buffer_object;
-
- TRACE("texture_gl %p.\n", texture_gl);
-
- sub_count = texture_gl->t.level_count * texture_gl->t.layer_count;
- for (i = 0; i < sub_count; ++i)
- {
- if (!(buffer_object = texture_gl->t.sub_resources[i].buffer_object))
- continue;
-
- TRACE("Deleting buffer object %u.\n", buffer_object);
-
- if (!context)
- {
- context = context_acquire(texture_gl->t.resource.device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
- }
-
- GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
- }
-
- if (!list_empty(&texture_gl->renderbuffers))
- {
- device = texture_gl->t.resource.device;
- if (!context)
- {
- context = context_acquire(device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
- }
-
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- TRACE("Deleting renderbuffer %u.\n", entry->id);
- context_gl_resource_released(device, entry->id, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
- heap_free(entry);
- }
- }
-
- if (context)
- context_release(context);
-
- wined3d_texture_gl_unload_texture(texture_gl);
-
- heap_free(texture_gl);
-}
-
static void adapter_gl_destroy_texture(struct wined3d_texture *texture)
{
struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture);
@@ -4820,7 +4765,7 @@ static void adapter_gl_destroy_texture(struct wined3d_texture *texture)
texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
wined3d_texture_cleanup(&texture_gl->t);
- wined3d_cs_destroy_object(device->cs, wined3d_texture_gl_destroy_object, texture_gl);
+ wined3d_cs_destroy_object(device->cs, heap_free, texture_gl);
if (swapchain_count)
wined3d_device_decref(device);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 98559e4f6c6..90c08876505 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1146,6 +1146,7 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
wine_rb_clear(&device->samplers, device_free_sampler, NULL);
device->adapter->adapter_ops->adapter_uninit_3d(device);
+ device->d3d_initialized = FALSE;
if ((view = device->fb.depth_stencil))
{
@@ -1170,8 +1171,6 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
heap_free(device->swapchains);
device->swapchains = NULL;
-
- device->d3d_initialized = FALSE;
}
/* Enables thread safety in the wined3d device and its resources. Called by DirectDraw
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 1c315a1dd77..7c9c8298519 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -636,51 +636,6 @@ static void wined3d_texture_gl_allocate_immutable_storage(struct wined3d_texture
checkGLcall("allocate immutable storage");
}
-void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl)
-{
- struct wined3d_device *device = texture_gl->t.resource.device;
- const struct wined3d_gl_info *gl_info = NULL;
- struct wined3d_context *context = NULL;
-
- if (texture_gl->t.resource.bind_count)
- device_invalidate_state(device, STATE_SAMPLER(texture_gl->t.sampler));
-
- if (texture_gl->texture_rgb.name || texture_gl->texture_srgb.name
- || texture_gl->rb_multisample || texture_gl->rb_resolved)
- {
- context = context_acquire(device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
- }
-
- if (texture_gl->texture_rgb.name)
- gltexture_delete(device, gl_info, &texture_gl->texture_rgb);
-
- if (texture_gl->texture_srgb.name)
- gltexture_delete(device, gl_info, &texture_gl->texture_srgb);
-
- if (texture_gl->rb_multisample)
- {
- TRACE("Deleting multisample renderbuffer %u.\n", texture_gl->rb_multisample);
- context_gl_resource_released(device, texture_gl->rb_multisample, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_multisample);
- texture_gl->rb_multisample = 0;
- }
-
- if (texture_gl->rb_resolved)
- {
- TRACE("Deleting resolved renderbuffer %u.\n", texture_gl->rb_resolved);
- context_gl_resource_released(device, texture_gl->rb_resolved, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_resolved);
- texture_gl->rb_resolved = 0;
- }
-
- if (context) context_release(context);
-
- wined3d_texture_set_dirty(&texture_gl->t);
-
- resource_unload(&texture_gl->t.resource);
-}
-
void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
@@ -1119,12 +1074,14 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture)
static void wined3d_texture_destroy_object(void *object)
{
struct wined3d_texture *texture = object;
+ struct wined3d_resource *resource;
struct wined3d_dc_info *dc_info;
unsigned int sub_count;
unsigned int i;
TRACE("texture %p.\n", texture);
+ resource = &texture->resource;
sub_count = texture->level_count * texture->layer_count;
if ((dc_info = texture->dc_info))
@@ -1156,12 +1113,14 @@ static void wined3d_texture_destroy_object(void *object)
}
heap_free(texture->overlay_info);
}
+
+ resource->resource_ops->resource_unload(resource);
}
void wined3d_texture_cleanup(struct wined3d_texture *texture)
{
- resource_cleanup(&texture->resource);
wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture);
+ resource_cleanup(&texture->resource);
}
static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture)
@@ -1789,6 +1748,12 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture,
return texture->texture_ops->texture_prepare_location(texture, sub_resource_idx, context, location);
}
+static void wined3d_texture_unload_location(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location)
+{
+ texture->texture_ops->texture_unload_location(texture, context, location);
+}
+
static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct wined3d_texture *texture,
unsigned int sub_resource_idx)
{
@@ -2903,10 +2868,79 @@ static BOOL wined3d_texture_gl_load_location(struct wined3d_texture *texture,
}
}
+static void wined3d_texture_gl_unload_location(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location)
+{
+ struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture);
+ struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+ struct wined3d_renderbuffer_entry *entry, *entry2;
+ unsigned int i, sub_count;
+
+ TRACE("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+
+ switch (location)
+ {
+ case WINED3D_LOCATION_BUFFER:
+ sub_count = texture->level_count * texture->layer_count;
+ for (i = 0; i < sub_count; ++i)
+ {
+ if (texture_gl->t.sub_resources[i].buffer_object)
+ wined3d_texture_remove_buffer_object(&texture_gl->t, i, context_gl->gl_info);
+ }
+ break;
+
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ if (texture_gl->texture_rgb.name)
+ gltexture_delete(texture_gl->t.resource.device, context_gl->gl_info, &texture_gl->texture_rgb);
+ break;
+
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ if (texture_gl->texture_srgb.name)
+ gltexture_delete(texture_gl->t.resource.device, context_gl->gl_info, &texture_gl->texture_srgb);
+ break;
+
+ case WINED3D_LOCATION_RB_MULTISAMPLE:
+ if (texture_gl->rb_multisample)
+ {
+ TRACE("Deleting multisample renderbuffer %u.\n", texture_gl->rb_multisample);
+ context_gl_resource_released(texture_gl->t.resource.device, texture_gl->rb_multisample, TRUE);
+ context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_multisample);
+ texture_gl->rb_multisample = 0;
+ }
+ break;
+
+ case WINED3D_LOCATION_RB_RESOLVED:
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers,
+ struct wined3d_renderbuffer_entry, entry)
+ {
+ context_gl_resource_released(texture_gl->t.resource.device, entry->id, TRUE);
+ context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+ list_remove(&entry->entry);
+ heap_free(entry);
+ }
+ list_init(&texture_gl->renderbuffers);
+ texture_gl->current_renderbuffer = NULL;
+
+ if (texture_gl->rb_resolved)
+ {
+ TRACE("Deleting resolved renderbuffer %u.\n", texture_gl->rb_resolved);
+ context_gl_resource_released(texture_gl->t.resource.device, texture_gl->rb_resolved, TRUE);
+ context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_resolved);
+ texture_gl->rb_resolved = 0;
+ }
+ break;
+
+ default:
+ ERR("Unhandled location %s.\n", wined3d_debug_location(location));
+ break;
+ }
+}
+
static const struct wined3d_texture_ops texture_gl_ops =
{
wined3d_texture_gl_prepare_location,
wined3d_texture_gl_load_location,
+ wined3d_texture_gl_unload_location,
wined3d_texture_gl_upload_data,
wined3d_texture_gl_download_data,
};
@@ -2936,65 +2970,59 @@ static void texture_resource_preload(struct wined3d_resource *resource)
context_release(context);
}
-static void wined3d_texture_gl_unload(struct wined3d_resource *resource)
+static void texture_resource_unload(struct wined3d_resource *resource)
{
- struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource));
- UINT sub_count = texture_gl->t.level_count * texture_gl->t.layer_count;
- struct wined3d_renderbuffer_entry *entry, *entry2;
+ struct wined3d_texture *texture = texture_from_resource(resource);
struct wined3d_device *device = resource->device;
unsigned int location = resource->map_binding;
- const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
- UINT i;
+ unsigned int sub_count, i;
+
+ TRACE("resource %p.\n", resource);
- TRACE("texture_gl %p.\n", texture_gl);
+ /* D3D is not initialised, so no GPU locations should currently exist.
+ * Moreover, we may not be able to acquire a valid context. */
+ if (!device->d3d_initialized)
+ return;
context = context_acquire(device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
if (location == WINED3D_LOCATION_BUFFER)
location = WINED3D_LOCATION_SYSMEM;
+ sub_count = texture->level_count * texture->layer_count;
for (i = 0; i < sub_count; ++i)
{
- struct wined3d_texture_sub_resource *sub_resource = &texture_gl->t.sub_resources[i];
-
if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
- && wined3d_texture_load_location(&texture_gl->t, i, context, location))
+ && wined3d_texture_load_location(texture, i, context, location))
{
- wined3d_texture_invalidate_location(&texture_gl->t, i, ~location);
+ wined3d_texture_invalidate_location(texture, i, ~location);
}
else
{
- /* We should only get here on device reset/teardown for implicit
- * resources. */
- if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
- || resource->type != WINED3D_RTYPE_TEXTURE_2D)
+ if (resource->access & WINED3D_RESOURCE_ACCESS_CPU)
ERR("Discarding %s %p sub-resource %u with resource access %s.\n",
debug_d3dresourcetype(resource->type), resource, i,
wined3d_debug_resource_access(resource->access));
- wined3d_texture_validate_location(&texture_gl->t, i, WINED3D_LOCATION_DISCARDED);
- wined3d_texture_invalidate_location(&texture_gl->t, i, ~WINED3D_LOCATION_DISCARDED);
+ wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_DISCARDED);
+ wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED);
}
-
- if (sub_resource->buffer_object)
- wined3d_texture_remove_buffer_object(&texture_gl->t, i, gl_info);
}
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- context_gl_resource_released(device, entry->id, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
- list_remove(&entry->entry);
- heap_free(entry);
- }
- list_init(&texture_gl->renderbuffers);
- texture_gl->current_renderbuffer = NULL;
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_BUFFER);
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_TEXTURE_SRGB);
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_RB_MULTISAMPLE);
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_RB_RESOLVED);
context_release(context);
- wined3d_texture_force_reload(&texture_gl->t);
- wined3d_texture_gl_unload_texture(texture_gl);
+ wined3d_texture_force_reload(texture);
+ if (texture->resource.bind_count)
+ device_invalidate_state(device, STATE_SAMPLER(texture->sampler));
+ wined3d_texture_set_dirty(texture);
+
+ resource_unload(&texture->resource);
}
static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
@@ -3177,7 +3205,7 @@ static const struct wined3d_resource_ops texture_resource_ops =
texture_resource_incref,
texture_resource_decref,
texture_resource_preload,
- wined3d_texture_gl_unload,
+ texture_resource_unload,
texture_resource_sub_resource_map,
texture_resource_sub_resource_unmap,
};
@@ -4088,10 +4116,17 @@ static BOOL wined3d_texture_no3d_load_location(struct wined3d_texture *texture,
return FALSE;
}
+static void wined3d_texture_no3d_unload_location(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location)
+{
+ TRACE("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+}
+
static const struct wined3d_texture_ops wined3d_texture_no3d_ops =
{
wined3d_texture_no3d_prepare_location,
wined3d_texture_no3d_load_location,
+ wined3d_texture_no3d_unload_location,
wined3d_texture_no3d_upload_data,
wined3d_texture_no3d_download_data,
};
@@ -4158,10 +4193,17 @@ static BOOL wined3d_texture_vk_load_location(struct wined3d_texture *texture,
return FALSE;
}
+static void wined3d_texture_vk_unload_location(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location)
+{
+ FIXME("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+}
+
static const struct wined3d_texture_ops wined3d_texture_vk_ops =
{
wined3d_texture_vk_prepare_location,
wined3d_texture_vk_load_location,
+ wined3d_texture_vk_unload_location,
wined3d_texture_vk_upload_data,
wined3d_texture_vk_download_data,
};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7d3b709a974..8f9ad1ce856 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3470,6 +3470,8 @@ struct wined3d_texture_ops
struct wined3d_context *context, unsigned int location);
BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_context *context, unsigned int location);
+ void (*texture_unload_location)(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location);
void (*texture_upload_data)(struct wined3d_context *context, const struct wined3d_const_bo_address *src_bo_addr,
const struct wined3d_format *src_format, const struct wined3d_box *src_box, unsigned int src_row_pitch,
unsigned int src_slice_pitch, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
@@ -3745,7 +3747,6 @@ void wined3d_texture_gl_prepare_texture(struct wined3d_texture_gl *texture_gl,
void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *texture_gl,
struct wined3d_context_gl *context_gl, unsigned int level,
const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
-void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl) DECLSPEC_HIDDEN;
struct wined3d_texture_vk
{
--
2.11.0
Dec. 6, 2019
[PATCH 1/3] wined3d: Unload buffer resources through buffer ops.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 17 +-----------
dlls/wined3d/buffer.c | 59 +++++++++++++++++++++++++++++++++++++-----
dlls/wined3d/wined3d_private.h | 4 +--
3 files changed, 55 insertions(+), 25 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index eb9965723a2..3408439660f 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4699,21 +4699,6 @@ static HRESULT adapter_gl_create_buffer(struct wined3d_device *device,
return hr;
}
-static void wined3d_buffer_gl_destroy_object(void *object)
-{
- struct wined3d_buffer_gl *buffer_gl = object;
- struct wined3d_context *context;
-
- if (buffer_gl->b.buffer_object)
- {
- context = context_acquire(buffer_gl->b.resource.device, NULL, 0);
- wined3d_buffer_gl_destroy_buffer_object(buffer_gl, wined3d_context_gl(context));
- context_release(context);
- }
-
- heap_free(buffer_gl);
-}
-
static void adapter_gl_destroy_buffer(struct wined3d_buffer *buffer)
{
struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer);
@@ -4729,7 +4714,7 @@ static void adapter_gl_destroy_buffer(struct wined3d_buffer *buffer)
if (swapchain_count)
wined3d_device_incref(device);
wined3d_buffer_cleanup(&buffer_gl->b);
- wined3d_cs_destroy_object(device->cs, wined3d_buffer_gl_destroy_object, buffer_gl);
+ wined3d_cs_destroy_object(device->cs, heap_free, buffer_gl);
if (swapchain_count)
wined3d_device_decref(device);
}
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 95fcdff7ef0..89dab8ebfdd 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -139,7 +139,7 @@ static void wined3d_buffer_gl_bind(struct wined3d_buffer_gl *buffer_gl, struct w
}
/* Context activation is done by the caller. */
-void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl,
+static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl,
struct wined3d_context_gl *context_gl)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
@@ -602,6 +602,12 @@ static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
return buffer->buffer_ops->buffer_prepare_location(buffer, context, location);
}
+static void wined3d_buffer_unload_location(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location)
+{
+ buffer->buffer_ops->buffer_unload_location(buffer, context, location);
+}
+
BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, DWORD location)
{
@@ -699,7 +705,7 @@ DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer,
return 0;
}
-static void buffer_unload(struct wined3d_resource *resource)
+static void buffer_resource_unload(struct wined3d_resource *resource)
{
struct wined3d_buffer *buffer = buffer_from_resource(resource);
@@ -713,7 +719,7 @@ static void buffer_unload(struct wined3d_resource *resource)
wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM);
wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER);
- wined3d_buffer_gl_destroy_buffer_object(wined3d_buffer_gl(buffer), wined3d_context_gl(context));
+ wined3d_buffer_unload_location(buffer, context, WINED3D_LOCATION_BUFFER);
buffer_clear_dirty_areas(buffer);
context_release(context);
@@ -731,21 +737,28 @@ static void buffer_unload(struct wined3d_resource *resource)
static void wined3d_buffer_drop_bo(struct wined3d_buffer *buffer)
{
buffer->flags &= ~WINED3D_BUFFER_USE_BO;
- buffer_unload(&buffer->resource);
+ buffer_resource_unload(&buffer->resource);
}
static void wined3d_buffer_destroy_object(void *object)
{
struct wined3d_buffer *buffer = object;
+ struct wined3d_context *context;
+ if (buffer->buffer_object)
+ {
+ context = context_acquire(buffer->resource.device, NULL, 0);
+ wined3d_buffer_unload_location(buffer, context, WINED3D_LOCATION_BUFFER);
+ context_release(context);
+ }
heap_free(buffer->conversion_map);
heap_free(buffer->maps);
}
void wined3d_buffer_cleanup(struct wined3d_buffer *buffer)
{
- resource_cleanup(&buffer->resource);
wined3d_cs_destroy_object(buffer->resource.device->cs, wined3d_buffer_destroy_object, buffer);
+ resource_cleanup(&buffer->resource);
}
ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
@@ -1264,7 +1277,7 @@ static const struct wined3d_resource_ops buffer_resource_ops =
buffer_resource_incref,
buffer_resource_decref,
buffer_resource_preload,
- buffer_unload,
+ buffer_resource_unload,
buffer_resource_sub_resource_map,
buffer_resource_sub_resource_unmap,
};
@@ -1382,7 +1395,7 @@ static HRESULT wined3d_buffer_init(struct wined3d_buffer *buffer, struct wined3d
if (!(buffer->maps = heap_alloc(sizeof(*buffer->maps))))
{
ERR("Out of memory.\n");
- buffer_unload(resource);
+ buffer_resource_unload(resource);
resource_cleanup(resource);
wined3d_resource_wait_idle(resource);
return E_OUTOFMEMORY;
@@ -1406,6 +1419,12 @@ static BOOL wined3d_buffer_no3d_prepare_location(struct wined3d_buffer *buffer,
return FALSE;
}
+static void wined3d_buffer_no3d_unload_location(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location)
+{
+ TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
+}
+
static void wined3d_buffer_no3d_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges)
{
@@ -1421,6 +1440,7 @@ static void wined3d_buffer_no3d_download_ranges(struct wined3d_buffer *buffer, s
static const struct wined3d_buffer_ops wined3d_buffer_no3d_ops =
{
wined3d_buffer_no3d_prepare_location,
+ wined3d_buffer_no3d_unload_location,
wined3d_buffer_no3d_upload_ranges,
wined3d_buffer_no3d_download_ranges,
};
@@ -1463,6 +1483,23 @@ static BOOL wined3d_buffer_gl_prepare_location(struct wined3d_buffer *buffer,
}
}
+static void wined3d_buffer_gl_unload_location(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location)
+{
+ TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
+
+ switch (location)
+ {
+ case WINED3D_LOCATION_BUFFER:
+ wined3d_buffer_gl_destroy_buffer_object(wined3d_buffer_gl(buffer), wined3d_context_gl(context));
+ break;
+
+ default:
+ ERR("Unhandled location %s.\n", wined3d_debug_location(location));
+ break;
+ }
+}
+
/* Context activation is done by the caller. */
static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges)
@@ -1506,6 +1543,7 @@ static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, str
static const struct wined3d_buffer_ops wined3d_buffer_gl_ops =
{
wined3d_buffer_gl_prepare_location,
+ wined3d_buffer_gl_unload_location,
wined3d_buffer_gl_upload_ranges,
wined3d_buffer_gl_download_ranges,
};
@@ -1542,6 +1580,12 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
}
}
+static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location)
+{
+ FIXME("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
+}
+
static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges)
{
@@ -1557,6 +1601,7 @@ static void wined3d_buffer_vk_download_ranges(struct wined3d_buffer *buffer, str
static const struct wined3d_buffer_ops wined3d_buffer_vk_ops =
{
wined3d_buffer_vk_prepare_location,
+ wined3d_buffer_vk_unload_location,
wined3d_buffer_vk_upload_ranges,
wined3d_buffer_vk_download_ranges,
};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0fc633ad4a5..7d3b709a974 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4120,6 +4120,8 @@ struct wined3d_buffer_ops
{
BOOL (*buffer_prepare_location)(struct wined3d_buffer *buffer,
struct wined3d_context *context, unsigned int location);
+ void (*buffer_unload_location)(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location);
void (*buffer_upload_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, const void *data,
unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges);
void (*buffer_download_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, void *data,
@@ -4187,8 +4189,6 @@ static inline struct wined3d_buffer_gl *wined3d_buffer_gl(struct wined3d_buffer
GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info,
uint32_t bind_flags) DECLSPEC_HIDDEN;
-void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl,
- struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined3d_device *device,
const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
--
2.11.0
Dec. 6, 2019
Re: [PATCH vkd3d] vkd3d: Remove redundant GetCopyableFootprints() resource size alignment checks.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 6, 2019
[PATCH vkd3d 6/6] vkd3d-shader: Handle VKD3DSPR_GSINSTID in vkd3d_dxbc_compiler_get_register_name().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 40280eb..3d88be9 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2500,6 +2500,9 @@ static bool vkd3d_dxbc_compiler_get_register_name(char *buffer, unsigned int buf
case VKD3DSPR_JOININSTID:
snprintf(buffer, buffer_size, "vJoinInstanceId");
break;
+ case VKD3DSPR_GSINSTID:
+ snprintf(buffer, buffer_size, "vGSInstanceID");
+ break;
case VKD3DSPR_PATCHCONST:
snprintf(buffer, buffer_size, "vpc%u", idx);
break;
--
2.11.0
Dec. 6, 2019
[PATCH vkd3d 5/6] vkd3d-shader: Avoid declaring outputs multiple times with incompatible types.
by Henri Verbeet
This would cause CoreValidation-Shader-InterfaceTypeMismatch validation
errors from Wine's test_shader_interstage_interface() d3d11 test. This
reverts parts of commits 1eb7eca411f71d8dec7cfae5c58c1dff9626a7e0 and
04ec461fb4224e126d271760123bb6d756c06582.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index a949e4a..40280eb 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -4438,8 +4438,13 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
{
use_private_variable = true;
write_mask = VKD3DSP_WRITEMASK_ALL;
+ entry = rb_get(&compiler->symbol_table, ®_symbol);
}
}
+ else if (!use_private_variable && (entry = rb_get(&compiler->symbol_table, ®_symbol)))
+ {
+ id = RB_ENTRY_VALUE(entry, const struct vkd3d_symbol, entry)->id;
+ }
else
{
if (builtin)
@@ -4487,15 +4492,15 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationPatch, NULL, 0);
vkd3d_dxbc_compiler_decorate_xfb_output(compiler, id, output_component_count, signature_element);
-
- compiler->output_info[signature_idx].id = id;
- compiler->output_info[signature_idx].component_type = component_type;
}
+ compiler->output_info[signature_idx].id = id;
+ compiler->output_info[signature_idx].component_type = component_type;
+
if (use_private_variable)
storage_class = SpvStorageClassPrivate;
- if ((entry = rb_get(&compiler->symbol_table, ®_symbol)))
+ if (entry)
var_id = RB_ENTRY_VALUE(entry, const struct vkd3d_symbol, entry)->id;
else if (!use_private_variable)
var_id = id;
--
2.11.0
Dec. 6, 2019
[PATCH vkd3d 4/6] vkd3d-shader: Handle normalised types in vkd3d_component_type_from_data_type().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 940cb76..100d515 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -838,6 +838,8 @@ static inline enum vkd3d_component_type vkd3d_component_type_from_data_type(
switch (data_type)
{
case VKD3D_DATA_FLOAT:
+ case VKD3D_DATA_UNORM:
+ case VKD3D_DATA_SNORM:
return VKD3D_TYPE_FLOAT;
case VKD3D_DATA_UINT:
return VKD3D_TYPE_UINT;
--
2.11.0
Dec. 6, 2019