Ver código fonte

Container clipboard and XML serialization (#848)

* Add a tab for compilation options
* Add support to copy/view containers, and to paste them into shader ops.
Marcelo Lopez Ruiz 7 anos atrás
pai
commit
3c729a038d

Diferenças do arquivo suprimidas por serem muito extensas
+ 206 - 252
tools/clang/tools/dotnetc/EditorForm.Designer.cs


+ 26 - 9
tools/clang/tools/dotnetc/EditorForm.cs

@@ -187,6 +187,7 @@ namespace MainNs
         private void compileToolStripMenuItem_Click(object sender, EventArgs e)
         {
             this.CompileDocument();
+            this.AnalysisTabControl.SelectedTab = this.DisassemblyTabPage;
         }
 
         private void errorListToolStripMenuItem_Click(object sender, EventArgs e)
@@ -1225,7 +1226,16 @@ namespace MainNs
             RichTextBox rtb = this.DeepActiveControl as RichTextBox;
             if (rtb != null)
             {
-                rtb.Paste(DataFormats.GetFormat(DataFormats.UnicodeText));
+                // Handle the container format.
+                if (Clipboard.ContainsData(ContainerData.DataFormat.Name))
+                {
+                    object o = Clipboard.GetData(ContainerData.DataFormat.Name);
+                    rtb.SelectedText = ContainerData.DataObjectToString(o);
+                }
+                else
+                {
+                    rtb.Paste(DataFormats.GetFormat(DataFormats.UnicodeText));
+                }
                 return;
             }
             TextBoxBase tb = this.ActiveControl as TextBoxBase;
@@ -2095,16 +2105,23 @@ namespace MainNs
                 return;
             }
 
-            byte[] bytes;
-            unsafe
+            DisplayBitstream(ContainerData.BlobToBytes(this.SelectedShaderBlob), "Bitstream Viewer - Selected Shader");
+        }
+
+        private void bitstreamFromClipboardToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (!Clipboard.ContainsData(ContainerData.DataFormat.Name))
             {
-                char* pBuffer = this.SelectedShaderBlob.GetBufferPointer();
-                uint size = this.SelectedShaderBlob.GetBufferSize();
-                bytes = new byte[size];
-                IntPtr ptr = new IntPtr(pBuffer);
-                System.Runtime.InteropServices.Marshal.Copy(ptr, bytes, 0, (int)size);
+                MessageBox.Show(this, "No shader blob on clipboard. Try pasting from the optimizer view.");
+                return;
             }
 
+            DisplayBitstream(ContainerData.DataObjectToBytes(Clipboard.GetData(ContainerData.DataFormat.Name)),
+                "Bitstream Viewer - Clipboard");
+        }
+
+        private void DisplayBitstream(byte[] bytes, string title)
+        {
             StatusBar statusBar = new StatusBar();
             statusBar.Dock = DockStyle.Bottom;
 
@@ -2154,7 +2171,7 @@ namespace MainNs
             container.Dock = DockStyle.Fill;
 
             Form form = new Form();
-            form.Text = "Bitstream Viewer";
+            form.Text = title;
             form.Controls.Add(container);
             form.Controls.Add(statusBar);
             binaryView.Bytes = bytes;

+ 43 - 0
tools/clang/tools/dotnetc/EditorModels.cs

@@ -304,4 +304,47 @@ namespace MainNs
 
         #endregion Private methods.
     }
+
+    class ContainerData
+    {
+        public static System.Windows.Forms.DataFormats.Format DataFormat =
+            System.Windows.Forms.DataFormats.GetFormat("DXBC");
+
+        public static string BlobToBase64(IDxcBlob blob)
+        {
+            return System.Convert.ToBase64String(BlobToBytes(blob));
+        }
+
+        public static byte[] BlobToBytes(IDxcBlob blob)
+        {
+            byte[] bytes;
+            unsafe
+            {
+                char* pBuffer = blob.GetBufferPointer();
+                uint size = blob.GetBufferSize();
+                bytes = new byte[size];
+                IntPtr ptr = new IntPtr(pBuffer);
+                System.Runtime.InteropServices.Marshal.Copy(ptr, bytes, 0, (int)size);
+            }
+            return bytes;
+        }
+
+        public static byte[] DataObjectToBytes(object data)
+        {
+            System.IO.Stream stream = data as System.IO.Stream;
+            if (stream == null)
+                return null;
+            byte[] bytes = new byte[stream.Length];
+            stream.Read(bytes, 0, (int)stream.Length);
+            return bytes;
+        }
+
+        public static string DataObjectToString(object data)
+        {
+            byte[] bytes = DataObjectToBytes(data);
+            if (bytes == null)
+                return "";
+            return System.Convert.ToBase64String(bytes);
+        }
+    }
 }

+ 1 - 1
tools/clang/tools/dotnetc/HlslHost.cs

@@ -5,7 +5,7 @@
 // This file is distributed under the University of Illinois Open Source     //
 // License. See LICENSE.TXT for details.                                     //
 //                                                                           //
-// Provides support for working with an out-of-process rendering host.      //
+// Provides support for working with an out-of-process rendering host.       //
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 

+ 47 - 19
tools/clang/tools/dotnetc/OptEditorForm.Designer.cs

@@ -37,6 +37,7 @@
             this.DiffButton = new System.Windows.Forms.RadioButton();
             this.RightButton = new System.Windows.Forms.RadioButton();
             this.ApplyChangesButton = new System.Windows.Forms.Button();
+            this.CopyContainerButton = new System.Windows.Forms.Button();
             this.LogBox = new System.Windows.Forms.RichTextBox();
             ((System.ComponentModel.ISupportInitialize)(this.TopContainer)).BeginInit();
             this.TopContainer.Panel1.SuspendLayout();
@@ -53,6 +54,7 @@
             // 
             this.TopContainer.Dock = System.Windows.Forms.DockStyle.Fill;
             this.TopContainer.Location = new System.Drawing.Point(0, 0);
+            this.TopContainer.Margin = new System.Windows.Forms.Padding(6);
             this.TopContainer.Name = "TopContainer";
             // 
             // TopContainer.Panel1
@@ -62,17 +64,20 @@
             // TopContainer.Panel2
             // 
             this.TopContainer.Panel2.Controls.Add(this.WorkContainer);
-            this.TopContainer.Size = new System.Drawing.Size(697, 469);
-            this.TopContainer.SplitterDistance = 232;
+            this.TopContainer.Size = new System.Drawing.Size(1394, 902);
+            this.TopContainer.SplitterDistance = 464;
+            this.TopContainer.SplitterWidth = 8;
             this.TopContainer.TabIndex = 0;
             // 
             // PassesListBox
             // 
             this.PassesListBox.Dock = System.Windows.Forms.DockStyle.Fill;
             this.PassesListBox.FormattingEnabled = true;
+            this.PassesListBox.ItemHeight = 25;
             this.PassesListBox.Location = new System.Drawing.Point(0, 0);
+            this.PassesListBox.Margin = new System.Windows.Forms.Padding(6);
             this.PassesListBox.Name = "PassesListBox";
-            this.PassesListBox.Size = new System.Drawing.Size(232, 469);
+            this.PassesListBox.Size = new System.Drawing.Size(464, 902);
             this.PassesListBox.TabIndex = 0;
             this.PassesListBox.SelectedIndexChanged += new System.EventHandler(this.PassesListBox_SelectedIndexChanged);
             // 
@@ -81,6 +86,7 @@
             this.WorkContainer.Dock = System.Windows.Forms.DockStyle.Fill;
             this.WorkContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
             this.WorkContainer.Location = new System.Drawing.Point(0, 0);
+            this.WorkContainer.Margin = new System.Windows.Forms.Padding(6);
             this.WorkContainer.Name = "WorkContainer";
             this.WorkContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
             // 
@@ -92,16 +98,18 @@
             // WorkContainer.Panel2
             // 
             this.WorkContainer.Panel2.Controls.Add(this.LogBox);
-            this.WorkContainer.Size = new System.Drawing.Size(461, 469);
-            this.WorkContainer.SplitterDistance = 400;
+            this.WorkContainer.Size = new System.Drawing.Size(922, 902);
+            this.WorkContainer.SplitterDistance = 825;
+            this.WorkContainer.SplitterWidth = 8;
             this.WorkContainer.TabIndex = 0;
             // 
             // CodeBox
             // 
             this.CodeBox.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.CodeBox.Location = new System.Drawing.Point(0, 29);
+            this.CodeBox.Location = new System.Drawing.Point(0, 56);
+            this.CodeBox.Margin = new System.Windows.Forms.Padding(6);
             this.CodeBox.Name = "CodeBox";
-            this.CodeBox.Size = new System.Drawing.Size(461, 371);
+            this.CodeBox.Size = new System.Drawing.Size(922, 769);
             this.CodeBox.TabIndex = 1;
             this.CodeBox.Text = "";
             this.CodeBox.SelectionChanged += new System.EventHandler(this.CodeBox_SelectionChanged);
@@ -115,18 +123,21 @@
             this.flowLayoutPanel1.Controls.Add(this.DiffButton);
             this.flowLayoutPanel1.Controls.Add(this.RightButton);
             this.flowLayoutPanel1.Controls.Add(this.ApplyChangesButton);
+            this.flowLayoutPanel1.Controls.Add(this.CopyContainerButton);
             this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top;
             this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
+            this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(6);
             this.flowLayoutPanel1.Name = "flowLayoutPanel1";
-            this.flowLayoutPanel1.Size = new System.Drawing.Size(461, 29);
+            this.flowLayoutPanel1.Size = new System.Drawing.Size(922, 56);
             this.flowLayoutPanel1.TabIndex = 0;
             // 
             // LeftButton
             // 
             this.LeftButton.AutoSize = true;
-            this.LeftButton.Location = new System.Drawing.Point(3, 3);
+            this.LeftButton.Location = new System.Drawing.Point(6, 6);
+            this.LeftButton.Margin = new System.Windows.Forms.Padding(6);
             this.LeftButton.Name = "LeftButton";
-            this.LeftButton.Size = new System.Drawing.Size(43, 17);
+            this.LeftButton.Size = new System.Drawing.Size(79, 29);
             this.LeftButton.TabIndex = 0;
             this.LeftButton.Text = "Left";
             this.LeftButton.UseVisualStyleBackColor = true;
@@ -136,9 +147,10 @@
             // 
             this.DiffButton.AutoSize = true;
             this.DiffButton.Checked = true;
-            this.DiffButton.Location = new System.Drawing.Point(52, 3);
+            this.DiffButton.Location = new System.Drawing.Point(97, 6);
+            this.DiffButton.Margin = new System.Windows.Forms.Padding(6);
             this.DiffButton.Name = "DiffButton";
-            this.DiffButton.Size = new System.Drawing.Size(41, 17);
+            this.DiffButton.Size = new System.Drawing.Size(75, 29);
             this.DiffButton.TabIndex = 1;
             this.DiffButton.TabStop = true;
             this.DiffButton.Text = "Diff";
@@ -148,9 +160,10 @@
             // RightButton
             // 
             this.RightButton.AutoSize = true;
-            this.RightButton.Location = new System.Drawing.Point(99, 3);
+            this.RightButton.Location = new System.Drawing.Point(184, 6);
+            this.RightButton.Margin = new System.Windows.Forms.Padding(6);
             this.RightButton.Name = "RightButton";
-            this.RightButton.Size = new System.Drawing.Size(50, 17);
+            this.RightButton.Size = new System.Drawing.Size(93, 29);
             this.RightButton.TabIndex = 2;
             this.RightButton.Text = "Right";
             this.RightButton.UseVisualStyleBackColor = true;
@@ -159,29 +172,43 @@
             // ApplyChangesButton
             // 
             this.ApplyChangesButton.Enabled = false;
-            this.ApplyChangesButton.Location = new System.Drawing.Point(155, 3);
+            this.ApplyChangesButton.Location = new System.Drawing.Point(289, 6);
+            this.ApplyChangesButton.Margin = new System.Windows.Forms.Padding(6);
             this.ApplyChangesButton.Name = "ApplyChangesButton";
-            this.ApplyChangesButton.Size = new System.Drawing.Size(98, 23);
+            this.ApplyChangesButton.Size = new System.Drawing.Size(196, 44);
             this.ApplyChangesButton.TabIndex = 3;
             this.ApplyChangesButton.Text = "Apply Changes";
             this.ApplyChangesButton.UseVisualStyleBackColor = true;
             this.ApplyChangesButton.Click += new System.EventHandler(this.ApplyChangesButton_Click);
             // 
+            // CopyContainerButton
+            // 
+            this.CopyContainerButton.Location = new System.Drawing.Point(497, 6);
+            this.CopyContainerButton.Margin = new System.Windows.Forms.Padding(6);
+            this.CopyContainerButton.Name = "CopyContainerButton";
+            this.CopyContainerButton.Size = new System.Drawing.Size(196, 44);
+            this.CopyContainerButton.TabIndex = 4;
+            this.CopyContainerButton.Text = "Copy Container";
+            this.CopyContainerButton.UseVisualStyleBackColor = true;
+            this.CopyContainerButton.Click += new System.EventHandler(this.CopyContainerButton_Click);
+            // 
             // LogBox
             // 
             this.LogBox.Dock = System.Windows.Forms.DockStyle.Fill;
             this.LogBox.Location = new System.Drawing.Point(0, 0);
+            this.LogBox.Margin = new System.Windows.Forms.Padding(6);
             this.LogBox.Name = "LogBox";
-            this.LogBox.Size = new System.Drawing.Size(461, 65);
+            this.LogBox.Size = new System.Drawing.Size(922, 69);
             this.LogBox.TabIndex = 0;
             this.LogBox.Text = "";
             // 
             // OptEditorForm
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(697, 469);
+            this.ClientSize = new System.Drawing.Size(1394, 902);
             this.Controls.Add(this.TopContainer);
+            this.Margin = new System.Windows.Forms.Padding(6);
             this.Name = "OptEditorForm";
             this.Text = "Optimizer Editor";
             this.Load += new System.EventHandler(this.OptEditorForm_Load);
@@ -212,5 +239,6 @@
         private System.Windows.Forms.Button ApplyChangesButton;
         private System.Windows.Forms.RichTextBox CodeBox;
         private System.Windows.Forms.RichTextBox LogBox;
+        private System.Windows.Forms.Button CopyContainerButton;
     }
 }

+ 26 - 0
tools/clang/tools/dotnetc/OptEditorForm.cs

@@ -140,6 +140,32 @@ namespace MainNs
         {
             EditorForm.HandleCodeSelectionChanged(this.CodeBox, null);
         }
+
+        private void CopyContainerButton_Click(object sender, EventArgs e)
+        {
+            // The intent is to copy compiled code (possibly customized) into the
+            // clipboard so it can be pasted into an XML file to be run interactively.
+
+            var text = this.CodeBox.Text;
+            var source = EditorForm.CreateBlobForText(this.Library, text);
+            var assembler = HlslDxcLib.CreateDxcAssembler();
+            var assembleResult = assembler.AssembleToContainer(source);
+            if (assembleResult.GetStatus() < 0)
+            {
+                var errors = assembleResult.GetErrors();
+                MessageBox.Show(EditorForm.GetStringFromBlob(this.Library, errors));
+                return;
+            }
+            var container = assembleResult.GetResult();
+
+            // Now copy that to the clipboard.
+            var bytes = ContainerData.BlobToBytes(container);
+            var stream = new System.IO.MemoryStream(bytes);
+            var dataObj = new DataObject();
+            dataObj.SetData(ContainerData.DataFormat.Name, stream);
+            dataObj.SetText(text);
+            Clipboard.SetDataObject(dataObj, true);
+        }
     }
 
     public class TextSection

+ 18 - 2
tools/clang/unittests/HLSL/ShaderOpTest.cpp

@@ -15,6 +15,7 @@
 #include <D3dx12.h>
 #include <d3dcompiler.h>
 #include <atlbase.h>
+#include <atlenc.h>
 
 #include "ShaderOpTest.h"
 
@@ -650,7 +651,21 @@ void ShaderOpTest::CreateShaders() {
     CComPtr<ID3DBlob> pCode;
     HRESULT hr = S_OK;
     LPCSTR pText = m_pShaderOp->GetShaderText(&S);
-    if (TargetUsesDxil(S.Target)) {
+    if (S.Compiled) {
+      int textLen = (int)strlen(pText);
+      int decodedLen = Base64DecodeGetRequiredLength(textLen);
+      // Length is an approximation, so we can't creat the final blob yet.
+      std::vector<BYTE> decoded;
+      decoded.resize(decodedLen);
+      if (!Base64Decode(pText, textLen, decoded.data(), &decodedLen)) {
+        ShaderOpLogFmt(L"Failed to decode compiled shader: %S\r\n", S.Name);
+        CHECK_HR(E_FAIL);
+      }
+      // decodedLen should have the correct size now.
+      CHECK_HR(D3DCreateBlob(decodedLen, &pCode));
+      memcpy(pCode->GetBufferPointer(), decoded.data(), decodedLen);
+    }
+    else if (TargetUsesDxil(S.Target)) {
       CComPtr<IDxcCompiler> pCompiler;
       CComPtr<IDxcLibrary> pLibrary;
       CComPtr<IDxcBlobEncoding> pTextBlob;
@@ -2038,7 +2053,8 @@ void ShaderOpParser::ParseShader(IXmlReader *pReader, ShaderOpShader *pShader) {
   CHECK_HR(ReadAttrStr(pReader, L"Name", &pShader->Name));
   CHECK_HR(ReadAttrStr(pReader, L"EntryPoint", &pShader->EntryPoint));
   CHECK_HR(ReadAttrStr(pReader, L"Target", &pShader->Target));
-  CHECK_HR(ReadAttrStr(pReader, L"Arguments", &pShader->Arguments))
+  CHECK_HR(ReadAttrStr(pReader, L"Arguments", &pShader->Arguments));
+  CHECK_HR(ReadAttrBOOL(pReader, L"Compiled", &pShader->Compiled))
 
   ReadElementContentStr(pReader, &pShader->Text);
   bool hasText = pShader->Text && *pShader->Text;

+ 1 - 0
tools/clang/unittests/HLSL/ShaderOpTest.h

@@ -154,6 +154,7 @@ public:
   LPCSTR  Text;       // HLSL Shader Text.
   LPCSTR  Arguments;  // Command line Arguments.
   LPCSTR  Defines;    // HLSL Defines.
+  BOOL    Compiled;   // Whether text is a base64-encoded value.
 };
 
 // Use this class to represent a value in the root signature.

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff