Inspired by a patch from Eric Pouech eric.pouech@gmail.com.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3dx9_36/tests/effect.c | 42 +++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-)
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index a13dc708726..ea90299f936 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -1475,16 +1475,16 @@ static void test_effect_parameter_value_GetMatrixPointerArray(const struct test_ float f[sizeof(D3DXMATRIX) / sizeof(float)]; D3DXMATRIX m; } fvalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE * sizeof(float) / sizeof(D3DXMATRIX)]; + D3DXMATRIX *matrix_pointer_array[ARRAY_SIZE(fvalue)]; const D3DXPARAMETER_DESC *res_desc = &res->desc; const char *res_full_name = res->full_name; - HRESULT hr; - D3DXMATRIX *matrix_pointer_array[ARRAY_SIZE(fvalue)]; UINT l, k, m, element, err = 0; union { DWORD d; float f; } cmp = {0xabababab}; + HRESULT hr;
for (element = 0; element <= res_desc->Elements + 1; ++element) { @@ -1670,20 +1670,28 @@ static void test_effect_parameter_value_GetMatrixTransposeArray(const struct tes static void test_effect_parameter_value_GetMatrixTransposePointerArray(const struct test_effect_parameter_value_result *res, ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i) { + union + { + float f[sizeof(D3DXMATRIX) / sizeof(float)]; + D3DXMATRIX m; + } fvalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE * sizeof(float) / sizeof(D3DXMATRIX)]; + D3DXMATRIX *matrix_pointer_array[sizeof(fvalue)]; const D3DXPARAMETER_DESC *res_desc = &res->desc; const char *res_full_name = res->full_name; - HRESULT hr; - DWORD cmp = 0xabababab; - FLOAT fvalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE]; - D3DXMATRIX *matrix_pointer_array[sizeof(fvalue)/sizeof(D3DXMATRIX)]; UINT l, k, m, element, err = 0; + union + { + DWORD d; + float f; + } cmp = {0xabababab}; + HRESULT hr;
for (element = 0; element <= res_desc->Elements + 1; ++element) { memset(fvalue, 0xab, sizeof(fvalue)); for (l = 0; l < element; ++l) { - matrix_pointer_array[l] = (D3DXMATRIX *)&fvalue[l * sizeof(**matrix_pointer_array) / sizeof(FLOAT)]; + matrix_pointer_array[l] = &fvalue[l].m; } hr = effect->lpVtbl->GetMatrixTransposePointerArray(effect, parameter, matrix_pointer_array, element); if (!element) @@ -1691,7 +1699,10 @@ static void test_effect_parameter_value_GetMatrixTransposePointerArray(const str ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixTransposePointerArray failed, got %#x, expected %#x\n", i, res_full_name, element, hr, D3D_OK);
- for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err; + for (m = 0; m < ARRAY_SIZE(fvalue); ++m) + for (l = 0; l < ARRAY_SIZE(fvalue[m].f); ++l) + if (fvalue[m].f[l] != cmp.f) + ++err; } else if (element <= res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS) { @@ -1706,23 +1717,30 @@ static void test_effect_parameter_value_GetMatrixTransposePointerArray(const str { if (k < res_desc->Columns && l < res_desc->Rows) { - if (!compare_float(fvalue[m * 16 + l + k * 4], get_float(res_desc->Type, + if (!compare_float(fvalue[m].m.m[k][l], get_float(res_desc->Type, &res_value[m * res_desc->Columns * res_desc->Rows + l * res_desc->Columns + k]), 512)) ++err; } - else if (fvalue[m * 16 + l + k * 4] != 0.0f) ++err; + else if (fvalue[m].m.m[k][l] != 0.0f) + ++err; } } }
- for (l = element * 16; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err; + for (m = element; m < ARRAY_SIZE(fvalue); ++m) + for (l = 0; l < ARRAY_SIZE(fvalue[m].f); ++l) + if (fvalue[m].f[l] != cmp.f) + ++err; } else { ok(hr == D3DERR_INVALIDCALL, "%u - %s[%u]: GetMatrixTransposePointerArray failed, got %#x, expected %#x\n", i, res_full_name, element, hr, D3DERR_INVALIDCALL);
- for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err; + for (m = 0; m < ARRAY_SIZE(fvalue); ++m) + for (l = 0; l < ARRAY_SIZE(fvalue[m].f); ++l) + if (fvalue[m].f[l] != cmp.f) + ++err; } ok(!err, "%u - %s[%u]: GetMatrixTransposePointerArray failed with %u errors\n", i, res_full_name, element, err); }
Inspired by a patch from Eric Pouech eric.pouech@gmail.com.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3dx9_36/tests/mesh.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c index 829e4ee0ff9..3274b2d38bc 100644 --- a/dlls/d3dx9_36/tests/mesh.c +++ b/dlls/d3dx9_36/tests/mesh.c @@ -4739,11 +4739,9 @@ static void test_update_semantics(void) D3DVERTEXELEMENT9 *decl_ptr; DWORD exp_vertex_size = sizeof(*vertices); DWORD vertex_size = 0; + BYTE *decl_mem; int equal; int i = 0; - int *decl_mem; - int filler_a = 0xaaaaaaaa; - int filler_b = 0xbbbbbbbb;
test_context = new_test_context(); if (!test_context) @@ -4815,22 +4813,20 @@ static void test_update_semantics(void) /* Check that GetDeclaration only writes up to the D3DDECL_END() marker and * not the full MAX_FVF_DECL_SIZE elements. */ - memset(declaration, filler_a, sizeof(declaration)); + memset(declaration, 0xaa, sizeof(declaration)); memcpy(declaration, declaration0, sizeof(declaration0)); hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration); ok(hr == D3D_OK, "Test UpdateSemantics, " "got %#x expected D3D_OK\n", hr); - memset(declaration, filler_b, sizeof(declaration)); + memset(declaration, 0xbb, sizeof(declaration)); hr = mesh->lpVtbl->GetDeclaration(mesh, declaration); ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr); - decl_mem = (int*)declaration; - for (i = sizeof(declaration0)/sizeof(*decl_mem); i < sizeof(declaration)/sizeof(*decl_mem); i++) - { - equal = memcmp(&decl_mem[i], &filler_b, sizeof(filler_b)); - ok(equal == 0, - "GetDeclaration wrote past the D3DDECL_END() marker. " - "Got %#x, expected %#x\n", decl_mem[i], filler_b); - if (equal != 0) break; + decl_mem = (BYTE *)declaration; + for (i = sizeof(declaration0); i < sizeof(declaration); ++i) + { + ok(decl_mem[i] == 0xbb, "Unexpected %#x.\n", decl_mem[i]); + if (equal != 0) + break; }
/* UpdateSemantics does not check for overlapping fields */
Rémi found a regression caused by that patch. His analysis suggests that it's probably correct for NtYieldExecution() to map to sched_yield().
Let's revert the patch and fix the issue in a slightly different way.
This reverts commit b1a79c6b9c3ada0c34b1411b60879962f1815e4d.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- configure.ac | 1 + dlls/ntdll/unix/sync.c | 6 +++++- include/config.h.in | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac index 6631d2f42fc..72018825610 100644 --- a/configure.ac +++ b/configure.ac @@ -1948,6 +1948,7 @@ AC_CHECK_FUNCS(\ posix_fallocate \ prctl \ proc_pidinfo \ + sched_yield \ setproctitle \ setprogname \ sigprocmask \ diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 0065f265e42..137d8d2c87d 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -1447,8 +1447,12 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait, */ NTSTATUS WINAPI NtYieldExecution(void) { - usleep(0); +#ifdef HAVE_SCHED_YIELD + sched_yield(); return STATUS_SUCCESS; +#else + return STATUS_NO_YIELD_PERFORMED; +#endif }
diff --git a/include/config.h.in b/include/config.h.in index 0c843a0423c..0fe50e8ce7c 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -443,6 +443,9 @@ /* Define to 1 if you have the `sched_setaffinity' function. */ #undef HAVE_SCHED_SETAFFINITY
+/* Define to 1 if you have the `sched_yield' function. */ +#undef HAVE_SCHED_YIELD + /* Define to 1 if `cmd' is a member of `scsireq_t'. */ #undef HAVE_SCSIREQ_T_CMD
This implements the general fix from b1a79c6b9c3ada0c34b1411b60879962f1815e4d (in particular, making sure that Sleep(0) will not immediately resume execution of the thread if there are no other runnable threads) while preserving the existing behavior of NtYieldExecution() / SwitchToThread(). Thanks Rémi for the idea.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/ntdll/unix/sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 137d8d2c87d..58fcc913fb7 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -1480,7 +1480,7 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou }
/* Note that we yield after establishing the desired timeout */ - NtYieldExecution(); + usleep(0); if (!when) return STATUS_SUCCESS;
for (;;)
All D3D versions seem to basically guarantee invariance for the vertex position at the very least. In practice, desktop GL implementations also do the same. That's not necessarily the case for tile based renderers, where the cost of providing invariance might be non negligible. We want this behavior though, so let's ask for it explicitly.
Based on a patch by Stefan Dösinger.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Move the invariant declaration in shader_glsl_generate_ffp_vertex_shader() in the proper place... v3: Fix invariant declaration for tessellation control shaders.
dlls/wined3d/glsl_shader.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index adfbf60e726..4e51402f1cf 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -2184,6 +2184,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c if (map & 1) shader_addline(buffer, "void subroutine%u();\n", i); }
+ if (version->type != WINED3D_SHADER_TYPE_PIXEL && version->type != WINED3D_SHADER_TYPE_COMPUTE) + { + if (version->type == WINED3D_SHADER_TYPE_HULL) + shader_addline(buffer, "out gl_PerVertex { invariant vec4 gl_Position; } gl_out[];\n"); + else + shader_addline(buffer, "invariant gl_Position;\n"); + } + /* Declare the constants (aka uniforms) */ if (shader->limits->constant_float > 0) { @@ -7125,6 +7133,8 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
shader_glsl_add_version_declaration(buffer, gl_info);
+ shader_addline(buffer, "invariant gl_Position;\n"); + if (per_vertex_point_size) { shader_addline(buffer, "uniform struct\n{\n"); @@ -8994,6 +9004,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr if (shader_glsl_use_explicit_attrib_location(gl_info)) shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n");
+ shader_addline(buffer, "invariant gl_Position;\n"); + for (i = 0; i < WINED3D_FFP_ATTRIBS_COUNT; ++i) { const char *type = i < ARRAY_SIZE(attrib_info) ? attrib_info[i].type : "vec4";
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com