/// <summary> /// コンスタントバッファ解決 /// </summary> /// <param name="reflection"></param> private void ResolveConstantBuffer(ShaderReflection reflection) { // すべてのコンスタントバッファを名前で辞書化する if (constantBufferObjects_ == null) { constantBufferObjects_ = new List <ConstantBufferObject>(); } var list = reflection.GetConstantBufferNameList(); foreach (var n in list) { int bind_index = 0; if (reflection.FindConstantBufferByName(n, out bind_index)) { if (!constantBufferDictionary_.ContainsKey(n)) { var obj = new ConstantBufferObject(); obj.name_ = n; obj.isSystem_ = false; obj.inst_ = reflection.CreateConstantBufferInstance(n); BufferDescription buffer_desc = new BufferDescription(); buffer_desc.Usage = ResourceUsage.Default; buffer_desc.CpuAccessFlags = CpuAccessFlags.None; buffer_desc.BindFlags = BindFlags.ConstantBuffer; buffer_desc.SizeInBytes = obj.inst_.BufferSize; obj.buffer_ = new D3D11Buffer(GraphicsCore.D3D11Device, buffer_desc); constantBufferDictionary_[n] = obj; } // システムのCBufferか? if (SystemCBufferNameList.Contains(n)) { int index = 0; foreach (string s in SystemCBufferNameList) { if (s == n) { break; } index++; } cbufferBindFlag_ |= 1u << index; constantBufferDictionary_[n].isSystem_ = true; } constantBufferObjects_.Add(constantBufferDictionary_[n]); nativeCBuffers_[bind_index] = constantBufferDictionary_[n].buffer_; if (cbufferNum_ < (bind_index + 1)) { cbufferNum_ = bind_index + 1; } } } }
/// <summary> /// 初期化 /// </summary> /// <param name="data"></param> public void Initialize(byte[] data) { var device = GraphicsCore.D3D11Device; // byte配列からポインタを取得 var handle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr ptr = handle.AddrOfPinnedObject(); BinaryHeader header = (BinaryHeader)Marshal.PtrToStructure(ptr, typeof(BinaryHeader)); IntPtr vs_ptr = ptr + (int)header.vs_offset; IntPtr ps_ptr = ptr + (int)header.ps_offset; name_ = "0x" + header.id.ToString("x8"); shaderId_ = header.id; // 頂点シェーダ using (ShaderBytecode bytecode = new ShaderBytecode(new SlimDX.DataStream(vs_ptr, header.vs_size, true, false))) { vertexShader_ = new VertexShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { // レイアウト生成 vertexAttr_ = reflect.GetVertexLayoutAttribute(); int layout_id = Shader.GetVertexLayoutID(vertexAttr_); inputLayout_ = new InputLayout(device, bytecode, sLayoutList[layout_id]); // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } // ピクセルシェーダ using (ShaderBytecode bytecode = new ShaderBytecode(new SlimDX.DataStream(ps_ptr, header.ps_size, true, false))) { pixelShader_ = new PixelShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } // ハンドル解放 handle.Free(); Initilaized = true; }
/// <summary> /// 生成 /// </summary> /// <param name="desc"></param> public ComputeShader(InitDesc desc) { var device = GraphicsCore.D3D11Device; var inc = new ShaderIncludeHandler(System.IO.Path.GetDirectoryName(desc.file_name)); using (var bytecode = ShaderBytecode.CompileFromFile(desc.file_name, desc.main, "cs_5_0", ShaderFlags.None, EffectFlags.None, desc.macro, inc)) { shader_ = new D3DComputeShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { // コンスタントバッファ解決 cbInst_ = reflect.CreateConstantBufferInstance("CB"); // 現状名前固定 if (cbInst_ != null) { BufferDescription buffer_desc = new BufferDescription(); buffer_desc.Usage = ResourceUsage.Default; buffer_desc.CpuAccessFlags = CpuAccessFlags.None; buffer_desc.BindFlags = BindFlags.ConstantBuffer; buffer_desc.SizeInBytes = cbInst_.BufferSize; constantBuffer_ = new D3D11Buffer(GraphicsCore.D3D11Device, buffer_desc); } } } }
/// <summary> /// 初期化 /// </summary> /// <param name="data"></param> public void Initialize(InitDesc desc) { var device = GraphicsCore.D3D11Device; shaderId_ = desc.id; name_ = desc.name; if (desc.file_name != null) { // ファイルから生成 // バイナリキャッシング string cacheDir = System.IO.Path.GetDirectoryName(desc.file_name) + "/cache"; if (!System.IO.Directory.Exists(cacheDir)) { System.IO.Directory.CreateDirectory(cacheDir); } string cacheFile = cacheDir + "/" + desc.name + "_" + desc.vs_main + "_" + desc.ps_main; string vsCacheFile = cacheFile + ".vsc"; string psCacheFile = cacheFile + ".psc"; // 頂点シェーダキャッシュ読み取り ShaderBytecode vsBytecode = null; if (System.IO.File.Exists(vsCacheFile)) { DateTime cacheTime = System.IO.File.GetLastWriteTime(vsCacheFile); DateTime editTime = System.IO.File.GetLastWriteTime(desc.file_name); if (cacheTime > editTime) { System.IO.FileStream stream = new System.IO.FileStream(vsCacheFile, FileMode.Open); var bytes = new byte[stream.Length]; stream.Read(bytes, 0, (int)stream.Length); vsBytecode = new ShaderBytecode(new SlimDX.DataStream(bytes, true, false)); } } // キャッシュになければコンパイルして生成 ShaderIncludeHandler inc = null; if (vsBytecode == null) { inc = new ShaderIncludeHandler(System.IO.Path.GetDirectoryName(desc.file_name)); vsBytecode = ShaderBytecode.CompileFromFile(desc.file_name, desc.vs_main, "vs_" + desc.profile, ShaderFlags.None, EffectFlags.None, desc.macro, inc); // キャッシュファイル保存 System.IO.FileStream stream = new System.IO.FileStream(vsCacheFile, FileMode.Create); vsBytecode.Data.CopyTo(stream); stream.Close(); } using (vsBytecode) { vertexShader_ = new VertexShader(device, vsBytecode); using (ShaderReflection reflect = new ShaderReflection(vsBytecode)) { vertexAttr_ = reflect.GetVertexLayoutAttribute(); int layout_id = Shader.GetVertexLayoutID(vertexAttr_); var signeture = ShaderSignature.GetInputSignature(vsBytecode); inputLayout_ = new InputLayout(device, signeture, sLayoutList[layout_id]); signeture.Dispose(); // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } // ピクセルシェーダキャッシュ読み取り if (desc.ps_main != null) { ShaderBytecode psBytecode = null; if (System.IO.File.Exists(psCacheFile)) { DateTime cacheTime = System.IO.File.GetLastWriteTime(psCacheFile); DateTime editTime = System.IO.File.GetLastWriteTime(desc.file_name); if (cacheTime > editTime) { System.IO.FileStream stream = new System.IO.FileStream(psCacheFile, FileMode.Open); var bytes = new byte[stream.Length]; stream.Read(bytes, 0, (int)stream.Length); psBytecode = new ShaderBytecode(new SlimDX.DataStream(bytes, true, false)); } } if (psBytecode == null) { if (inc == null) { inc = new ShaderIncludeHandler(System.IO.Path.GetDirectoryName(desc.file_name)); } psBytecode = ShaderBytecode.CompileFromFile(desc.file_name, desc.ps_main, "ps_" + desc.profile, ShaderFlags.None, EffectFlags.None, desc.macro, inc); // キャッシュファイル保存 System.IO.FileStream stream = new System.IO.FileStream(psCacheFile, FileMode.Create); psBytecode.Data.CopyTo(stream); stream.Close(); } using (psBytecode) { pixelShader_ = new PixelShader(device, psBytecode); using (ShaderReflection reflect = new ShaderReflection(psBytecode)) { // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } } } else { // stringから生成 // 頂点シェーダ using (var bytecode = ShaderBytecode.Compile(desc.vs_string, desc.vs_main, "vs_" + desc.profile, ShaderFlags.None, EffectFlags.None)) { vertexShader_ = new VertexShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { vertexAttr_ = reflect.GetVertexLayoutAttribute(); int layout_id = Shader.GetVertexLayoutID(vertexAttr_); var signeture = ShaderSignature.GetInputSignature(bytecode); inputLayout_ = new InputLayout(device, signeture, sLayoutList[layout_id]); signeture.Dispose(); // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } // ピクセルシェーダ if (desc.ps_main != null) { using (var bytecode = ShaderBytecode.Compile(desc.ps_string, desc.ps_main, "ps_" + desc.profile, ShaderFlags.None, EffectFlags.None)) { pixelShader_ = new PixelShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } } } Initilaized = true; }