Kaynağa Gözat

ContainerAssembler and Validation fixes.

- zero DxilProgramSignatureElement to prevent garbage in signature
- rewrite bitcode when stripping root signature
- use correct part when reading debug module in ValidateDxilContainer
- report general error message when signature validation fails
Tex Riddell 8 yıl önce
ebeveyn
işleme
a3e0b5828d

+ 11 - 5
lib/HLSL/DxilContainerAssembler.cpp

@@ -174,6 +174,7 @@ private:
       eltRows = pElement->GetRows() / eltCount;
       eltRows = pElement->GetRows() / eltCount;
 
 
     DxilProgramSignatureElement sig;
     DxilProgramSignatureElement sig;
+    memset(&sig, 0, sizeof(DxilProgramSignatureElement));
     sig.Stream = pElement->GetOutputStream();
     sig.Stream = pElement->GetOutputStream();
     sig.SemanticName = GetSemanticOffset(pElement);
     sig.SemanticName = GetSemanticOffset(pElement);
     sig.SystemValue = KindToSystemValue(pElement->GetKind(), m_domain);
     sig.SystemValue = KindToSystemValue(pElement->GetKind(), m_domain);
@@ -615,8 +616,6 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
   DXASSERT_NOMSG(pModuleBitcode != nullptr);
   DXASSERT_NOMSG(pModuleBitcode != nullptr);
   DXASSERT_NOMSG(pFinalStream != nullptr);
   DXASSERT_NOMSG(pFinalStream != nullptr);
 
 
-  CComPtr<AbstractMemoryStream> pProgramStream;
-
   DxilProgramSignatureWriter inputSigWriter(pModule->GetInputSignature(),
   DxilProgramSignatureWriter inputSigWriter(pModule->GetInputSignature(),
                                             pModule->GetTessellatorDomain(),
                                             pModule->GetTessellatorDomain(),
                                             /*IsInput*/ true);
                                             /*IsInput*/ true);
@@ -658,20 +657,27 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
 
 
   // Write the root signature (RTS0) part.
   // Write the root signature (RTS0) part.
   DxilProgramRootSignatureWriter rootSigWriter(pModule->GetRootSignature());
   DxilProgramRootSignatureWriter rootSigWriter(pModule->GetRootSignature());
+  CComPtr<AbstractMemoryStream> pInputProgramStream = pModuleBitcode;
   if (!pModule->GetRootSignature().IsEmpty()) {
   if (!pModule->GetRootSignature().IsEmpty()) {
     writer.AddPart(
     writer.AddPart(
         DFCC_RootSignature, rootSigWriter.size(),
         DFCC_RootSignature, rootSigWriter.size(),
         [&](AbstractMemoryStream *pStream) { rootSigWriter.write(pStream); });
         [&](AbstractMemoryStream *pStream) { rootSigWriter.write(pStream); });
     pModule->StripRootSignatureFromMetadata();
     pModule->StripRootSignatureFromMetadata();
+    pInputProgramStream.Release();
+    CComPtr<IMalloc> pMalloc;
+    IFT(CoGetMalloc(1, &pMalloc));
+    IFT(CreateMemoryStream(pMalloc, &pInputProgramStream));
+    raw_stream_ostream outStream(pInputProgramStream.p);
+    WriteBitcodeToFile(pModule->GetModule(), outStream, true);
   }
   }
 
 
   // If we have debug information present, serialize it to a debug part, then use the stripped version as the canonical program version.
   // If we have debug information present, serialize it to a debug part, then use the stripped version as the canonical program version.
-  pProgramStream = pModuleBitcode;
+  CComPtr<AbstractMemoryStream> pProgramStream = pInputProgramStream;
   if (HasDebugInfo(*pModule->GetModule())) {
   if (HasDebugInfo(*pModule->GetModule())) {
     uint32_t debugInUInt32, debugPaddingBytes;
     uint32_t debugInUInt32, debugPaddingBytes;
-    GetPaddedProgramPartSize(pModuleBitcode, debugInUInt32, debugPaddingBytes);
+    GetPaddedProgramPartSize(pInputProgramStream, debugInUInt32, debugPaddingBytes);
     writer.AddPart(DFCC_ShaderDebugInfoDXIL, debugInUInt32 * sizeof(uint32_t) + sizeof(DxilProgramHeader), [&](AbstractMemoryStream *pStream) {
     writer.AddPart(DFCC_ShaderDebugInfoDXIL, debugInUInt32 * sizeof(uint32_t) + sizeof(DxilProgramHeader), [&](AbstractMemoryStream *pStream) {
-      WriteProgramPart(pModule->GetShaderModel(), pModuleBitcode, pStream);
+      WriteProgramPart(pModule->GetShaderModel(), pInputProgramStream, pStream);
     });
     });
 
 
     pProgramStream.Release();
     pProgramStream.Release();

+ 1 - 1
lib/HLSL/DxilValidation.cpp

@@ -4419,7 +4419,7 @@ HRESULT ValidateDxilContainer(const void *pContainer,
 
 
   if (pDbgPart) {
   if (pDbgPart) {
     GetDxilProgramBitcode(
     GetDxilProgramBitcode(
-      reinterpret_cast<const DxilProgramHeader *>(GetDxilPartData(pPart)),
+      reinterpret_cast<const DxilProgramHeader *>(GetDxilPartData(pDbgPart)),
       &pIL, &ILLength);
       &pIL, &ILLength);
     if (FAILED(hr = ValidateLoadModule(pIL, ILLength, pDebugModule, DbgCtx, DiagStream))) {
     if (FAILED(hr = ValidateLoadModule(pIL, ILLength, pDebugModule, DbgCtx, DiagStream))) {
       return hr;
       return hr;

+ 5 - 1
tools/clang/tools/dxcompiler/dxcvalidator.cpp

@@ -156,7 +156,11 @@ HRESULT DxcValidator::ValidateWithOptModules(
     } else {
     } else {
       validationStatus = RunValidation(pShader, pModule, pDebugModule, pDiagStream);
       validationStatus = RunValidation(pShader, pModule, pDebugModule, pDiagStream);
     }
     }
-
+    if (FAILED(validationStatus)) {
+      std::string msg("Validation failed.\n");
+      ULONG cbWritten;
+      pDiagStream->Write(msg.c_str(), msg.size(), &cbWritten);
+    }
     // Assemble the result object.
     // Assemble the result object.
     CComPtr<IDxcBlob> pDiagBlob;
     CComPtr<IDxcBlob> pDiagBlob;
     CComPtr<IDxcBlobEncoding> pDiagBlobEnconding;
     CComPtr<IDxcBlobEncoding> pDiagBlobEnconding;