diff options
author | Christoph Bumiller <[email protected]> | 2011-10-20 18:37:07 +0200 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2011-10-21 23:00:36 +0200 |
commit | d2cc8aedb5d544608842b58b6ae4754313ded939 (patch) | |
tree | a3bb70799326a724755022518945a4971c40fa07 /src | |
parent | 47eb8a23eb03d885353442221ea24a8928d2c31a (diff) |
d3d1x: add shader signature to sm4_program
Correct linkage requires examining the signature itself, it cannot
be reconstructed from declarations only since unused registers may
have been omitted from them.
Diffstat (limited to 'src')
5 files changed, 52 insertions, 7 deletions
diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/include/dxbc.h b/src/gallium/state_trackers/d3d1x/d3d1xshader/include/dxbc.h index 5c7c87e5e8e..0343a67f863 100644 --- a/src/gallium/state_trackers/d3d1x/d3d1xshader/include/dxbc.h +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/include/dxbc.h @@ -41,6 +41,7 @@ #define FOURCC_SHDR FOURCC('S', 'H', 'D', 'R') #define FOURCC_SHEX FOURCC('S', 'H', 'E', 'X') #define FOURCC_STAT FOURCC('S', 'T', 'A', 'T') +#define FOURCC_PCSG FOURCC('P', 'C', 'S', 'G') /* this is always little-endian! */ struct dxbc_chunk_header @@ -98,9 +99,21 @@ static inline dxbc_chunk_header* dxbc_find_shader_bytecode(const void* data, int return chunk; } -static inline dxbc_chunk_signature* dxbc_find_signature(const void* data, int size, bool output) +#define DXBC_FIND_INPUT_SIGNATURE 0 +#define DXBC_FIND_OUTPUT_SIGNATURE 1 +#define DXBC_FIND_PATCH_SIGNATURE 2 + +static inline dxbc_chunk_signature* dxbc_find_signature(const void* data, int size, unsigned kind) { - return (dxbc_chunk_signature*)dxbc_find_chunk(data, size, output ? FOURCC_OSGN : FOURCC_ISGN); + unsigned fourcc; + switch(kind) { + case DXBC_FIND_INPUT_SIGNATURE: fourcc = FOURCC_ISGN; break; + case DXBC_FIND_OUTPUT_SIGNATURE: fourcc = FOURCC_OSGN; break; + case DXBC_FIND_PATCH_SIGNATURE: fourcc = FOURCC_PCSG; break; + default: + return NULL; + } + return (dxbc_chunk_signature*)dxbc_find_chunk(data, size, fourcc); } struct _D3D11_SIGNATURE_PARAMETER_DESC; diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/include/sm4.h b/src/gallium/state_trackers/d3d1x/d3d1xshader/include/sm4.h index 1db6bab3a39..43627f7c0ba 100644 --- a/src/gallium/state_trackers/d3d1x/d3d1xshader/include/sm4.h +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/include/sm4.h @@ -351,12 +351,21 @@ private: {} }; +struct _D3D11_SIGNATURE_PARAMETER_DESC; + struct sm4_program { sm4_token_version version; std::vector<sm4_dcl*> dcls; std::vector<sm4_insn*> insns; + _D3D11_SIGNATURE_PARAMETER_DESC* params_in; + _D3D11_SIGNATURE_PARAMETER_DESC* params_out; + _D3D11_SIGNATURE_PARAMETER_DESC* params_patch; + unsigned num_params_in; + unsigned num_params_out; + unsigned num_params_patch; + /* for ifs, the insn number of the else or endif if there is no else * for elses, the insn number of the endif * for endifs, the insn number of the if @@ -373,6 +382,7 @@ struct sm4_program { memset(&version, 0, sizeof(version)); labels_found = false; + num_params_in = num_params_out = num_params_patch = 0; } ~sm4_program() @@ -381,6 +391,13 @@ struct sm4_program delete *i; for(std::vector<sm4_insn*>::iterator i = insns.begin(), e = insns.end(); i != e; ++i) delete *i; + + if(num_params_in) + free(params_in); + if(num_params_out) + free(params_out); + if(num_params_patch) + free(params_patch); } void dump(); diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_parse.cpp b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_parse.cpp index 4903e2c3b94..05d10c19543 100644 --- a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_parse.cpp +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_parse.cpp @@ -78,6 +78,7 @@ int dxbc_parse_signature(dxbc_chunk_signature* sig, D3D11_SIGNATURE_PARAMETER_DE param.SemanticIndex = bswap_le32(sig->elements[i].semantic_index); param.SystemValueType = (D3D_NAME)bswap_le32(sig->elements[i].system_value_type); param.ComponentType = (D3D_REGISTER_COMPONENT_TYPE)bswap_le32(sig->elements[i].component_type); + param.Register = bswap_le32(sig->elements[i].register_num); param.Mask = sig->elements[i].mask; param.ReadWriteMask = sig->elements[i].read_write_mask; param.Stream = sig->elements[i].stream; diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_misc.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_misc.h index 357f51bcb9b..85c694fdf15 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_misc.h +++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_misc.h @@ -52,7 +52,7 @@ HRESULT D3D10GetInputSignatureBlob( ID3D10Blob **signature_blob ) { - dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode, bytecode_length, false); + dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_INPUT_SIGNATURE); if(!sig) return E_FAIL; @@ -65,7 +65,7 @@ HRESULT D3D10GetOutputSignatureBlob( ID3D10Blob **signature_blob ) { - dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode, bytecode_length, true); + dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_OUTPUT_SIGNATURE); if(!sig) return E_FAIL; @@ -79,10 +79,10 @@ HRESULT D3D10GetInputAndOutputSignatureBlob( ) { dxbc_chunk_signature* sigs[2]; - sigs[0] = dxbc_find_signature(shader_bytecode, bytecode_length, false); + sigs[0] = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_INPUT_SIGNATURE); if(!sigs[0]) return E_FAIL; - sigs[1] = dxbc_find_signature(shader_bytecode, bytecode_length, true); + sigs[1] = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_OUTPUT_SIGNATURE); if(!sigs[1]) return E_FAIL; diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h index 617bd435099..33cea8380cd 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h +++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h @@ -600,7 +600,7 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen // putting semantics matching in the core API seems to be a (minor) design mistake - struct dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode_with_input_signature, bytecode_length, false); + struct dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode_with_input_signature, bytecode_length, DXBC_FIND_INPUT_SIGNATURE); D3D11_SIGNATURE_PARAMETER_DESC* params; unsigned num_params = dxbc_parse_signature(sig, ¶ms); @@ -1211,6 +1211,20 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen if(dump) sm4->dump(); + struct dxbc_chunk_signature* sig; + + sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_INPUT_SIGNATURE); + if(sig) + sm4->num_params_in = dxbc_parse_signature(sig, &sm4->params_in); + + sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_OUTPUT_SIGNATURE); + if(sig) + sm4->num_params_out = dxbc_parse_signature(sig, &sm4->params_out); + + sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_PATCH_SIGNATURE); + if(sig) + sm4->num_params_patch = dxbc_parse_signature(sig, &sm4->params_patch); + struct pipe_shader_state tgsi_shader; memset(&tgsi_shader, 0, sizeof(tgsi_shader)); tgsi_shader.tokens = (const tgsi_token*)sm4_to_tgsi(*sm4); |