Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2 changes: - use wined3d_format_convert_from_float() instead of introducing d3dcolor_from_wined3d_color(); - renamed clamp_vec() to wined3d_color_clamp(); - do not assume D3DCOLOR format for input stream color value; - introduced material_specular_state_color variable.
dlls/wined3d/device.c | 198 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 161 insertions(+), 37 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 5272e2ef23..81a76398a7 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3072,20 +3072,141 @@ static unsigned int wined3d_get_flexible_vertex_size(DWORD fvf) return size; }
+static void wined3d_format_get_color(const struct wined3d_format *format, const BYTE *data, + struct wined3d_color *color) +{ + static const struct wined3d_color default_color = {0.0f, 0.0f, 0.0f, 1.0f}; + float *output = &color->r; + unsigned int i; + + switch (format->id) + { + case WINED3DFMT_B8G8R8A8_UNORM: + wined3d_color_from_d3dcolor(color, *(const DWORD *)data); + break; + + case WINED3DFMT_R8G8B8A8_UNORM: + { + DWORD value = *(const DWORD *)data; + + color->r = (value & 0xff) / 255.0f; + color->g = ((value >> 8) & 0xff) / 255.0f; + color->b = ((value >> 16) & 0xff) / 255.0f; + color->a = ((value >> 24) & 0xff) / 255.0f; + break; + } + + case WINED3DFMT_R16G16_UNORM: + case WINED3DFMT_R16G16B16A16_UNORM: + { + const unsigned short *ushort_data = (const unsigned short *)data; + + *color = default_color; + + for (i = 0; i < format->component_count; ++i) + output[i] = ushort_data[i] / 65535.0f; + + break; + } + + case WINED3DFMT_R32_FLOAT: + case WINED3DFMT_R32G32_FLOAT: + case WINED3DFMT_R32G32B32_FLOAT: + case WINED3DFMT_R32G32B32A32_FLOAT: + { + const float *float_data = (const float *)data; + + for (i = 0; i < format->component_count; ++i) + output[i] = float_data[i]; + + break; + } + + default: + { + static BOOL warned; + + *color = default_color; + + if (!warned) + { + FIXME("Unhandled color format conversion, format %s.\n", debug_d3dformat(format->id)); + warned = TRUE; + } + break; + } + } +} + +static void color_from_mcs(struct wined3d_color *color, enum wined3d_material_color_source mcs, + const struct wined3d_color *material_color, unsigned int index, + const struct wined3d_stream_info *stream_info) +{ + const struct wined3d_stream_info_element *element = NULL; + + switch (mcs) + { + case WINED3D_MCS_MATERIAL: + *color = *material_color; + return; + case WINED3D_MCS_COLOR1: + if (!(stream_info->use_map & (1u << WINED3D_FFP_DIFFUSE))) + { + color->r = color->g = color->b = color->a = 1.0f; + return; + } + element = &stream_info->elements[WINED3D_FFP_DIFFUSE]; + break; + case WINED3D_MCS_COLOR2: + if (!(stream_info->use_map & (1u << WINED3D_FFP_SPECULAR))) + { + color->r = color->g = color->b = 0.0f; + color->a = 1.0f; + return; + } + element = &stream_info->elements[WINED3D_FFP_SPECULAR]; + break; + default: + color->r = color->g = color->b = color->a = 0.0f; + ERR("Invalid material color source %#x.\n", mcs); + return; + } + wined3d_format_get_color(element->format, element->data.addr + index * element->stride, color); +} + +static float clamp(float value, float min_value, float max_value) +{ + return value < min_value ? min_value : value > max_value ? max_value : value; +} + +static void wined3d_color_clamp(struct wined3d_color *dst, const struct wined3d_color *src, + float min_value, float max_value) +{ + dst->r = clamp(src->r, min_value, max_value); + dst->g = clamp(src->g, min_value, max_value); + dst->b = clamp(src->b, min_value, max_value); + dst->a = clamp(src->a, min_value, max_value); +} + /* Context activation is done by the caller. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount, const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD flags, DWORD dst_fvf) { + enum wined3d_material_color_source diffuse_source, specular_source; + const struct wined3d_color *material_specular_state_color; struct wined3d_matrix mat, proj_mat, view_mat, world_mat; + const struct wined3d_state *state = &device->state; + const struct wined3d_format *output_color_format; + static const struct wined3d_color black; struct wined3d_map_desc map_desc; struct wined3d_box box = {0}; struct wined3d_viewport vp; unsigned int vertex_size; + BOOL doClip, lighting; + DWORD numTextures; unsigned int i; BYTE *dest_ptr; - BOOL doClip; - DWORD numTextures; HRESULT hr;
if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL)) @@ -3095,11 +3216,11 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
if (!(stream_info->use_map & (1u << WINED3D_FFP_POSITION))) { - ERR("Source has no position mask\n"); + ERR("Source has no position mask.\n"); return WINED3DERR_INVALIDCALL; }
- if (device->state.render_states[WINED3D_RS_CLIPPING]) + if (state->render_states[WINED3D_RS_CLIPPING]) { static BOOL warned = FALSE; /* @@ -3156,11 +3277,37 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n", vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z);
+ lighting = state->render_states[WINED3D_RS_LIGHTING] + && (dst_fvf & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR)); + multiply_matrix(&mat,&view_mat,&world_mat); multiply_matrix(&mat,&proj_mat,&mat);
numTextures = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+ if (lighting) + { + if (state->render_states[WINED3D_RS_COLORVERTEX]) + { + diffuse_source = validate_material_colour_source(stream_info->use_map, + state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]); + specular_source = validate_material_colour_source(stream_info->use_map, + state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]); + } + else + { + diffuse_source = specular_source = WINED3D_MCS_MATERIAL; + } + } + else + { + diffuse_source = WINED3D_MCS_COLOR1; + specular_source = WINED3D_MCS_COLOR2; + } + output_color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, 0); + material_specular_state_color = state->render_states[WINED3D_RS_SPECULARENABLE] + ? &state->material.specular : &black; + for (i = 0; i < dwCount; i+= 1) { unsigned int tex_index;
@@ -3278,47 +3425,24 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
if (dst_fvf & WINED3DFVF_DIFFUSE) { - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE]; - const DWORD *color_d = (const DWORD *)(element->data.addr + i * element->stride); - if (!(stream_info->use_map & (1u << WINED3D_FFP_DIFFUSE))) - { - static BOOL warned = FALSE; + struct wined3d_color material_diffuse;
- if(!warned) { - ERR("No diffuse color in source, but destination has one\n"); - warned = TRUE; - } + color_from_mcs(&material_diffuse, diffuse_source, &state->material.diffuse, i, stream_info);
- *( (DWORD *) dest_ptr) = 0xffffffff; - dest_ptr += sizeof(DWORD); - } - else - { - copy_and_next(dest_ptr, color_d, sizeof(DWORD)); - } + wined3d_color_clamp(&material_diffuse, &material_diffuse, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &material_diffuse); + dest_ptr += sizeof(DWORD); }
if (dst_fvf & WINED3DFVF_SPECULAR) { - /* What's the color value in the feedback buffer? */ - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR]; - const DWORD *color_s = (const DWORD *)(element->data.addr + i * element->stride); - if (!(stream_info->use_map & (1u << WINED3D_FFP_SPECULAR))) - { - static BOOL warned = FALSE; + struct wined3d_color material_specular;
- if(!warned) { - ERR("No specular color in source, but destination has one\n"); - warned = TRUE; - } + color_from_mcs(&material_specular, specular_source, material_specular_state_color, i, stream_info);
- *(DWORD *)dest_ptr = 0xff000000; - dest_ptr += sizeof(DWORD); - } - else - { - copy_and_next(dest_ptr, color_s, sizeof(DWORD)); - } + wined3d_color_clamp(&material_specular, &material_specular, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &material_specular); + dest_ptr += sizeof(DWORD); }
for (tex_index = 0; tex_index < numTextures; ++tex_index)
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/wined3d/glsl_shader.c | 13 ------------- dlls/wined3d/wined3d_private.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index f85fb5a3e1..a3105169c7 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1374,19 +1374,6 @@ static void shader_glsl_ffp_vertex_lightambient_uniform(const struct wined3d_con checkGLcall("glUniform3fv"); }
-static void multiply_vector_matrix(struct wined3d_vec4 *dest, const struct wined3d_vec4 *src1, - const struct wined3d_matrix *src2) -{ - struct wined3d_vec4 temp; - - temp.x = (src1->x * src2->_11) + (src1->y * src2->_21) + (src1->z * src2->_31) + (src1->w * src2->_41); - temp.y = (src1->x * src2->_12) + (src1->y * src2->_22) + (src1->z * src2->_32) + (src1->w * src2->_42); - temp.z = (src1->x * src2->_13) + (src1->y * src2->_23) + (src1->z * src2->_33) + (src1->w * src2->_43); - temp.w = (src1->x * src2->_14) + (src1->y * src2->_24) + (src1->z * src2->_34) + (src1->w * src2->_44); - - *dest = temp; -} - static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int light, const struct wined3d_light_info *light_info, struct glsl_shader_prog_link *prog) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 34fa1d3ef3..9029ca18f3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4850,6 +4850,19 @@ static inline enum wined3d_material_color_source validate_material_colour_source return WINED3D_MCS_MATERIAL; }
+static inline void multiply_vector_matrix(struct wined3d_vec4 *dest, const struct wined3d_vec4 *src1, + const struct wined3d_matrix *src2) +{ + struct wined3d_vec4 temp; + + temp.x = (src1->x * src2->_11) + (src1->y * src2->_21) + (src1->z * src2->_31) + (src1->w * src2->_41); + temp.y = (src1->x * src2->_12) + (src1->y * src2->_22) + (src1->z * src2->_32) + (src1->w * src2->_42); + temp.z = (src1->x * src2->_13) + (src1->y * src2->_23) + (src1->z * src2->_33) + (src1->w * src2->_43); + temp.w = (src1->x * src2->_14) + (src1->y * src2->_24) + (src1->z * src2->_34) + (src1->w * src2->_44); + + *dest = temp; +} + BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) DECLSPEC_HIDDEN;
void compute_normal_matrix(float *normal_matrix, BOOL legacy_lighting,
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=52388
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2 changes: - rename dot_vec3 to wined3d_vec3_dot(); - use wined3d_vec3_dot() in normalize_vec3(); - use functions with explicit types instead of madd_vec(); - rename multiply_vector3_matrix() to multiply_vector3_matrix3(); - introduce 'struct wined3d_matrix3' and use it in multiply_vector3_matrix3(). - increase bit field size for light count.
dlls/ddraw/tests/ddraw1.c | 4 +- dlls/wined3d/device.c | 310 +++++++++++++++++++++++++++++++-- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 298 insertions(+), 17 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 7dda6eba20..9525b2dc0c 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -5894,7 +5894,7 @@ static void test_material(void) ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); color = get_surface_color(rt, 320, 240); if (test_data[i].material) - todo_wine ok(compare_color(color, test_data[i].expected_color, 1) + ok(compare_color(color, test_data[i].expected_color, 1) /* The Windows 8 testbot appears to return undefined results. */ || broken(TRUE), "Got unexpected color 0x%08x, test %u.\n", color, i); @@ -6273,7 +6273,7 @@ static void test_lighting(void) ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240); - todo_wine ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color); + ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color); }
IDirect3DExecuteBuffer_Release(execute_buffer); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 81a76398a7..8576012f21 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3174,6 +3174,11 @@ static void color_from_mcs(struct wined3d_color *color, enum wined3d_material_co wined3d_format_get_color(element->format, element->data.addr + index * element->stride, color); }
+static float wined3d_vec3_dot(const struct wined3d_vec3 *src1, const struct wined3d_vec3 *src2) +{ + return src1->x * src2->x + src1->y * src2->y + src1->z * src2->z; +} + static float clamp(float value, float min_value, float max_value) { return value < min_value ? min_value : value > max_value ? max_value : value; @@ -3188,12 +3193,220 @@ static void wined3d_color_clamp(struct wined3d_color *dst, const struct wined3d_ dst->a = clamp(src->a, min_value, max_value); }
+static void normalize_vec3(struct wined3d_vec3 *dest, const struct wined3d_vec3 *src) +{ + float rnorm = 1.0f / sqrtf(wined3d_vec3_dot(src, src)); + + *dest = *src; + if (isfinite(rnorm)) + { + dest->x *= rnorm; + dest->y *= rnorm; + dest->z *= rnorm; + } +} + +static void madd_color_rgb(struct wined3d_color *dst, const struct wined3d_color *src, float c) +{ + dst->r += src->r * c; + dst->g += src->g * c; + dst->b += src->b * c; +} + +static void madd_color(struct wined3d_color *dst, const struct wined3d_color *src, float c) +{ + dst->r += src->r * c; + dst->g += src->g * c; + dst->b += src->b * c; + dst->a += src->a * c; +} + +struct wined3d_matrix3 +{ + float _11, _12, _13; + float _21, _22, _23; + float _31, _32, _33; +}; + +static void multiply_vector3_matrix3(struct wined3d_vec3 *dest, const struct wined3d_vec3 *src1, + const struct wined3d_matrix3 *mat) +{ + struct wined3d_vec3 temp; + + temp.x = (src1->x * mat->_11) + (src1->y * mat->_21) + (src1->z * mat->_31); + temp.y = (src1->x * mat->_12) + (src1->y * mat->_22) + (src1->z * mat->_32); + temp.z = (src1->x * mat->_13) + (src1->y * mat->_23) + (src1->z * mat->_33); + + *dest = temp; +} + +struct light_transformed +{ + struct wined3d_color diffuse, specular, ambient; + struct wined3d_vec4 position; + struct wined3d_vec3 direction; + float range, falloff, c_att, l_att, q_att, cos_htheta, cos_hphi; +}; + +struct lights_settings +{ + struct light_transformed lights[WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS]; + struct wined3d_color ambient_light; + struct wined3d_matrix modelview_matrix; + struct wined3d_matrix3 normal_matrix; + + DWORD point_light_count : 8; + DWORD spot_light_count : 8; + DWORD directional_light_count : 8; + DWORD parallel_point_light_count : 8; + DWORD legacy_lighting : 1; + DWORD normalize : 1; + DWORD localviewer : 1; + DWORD padding : 29; +}; + +static void init_transformed_lights(struct lights_settings *ls, const struct wined3d_state *state, + BOOL legacy_lighting) +{ + const struct wined3d_light_info *lights[WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS]; + const struct wined3d_light_info *light_info; + struct light_transformed *light; + unsigned int lights_count; + struct wined3d_vec4 vec4; + unsigned int i, index; + + memset(ls, 0, sizeof(*ls)); + + wined3d_color_from_d3dcolor(&ls->ambient_light, state->render_states[WINED3D_RS_AMBIENT]); + ls->legacy_lighting = !!legacy_lighting; + ls->normalize = !!state->render_states[WINED3D_RS_NORMALIZENORMALS]; + ls->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER]; + + multiply_matrix(&ls->modelview_matrix, &state->transforms[WINED3D_TS_VIEW], + &state->transforms[WINED3D_TS_WORLD_MATRIX(0)]); + compute_normal_matrix(&ls->normal_matrix._11, legacy_lighting, &ls->modelview_matrix); + + index = 0; + for (i = 0; i < LIGHTMAP_SIZE && index < WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS; ++i) + { + LIST_FOR_EACH_ENTRY(light_info, &state->light_state.light_map[i], struct wined3d_light_info, entry) + { + if (!light_info->enabled) + continue; + + switch (light_info->OriginalParms.type) + { + case WINED3D_LIGHT_DIRECTIONAL: + ++ls->directional_light_count; + break; + default: + FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); + continue; + } + lights[index] = light_info; + if (++index == WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS) + break; + } + } + + lights_count = index; + index = 0; + for (i = 0; i < lights_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_DIRECTIONAL) + continue; + + light = &ls->lights[index]; + multiply_vector_matrix(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]); + normalize_vec3(&light->direction, (const struct wined3d_vec3 *)&vec4); + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } +} + +static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, + const struct wined3d_vec3 *dir, float att, float material_shininess, + const struct wined3d_vec3 *normal_transformed, + const struct wined3d_vec3 *position_transformed_normalized, + const struct light_transformed *light, const struct lights_settings *ls) +{ + struct wined3d_vec3 vec3; + float t, c; + + c = clamp(wined3d_vec3_dot(dir, normal_transformed), 0.0f, 1.0f); + madd_color_rgb(diffuse, &light->diffuse, c * att); + + if (ls->localviewer) + { + vec3.x = dir->x - position_transformed_normalized->x; + vec3.y = dir->y - position_transformed_normalized->y; + vec3.z = dir->z - position_transformed_normalized->z; + } + else + { + vec3.x = dir->x; + vec3.y = dir->y; + vec3.z = dir->z - 1.0f; + } + normalize_vec3(&vec3, &vec3); + t = wined3d_vec3_dot(normal_transformed, &vec3); + if (t > 0.0f && (!ls->legacy_lighting || material_shininess > 0.0f) + && wined3d_vec3_dot(dir, normal_transformed) > 0.0f) + madd_color(specular, &light->specular, att * powf(t, material_shininess)); +} + +static void compute_light(struct wined3d_color *ambient, struct wined3d_color *diffuse, + struct wined3d_color *specular, const struct lights_settings *ls, const struct wined3d_vec3 *normal, + const struct wined3d_vec4 *position, float material_shininess) +{ + struct wined3d_vec3 position_transformed_normalized; + struct wined3d_vec3 normal_transformed = {0.0f}; + struct wined3d_vec4 position_transformed; + const struct light_transformed *light; + unsigned int i, index; + float rcp_w; + + multiply_vector_matrix(&position_transformed, position, &ls->modelview_matrix); + rcp_w = 1.0f / position_transformed.w; + position_transformed.x *= rcp_w; + position_transformed.y *= rcp_w; + position_transformed.z *= rcp_w; + position_transformed.w = 1.0f; + normalize_vec3(&position_transformed_normalized, (const struct wined3d_vec3 *)&position_transformed); + + if (normal) + { + multiply_vector3_matrix3(&normal_transformed, normal, &ls->normal_matrix); + if (ls->normalize) + normalize_vec3(&normal_transformed, &normal_transformed); + } + + diffuse->r = diffuse->g = diffuse->b = diffuse->a = 0.0f; + *specular = *diffuse; + *ambient = ls->ambient_light; + + index = 0; + for (i = 0; i < ls->directional_light_count; ++i, ++index) + { + light = &ls->lights[index]; + + madd_color_rgb(ambient, &light->ambient, 1.0f); + if (normal) + update_light_diffuse_specular(diffuse, specular, &light->direction, 1.0f, material_shininess, + &normal_transformed, &position_transformed_normalized, light, ls); + } +} + /* Context activation is done by the caller. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount, const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD flags, DWORD dst_fvf) { - enum wined3d_material_color_source diffuse_source, specular_source; + enum wined3d_material_color_source ambient_source, diffuse_source, emissive_source, specular_source; const struct wined3d_color *material_specular_state_color; struct wined3d_matrix mat, proj_mat, view_mat, world_mat; const struct wined3d_state *state = &device->state; @@ -3202,6 +3415,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO struct wined3d_map_desc map_desc; struct wined3d_box box = {0}; struct wined3d_viewport vp; + struct lights_settings ls; unsigned int vertex_size; BOOL doClip, lighting; DWORD numTextures; @@ -3209,11 +3423,6 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO BYTE *dest_ptr; HRESULT hr;
- if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL)) - { - WARN(" lighting state not saved yet... Some strange stuff may happen !\n"); - } - if (!(stream_info->use_map & (1u << WINED3D_FFP_POSITION))) { ERR("Source has no position mask.\n"); @@ -3291,13 +3500,19 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO { diffuse_source = validate_material_colour_source(stream_info->use_map, state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]); + ambient_source = validate_material_colour_source(stream_info->use_map, + state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE]); + emissive_source = validate_material_colour_source(stream_info->use_map, + state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE]); specular_source = validate_material_colour_source(stream_info->use_map, state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]); } else { - diffuse_source = specular_source = WINED3D_MCS_MATERIAL; + ambient_source = diffuse_source = emissive_source = specular_source = WINED3D_MCS_MATERIAL; } + init_transformed_lights(&ls, state, device->adapter->d3d_info.wined3d_creation_flags + & WINED3D_LEGACY_FFP_LIGHTING); } else { @@ -3309,13 +3524,15 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO ? &state->material.specular : &black;
for (i = 0; i < dwCount; i+= 1) { + struct wined3d_color ambient, diffuse, specular; + const struct wined3d_stream_info_element *position_element + = &stream_info->elements[WINED3D_FFP_POSITION]; + const float *p = (const float *)(position_element->data.addr + i * position_element->stride); unsigned int tex_index;
if ( ((dst_fvf & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZ ) || ((dst_fvf & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) ) { /* The position first */ - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_POSITION]; - const float *p = (const float *)(element->data.addr + i * element->stride); float x, y, z, rhw; TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]);
@@ -3423,25 +3640,88 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO copy_and_next(dest_ptr, normal, 3 * sizeof(float)); }
+ if (lighting) + { + const struct wined3d_stream_info_element *element; + struct wined3d_vec4 position; + struct wined3d_vec3 *normal; + + position.x = p[0]; + position.y = p[1]; + position.z = p[2]; + position.w = 1.0f; + + if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL)) + { + element = &stream_info->elements[WINED3D_FFP_NORMAL]; + normal = (struct wined3d_vec3 *)(element->data.addr + i * element->stride); + } + else + { + normal = NULL; + } + compute_light(&ambient, &diffuse, &specular, &ls, normal, &position, + state->render_states[WINED3D_RS_SPECULARENABLE] ? state->material.power : 0.0f); + } + if (dst_fvf & WINED3DFVF_DIFFUSE) { - struct wined3d_color material_diffuse; + struct wined3d_color material_diffuse, material_ambient, material_emissive, diffuse_color;
color_from_mcs(&material_diffuse, diffuse_source, &state->material.diffuse, i, stream_info);
- wined3d_color_clamp(&material_diffuse, &material_diffuse, 0.0f, 1.0f); - *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &material_diffuse); + if (lighting) + { + color_from_mcs(&material_ambient, ambient_source, &state->material.ambient, i, stream_info); + color_from_mcs(&material_emissive, emissive_source, &state->material.emissive, i, stream_info); + + diffuse_color.a = material_diffuse.a; + diffuse_color.r = ambient.r * material_ambient.r + + diffuse.r * material_diffuse.r + material_emissive.r; + diffuse_color.g = ambient.g * material_ambient.g + + diffuse.g * material_diffuse.g + material_emissive.g; + diffuse_color.b = ambient.b * material_ambient.b + + diffuse.b * material_diffuse.b + material_emissive.b; + } + else + { + diffuse_color = material_diffuse; + } + wined3d_color_clamp(&diffuse_color, &diffuse_color, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &diffuse_color); dest_ptr += sizeof(DWORD); }
if (dst_fvf & WINED3DFVF_SPECULAR) { - struct wined3d_color material_specular; + struct wined3d_color material_specular, specular_color;
color_from_mcs(&material_specular, specular_source, material_specular_state_color, i, stream_info);
- wined3d_color_clamp(&material_specular, &material_specular, 0.0f, 1.0f); - *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &material_specular); + if (lighting) + { + specular_color.a = specular.a * material_specular.a; + specular_color.r = specular.r * material_specular.r; + specular_color.g = specular.g * material_specular.g; + specular_color.b = specular.b * material_specular.b; + if (state->render_states[WINED3D_RS_FOGENABLE]) + { + static BOOL warned; + + if (!warned) + { + FIXME("Fog factor is not implemented.\n"); + warned = TRUE; + } + specular_color.a = 1.0f; + } + } + else + { + specular_color = material_specular; + } + wined3d_color_clamp(&specular_color, &specular_color, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &specular_color); dest_ptr += sizeof(DWORD); }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9029ca18f3..bd77881e27 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -270,6 +270,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup #define WINED3D_MAX_VERTEX_SAMPLERS 4 #define WINED3D_MAX_COMBINED_SAMPLERS (WINED3D_MAX_FRAGMENT_SAMPLERS + WINED3D_MAX_VERTEX_SAMPLERS) #define WINED3D_MAX_ACTIVE_LIGHTS 8 +#define WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS 32 #define WINED3D_MAX_CLIP_DISTANCES 8 #define MAX_CONSTANT_BUFFERS 15 #define MAX_SAMPLER_OBJECTS 16
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=52389
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
On Fri, 17 May 2019 at 13:22, Paul Gofman gofmanp@gmail.com wrote:
+static void normalize_vec3(struct wined3d_vec3 *dest, const struct wined3d_vec3 *src) +{
- float rnorm = 1.0f / sqrtf(wined3d_vec3_dot(src, src));
- *dest = *src;
- if (isfinite(rnorm))
- {
dest->x *= rnorm;
dest->y *= rnorm;
dest->z *= rnorm;
- }
+}
I didn't explicitly mention it in my reply to the previous version, but we would want to use the same naming scheme here and for other helpers as well. (So wined3d_vec3_normalise(), wined3d_color_mul_add(), wined3d_vec3_m3x3(), etc.)
Here too, it seems like init_transformed_lights() could reuse most of wined3d_ffp_get_vs_settings().
Do you suggest to use wined3d_ffp_get_vs_settings() directly? It probably needs some redesign first for that, as it uses gl_info and hardware limits (light count, as well as bitfields in settings structure). Or do you mean factoring out some functions like init_light_sources() to use in process_vertices_strided() and init_light_settings() which would use some more generic structure and parameters not to depend on GL limits?
On 5/17/19 17:45, Henri Verbeet wrote:
Here too, it seems like init_transformed_lights() could reuse most of wined3d_ffp_get_vs_settings().
I think there is one more thing to take into consideration here. I started doing tests for _ProcessVertices() with lighting in ddraw7, and came across a weird thing. It does not treat zero shininess in material the same way as normal DrawPrimitive workflow does. It outputs values like the previously used material shininess is left there, the results for that tests are different from DrawPrimitive() (while the same for the other ones). I suspect we can come across more differences in software vertex processing corner cases and might need to handle raw states a bit different from the hardware drawing pipeline.
On 5/17/19 18:18, Paul Gofman wrote:
Do you suggest to use wined3d_ffp_get_vs_settings() directly? It probably needs some redesign first for that, as it uses gl_info and hardware limits (light count, as well as bitfields in settings structure). Or do you mean factoring out some functions like init_light_sources() to use in process_vertices_strided() and init_light_settings() which would use some more generic structure and parameters not to depend on GL limits?
On 5/17/19 17:45, Henri Verbeet wrote:
Here too, it seems like init_transformed_lights() could reuse most of wined3d_ffp_get_vs_settings().
On Fri, 17 May 2019 at 19:48, Paul Gofman gofmanp@gmail.com wrote:
Do you suggest to use wined3d_ffp_get_vs_settings() directly? It probably needs some redesign first for that, as it uses gl_info and hardware limits (light count, as well as bitfields in settings structure). Or do you mean factoring out some functions like init_light_sources() to use in process_vertices_strided() and init_light_settings() which would use some more generic structure and parameters not to depend on GL limits?
My thinking was to just use it as-is, and then either ignore or fix-up the differences afterwards. Light counts would have to be handled separately because of the bitfield sizes, but that's fairly straight-forward code.
On 5/17/19 18:42, Henri Verbeet wrote:
On Fri, 17 May 2019 at 19:48, Paul Gofman gofmanp@gmail.com wrote:
Do you suggest to use wined3d_ffp_get_vs_settings() directly? It probably needs some redesign first for that, as it uses gl_info and hardware limits (light count, as well as bitfields in settings structure). Or do you mean factoring out some functions like init_light_sources() to use in process_vertices_strided() and init_light_settings() which would use some more generic structure and parameters not to depend on GL limits?
My thinking was to just use it as-is, and then either ignore or fix-up the differences afterwards. Light counts would have to be handled separately because of the bitfield sizes, but that's fairly straight-forward code.
Do you think it is ok then just to use it (providing the first context from device, as I don't have one in process_vertices()), initialize wined3d_ffp_vs_settings and use the fields from there to initialize the similar fieldsin the local structure (as I cannot replace it anyway due to the lights)? I can do that of course, my only concern is that it might end up adding nearly the same amount of code that it saves.
On Fri, 17 May 2019 at 20:47, Paul Gofman gofmanp@gmail.com wrote:
Do you think it is ok then just to use it (providing the first context from device, as I don't have one in process_vertices()), initialize wined3d_ffp_vs_settings and use the fields from there to initialize the similar fieldsin the local structure (as I cannot replace it anyway due to the lights)? I can do that of course, my only concern is that it might end up adding nearly the same amount of code that it saves.
You can acquire a context by calling "context_acquire(device, NULL, 0);", and release it again with "context_release();". Using the wined3d_ffp_vs_settings structure to initialise the lights_settings structure would be fine. Another option would be to embed the wined3d_ffp_vs_settings structure in the lights_settings one. I'm not against extracting helpers from wined3d_ffp_get_vs_settings() for specific fields either if that ends up making more sense though, although I'd expect you'd need most of what's in wined3d_ffp_vs_settings at some point. The concern is more about duplicated code diverging over time than about saving lines of code.
On 5/17/19 20:01, Henri Verbeet wrote:
On Fri, 17 May 2019 at 20:47, Paul Gofman gofmanp@gmail.com wrote:
Do you think it is ok then just to use it (providing the first context from device, as I don't have one in process_vertices()), initialize wined3d_ffp_vs_settings and use the fields from there to initialize the similar fieldsin the local structure (as I cannot replace it anyway due to the lights)? I can do that of course, my only concern is that it might end up adding nearly the same amount of code that it saves.
You can acquire a context by calling "context_acquire(device, NULL, 0);", and release it again with "context_release();".
I figured I can't acquire context if CSMT is on because the wined3d_process_vertices() is called not from CSMT thread. Does it mean we should make wined3d_device_process_vertices() go through CSMT first, or I rather make wined3d_ffp_get_vs_settings() work with NULL context (by skipping the fields which can't be estimated without)?
On Fri, May 17, 2019 at 8:09 PM Paul Gofman gofmanp@gmail.com wrote:
On 5/17/19 20:01, Henri Verbeet wrote:
On Fri, 17 May 2019 at 20:47, Paul Gofman gofmanp@gmail.com wrote:
Do you think it is ok then just to use it (providing the first context from device, as I don't have one in process_vertices()), initialize wined3d_ffp_vs_settings and use the fields from there to initialize the similar fieldsin the local structure (as I cannot replace it anyway due to the lights)? I can do that of course, my only concern is that it might end up adding nearly the same amount of code that it saves.
You can acquire a context by calling "context_acquire(device, NULL, 0);", and release it again with "context_release();".
I figured I can't acquire context if CSMT is on because the wined3d_process_vertices() is called not from CSMT thread. Does it mean we should make wined3d_device_process_vertices() go through CSMT first, or I rather make wined3d_ffp_get_vs_settings() work with NULL context (by skipping the fields which can't be estimated without)?
I'd try with the latter first. Moving process_vertices() over to the CS thread seems awkward to me.
FWIW we should probably get rid of the struct gl_info uses in wined3d_ffp_get_vs_settings(), maybe by setting a flag in d3d_info if we have enough (backend / GL) varyings to support all the fixed function (d3d) varyings. Actually, all the uses of wined3d_max_compat_varyings() are like that, we could get rid of the function entirely. I can write the patch if you haven't already.
That aside, I think wined3d_ffp_get_vs_settings() shouldn't have a context parameter but simply get stream_info and d3d_info from the caller. You want to pass your own stream_info from wined3d_device_process_vertices() anyway and you can get to d3d_info from device->adapter.
On Sun, 19 May 2019 at 02:10, Matteo Bruni matteo.mystral@gmail.com wrote:
I'd try with the latter first. Moving process_vertices() over to the CS thread seems awkward to me.
Yeah.
FWIW we should probably get rid of the struct gl_info uses in wined3d_ffp_get_vs_settings(), maybe by setting a flag in d3d_info if we have enough (backend / GL) varyings to support all the fixed function (d3d) varyings. Actually, all the uses of wined3d_max_compat_varyings() are like that, we could get rid of the function entirely. I can write the patch if you haven't already.
I think that makes sense. (And no, I haven't written that yet.)
That aside, I think wined3d_ffp_get_vs_settings() shouldn't have a context parameter but simply get stream_info and d3d_info from the caller. You want to pass your own stream_info from wined3d_device_process_vertices() anyway and you can get to d3d_info from device->adapter.
I think that makes sense too.
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/tests/ddraw1.c | 288 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 9525b2dc0c..7c9721e78a 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -415,6 +415,27 @@ static void emit_tquad_tlist(void **ptr, WORD base_idx) *ptr = tri; }
+static void emit_tri_indices(void **ptr, WORD *indices, unsigned int primitive_count) +{ + D3DINSTRUCTION *inst = *ptr; + D3DTRIANGLE *tri = (D3DTRIANGLE *)(inst + 1); + unsigned int i; + + inst->bOpcode = D3DOP_TRIANGLE; + inst->bSize = sizeof(*tri); + inst->wCount = primitive_count; + + for (i = 0; i < primitive_count; ++i) + { + U1(*tri).v1 = indices[i * 3]; + U2(*tri).v2 = indices[i * 3 + 1]; + U3(*tri).v3 = indices[i * 3 + 2]; + tri->wFlags = D3DTRIFLAG_START; + ++tri; + } + *ptr = tri; +} + static void emit_texture_load(void **ptr, D3DTEXTUREHANDLE dst_texture, D3DTEXTUREHANDLE src_texture) { @@ -679,6 +700,22 @@ static IDirect3DMaterial *create_emissive_material(IDirect3DDevice *device, floa return create_material(device, &mat); }
+static IDirect3DMaterial *create_specular_material(IDirect3DDevice *device, + float r, float g, float b, float a, float power) +{ + D3DMATERIAL mat; + + memset(&mat, 0, sizeof(mat)); + mat.dwSize = sizeof(mat); + U1(U2(mat).specular).r = r; + U2(U2(mat).specular).g = g; + U3(U2(mat).specular).b = b; + U4(U2(mat).specular).a = a; + U4(mat).power = power; + + return create_material(device, &mat); +} + static void destroy_material(IDirect3DMaterial *material) { IDirect3DMaterial_Release(material); @@ -6294,6 +6331,256 @@ static void test_lighting(void) DestroyWindow(window); }
+static void test_specular_lighting(void) +{ + static const unsigned int vertices_side = 5; + const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3; + const unsigned int vertex_count = vertices_side * vertices_side; + static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; + static D3DMATRIX mat = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + /* Use of D3DLIGHT2 instead of D3DLIGHT is intentional. Using D3DLIGHT + without dwFlags looks broken on Windows 7: directional light behaves + as if _LOCALVIEWER state is off, point and spot lights do not work + at all and always output zero colors. */ + static D3DLIGHT2 directional = + { + sizeof(D3DLIGHT2), + D3DLIGHT_DIRECTIONAL, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {1.0f}}, + }; + static const struct expected_color + { + unsigned int x, y; + D3DCOLOR color; + } + expected_directional_local[] = + { + {160, 120, 0x003c3c3c}, + {320, 120, 0x00717171}, + {480, 120, 0x003c3c3c}, + {160, 240, 0x00717171}, + {320, 240, 0x00ffffff}, + {480, 240, 0x00717171}, + {160, 360, 0x003c3c3c}, + {320, 360, 0x00717171}, + {480, 360, 0x003c3c3c}, + }, + expected_zero[] = + { + {160, 120, 0x00000000}, + {320, 120, 0x00000000}, + {480, 120, 0x00000000}, + {160, 240, 0x00000000}, + {320, 240, 0x00000000}, + {480, 240, 0x00000000}, + {160, 360, 0x00000000}, + {320, 360, 0x00000000}, + {480, 360, 0x00000000}, + }; + static const struct + { + D3DLIGHT2 *light; + float specular_power; + const struct expected_color *expected; + unsigned int expected_count; + } + tests[] = + { + {&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)}, + {&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + }; + + D3DMATRIXHANDLE world_handle, view_handle, proj_handle; + IDirect3DMaterial *material, *background_material; + IDirect3DExecuteBuffer *execute_buffer; + D3DEXECUTEBUFFERDESC exec_desc; + D3DMATERIALHANDLE mat_handle; + IDirect3DViewport *viewport; + unsigned int i, j, x, y; + IDirect3DDevice *device; + IDirectDrawSurface *rt; + IDirect3DLight *light; + IDirectDraw*ddraw; + UINT inst_length; + D3DVERTEX *quad; + IDirect3D *d3d; + D3DCOLOR color; + ULONG refcount; + WORD *indices; + BOOL is_warp; + HWND window; + HRESULT hr; + void *ptr; + + window = create_window(); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + IDirectDraw_Release(ddraw); + DestroyWindow(window); + return; + } + is_warp = ddraw_is_warp(ddraw); + + quad = HeapAlloc(GetProcessHeap(), 0, vertex_count * sizeof(*quad)); + indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices)); + for (i = 0, y = 0; y < vertices_side; ++y) + { + for (x = 0; x < vertices_side; ++x) + { + U1(quad[i]).x = x * 2.0f / (vertices_side - 1) - 1.0f; + U2(quad[i]).y = y * 2.0f / (vertices_side - 1) - 1.0f; + U3(quad[i]).z = 1.0f; + U4(quad[i]).nx = 0.0f; + U5(quad[i]).ny = 0.0f; + U6(quad[i]).nz = -1.0f; + U7(quad[i]).tu = 0.0f; + U8(quad[i++]).tv = 0.0f; + } + } + for (i = 0, y = 0; y < (vertices_side - 1); ++y) + { + for (x = 0; x < (vertices_side - 1); ++x) + { + indices[i++] = y * vertices_side + x + 1; + indices[i++] = y * vertices_side + x; + indices[i++] = (y + 1) * vertices_side + x; + indices[i++] = y * vertices_side + x + 1; + indices[i++] = (y + 1) * vertices_side + x; + indices[i++] = (y + 1) * vertices_side + x + 1; + } + } + + hr = IDirect3DDevice_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + viewport = create_viewport(device, 0, 0, 640, 480); + background_material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f); + viewport_set_background(device, viewport, background_material); + + hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice_CreateMatrix(device, &world_handle); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, world_handle, &mat); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_CreateMatrix(device, &view_handle); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, view_handle, &mat); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_CreateMatrix(device, &proj_handle); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, proj_handle, &mat); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + + hr = IDirect3D_CreateLight(d3d, &light, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DViewport_AddLight(viewport, light); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + memset(&exec_desc, 0, sizeof(exec_desc)); + exec_desc.dwSize = sizeof(exec_desc); + exec_desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS; + exec_desc.dwBufferSize = 10240; + exec_desc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY; + + hr = IDirect3DDevice_CreateExecuteBuffer(device, &exec_desc, &execute_buffer, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + tests[i].light->dwFlags = D3DLIGHT_ACTIVE; + material = create_specular_material(device, 1.0f, 1.0f, 1.0f, 1.0f, tests[i].specular_power); + hr = IDirect3DMaterial_GetHandle(material, device, &mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DLight_SetLight(light, (D3DLIGHT *)tests[i].light); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice_BeginScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + memcpy(exec_desc.lpData, quad, sizeof(*quad) * vertex_count); + ptr = ((BYTE *)exec_desc.lpData) + sizeof(*quad) * vertex_count; + + emit_set_ls(&ptr, D3DLIGHTSTATE_MATERIAL, mat_handle); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_WORLD, world_handle); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_VIEW, view_handle); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_PROJECTION, proj_handle); + emit_set_rs(&ptr, D3DRENDERSTATE_ZENABLE, FALSE); + emit_set_rs(&ptr, D3DRENDERSTATE_SPECULARENABLE, TRUE); + + emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, vertex_count); + emit_tri_indices(&ptr, indices, indices_count / 3); + emit_end(&ptr); + inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData; + ok(inst_length <= exec_desc.dwBufferSize, "Execute buffer overflow, size %u.\n", inst_length); + inst_length -= sizeof(*quad) * vertex_count; + + hr = IDirect3DExecuteBuffer_Unlock(execute_buffer); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + set_execute_data(execute_buffer, vertex_count, sizeof(*quad) * vertex_count, inst_length); + hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice_EndScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (j = 0; j < tests[i].expected_count; ++j) + { + color = get_surface_color(rt, tests[i].expected[j].x, tests[i].expected[j].y); + ok(compare_color(color, tests[i].expected[j].color, 1) + || broken(is_warp && compare_color(color, 0x00ff0000, 1)), + "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n", + tests[i].expected[j].color, tests[i].expected[j].x, + tests[i].expected[j].y, color, i); + } + destroy_material(material); + } + + IDirect3DExecuteBuffer_Release(execute_buffer); + IDirect3DDevice_DeleteMatrix(device, world_handle); + IDirect3DDevice_DeleteMatrix(device, view_handle); + IDirect3DDevice_DeleteMatrix(device, proj_handle); + + hr = IDirect3DViewport_DeleteLight(viewport, light); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + IDirect3DLight_Release(light); + destroy_material(background_material); + destroy_viewport(device, viewport); + IDirectDrawSurface_Release(rt); + refcount = IDirect3DDevice_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D_Release(d3d); + refcount = IDirectDraw_Release(ddraw); + ok(!refcount, "Ddraw object has %u references left.\n", refcount); + DestroyWindow(window); + HeapFree(GetProcessHeap(), 0, indices); + HeapFree(GetProcessHeap(), 0, quad); +} + static void test_palette_gdi(void) { IDirectDrawSurface *surface, *primary; @@ -12552,6 +12839,7 @@ START_TEST(ddraw1) test_p8_blit(); test_material(); test_lighting(); + test_specular_lighting(); test_palette_gdi(); test_palette_alpha(); test_lost_device();
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=52390
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/tests/ddraw1.c | 62 +++++++++++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 61 +++++++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 7c9721e78a..965b1794b0 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -6355,6 +6355,39 @@ static void test_specular_lighting(void) {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, {{0.0f}, {0.0f}, {0.0f}}, {{0.0f}, {0.0f}, {1.0f}}, + }, + point = + { + sizeof(D3DLIGHT2), + D3DLIGHT_POINT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + 100.0f, + 0.0f, + 0.0f, 0.0f, 1.0f, + }, + point_side = + { + sizeof(D3DLIGHT2), + D3DLIGHT_POINT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{-1.1f}, {0.0f}, {1.1f}}, + {{0.0f}, {0.0f}, {0.0f}}, + 100.0f, + 0.0f, + 1.0f, 0.0f, 0.0f, + }, + point_far = + { + sizeof(D3DLIGHT2), + D3DLIGHT_POINT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.1f}}, + {{0.0f}, {0.0f}, {0.0f}}, + 1.0f, + 0.0f, + 1.0f, 0.0f, 0.0f, }; static const struct expected_color { @@ -6373,6 +6406,30 @@ static void test_specular_lighting(void) {320, 360, 0x00717171}, {480, 360, 0x003c3c3c}, }, + expected_point_local[] = + { + {160, 120, 0x00000000}, + {320, 120, 0x00090909}, + {480, 120, 0x00000000}, + {160, 240, 0x00090909}, + {320, 240, 0x00fafafa}, + {480, 240, 0x00090909}, + {160, 360, 0x00000000}, + {320, 360, 0x00090909}, + {480, 360, 0x00000000}, + }, + expected_point_far[] = + { + {160, 120, 0x00000000}, + {320, 120, 0x00000000}, + {480, 120, 0x00000000}, + {160, 240, 0x00000000}, + {320, 240, 0x00ffffff}, + {480, 240, 0x00000000}, + {160, 360, 0x00000000}, + {320, 360, 0x00000000}, + {480, 360, 0x00000000}, + }, expected_zero[] = { {160, 120, 0x00000000}, @@ -6395,7 +6452,12 @@ static void test_specular_lighting(void) tests[] = { {&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)}, + {&point, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)}, + {&point_side, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {&point_far, 1.0f, expected_point_far, ARRAY_SIZE(expected_point_far)}, {&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {&point, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {&point_far, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, };
D3DMATRIXHANDLE world_handle, view_handle, proj_handle; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8576012f21..76dcd3b1c6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3299,6 +3299,9 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win case WINED3D_LIGHT_DIRECTIONAL: ++ls->directional_light_count; break; + case WINED3D_LIGHT_POINT: + ++ls->point_light_count; + break; default: FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); continue; @@ -3326,6 +3329,26 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win light->specular = light_info->OriginalParms.specular; ++index; } + + for (i = 0; i < lights_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_POINT) + continue; + + light = &ls->lights[index]; + + multiply_vector_matrix(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + light->range = light_info->OriginalParms.range; + light->c_att = light_info->OriginalParms.attenuation0; + light->l_att = light_info->OriginalParms.attenuation1; + light->q_att = light_info->OriginalParms.attenuation2; + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } }
static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, @@ -3367,8 +3390,9 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d struct wined3d_vec3 normal_transformed = {0.0f}; struct wined3d_vec4 position_transformed; const struct light_transformed *light; + struct wined3d_vec3 dir, dst; unsigned int i, index; - float rcp_w; + float rcp_w, att;
multiply_vector_matrix(&position_transformed, position, &ls->modelview_matrix); rcp_w = 1.0f / position_transformed.w; @@ -3399,6 +3423,41 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d update_light_diffuse_specular(diffuse, specular, &light->direction, 1.0f, material_shininess, &normal_transformed, &position_transformed_normalized, light, ls); } + + for (i = 0; i < ls->point_light_count; ++i, ++index) + { + light = &ls->lights[index]; + dir.x = light->position.x - position_transformed.x; + dir.y = light->position.y - position_transformed.y; + dir.z = light->position.z - position_transformed.z; + + dst.z = wined3d_vec3_dot(&dir, &dir); + dst.y = sqrtf(dst.z); + dst.x = 1.0f; + if (ls->legacy_lighting) + { + dst.y = (light->range - dst.y) / light->range; + if (!(dst.y > 0.0f)) + continue; + dst.z = dst.y * dst.y; + } + else + { + if (!(dst.y <= light->range)) + continue; + } + att = dst.x * light->c_att + dst.y * light->l_att + dst.z * light->q_att; + if (!ls->legacy_lighting) + att = 1.0f / att; + + madd_color_rgb(ambient, &light->ambient, att); + if (normal) + { + normalize_vec3(&dir, &dir); + update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, + &normal_transformed, &position_transformed_normalized, light, ls); + } + } }
/* Context activation is done by the caller. */
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=52391
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/tests/ddraw1.c | 26 ++++++++++++++ dlls/wined3d/device.c | 76 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 965b1794b0..0dfc8c48b1 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -6367,6 +6367,18 @@ static void test_specular_lighting(void) 0.0f, 0.0f, 0.0f, 1.0f, }, + spot = + { + sizeof(D3DLIGHT2), + D3DLIGHT_SPOT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {1.0f}}, + 100.0f, + 1.0f, + 0.0f, 0.0f, 1.0f, + M_PI / 12.0f, M_PI / 3.0f + }, point_side = { sizeof(D3DLIGHT2), @@ -6418,6 +6430,18 @@ static void test_specular_lighting(void) {320, 360, 0x00090909}, {480, 360, 0x00000000}, }, + expected_spot_local[] = + { + {160, 120, 0x00000000}, + {320, 120, 0x00020202}, + {480, 120, 0x00000000}, + {160, 240, 0x00020202}, + {320, 240, 0x00fafafa}, + {480, 240, 0x00020202}, + {160, 360, 0x00000000}, + {320, 360, 0x00020202}, + {480, 360, 0x00000000}, + }, expected_point_far[] = { {160, 120, 0x00000000}, @@ -6453,10 +6477,12 @@ static void test_specular_lighting(void) { {&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)}, {&point, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)}, + {&spot, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)}, {&point_side, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point_far, 1.0f, expected_point_far, ARRAY_SIZE(expected_point_far)}, {&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {&spot, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point_far, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, };
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 76dcd3b1c6..843f63e12b 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3302,6 +3302,9 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win case WINED3D_LIGHT_POINT: ++ls->point_light_count; break; + case WINED3D_LIGHT_SPOT: + ++ls->spot_light_count; + break; default: FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); continue; @@ -3349,6 +3352,31 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win light->specular = light_info->OriginalParms.specular; ++index; } + + for (i = 0; i < lights_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_SPOT) + continue; + + light = &ls->lights[index]; + + multiply_vector_matrix(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + multiply_vector_matrix(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]); + normalize_vec3(&light->direction, (const struct wined3d_vec3 *)&vec4); + light->range = light_info->OriginalParms.range; + light->falloff = light_info->OriginalParms.falloff; + light->c_att = light_info->OriginalParms.attenuation0; + light->l_att = light_info->OriginalParms.attenuation1; + light->q_att = light_info->OriginalParms.attenuation2; + light->cos_htheta = cosf(light_info->OriginalParms.theta / 2.0f); + light->cos_hphi = cosf(light_info->OriginalParms.phi / 2.0f); + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } }
static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, @@ -3458,6 +3486,54 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d &normal_transformed, &position_transformed_normalized, light, ls); } } + + for (i = 0; i < ls->spot_light_count; ++i, ++index) + { + float t; + + light = &ls->lights[index]; + + dir.x = light->position.x - position_transformed.x; + dir.y = light->position.y - position_transformed.y; + dir.z = light->position.z - position_transformed.z; + + dst.z = wined3d_vec3_dot(&dir, &dir); + dst.y = sqrtf(dst.z); + dst.x = 1.0f; + + if (ls->legacy_lighting) + { + dst.y = (light->range - dst.y) / light->range; + if (!(dst.y > 0.0f)) + continue; + dst.z = dst.y * dst.y; + } + else + { + if (!(dst.y <= light->range)) + continue; + } + normalize_vec3(&dir, &dir); + t = -wined3d_vec3_dot(&dir, &light->direction); + if (t > light->cos_htheta) + att = 1.0f; + else if (t <= light->cos_hphi) + att = 0.0f; + else + att = powf((t - light->cos_hphi) / (light->cos_htheta - light->cos_hphi), light->falloff); + + t = dst.x * light->c_att + dst.y * light->l_att + dst.z * light->q_att; + if (ls->legacy_lighting) + att *= t; + else + att /= t; + + madd_color_rgb(ambient, &light->ambient, att); + + if (normal) + update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, + &normal_transformed, &position_transformed_normalized, light, ls); + } }
/* Context activation is done by the caller. */
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=52392
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/tests/ddraw1.c | 22 ++++++++++++++++++++++ dlls/wined3d/device.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 0dfc8c48b1..7b4917bb6e 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -6379,6 +6379,14 @@ static void test_specular_lighting(void) 0.0f, 0.0f, 1.0f, M_PI / 12.0f, M_PI / 3.0f }, + parallelpoint = + { + sizeof(D3DLIGHT2), + D3DLIGHT_PARALLELPOINT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.5f}, {0.0f}, {-1.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + }, point_side = { sizeof(D3DLIGHT2), @@ -6442,6 +6450,18 @@ static void test_specular_lighting(void) {320, 360, 0x00020202}, {480, 360, 0x00000000}, }, + expected_parallelpoint[] = + { + {160, 120, 0x00050505}, + {320, 120, 0x002c2c2c}, + {480, 120, 0x006e6e6e}, + {160, 240, 0x00090909}, + {320, 240, 0x00717171}, + {480, 240, 0x00ffffff}, + {160, 360, 0x00050505}, + {320, 360, 0x002c2c2c}, + {480, 360, 0x006e6e6e}, + }, expected_point_far[] = { {160, 120, 0x00000000}, @@ -6478,11 +6498,13 @@ static void test_specular_lighting(void) {&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)}, {&point, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)}, {&spot, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)}, + {¶llelpoint, 30.0f, expected_parallelpoint, ARRAY_SIZE(expected_parallelpoint)}, {&point_side, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point_far, 1.0f, expected_point_far, ARRAY_SIZE(expected_point_far)}, {&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&spot, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {¶llelpoint, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point_far, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, };
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 843f63e12b..c44b5003f7 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3305,6 +3305,9 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win case WINED3D_LIGHT_SPOT: ++ls->spot_light_count; break; + case WINED3D_LIGHT_PARALLELPOINT: + ++ls->parallel_point_light_count; + break; default: FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); continue; @@ -3377,6 +3380,22 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win light->specular = light_info->OriginalParms.specular; ++index; } + + for (i = 0; i < lights_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_PARALLELPOINT) + continue; + + light = &ls->lights[index]; + + multiply_vector_matrix(&vec4, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + normalize_vec3((struct wined3d_vec3 *)&light->position, (const struct wined3d_vec3 *)&vec4); + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } }
static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, @@ -3534,6 +3553,16 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, &normal_transformed, &position_transformed_normalized, light, ls); } + + for (i = 0; i < ls->parallel_point_light_count; ++i, ++index) + { + light = &ls->lights[index]; + + madd_color_rgb(ambient, &light->ambient, 1.0f); + if (normal) + update_light_diffuse_specular(diffuse, specular, (const struct wined3d_vec3 *)&light->position, + 1.0f, material_shininess, &normal_transformed, &position_transformed_normalized, light, ls); + } }
/* Context activation is done by the caller. */
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=52393
Your paranoid android.
=== wvistau64_he (32 bit report) ===
ddraw: ddraw1.c:2800: Test failed: Expected message 0x46, but didn't receive it. ddraw1.c:2802: Test failed: Expected screen size 1024x768, got 0x0. ddraw1.c:2808: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2838: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2845: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2871: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2894: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2923: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2949: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2969: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3005: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3015: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3041: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3064: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3086: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3112: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3132: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3169: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746).
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/wined3d/wined3d_private.h:4850 Task: Patch failed to apply
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=52387
Your paranoid android.
=== debian9 (build log) ===
collect2: error: ld returned 1 exit status Makefile:1356: recipe for target 'wined3d.dll.so' failed Makefile:8708: recipe for target 'dlls/wined3d' failed Task: The win32 build failed
=== debian9 (build log) ===
collect2: error: ld returned 1 exit status Makefile:1336: recipe for target 'wined3d.dll.so' failed Makefile:8443: recipe for target 'dlls/wined3d' failed Task: The wow64 build failed
On Fri, 17 May 2019 at 13:22, Paul Gofman gofmanp@gmail.com wrote:
+static void wined3d_format_get_color(const struct wined3d_format *format, const BYTE *data,
struct wined3d_color *color)
+{
Thinking about it a bit more, perhaps the the long term direction we want this to go is something like "wined3d_format_get_vec4()", instead of making this specific to colours. No rush though, it would be fine to wait with that until it's actually needed.
case WINED3DFMT_R32_FLOAT:
case WINED3DFMT_R32G32_FLOAT:
case WINED3DFMT_R32G32B32_FLOAT:
case WINED3DFMT_R32G32B32A32_FLOAT:
{
const float *float_data = (const float *)data;
for (i = 0; i < format->component_count; ++i)
output[i] = float_data[i];
break;
}
Note that you leave the "implicit" components uninitialised in this case, while you do initialise them for the other formats.
- if (lighting)
- {
if (state->render_states[WINED3D_RS_COLORVERTEX])
{
diffuse_source = validate_material_colour_source(stream_info->use_map,
state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]);
specular_source = validate_material_colour_source(stream_info->use_map,
state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
}
else
{
diffuse_source = specular_source = WINED3D_MCS_MATERIAL;
}
- }
- else
- {
diffuse_source = WINED3D_MCS_COLOR1;
specular_source = WINED3D_MCS_COLOR2;
- }
In case it helps, wined3d_ffp_get_vs_settings() already does something very similar, perhaps it makes sense to start from the wined3d_ffp_vs_settings structure, instead of the raw state.