d3d1x: add shader signature to sm4_program
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 20 Oct 2011 16:37:07 +0000 (18:37 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 21 Oct 2011 21:00:36 +0000 (23:00 +0200)
Correct linkage requires examining the signature itself, it cannot
be reconstructed from declarations only since unused registers may
have been omitted from them.

src/gallium/state_trackers/d3d1x/d3d1xshader/include/dxbc.h
src/gallium/state_trackers/d3d1x/d3d1xshader/include/sm4.h
src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_parse.cpp
src/gallium/state_trackers/d3d1x/gd3d11/d3d11_misc.h
src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h

index 5c7c87e5e8e3c597ab7b330cbbb586490450c2a2..0343a67f8631ff2c14936c1849ee2b396b0ae148 100644 (file)
@@ -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;
index 1db6bab3a39cdb48e96e661fa3faea4ede360849..43627f7c0bacb2d8ff22a3fa0f8503e6940fab7c 100644 (file)
@@ -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();
index 4903e2c3b941bff8c96eb9962b3d876cee7392a2..05d10c19543293c38046def0b7d619eac962b0de 100644 (file)
@@ -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;
index 357f51bcb9ba5c7cedc4c7da77430dfda995c31a..85c694fdf15005f5e59ea85966fe252a37c6f939 100644 (file)
@@ -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;
 
index 617bd4350995741ec56cda117029b3af777d987a..33cea8380cda5823c71406c2aba1871f3e322d43 100644 (file)
@@ -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, &params);
 
@@ -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);