diff --git a/dlls/d3dcompiler_43/compiler.c b/dlls/d3dcompiler_43/compiler.c index 4942985c8de..985fc72adde 100644 --- a/dlls/d3dcompiler_43/compiler.c +++ b/dlls/d3dcompiler_43/compiler.c @@ -490,6 +490,103 @@ HRESULT WINAPI D3DAssemble(const void *data, SIZE_T datasize, const char *filena return hr; } +struct target_info { + const char *name; + enum shader_type type; + DWORD sm_major; + DWORD sm_minor; + DWORD level_major; + DWORD level_minor; + BOOL sw; + BOOL support; +}; + +/* Must be kept sorted for binary search */ +static const struct target_info targets_info[] = { + { "cs_4_0", ST_UNKNOWN, 4, 0, 0, 0, FALSE, FALSE }, + { "cs_4_1", ST_UNKNOWN, 4, 1, 0, 0, FALSE, FALSE }, + { "cs_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, + { "ds_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, + { "fx_2_0", ST_UNKNOWN, 2, 0, 0, 0, FALSE, FALSE }, + { "fx_4_0", ST_UNKNOWN, 4, 0, 0, 0, FALSE, FALSE }, + { "fx_4_1", ST_UNKNOWN, 4, 1, 0, 0, FALSE, FALSE }, + { "fx_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, + { "gs_4_0", ST_UNKNOWN, 4, 0, 0, 0, FALSE, FALSE }, + { "gs_4_1", ST_UNKNOWN, 4, 1, 0, 0, FALSE, FALSE }, + { "gs_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, + { "hs_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, + { "ps.1.0", ST_PIXEL, 1, 0, 0, 0, FALSE, TRUE }, + { "ps.1.1", ST_PIXEL, 1, 1, 0, 0, FALSE, FALSE }, + { "ps.1.2", ST_PIXEL, 1, 2, 0, 0, FALSE, FALSE }, + { "ps.1.3", ST_PIXEL, 1, 3, 0, 0, FALSE, FALSE }, + { "ps.1.4", ST_PIXEL, 1, 4, 0, 0, FALSE, FALSE }, + { "ps.2.0", ST_PIXEL, 2, 0, 0, 0, FALSE, TRUE }, + { "ps.2.a", ST_PIXEL, 2, 1, 0, 0, FALSE, FALSE }, + { "ps.2.b", ST_PIXEL, 2, 2, 0, 0, FALSE, FALSE }, + { "ps.2.sw", ST_PIXEL, 2, 0, 0, 0, TRUE, FALSE }, + { "ps.3.0", ST_PIXEL, 3, 0, 0, 0, FALSE, TRUE }, + { "ps_1_0", ST_PIXEL, 1, 0, 0, 0, FALSE, TRUE }, + { "ps_1_1", ST_PIXEL, 1, 1, 0, 0, FALSE, FALSE }, + { "ps_1_2", ST_PIXEL, 1, 2, 0, 0, FALSE, FALSE }, + { "ps_1_3", ST_PIXEL, 1, 3, 0, 0, FALSE, FALSE }, + { "ps_1_4", ST_PIXEL, 1, 4, 0, 0, FALSE, FALSE }, + { "ps_2_0", ST_PIXEL, 2, 0, 0, 0, FALSE, TRUE }, + { "ps_2_a", ST_PIXEL, 2, 1, 0, 0, FALSE, FALSE }, + { "ps_2_b", ST_PIXEL, 2, 2, 0, 0, FALSE, FALSE }, + { "ps_2_sw", ST_PIXEL, 2, 0, 0, 0, TRUE, FALSE }, + { "ps_3_0", ST_PIXEL, 3, 0, 0, 0, FALSE, TRUE }, + { "ps_3_sw", ST_PIXEL, 3, 0, 0, 0, TRUE, FALSE }, + { "ps_4_0", ST_PIXEL, 4, 0, 0, 0, FALSE, TRUE }, + { "ps_4_0_level_9_0", ST_PIXEL, 4, 0, 9, 0, FALSE, FALSE }, + { "ps_4_0_level_9_1", ST_PIXEL, 4, 0, 9, 1, FALSE, FALSE }, + { "ps_4_0_level_9_3", ST_PIXEL, 4, 0, 9, 3, FALSE, FALSE }, + { "ps_4_1", ST_PIXEL, 4, 1, 0, 0, FALSE, TRUE }, + { "ps_5_0", ST_PIXEL, 5, 0, 0, 0, FALSE, TRUE }, + { "tx_1_0", ST_UNKNOWN, 1, 0, 0, 0, FALSE, FALSE }, + { "vs.1.0", ST_VERTEX, 1, 0, 0, 0, FALSE, TRUE }, + { "vs.1.1", ST_VERTEX, 1, 1, 0, 0, FALSE, TRUE }, + { "vs.2.0", ST_VERTEX, 2, 0, 0, 0, FALSE, TRUE }, + { "vs.2.a", ST_VERTEX, 2, 1, 0, 0, FALSE, FALSE }, + { "vs.2.sw", ST_VERTEX, 2, 0, 0, 0, TRUE, FALSE }, + { "vs.3.0", ST_VERTEX, 3, 0, 0, 0, FALSE, TRUE }, + { "vs.3.sw", ST_VERTEX, 3, 0, 0, 0, TRUE, FALSE }, + { "vs_1_0", ST_VERTEX, 1, 0, 0, 0, FALSE, TRUE }, + { "vs_1_1", ST_VERTEX, 1, 1, 0, 0, FALSE, TRUE }, + { "vs_2_0", ST_VERTEX, 2, 0, 0, 0, FALSE, TRUE }, + { "vs_2_a", ST_VERTEX, 2, 1, 0, 0, FALSE, FALSE }, + { "vs_2_sw", ST_VERTEX, 2, 0, 0, 0, TRUE, FALSE }, + { "vs_3_0", ST_VERTEX, 3, 0, 0, 0, FALSE, TRUE }, + { "vs_3_sw", ST_VERTEX, 3, 0, 0, 0, TRUE, FALSE }, + { "vs_4_0", ST_VERTEX, 4, 0, 0, 0, FALSE, TRUE }, + { "vs_4_0_level_9_0", ST_VERTEX, 4, 0, 9, 0, FALSE, FALSE }, + { "vs_4_0_level_9_1", ST_VERTEX, 4, 0, 9, 1, FALSE, FALSE }, + { "vs_4_0_level_9_3", ST_VERTEX, 4, 0, 9, 3, FALSE, FALSE }, + { "vs_4_1", ST_VERTEX, 4, 1, 0, 0, FALSE, TRUE }, + { "vs_5_0", ST_VERTEX, 5, 0, 0, 0, FALSE, TRUE }, +}; + +static const struct target_info * get_target_info(const char *target) +{ + LONG min = 0; + LONG max = sizeof(targets_info) / sizeof(targets_info[0]) - 1; + LONG cur; + int res; + + while (min <= max) + { + cur = (min + max) / 2; + res = strcmp(target, targets_info[cur].name); + if (res < 0) + max = cur - 1; + else if (res > 0) + min = cur + 1; + else + return &targets_info[cur]; + } + + return NULL; +} + static HRESULT compile_shader(const char *preproc_shader, const char *target, const char *entrypoint, ID3DBlob **shader_blob, ID3DBlob **error_messages) { @@ -500,38 +597,32 @@ static HRESULT compile_shader(const char *preproc_shader, const char *target, co ID3DBlob *buffer; char *pos; enum shader_type shader_type; + const struct target_info *info; TRACE("Preprocessed shader source: %s\n", debugstr_a(preproc_shader)); - TRACE("Parsing compilation target %s.\n", debugstr_a(target)); - if (strlen(target) != 6 || target[1] != 's' || target[2] != '_' || target[4] != '_') + TRACE("Checking compilation target %s\n", debugstr_a(target)); + info = get_target_info(target); + if (!info) { - FIXME("Unknown compilation target %s.\n", debugstr_a(target)); + FIXME("Unknown compilation target %s\n", debugstr_a(target)); return D3DERR_INVALIDCALL; } - - if (target[0] == 'v') - shader_type = ST_VERTEX; - else if (target[0] == 'p') - shader_type = ST_PIXEL; else { - FIXME("Unsupported shader target type %s.\n", debugstr_a(target)); - return D3DERR_INVALIDCALL; + if (!info->support) + { + FIXME("Compilation target %s not yet supported\n", debugstr_a(target)); + return D3DERR_INVALIDCALL; + } + else + { + shader_type = info->type; + major = info->sm_major; + minor = info->sm_minor; + } } - major = target[3] - '0'; - if (major == 0 || major > 5) - { - FIXME("Unsupported shader target major version %d.\n", major); - return D3DERR_INVALIDCALL; - } - minor = target[5] - '0'; - if (minor > 1 || (minor == 1 && (shader_type != ST_VERTEX || major > 1))) - { - FIXME("Unsupported shader target minor version %d.\n", minor); - return D3DERR_INVALIDCALL; - } shader = parse_hlsl_shader(preproc_shader, shader_type, major, minor, entrypoint, &messages); if (messages) diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index c8a92f1d3cb..d25b4e54d56 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -49,8 +49,9 @@ const char *debug_d3dcompiler_shader_variable_type(D3D_SHADER_VARIABLE_TYPE t) D enum shader_type { + ST_UNKNOWN, ST_VERTEX, - ST_PIXEL, + ST_PIXEL }; typedef enum BWRITER_COMPARISON_TYPE {