This will allow parsing and compiling shaders a bit later, which is useful for FFP. It will also help if we want to collect together shader initialization to go through a single entry point instead of six individual ones.
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/shader.c | 342 +++++++++++++++++++++--------------------- 1 file changed, 171 insertions(+), 171 deletions(-)
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 9c3b02a567f..671aaa929cc 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2097,6 +2097,177 @@ static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_l } }
+static struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s, + unsigned int stream_idx, const char *semantic_name, unsigned int semantic_idx) +{ + struct wined3d_shader_signature_element *e = s->elements; + unsigned int i; + + for (i = 0; i < s->element_count; ++i) + { + if (e[i].stream_idx == stream_idx + && !stricmp(e[i].semantic_name, semantic_name) + && e[i].semantic_idx == semantic_idx) + return &e[i]; + } + + return NULL; +} + +BOOL shader_get_stream_output_register_info(const struct wined3d_shader *shader, + const struct wined3d_stream_output_element *so_element, unsigned int *register_idx, unsigned int *component_idx) +{ + const struct wined3d_shader_signature_element *output; + unsigned int idx; + + if (!(output = shader_find_signature_element(&shader->output_signature, + so_element->stream_idx, so_element->semantic_name, so_element->semantic_idx))) + return FALSE; + + for (idx = 0; idx < 4; ++idx) + { + if (output->mask & (1u << idx)) + break; + } + idx += so_element->component_idx; + + *register_idx = output->register_idx; + *component_idx = idx; + return TRUE; +} + +static HRESULT geometry_shader_init_so_desc(struct wined3d_geometry_shader *gs, struct wined3d_device *device, + const struct wined3d_stream_output_desc *so_desc) +{ + struct wined3d_so_desc_entry *s; + struct wine_rb_entry *entry; + unsigned int i; + size_t size; + char *name; + + if ((entry = wine_rb_get(&device->so_descs, so_desc))) + { + gs->so_desc = &WINE_RB_ENTRY_VALUE(entry, struct wined3d_so_desc_entry, entry)->desc; + return WINED3D_OK; + } + + size = FIELD_OFFSET(struct wined3d_so_desc_entry, elements[so_desc->element_count]); + for (i = 0; i < so_desc->element_count; ++i) + { + const char *n = so_desc->elements[i].semantic_name; + + if (n) + size += strlen(n) + 1; + } + if (!(s = malloc(size))) + return E_OUTOFMEMORY; + + s->desc = *so_desc; + + memcpy(s->elements, so_desc->elements, so_desc->element_count * sizeof(*s->elements)); + s->desc.elements = s->elements; + + name = (char *)&s->elements[s->desc.element_count]; + for (i = 0; i < so_desc->element_count; ++i) + { + struct wined3d_stream_output_element *e = &s->elements[i]; + + if (!e->semantic_name) + continue; + + size = strlen(e->semantic_name) + 1; + memcpy(name, e->semantic_name, size); + e->semantic_name = name; + name += size; + } + + if (wine_rb_put(&device->so_descs, &s->desc, &s->entry) == -1) + { + free(s); + return E_FAIL; + } + gs->so_desc = &s->desc; + + return WINED3D_OK; +} + +static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, + const struct wined3d_stream_output_desc *so_desc) +{ + const struct wined3d_shader_frontend *fe = shader->frontend; + const struct wined3d_shader_signature_element *output; + unsigned int i, component_idx, register_idx, mask; + struct wined3d_shader_version shader_version; + const DWORD *ptr; + void *fe_data; + HRESULT hr; + + if (!so_desc) + return WINED3D_OK; + + if (!(fe_data = fe->shader_init(shader->function, shader->functionLength, &shader->output_signature))) + { + WARN("Failed to initialise frontend data.\n"); + return WINED3DERR_INVALIDCALL; + } + fe->shader_read_header(fe_data, &ptr, &shader_version); + fe->shader_free(fe_data); + + switch (shader_version.type) + { + case WINED3D_SHADER_TYPE_VERTEX: + case WINED3D_SHADER_TYPE_DOMAIN: + shader->function = NULL; + shader->functionLength = 0; + break; + case WINED3D_SHADER_TYPE_GEOMETRY: + break; + default: + WARN("Wrong shader type %s.\n", debug_shader_type(shader_version.type)); + return E_INVALIDARG; + } + + if (!shader->function) + { + shader->reg_maps.shader_version = shader_version; + shader->reg_maps.shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; + shader_set_limits(shader); + if (FAILED(hr = shader_scan_output_signature(shader))) + return hr; + } + + for (i = 0; i < so_desc->element_count; ++i) + { + const struct wined3d_stream_output_element *e = &so_desc->elements[i]; + + if (!e->semantic_name) + continue; + if (!(output = shader_find_signature_element(&shader->output_signature, + e->stream_idx, e->semantic_name, e->semantic_idx)) + || !shader_get_stream_output_register_info(shader, e, ®ister_idx, &component_idx)) + { + WARN("Failed to find output signature element for stream output entry.\n"); + return E_INVALIDARG; + } + + mask = wined3d_mask_from_size(e->component_count) << component_idx; + if ((output->mask & 0xff & mask) != mask) + { + WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n", + component_idx, e->component_count, mask, output->mask & 0xff); + return E_INVALIDARG; + } + } + + if (FAILED(hr = geometry_shader_init_so_desc(&shader->u.gs, shader->device, so_desc))) + { + WARN("Failed to initialise stream output description, hr %#lx.\n", hr); + return hr; + } + + return WINED3D_OK; +} + static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d_device *device, enum wined3d_shader_type type, unsigned int float_const_count) { @@ -2572,177 +2743,6 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ return WINED3D_OK; }
-static struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s, - unsigned int stream_idx, const char *semantic_name, unsigned int semantic_idx) -{ - struct wined3d_shader_signature_element *e = s->elements; - unsigned int i; - - for (i = 0; i < s->element_count; ++i) - { - if (e[i].stream_idx == stream_idx - && !stricmp(e[i].semantic_name, semantic_name) - && e[i].semantic_idx == semantic_idx) - return &e[i]; - } - - return NULL; -} - -BOOL shader_get_stream_output_register_info(const struct wined3d_shader *shader, - const struct wined3d_stream_output_element *so_element, unsigned int *register_idx, unsigned int *component_idx) -{ - const struct wined3d_shader_signature_element *output; - unsigned int idx; - - if (!(output = shader_find_signature_element(&shader->output_signature, - so_element->stream_idx, so_element->semantic_name, so_element->semantic_idx))) - return FALSE; - - for (idx = 0; idx < 4; ++idx) - { - if (output->mask & (1u << idx)) - break; - } - idx += so_element->component_idx; - - *register_idx = output->register_idx; - *component_idx = idx; - return TRUE; -} - -static HRESULT geometry_shader_init_so_desc(struct wined3d_geometry_shader *gs, struct wined3d_device *device, - const struct wined3d_stream_output_desc *so_desc) -{ - struct wined3d_so_desc_entry *s; - struct wine_rb_entry *entry; - unsigned int i; - size_t size; - char *name; - - if ((entry = wine_rb_get(&device->so_descs, so_desc))) - { - gs->so_desc = &WINE_RB_ENTRY_VALUE(entry, struct wined3d_so_desc_entry, entry)->desc; - return WINED3D_OK; - } - - size = FIELD_OFFSET(struct wined3d_so_desc_entry, elements[so_desc->element_count]); - for (i = 0; i < so_desc->element_count; ++i) - { - const char *n = so_desc->elements[i].semantic_name; - - if (n) - size += strlen(n) + 1; - } - if (!(s = malloc(size))) - return E_OUTOFMEMORY; - - s->desc = *so_desc; - - memcpy(s->elements, so_desc->elements, so_desc->element_count * sizeof(*s->elements)); - s->desc.elements = s->elements; - - name = (char *)&s->elements[s->desc.element_count]; - for (i = 0; i < so_desc->element_count; ++i) - { - struct wined3d_stream_output_element *e = &s->elements[i]; - - if (!e->semantic_name) - continue; - - size = strlen(e->semantic_name) + 1; - memcpy(name, e->semantic_name, size); - e->semantic_name = name; - name += size; - } - - if (wine_rb_put(&device->so_descs, &s->desc, &s->entry) == -1) - { - free(s); - return E_FAIL; - } - gs->so_desc = &s->desc; - - return WINED3D_OK; -} - -static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, - const struct wined3d_stream_output_desc *so_desc) -{ - const struct wined3d_shader_frontend *fe = shader->frontend; - const struct wined3d_shader_signature_element *output; - unsigned int i, component_idx, register_idx, mask; - struct wined3d_shader_version shader_version; - const DWORD *ptr; - void *fe_data; - HRESULT hr; - - if (!so_desc) - return WINED3D_OK; - - if (!(fe_data = fe->shader_init(shader->function, shader->functionLength, &shader->output_signature))) - { - WARN("Failed to initialise frontend data.\n"); - return WINED3DERR_INVALIDCALL; - } - fe->shader_read_header(fe_data, &ptr, &shader_version); - fe->shader_free(fe_data); - - switch (shader_version.type) - { - case WINED3D_SHADER_TYPE_VERTEX: - case WINED3D_SHADER_TYPE_DOMAIN: - shader->function = NULL; - shader->functionLength = 0; - break; - case WINED3D_SHADER_TYPE_GEOMETRY: - break; - default: - WARN("Wrong shader type %s.\n", debug_shader_type(shader_version.type)); - return E_INVALIDARG; - } - - if (!shader->function) - { - shader->reg_maps.shader_version = shader_version; - shader->reg_maps.shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; - shader_set_limits(shader); - if (FAILED(hr = shader_scan_output_signature(shader))) - return hr; - } - - for (i = 0; i < so_desc->element_count; ++i) - { - const struct wined3d_stream_output_element *e = &so_desc->elements[i]; - - if (!e->semantic_name) - continue; - if (!(output = shader_find_signature_element(&shader->output_signature, - e->stream_idx, e->semantic_name, e->semantic_idx)) - || !shader_get_stream_output_register_info(shader, e, ®ister_idx, &component_idx)) - { - WARN("Failed to find output signature element for stream output entry.\n"); - return E_INVALIDARG; - } - - mask = wined3d_mask_from_size(e->component_count) << component_idx; - if ((output->mask & 0xff & mask) != mask) - { - WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n", - component_idx, e->component_count, mask, output->mask & 0xff); - return E_INVALIDARG; - } - } - - if (FAILED(hr = geometry_shader_init_so_desc(&shader->u.gs, shader->device, so_desc))) - { - WARN("Failed to initialise stream output description, hr %#lx.\n", hr); - return hr; - } - - return WINED3D_OK; -} - static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, const struct wined3d_shader_desc *desc, const struct wined3d_stream_output_desc *so_desc, void *parent, const struct wined3d_parent_ops *parent_ops)
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/shader.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 671aaa929cc..1b133cb3a60 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2269,7 +2269,7 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, }
static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d_device *device, - enum wined3d_shader_type type, unsigned int float_const_count) + enum wined3d_shader_type type, const struct wined3d_stream_output_desc *so_desc, unsigned int float_const_count) { const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; @@ -2281,6 +2281,14 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d TRACE("shader %p, device %p, type %s, float_const_count %u.\n", shader, device, debug_shader_type(type), float_const_count);
+ if (type == WINED3D_SHADER_TYPE_GEOMETRY) + { + if (FAILED(hr = geometry_shader_init_stream_output(shader, so_desc))) + return hr; + if (!shader->function) + return S_OK; + } + fe = shader->frontend; if (!(shader->frontend_data = fe->shader_init(shader->function, shader->functionLength, &shader->output_signature))) @@ -2719,7 +2727,7 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ return hr;
if (FAILED(hr = shader_set_function(shader, device, - WINED3D_SHADER_TYPE_VERTEX, device->adapter->d3d_info.limits.vs_uniform_count))) + WINED3D_SHADER_TYPE_VERTEX, NULL, device->adapter->d3d_info.limits.vs_uniform_count))) { shader_cleanup(shader); return hr; @@ -2752,11 +2760,7 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3 if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) return hr;
- if (FAILED(hr = geometry_shader_init_stream_output(shader, so_desc))) - goto fail; - - if (shader->function - && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0))) + if (FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, so_desc, 0))) goto fail;
return WINED3D_OK; @@ -3088,7 +3092,7 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d return hr;
if (FAILED(hr = shader_set_function(shader, device, - WINED3D_SHADER_TYPE_PIXEL, d3d_info->limits.ps_uniform_count))) + WINED3D_SHADER_TYPE_PIXEL, NULL, d3d_info->limits.ps_uniform_count))) { shader_cleanup(shader); return hr; @@ -3180,7 +3184,7 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru return hr; }
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0))) + if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, NULL, 0))) { shader_cleanup(object); free(object); @@ -3214,7 +3218,7 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru return hr; }
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0))) + if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, NULL, 0))) { shader_cleanup(object); free(object); @@ -3276,7 +3280,7 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru return hr; }
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0))) + if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, NULL, 0))) { shader_cleanup(object); free(object);
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/shader.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 1b133cb3a60..ac450df2c57 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2268,7 +2268,7 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, return WINED3D_OK; }
-static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d_device *device, +static HRESULT shader_set_function(struct wined3d_shader *shader, enum wined3d_shader_type type, const struct wined3d_stream_output_desc *so_desc, unsigned int float_const_count) { const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; @@ -2278,8 +2278,8 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d unsigned int backend_version; HRESULT hr;
- TRACE("shader %p, device %p, type %s, float_const_count %u.\n", - shader, device, debug_shader_type(type), float_const_count); + TRACE("shader %p, type %s, float_const_count %u.\n", + shader, debug_shader_type(type), float_const_count);
if (type == WINED3D_SHADER_TYPE_GEOMETRY) { @@ -2305,7 +2305,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d WARN("Wrong shader type %s.\n", debug_shader_type(reg_maps->shader_version.type)); return WINED3DERR_INVALIDCALL; } - if (version->major > shader_max_version_from_feature_level(device->cs->c.state->feature_level)) + if (version->major > shader_max_version_from_feature_level(shader->device->cs->c.state->feature_level)) { WARN("Shader version %u not supported by this device.\n", version->major); return WINED3DERR_INVALIDCALL; @@ -2726,7 +2726,7 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) return hr;
- if (FAILED(hr = shader_set_function(shader, device, + if (FAILED(hr = shader_set_function(shader, WINED3D_SHADER_TYPE_VERTEX, NULL, device->adapter->d3d_info.limits.vs_uniform_count))) { shader_cleanup(shader); @@ -2760,7 +2760,7 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3 if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) return hr;
- if (FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, so_desc, 0))) + if (FAILED(hr = shader_set_function(shader, WINED3D_SHADER_TYPE_GEOMETRY, so_desc, 0))) goto fail;
return WINED3D_OK; @@ -3091,7 +3091,7 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) return hr;
- if (FAILED(hr = shader_set_function(shader, device, + if (FAILED(hr = shader_set_function(shader, WINED3D_SHADER_TYPE_PIXEL, NULL, d3d_info->limits.ps_uniform_count))) { shader_cleanup(shader); @@ -3184,7 +3184,7 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru return hr; }
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, NULL, 0))) + if (FAILED(hr = shader_set_function(object, WINED3D_SHADER_TYPE_COMPUTE, NULL, 0))) { shader_cleanup(object); free(object); @@ -3218,7 +3218,7 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru return hr; }
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, NULL, 0))) + if (FAILED(hr = shader_set_function(object, WINED3D_SHADER_TYPE_DOMAIN, NULL, 0))) { shader_cleanup(object); free(object); @@ -3280,7 +3280,7 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru return hr; }
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, NULL, 0))) + if (FAILED(hr = shader_set_function(object, WINED3D_SHADER_TYPE_HULL, NULL, 0))) { shader_cleanup(object); free(object);
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/shader.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index ac450df2c57..834dd7a2855 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2313,8 +2313,24 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, switch (type) { case WINED3D_SHADER_TYPE_VERTEX: + for (unsigned int i = 0; i < shader->input_signature.element_count; ++i) + { + const struct wined3d_shader_signature_element *input = &shader->input_signature.elements[i]; + + if (!(reg_maps->input_registers & (1u << input->register_idx)) || !input->semantic_name) + continue; + + shader->u.vs.attributes[input->register_idx].usage = + shader_usage_from_semantic_name(input->semantic_name); + shader->u.vs.attributes[input->register_idx].usage_idx = input->semantic_idx; + } + + if (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) + shader->load_local_constsF = TRUE; + backend_version = d3d_info->limits.vs_version; break; + case WINED3D_SHADER_TYPE_HULL: backend_version = d3d_info->limits.hs_version; break; @@ -2719,8 +2735,6 @@ fail: static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { - struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - unsigned int i; HRESULT hr;
if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) @@ -2733,21 +2747,6 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ return hr; }
- for (i = 0; i < shader->input_signature.element_count; ++i) - { - const struct wined3d_shader_signature_element *input = &shader->input_signature.elements[i]; - - if (!(reg_maps->input_registers & (1u << input->register_idx)) || !input->semantic_name) - continue; - - shader->u.vs.attributes[input->register_idx].usage = - shader_usage_from_semantic_name(input->semantic_name); - shader->u.vs.attributes[input->register_idx].usage_idx = input->semantic_idx; - } - - if (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) - shader->load_local_constsF = TRUE; - return WINED3D_OK; }
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/shader.c | 83 +++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 42 deletions(-)
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 834dd7a2855..e82b382ee2d 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2274,6 +2274,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; const struct wined3d_shader_version *version = ®_maps->shader_version; + unsigned int highest_reg_used = 0, num_regs_used = 0; const struct wined3d_shader_frontend *fe; unsigned int backend_version; HRESULT hr; @@ -2341,6 +2342,46 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, backend_version = d3d_info->limits.gs_version; break; case WINED3D_SHADER_TYPE_PIXEL: + for (unsigned int i = 0; i < MAX_REG_INPUT; ++i) + { + if (shader->u.ps.input_reg_used & (1u << i)) + { + ++num_regs_used; + highest_reg_used = i; + } + } + + /* Don't do any register mapping magic if it is not needed, + * or if we can't achieve anything anyway. */ + if (highest_reg_used < (d3d_info->limits.varying_count / 4) + || num_regs_used > (d3d_info->limits.varying_count / 4) + || shader->reg_maps.shader_version.major >= 4) + { + if (num_regs_used > (d3d_info->limits.varying_count / 4)) + { + /* This happens with relative addressing. The input mapper + * function warns about this if the higher registers are + * declared too, so don't write a FIXME here. */ + WARN("More varying registers used than supported.\n"); + } + + for (unsigned int i = 0; i < MAX_REG_INPUT; ++i) + shader->u.ps.input_reg_map[i] = i; + + shader->u.ps.declared_in_count = highest_reg_used + 1; + } + else + { + shader->u.ps.declared_in_count = 0; + for (unsigned int i = 0; i < MAX_REG_INPUT; ++i) + { + if (shader->u.ps.input_reg_used & (1u << i)) + shader->u.ps.input_reg_map[i] = shader->u.ps.declared_in_count++; + else + shader->u.ps.input_reg_map[i] = ~0u; + } + } + backend_version = d3d_info->limits.ps_version; break; case WINED3D_SHADER_TYPE_COMPUTE: @@ -3084,7 +3125,6 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - unsigned int i, highest_reg_used = 0, num_regs_used = 0; HRESULT hr;
if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) @@ -3097,47 +3137,6 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d return hr; }
- for (i = 0; i < MAX_REG_INPUT; ++i) - { - if (shader->u.ps.input_reg_used & (1u << i)) - { - ++num_regs_used; - highest_reg_used = i; - } - } - - /* Don't do any register mapping magic if it is not needed, or if we can't - * achieve anything anyway */ - if (highest_reg_used < (d3d_info->limits.varying_count / 4) - || num_regs_used > (d3d_info->limits.varying_count / 4) - || shader->reg_maps.shader_version.major >= 4) - { - if (num_regs_used > (d3d_info->limits.varying_count / 4)) - { - /* This happens with relative addressing. The input mapper function - * warns about this if the higher registers are declared too, so - * don't write a FIXME here */ - WARN("More varying registers used than supported\n"); - } - - for (i = 0; i < MAX_REG_INPUT; ++i) - { - shader->u.ps.input_reg_map[i] = i; - } - - shader->u.ps.declared_in_count = highest_reg_used + 1; - } - else - { - shader->u.ps.declared_in_count = 0; - for (i = 0; i < MAX_REG_INPUT; ++i) - { - if (shader->u.ps.input_reg_used & (1u << i)) - shader->u.ps.input_reg_map[i] = shader->u.ps.declared_in_count++; - else shader->u.ps.input_reg_map[i] = ~0U; - } - } - return WINED3D_OK; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=148630
Your paranoid android.
=== debian11b (64 bit WoW report) ===
d3d9: visual.c:2095: Test failed: Expected color 00ff0000, got 00000000 (for input -2.400000, instruction mov) visual.c:2095: Test failed: Expected color 00ffff00, got 00000000 (for input -1.600000, instruction mov) visual.c:2095: Test failed: Expected color 0000ff00, got 00000000 (for input -0.400000, instruction mov) visual.c:2095: Test failed: Expected color 0000ffff, got 00000000 (for input 0.400000, instruction mov) visual.c:2095: Test failed: Expected color 000000ff, got 00000000 (for input 1.600000, instruction mov) visual.c:2095: Test failed: Expected color 00ff00ff, got 00000000 (for input 2.400000, instruction mov) visual.c:2095: Test failed: Expected color 00ffff00, got 00000000 (for input -2.400000, instruction mova) visual.c:2095: Test failed: Expected color 00ffff00, got 00000000 (for input -1.600000, instruction mova) visual.c:2095: Test failed: Expected color 0000ffff, got 00000000 (for input -0.400000, instruction mova) visual.c:2095: Test failed: Expected color 0000ffff, got 00000000 (for input 0.400000, instruction mova) visual.c:2095: Test failed: Expected color 00ff00ff, got 00000000 (for input 1.600000, instruction mova) visual.c:2095: Test failed: Expected color 00ff00ff, got 00000000 (for input 2.400000, instruction mova)
Report validation errors: winmm:mci crashed (c0000008)
This merge request was approved by Jan Sikorski.