From e5c4008cfb518705fb58b611ba56427a028b0aaf Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 17 Nov 2015 21:29:54 -1000 Subject: [PATCH] git add of HLSL sources.. derp --- hecl/include/HECL/Backend/HLSL.hpp | 37 +++ hecl/lib/Backend/HLSL.cpp | 490 +++++++++++++++++++++++++++++ 2 files changed, 527 insertions(+) create mode 100644 hecl/include/HECL/Backend/HLSL.hpp create mode 100644 hecl/lib/Backend/HLSL.cpp diff --git a/hecl/include/HECL/Backend/HLSL.hpp b/hecl/include/HECL/Backend/HLSL.hpp new file mode 100644 index 000000000..6f08366e5 --- /dev/null +++ b/hecl/include/HECL/Backend/HLSL.hpp @@ -0,0 +1,37 @@ +#ifndef HECLBACKEND_HLSL_HPP +#define HECLBACKEND_HLSL_HPP + +#include "ProgrammableCommon.hpp" + +namespace HECL +{ +namespace Backend +{ + +struct HLSL : ProgrammableCommon +{ + void reset(const IR& ir, Diagnostics& diag); + std::string makeVert(unsigned col, unsigned uv, unsigned w, + unsigned skinSlots, unsigned texMtxs) const; + std::string makeFrag(const ShaderFunction& lighting=ShaderFunction()) const; + std::string makeFrag(const ShaderFunction& lighting, + const ShaderFunction& post) const; + +private: + std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; + std::string GenerateVertToFragStruct() const; + std::string GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const; + + std::string EmitVec3(const atVec4f& vec) const + { + return HECL::Format("float3(%g,%g,%g)", vec.vec[0], vec.vec[1], vec.vec[2]); + } + + std::string EmitTexGenSource2(TexGenSrc src, int uvIdx) const; + std::string EmitTexGenSource4(TexGenSrc src, int uvIdx) const; +}; + +} +} + +#endif // HECLBACKEND_HLSL_HPP diff --git a/hecl/lib/Backend/HLSL.cpp b/hecl/lib/Backend/HLSL.cpp new file mode 100644 index 000000000..f415a89da --- /dev/null +++ b/hecl/lib/Backend/HLSL.cpp @@ -0,0 +1,490 @@ +#include "HECL/Backend/HLSL.hpp" +#include "HECL/Runtime.hpp" +#include +#include +#include + +static LogVisor::LogModule Log("HECL::Backend::HLSL"); + +namespace HECL +{ +namespace Backend +{ + +std::string HLSL::EmitTexGenSource2(TexGenSrc src, int uvIdx) const +{ + switch (src) + { + case TG_POS: + return "v.posIn.xy\n"; + case TG_NRM: + return "v.normIn.xy\n"; + case TG_UV: + return HECL::Format("v.uvIn[%u]", uvIdx); + default: break; + } + return std::string(); +} + +std::string HLSL::EmitTexGenSource4(TexGenSrc src, int uvIdx) const +{ + switch (src) + { + case TG_POS: + return "float4(v.posIn, 1.0)\n"; + case TG_NRM: + return "float4(v.normIn, 1.0)\n"; + case TG_UV: + return HECL::Format("float4(v.uvIn[%u], 0.0, 1.0)", uvIdx); + default: break; + } + return std::string(); +} + +std::string HLSL::GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const +{ + std::string retval = + "struct VertData\n" + "{\n" + " float3 posIn : POSITION;\n" + " float3 normIn : NORMAL;\n"; + + if (col) + retval += HECL::Format(" float4 colIn[%u] : COLOR;\n", col); + + if (uv) + retval += HECL::Format(" float2 uvIn[%u] : UV;\n", uv); + + if (w) + retval += HECL::Format(" float4 weightIn[%u] : WEIGHT;\n", w); + + return retval + "};\n"; +} + +std::string HLSL::GenerateVertToFragStruct() const +{ + std::string retval = + "struct VertToFrag\n" + "{\n" + " float4 mvpPos : SV_Position;\n" + " float4 mvPos : POSITION;\n" + " float4 mvNorm : NORMAL;\n"; + + if (m_tcgs.size()) + retval += HECL::Format(" float2 tcgs[%u] : UV;\n", unsigned(m_tcgs.size())); + + return retval + "};\n"; +} + +std::string HLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const +{ + if (skinSlots == 0) + skinSlots = 1; + std::string retval = HECL::Format("cbuffer HECLVertUniform : register(b0)\n" + "{\n" + " float4x4 mv[%u];\n" + " float4x4 mvInv[%u];\n" + " float4x4 proj;\n", + skinSlots, skinSlots); + if (texMtxs) + retval += HECL::Format(" float4x4 texMtxs[%u];\n", texMtxs); + return retval + "};\n"; +} + +void HLSL::reset(const IR& ir, Diagnostics& diag) +{ + /* Common programmable interpretation */ + ProgrammableCommon::reset(ir, diag, "HLSL"); +} + +std::string HLSL::makeVert(unsigned col, unsigned uv, unsigned w, + unsigned s, unsigned tm) const +{ + std::string retval = + GenerateVertInStruct(col, uv, w) + "\n" + + GenerateVertToFragStruct() + "\n" + + GenerateVertUniformStruct(s, tm) + "\n" + + "VertToFrag main(in VertData v)\n" + "{\n" + " VertToFrag vtf;\n"; + + if (s) + { + /* skinned */ + retval += " vec4 posAccum = float4(0.0,0.0,0.0,0.0);\n" + " vec4 normAccum = float4(0.0,0.0,0.0,0.0);\n"; + for (size_t i=0 ; i(gfxFactory)) {} + + ShaderCachedData buildShaderFromIR(const ShaderTag& tag, + const HECL::Frontend::IR& ir, + HECL::Frontend::Diagnostics& diag, + boo::IShaderPipeline** objOut) + { + m_backend.reset(ir, diag); + + std::string vertSource = + m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), + tag.getSkinSlotCount(), tag.getTexMtxCount()); + + std::string fragSource = m_backend.makeFrag(); + ComPtr vertBlob; + ComPtr fragBlob; + ComPtr pipelineBlob; + *objOut = + m_gfxFactory->newShaderPipeline(vertSource.c_str(), fragSource.c_str(), + vertBlob, fragBlob, pipelineBlob, + tag.newVertexFormat(m_gfxFactory), + m_backend.m_blendSrc, m_backend.m_blendDst, + tag.getDepthTest(), tag.getDepthWrite(), + tag.getBackfaceCulling()); + if (!*objOut) + Log.report(LogVisor::FatalError, "unable to build shader"); + + atUint32 vertSz = 0; + atUint32 fragSz = 0; + atUint32 pipelineSz = 0; + if (vertBlob) + vertSz = vertBlob->GetBufferSize(); + if (fragBlob) + fragSz = fragBlob->GetBufferSize(); + if (pipelineBlob) + pipelineSz = pipelineBlob->GetBufferSize(); + + size_t cachedSz = 14 + vertSz + fragSz + pipelineSz; + + ShaderCachedData dataOut(tag, cachedSz); + Athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz); + w.writeUByte(m_backend.m_blendSrc); + w.writeUByte(m_backend.m_blendDst); + + if (vertBlob) + { + w.writeUint32Big(vertSz); + w.writeUBytes((atUint8*)vertBlob->GetBufferPointer(), vertSz); + } + else + w.writeUint32Big(0); + + if (fragBlob) + { + w.writeUint32Big(fragSz); + w.writeUBytes((atUint8*)fragBlob->GetBufferPointer(), fragSz); + } + else + w.writeUint32Big(0); + + if (pipelineBlob) + { + w.writeUint32Big(pipelineSz); + w.writeUBytes((atUint8*)pipelineBlob->GetBufferPointer(), pipelineSz); + } + else + w.writeUint32Big(0); + + return dataOut; + } + + boo::IShaderPipeline* buildShaderFromCache(const ShaderCachedData& data) + { + const ShaderTag& tag = data.m_tag; + Athena::io::MemoryReader r(data.m_data.get(), data.m_sz); + boo::BlendFactor blendSrc = boo::BlendFactor(r.readUByte()); + boo::BlendFactor blendDst = boo::BlendFactor(r.readUByte()); + + atUint32 vertSz = r.readUint32Big(); + ComPtr vertBlob; + if (vertSz) + { + D3DCreateBlobPROC(vertSz, &vertBlob); + r.readUBytesToBuf(vertBlob->GetBufferPointer(), vertSz); + } + + atUint32 fragSz = r.readUint32Big(); + ComPtr fragBlob; + if (fragSz) + { + D3DCreateBlobPROC(fragSz, &fragBlob); + r.readUBytesToBuf(fragBlob->GetBufferPointer(), fragSz); + } + + atUint32 pipelineSz = r.readUint32Big(); + ComPtr pipelineBlob; + if (pipelineSz) + { + D3DCreateBlobPROC(pipelineSz, &pipelineBlob); + r.readUBytesToBuf(pipelineBlob->GetBufferPointer(), pipelineSz); + } + + boo::IShaderPipeline* ret = + m_gfxFactory->newShaderPipeline(nullptr, nullptr, + vertBlob, fragBlob, pipelineBlob, + tag.newVertexFormat(m_gfxFactory), + blendSrc, blendDst, + tag.getDepthTest(), tag.getDepthWrite(), + tag.getBackfaceCulling()); + if (!ret) + Log.report(LogVisor::FatalError, "unable to build shader"); + return ret; + } + + ShaderCachedData buildExtendedShaderFromIR(const ShaderTag& tag, + const HECL::Frontend::IR& ir, + HECL::Frontend::Diagnostics& diag, + const std::vector& extensionSlots, + FReturnExtensionShader returnFunc) + { + m_backend.reset(ir, diag); + + std::string vertSource = + m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), + tag.getSkinSlotCount(), tag.getTexMtxCount()); + + ComPtr vertBlob; + std::vector, ComPtr>> fragPipeBlobs; + fragPipeBlobs.reserve(extensionSlots.size()); + + size_t cachedSz = 6 + 8 * extensionSlots.size(); + for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots) + { + std::string fragSource = m_backend.makeFrag(slot.lighting, slot.post); + fragPipeBlobs.emplace_back(); + std::pair, ComPtr>& fragPipeBlob = fragPipeBlobs.back(); + boo::IShaderPipeline* ret = + m_gfxFactory->newShaderPipeline(vertSource.c_str(), fragSource.c_str(), + vertBlob, fragPipeBlob.first, fragPipeBlob.second, + tag.newVertexFormat(m_gfxFactory), + m_backend.m_blendSrc, m_backend.m_blendDst, + tag.getDepthTest(), tag.getDepthWrite(), + tag.getBackfaceCulling()); + if (!ret) + Log.report(LogVisor::FatalError, "unable to build shader"); + if (fragPipeBlob.first) + cachedSz += fragPipeBlob.first->GetBufferSize(); + if (fragPipeBlob.second) + cachedSz += fragPipeBlob.second->GetBufferSize(); + returnFunc(ret); + } + if (vertBlob) + cachedSz += vertBlob->GetBufferSize(); + + ShaderCachedData dataOut(tag, cachedSz); + Athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz); + w.writeUByte(m_backend.m_blendSrc); + w.writeUByte(m_backend.m_blendDst); + + if (vertBlob) + { + w.writeUint32Big(vertBlob->GetBufferSize()); + w.writeUBytes((atUint8*)vertBlob->GetBufferPointer(), vertBlob->GetBufferSize()); + } + else + w.writeUint32Big(0); + + for (const std::pair, ComPtr>& fragPipeBlob : fragPipeBlobs) + { + if (fragPipeBlob.first) + { + w.writeUint32Big(fragPipeBlob.first->GetBufferSize()); + w.writeUBytes((atUint8*)fragPipeBlob.first->GetBufferPointer(), fragPipeBlob.first->GetBufferSize()); + } + else + w.writeUint32Big(0); + + if (fragPipeBlob.second) + { + w.writeUint32Big(fragPipeBlob.second->GetBufferSize()); + w.writeUBytes((atUint8*)fragPipeBlob.second->GetBufferPointer(), fragPipeBlob.second->GetBufferSize()); + } + else + w.writeUint32Big(0); + } + + return dataOut; + } + + void buildExtendedShaderFromCache(const ShaderCachedData& data, + const std::vector& extensionSlots, + FReturnExtensionShader returnFunc) + { + const ShaderTag& tag = data.m_tag; + Athena::io::MemoryReader r(data.m_data.get(), data.m_sz); + boo::BlendFactor blendSrc = boo::BlendFactor(r.readUByte()); + boo::BlendFactor blendDst = boo::BlendFactor(r.readUByte()); + + atUint32 vertSz = r.readUint32Big(); + ComPtr vertBlob; + if (vertSz) + { + D3DCreateBlobPROC(vertSz, &vertBlob); + r.readUBytesToBuf(vertBlob->GetBufferPointer(), vertSz); + } + + for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots) + { + atUint32 fragSz = r.readUint32Big(); + ComPtr fragBlob; + if (fragSz) + { + D3DCreateBlobPROC(fragSz, &fragBlob); + r.readUBytesToBuf(fragBlob->GetBufferPointer(), fragSz); + } + + atUint32 pipelineSz = r.readUint32Big(); + ComPtr pipelineBlob; + if (pipelineSz) + { + D3DCreateBlobPROC(pipelineSz, &pipelineBlob); + r.readUBytesToBuf(pipelineBlob->GetBufferPointer(), pipelineSz); + } + + boo::IShaderPipeline* ret = + m_gfxFactory->newShaderPipeline(nullptr, nullptr, + vertBlob, fragBlob, pipelineBlob, + tag.newVertexFormat(m_gfxFactory), + blendSrc, blendDst, + tag.getDepthTest(), tag.getDepthWrite(), + tag.getBackfaceCulling()); + if (!ret) + Log.report(LogVisor::FatalError, "unable to build shader"); + returnFunc(ret); + } + } +}; + +IShaderBackendFactory* _NewHLSLBackendFactory(boo::IGraphicsDataFactory* gfxFactory) +{ + return new struct HLSLBackendFactory(gfxFactory); +} + +} +}