These signatures extend the OSG5 format by a minimum precision hint, which gets ignored for now but could be implemented using 16-bit floats in the future.
Fixes some shader parsing errors in Resident Evil 2.
Based on a vkd3d patch by Philip Rebohle.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/shader_sm4.c | 21 ++++++++++++++++++--- include/wine/wined3d.h | 1 + 2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c index 4635910269f..005be96a51f 100644 --- a/dlls/wined3d/shader_sm4.c +++ b/dlls/wined3d/shader_sm4.c @@ -1820,10 +1820,13 @@ const struct wined3d_shader_frontend sm4_shader_frontend =
#define TAG_AON9 WINEMAKEFOURCC('A', 'o', 'n', '9') #define TAG_DXBC WINEMAKEFOURCC('D', 'X', 'B', 'C') +#define TAG_ISG1 WINEMAKEFOURCC('I', 'S', 'G', '1') #define TAG_ISGN WINEMAKEFOURCC('I', 'S', 'G', 'N') +#define TAG_OSG1 WINEMAKEFOURCC('O', 'S', 'G', '1') #define TAG_OSG5 WINEMAKEFOURCC('O', 'S', 'G', '5') #define TAG_OSGN WINEMAKEFOURCC('O', 'S', 'G', 'N') #define TAG_PCSG WINEMAKEFOURCC('P', 'C', 'S', 'G') +#define TAG_PSG1 WINEMAKEFOURCC('P', 'S', 'G', '1') #define TAG_SHDR WINEMAKEFOURCC('S', 'H', 'D', 'R') #define TAG_SHEX WINEMAKEFOURCC('S', 'H', 'E', 'X')
@@ -1955,6 +1958,7 @@ static HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_si struct wined3d_shader_signature *s) { struct wined3d_shader_signature_element *e; + bool has_stream_index, has_min_precision; const char *ptr = data; unsigned int i; DWORD count; @@ -1982,11 +1986,14 @@ static HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_si return E_OUTOFMEMORY; }
+ has_min_precision = tag == TAG_OSG1 || tag == TAG_PSG1 || tag == TAG_ISG1; + has_stream_index = tag == TAG_OSG5 || has_min_precision; + for (i = 0; i < count; ++i) { DWORD name_offset;
- if (tag == TAG_OSG5) + if (has_stream_index) read_dword(&ptr, &e[i].stream_idx); else e[i].stream_idx = 0; @@ -2003,10 +2010,15 @@ static HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_si read_dword(&ptr, &e[i].register_idx); read_dword(&ptr, &e[i].mask);
+ if (has_min_precision) + read_dword(&ptr, &e[i].min_precision); + else + e[i].min_precision = 0; + TRACE("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, " - "type %u, register idx: %u, use_mask %#x, input_mask %#x.\n", + "type %u, register idx: %u, use_mask %#x, input_mask %#x, min_precision %u.\n", e[i].stream_idx, debugstr_a(e[i].semantic_name), e[i].semantic_idx, e[i].sysval_semantic, - e[i].component_type, e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff); + e[i].component_type, e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff, e[i].min_precision); }
s->elements = e; @@ -2024,6 +2036,7 @@ static HRESULT shader_dxbc_chunk_handler(const char *data, DWORD data_size, DWOR switch (tag) { case TAG_ISGN: + case TAG_ISG1: if (ctx->max_version < 4) { TRACE("Skipping shader input signature.\n"); @@ -2039,6 +2052,7 @@ static HRESULT shader_dxbc_chunk_handler(const char *data, DWORD data_size, DWOR break;
case TAG_OSGN: + case TAG_OSG1: case TAG_OSG5: if (ctx->max_version < 4) { @@ -2055,6 +2069,7 @@ static HRESULT shader_dxbc_chunk_handler(const char *data, DWORD data_size, DWOR break;
case TAG_PCSG: + case TAG_PSG1: if (shader->patch_constant_signature.elements) { FIXME("Multiple patch constant signatures.\n"); diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 7a6588ea4f4..1fdbd105cc4 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2107,6 +2107,7 @@ struct wined3d_shader_signature_element enum wined3d_component_type component_type; unsigned int register_idx; DWORD mask; + unsigned int min_precision; };
struct wined3d_shader_signature