diff --git a/code/foundation/util/string.h b/code/foundation/util/string.h index b58900f6b..983d6dbb8 100644 --- a/code/foundation/util/string.h +++ b/code/foundation/util/string.h @@ -46,7 +46,6 @@ namespace Math namespace Util { class Blob; - class String { public: @@ -353,6 +352,8 @@ class String static String FromBase64(const String&); /// convert from "anything" template static String From(const T& t); + /// Hash a string + static constexpr uint Hash(const char* c, std::size_t s); /// construct a hex string from an int template @@ -691,20 +692,8 @@ String::IsValid() const inline uint32_t String::HashCode() const { - uint32_t hash = 0; const char* ptr = this->AsCharPtr(); - SizeT len = this->strLen; - SizeT i; - for (i = 0; i < len; i++) - { - hash += ptr[i]; - hash += hash << 10; - hash ^= hash >> 6; - } - hash += hash << 3; - hash ^= hash >> 11; - hash += hash << 15; - return hash; + return Hash(ptr, this->strLen); } //------------------------------------------------------------------------------ @@ -1190,6 +1179,27 @@ String::AppendMat4(const Math::mat4& val) this->Append(FromMat4(val)); } #endif + + +//------------------------------------------------------------------------------ +/** +*/ +constexpr uint +String::Hash(const char* c, std::size_t s) +{ + uint hash = 0; + std::size_t i; + for (i = 0; i < s; i++) + { + hash += c[i]; + hash += hash << 10; + hash ^= hash >> 6; + } + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + return hash; +} inline auto Format = &String::Sprintf; @@ -1209,22 +1219,8 @@ Util::String operator ""_str(const char* c, std::size_t s); constexpr uint operator ""_hash(const char* c, std::size_t s) { - uint hash = 0; - const char* ptr = c; - std::size_t len = s; - std::size_t i; - for (i = 0; i < len; i++) - { - hash += ptr[i]; - hash += hash << 10; - hash ^= hash >> 6; - } - hash += hash << 3; - hash ^= hash >> 11; - hash += hash << 15; - return hash; + return Util::String::Hash(c, s); } - //------------------------------------------------------------------------------ diff --git a/code/render/CMakeLists.txt b/code/render/CMakeLists.txt index 263bf578b..c99b1dc0b 100644 --- a/code/render/CMakeLists.txt +++ b/code/render/CMakeLists.txt @@ -124,8 +124,6 @@ ENDIF() antialiasquality.cc antialiasquality.h barrier.h - batchgroup.cc - batchgroup.h buffer.cc buffer.h gpubuffertypes.h diff --git a/code/render/coregraphics/batchgroup.cc b/code/render/coregraphics/batchgroup.cc deleted file mode 100644 index 5654aef27..000000000 --- a/code/render/coregraphics/batchgroup.cc +++ /dev/null @@ -1,57 +0,0 @@ -//------------------------------------------------------------------------------ -// batchgroup.cc -// (C) 2013-2020 Individual contributors, see AUTHORS file -//------------------------------------------------------------------------------ - -#include "coregraphics/batchgroup.h" -#include "graphics/graphicsserver.h" - -namespace CoreGraphics -{ - -using namespace Util; - -//------------------------------------------------------------------------------ -/** - Private constructor, only the ModelServer may create the central - ModelNodeType registry. -*/ -BatchGroup::BatchGroup() -{ - this->nameToCode.Reserve(NumBatchGroups); - this->codeToName.Reserve(NumBatchGroups); -} - -//------------------------------------------------------------------------------ -/** -*/ -BatchGroup::Code -BatchGroup::FromName(const Name& name) -{ - BatchGroup& registry = Graphics::GraphicsServer::Instance()->batchGroupRegistry; - IndexT index = registry.nameToCode.FindIndex(name); - if (InvalidIndex != index) - { - return registry.nameToCode.ValueAtIndex(index); - } - else - { - // name hasn't been registered yet - registry.codeToName.Append(name); - Code code = registry.codeToName.Size() - 1; - registry.nameToCode.Add(name, code); - return code; - } -} - -//------------------------------------------------------------------------------ -/** -*/ -BatchGroup::Name -BatchGroup::ToName(Code c) -{ - BatchGroup& registry = Graphics::GraphicsServer::Instance()->batchGroupRegistry; - return registry.codeToName[c]; -} - -} // namespace Graphics diff --git a/code/render/coregraphics/batchgroup.h b/code/render/coregraphics/batchgroup.h deleted file mode 100644 index 75dd326c1..000000000 --- a/code/render/coregraphics/batchgroup.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once -//------------------------------------------------------------------------------ -/** - @class CoreGraphics::BatchGroup - - BatchGroup denotes a zero indexed name registry which corresponds to the - type of materials being batched during a FrameBatch. The name from the - 'batchType' field gets converted into an index in this class, which is then - used when retrieving all materials which utilizes this batch type. - - Materials have the same field in their template definition, meaning that - for each frame batch using a specific batch type, all materials with the same - batch type defined will be rendered in this pass, which acts as the bridge - between the frame shader system and the material rendering system. - - @copyright - (C) 2007 Radon Labs GmbH - (C) 2013-2020 Individual contributors, see AUTHORS file -*/ -#include "core/types.h" -#include "util/stringatom.h" -#include "util/array.h" -#include "util/dictionary.h" - -namespace Graphics { class GraphicsServer; } - -//------------------------------------------------------------------------------ -namespace CoreGraphics -{ -class BatchGroup -{ -public: - /// human readable name of a ModelNodeType - typedef Util::StringAtom Name; - /// binary code for a ModelNodeType - typedef IndexT Code; - - /// convert from string - static Code FromName(const Name& name); - /// convert to string - static Name ToName(Code c); - /// maximum number of different ModelNodeTypes - static const IndexT NumBatchGroups = 256; - /// invalid model node type code - static const IndexT InvalidBatchGroup = InvalidIndex; - -private: - friend class Graphics::GraphicsServer; - - /// constructor - BatchGroup(); - - Util::Dictionary nameToCode; - Util::Array codeToName; -}; - -} // namespace CoreGraphics -//------------------------------------------------------------------------------ - diff --git a/code/render/frame/framescriptloader.cc b/code/render/frame/framescriptloader.cc index 147efa05b..04584f1ff 100644 --- a/code/render/frame/framescriptloader.cc +++ b/code/render/frame/framescriptloader.cc @@ -1138,9 +1138,9 @@ void FrameScriptLoader::ParseSubpassBatch(const Ptr& script, Frame::FrameSubpass* subpass, JzonValue* node) { JzonValue* name = jzon_get(node, "name"); - CoreGraphics::BatchGroup::Code batch = CoreGraphics::BatchGroup::FromName(name->string_value); + MaterialTemplates::BatchGroup batch = MaterialTemplates::BatchGroupFromName(name->string_value); n_assert(name != nullptr); - if (MaterialTemplates::Configs.FindIndex(batch) == InvalidIndex) + if (batch == MaterialTemplates::BatchGroup::Invalid) { n_warning("[FrameScript] - Skipping, batch with name '%s' because it's not rendered by any material\n", name->string_value); return; @@ -1158,7 +1158,7 @@ FrameScriptLoader::ParseSubpassBatch(const Ptr& script, Fram ParseResourceDependencies(script, op, inputs); } - op->batch = CoreGraphics::BatchGroup::FromName(name->string_value); + op->batch = batch; subpass->AddChild(op); } @@ -1169,9 +1169,9 @@ void FrameScriptLoader::ParseSubpassSortedBatch(const Ptr& script, Frame::FrameSubpass* subpass, JzonValue* node) { JzonValue* name = jzon_get(node, "name"); - CoreGraphics::BatchGroup::Code batch = CoreGraphics::BatchGroup::FromName(name->string_value); + MaterialTemplates::BatchGroup batch = MaterialTemplates::BatchGroupFromName(name->string_value); n_assert(name != nullptr); - if (MaterialTemplates::Configs.FindIndex(batch) == InvalidIndex) + if (batch == MaterialTemplates::BatchGroup::Invalid) { n_warning("Skipping, batch with name '%s' because it's not rendered by any material\n", name->string_value); return; diff --git a/code/render/frame/framesubpassbatch.cc b/code/render/frame/framesubpassbatch.cc index 2b58a43ad..a000fde9b 100644 --- a/code/render/frame/framesubpassbatch.cc +++ b/code/render/frame/framesubpassbatch.cc @@ -58,11 +58,11 @@ FrameSubpassBatch::AllocCompiled(Memory::ArenaAllocator& allocator) /** */ void -FrameSubpassBatch::DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, CoreGraphics::BatchGroup::Code batch, const Graphics::GraphicsEntityId id, const IndexT bufferIndex) +FrameSubpassBatch::DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, MaterialTemplates::BatchGroup batch, const Graphics::GraphicsEntityId id, const IndexT bufferIndex) { // get current view and visibility draw list const Visibility::ObserverContext::VisibilityDrawList* drawList = Visibility::ObserverContext::GetVisibilityDrawList(id); - const Util::Array& types = MaterialTemplates::Configs[batch]; + const Util::Array& types = MaterialTemplates::Configs[(uint)batch]; if (types.Size() != 0 && (drawList != nullptr)) { for (IndexT typeIdx = 0; typeIdx < types.Size(); typeIdx++) @@ -153,11 +153,11 @@ FrameSubpassBatch::DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, CoreGraphic /** */ void -FrameSubpassBatch::DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, CoreGraphics::BatchGroup::Code batch, const Graphics::GraphicsEntityId id, const SizeT numInstances, const IndexT baseInstance, const IndexT bufferIndex) +FrameSubpassBatch::DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, MaterialTemplates::BatchGroup batch, const Graphics::GraphicsEntityId id, const SizeT numInstances, const IndexT baseInstance, const IndexT bufferIndex) { // get current view and visibility draw list const Visibility::ObserverContext::VisibilityDrawList* drawList = Visibility::ObserverContext::GetVisibilityDrawList(id); - const Util::Array& types = MaterialTemplates::Configs[batch]; + const Util::Array& types = MaterialTemplates::Configs[(uint)batch]; if (types.Size() != 0 && (drawList != nullptr)) { for (IndexT typeIdx = 0; typeIdx < types.Size(); typeIdx++) diff --git a/code/render/frame/framesubpassbatch.h b/code/render/frame/framesubpassbatch.h index 354b66e0d..283a37f29 100644 --- a/code/render/frame/framesubpassbatch.h +++ b/code/render/frame/framesubpassbatch.h @@ -8,7 +8,7 @@ */ //------------------------------------------------------------------------------ #include "frameop.h" -#include "coregraphics/batchgroup.h" +#include "materials/materialtemplates.h" #include "graphics/graphicsentity.h" namespace Frame { @@ -24,16 +24,16 @@ class FrameSubpassBatch : public FrameOp { void Run(const CoreGraphics::CmdBufferId cmdBuf, const IndexT frameIndex, const IndexT bufferIndex) override; - CoreGraphics::BatchGroup::Code batch; + MaterialTemplates::BatchGroup batch; }; FrameOp::Compiled* AllocCompiled(Memory::ArenaAllocator& allocator); - CoreGraphics::BatchGroup::Code batch; + MaterialTemplates::BatchGroup batch; /// Do the actual drawing - static void DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, CoreGraphics::BatchGroup::Code batch, const Graphics::GraphicsEntityId id, const IndexT bufferIndex); + static void DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, MaterialTemplates::BatchGroup batch, const Graphics::GraphicsEntityId id, const IndexT bufferIndex); /// Do the actual drawing, but with duplicate instances - static void DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, CoreGraphics::BatchGroup::Code batch, const Graphics::GraphicsEntityId id, const SizeT numInstances, const IndexT baseInstance, const IndexT bufferIndex); + static void DrawBatch(const CoreGraphics::CmdBufferId cmdBuf, MaterialTemplates::BatchGroup batch, const Graphics::GraphicsEntityId id, const SizeT numInstances, const IndexT baseInstance, const IndexT bufferIndex); }; } // namespace Frame2 diff --git a/code/render/frame/framesubpassorderedbatch.h b/code/render/frame/framesubpassorderedbatch.h index 2ab2b9759..822e5dc9e 100644 --- a/code/render/frame/framesubpassorderedbatch.h +++ b/code/render/frame/framesubpassorderedbatch.h @@ -9,7 +9,6 @@ */ //------------------------------------------------------------------------------ #include "frameop.h" -#include "coregraphics/batchgroup.h" namespace Frame { class FrameSubpassOrderedBatch : public FrameOp @@ -24,12 +23,12 @@ class FrameSubpassOrderedBatch : public FrameOp { void Run(const CoreGraphics::CmdBufferId cmdBuf, const IndexT frameIndex, const IndexT bufferIndex) override; - CoreGraphics::BatchGroup::Code batch; + MaterialTemplates::BatchGroup batch; }; FrameOp::Compiled* AllocCompiled(Memory::ArenaAllocator& allocator); - CoreGraphics::BatchGroup::Code batch; + MaterialTemplates::BatchGroup batch; }; } // namespace Frame2 diff --git a/code/render/graphics/graphicsserver.h b/code/render/graphics/graphicsserver.h index f697856cb..803b2c5cf 100644 --- a/code/render/graphics/graphicsserver.h +++ b/code/render/graphics/graphicsserver.h @@ -15,7 +15,6 @@ #include "framesync/framesynctimer.h" #include "util/stringatom.h" #include "ids/idgenerationpool.h" -#include "coregraphics/batchgroup.h" #include "stage.h" #include "graphicsentity.h" #include "coregraphics/graphicsdevice.h" @@ -123,7 +122,6 @@ class GraphicsServer : public Core::RefCounted void OnWindowResized(CoreGraphics::WindowId wndId); private: - friend class CoreGraphics::BatchGroup; Ids::IdGenerationPool entityPool; @@ -136,7 +134,6 @@ class GraphicsServer : public Core::RefCounted Util::Array> stages; Util::Array> views; - CoreGraphics::BatchGroup batchGroupRegistry; Ptr currentView; Ptr displayDevice; diff --git a/code/render/lighting/lightcontext.cc b/code/render/lighting/lightcontext.cc index 61794d711..5d4e5fade 100644 --- a/code/render/lighting/lightcontext.cc +++ b/code/render/lighting/lightcontext.cc @@ -57,8 +57,8 @@ struct CoreGraphics::TextureId terrainShadowMap = CoreGraphics::InvalidTextureId; uint terrainShadowMapSize; uint terrainSize; - CoreGraphics::BatchGroup::Code spotlightsBatchCode; - CoreGraphics::BatchGroup::Code globalLightsBatchCode; + MaterialTemplates::BatchGroup spotlightsBatchCode; + MaterialTemplates::BatchGroup globalLightsBatchCode; CSMUtil csmUtil{ Shared::NUM_CASCADES }; @@ -153,8 +153,8 @@ LightContext::Create(const Ptr& frameScript) #endif // create shadow mapping frame script - lightServerState.spotlightsBatchCode = CoreGraphics::BatchGroup::FromName("SpotLightShadow"); - lightServerState.globalLightsBatchCode = CoreGraphics::BatchGroup::FromName("GlobalShadow"); + lightServerState.spotlightsBatchCode = MaterialTemplates::BatchGroupFromName("SpotLightShadow"); + lightServerState.globalLightsBatchCode = MaterialTemplates::BatchGroupFromName("GlobalShadow"); lightServerState.globalLightShadowMap = frameScript->GetTexture("SunShadowDepth"); lightServerState.localLightShadows = frameScript->GetTexture("LocalLightShadow"); if (lightServerState.terrainShadowMap == CoreGraphics::InvalidTextureId) @@ -580,7 +580,6 @@ LightContext::SetupAreaLight( const MaterialTemplates::MaterialTemplateValue& value = MaterialTemplates::base::__AreaLight.__EmissiveColor; void* mem = Materials::MaterialLoader::AllocateConstantMemory(value.GetSize()); - const Materials::ShaderConfigBatchConstant* batchConstant = &MaterialTemplates::base::__AreaLight.__LightMeshes_EmissiveColor; MaterialInterfaces::ArealightMaterial* data = (MaterialInterfaces::ArealightMaterial*)StackAlloc(matTemplate->bufferSize); (color * intensity).store(data->EmissiveColor); diff --git a/code/render/materials/material.cc b/code/render/materials/material.cc index 87bfd913d..e8b626104 100644 --- a/code/render/materials/material.cc +++ b/code/render/materials/material.cc @@ -310,9 +310,9 @@ MaterialGetTemplate(const MaterialId mat) /** */ const Materials::BatchIndex -MaterialGetBatchIndex(const MaterialId mat, const CoreGraphics::BatchGroup::Code code) +MaterialGetBatchIndex(const MaterialId mat, const MaterialTemplates::BatchGroup batch) { - return materialAllocator.Get(mat.id)->passes[code]->index; + return materialAllocator.Get(mat.id)->passes[batch]->index; } //------------------------------------------------------------------------------ diff --git a/code/render/materials/material.h b/code/render/materials/material.h index 80f1a4210..51c7aeb46 100644 --- a/code/render/materials/material.h +++ b/code/render/materials/material.h @@ -12,22 +12,21 @@ #include "ids/id.h" #include "ids/idallocator.h" #include "resources/resourceid.h" -#include "coregraphics/batchgroup.h" #include "coregraphics/texture.h" #include "coregraphics/buffer.h" #include "materialvariant.h" + namespace MaterialTemplates { struct Entry; +enum class BatchGroup; }; namespace Materials { -struct ShaderConfigBatchConstant; struct ShaderConfigBatchTexture; - RESOURCE_ID_TYPE(MaterialId); ID_32_24_8_NAMED_TYPE(MaterialInstanceId, instance, materialId, materialGeneration, material); // 32 bits instance, 24 bits material, 8 bits type @@ -66,7 +65,7 @@ void MaterialApply(const MaterialId id, const CoreGraphics::CmdBufferId buf, Ind /// Get material shader config const MaterialTemplates::Entry* MaterialGetTemplate(const MaterialId mat); /// Get batch index from code -const Materials::BatchIndex MaterialGetBatchIndex(const MaterialId mat, const CoreGraphics::BatchGroup::Code code); +const Materials::BatchIndex MaterialGetBatchIndex(const MaterialId mat, const MaterialTemplates::BatchGroup batch); /// Get sort code uint64_t MaterialGetSortCode(const MaterialId mat); diff --git a/code/render/materials/materialtemplatetypes.h b/code/render/materials/materialtemplatetypes.h index ef73f9ce0..00382fad6 100644 --- a/code/render/materials/materialtemplatetypes.h +++ b/code/render/materials/materialtemplatetypes.h @@ -11,6 +11,7 @@ namespace MaterialTemplates { +enum class BatchGroup; struct MaterialTemplateValue { enum Type @@ -83,8 +84,8 @@ struct Entry #ifdef WITH_NEBULA_EDITOR Util::Dictionary valuesByHash; Util::Dictionary texturesByHash; -#endif WITH_NEBULA_EDITOR - Util::Dictionary passes; +#endif + Util::Dictionary passes; Util::Array> texturesPerBatch; Util::Array> textureBatchLookup; }; diff --git a/code/render/materials/shaderconfig.h b/code/render/materials/shaderconfig.h index 9e84cc549..b1f60ad35 100644 --- a/code/render/materials/shaderconfig.h +++ b/code/render/materials/shaderconfig.h @@ -8,7 +8,6 @@ */ //------------------------------------------------------------------------------ #include "util/hashtable.h" -#include "coregraphics/batchgroup.h" #include "coregraphics/shader.h" #include "memory/arenaallocator.h" #include "util/variant.h" @@ -22,43 +21,15 @@ namespace MaterialTemplates { - struct MaterialTemplateValue; struct MaterialTemplateTexture; } namespace Materials { -struct ShaderConfigTexture -{ - Util::String name; - CoreGraphics::TextureId defaultValue; - CoreGraphics::TextureType type; - bool system : 1; -}; - struct ShaderConfigBatchTexture { IndexT slot; const MaterialTemplates::MaterialTemplateTexture* def; }; -struct ShaderConfigConstant -{ - Util::String name; - MaterialVariant def, min, max; - bool system : 1; -}; - -struct ShaderConfigBatchConstant -{ - IndexT offset, slot, group; - const MaterialTemplates::MaterialTemplateValue* def; - - // Returns true if valid - const bool Valid() const - { - return offset != InvalidIndex && slot != InvalidIndex && group != InvalidIndex; - } -}; - } // namespace Materials diff --git a/code/render/models/modelcontext.cc b/code/render/models/modelcontext.cc index e2a8044ce..f06e68ce7 100644 --- a/code/render/models/modelcontext.cc +++ b/code/render/models/modelcontext.cc @@ -448,7 +448,7 @@ ModelContext::GetNodeIndex(const Graphics::GraphicsEntityId id, const Util::Stri /** */ ModelContext::MaterialInstanceContext& -ModelContext::SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, const IndexT nodeIndex, const CoreGraphics::BatchGroup::Code batch) +ModelContext::SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, const IndexT nodeIndex, const MaterialTemplates::BatchGroup batch) { // This is a bit hacky, but we really need to only do this once per node and batch. // What we do is that we get the batch index from the batch lookup map, and the variable indexes @@ -478,7 +478,7 @@ ModelContext::SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, /** */ ModelContext::MaterialInstanceContext& -ModelContext::SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, const CoreGraphics::BatchGroup::Code batch) +ModelContext::SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, const MaterialTemplates::BatchGroup batch) { return SetupMaterialInstanceContext(id, 0, batch); } diff --git a/code/render/models/modelcontext.h b/code/render/models/modelcontext.h index a9bde21bb..1e940662a 100644 --- a/code/render/models/modelcontext.h +++ b/code/render/models/modelcontext.h @@ -101,9 +101,9 @@ class ModelContext : public Graphics::GraphicsContext /// Get node index based on name static IndexT GetNodeIndex(const Graphics::GraphicsEntityId id, const Util::StringAtom& name); /// Setup material instance context - static MaterialInstanceContext& SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, const IndexT nodeIndex, const CoreGraphics::BatchGroup::Code batch); + static MaterialInstanceContext& SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, const IndexT nodeIndex, const MaterialTemplates::BatchGroup batch); /// Setup material instance context - static MaterialInstanceContext& SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, const CoreGraphics::BatchGroup::Code batch); + static MaterialInstanceContext& SetupMaterialInstanceContext(const Graphics::GraphicsEntityId id, const MaterialTemplates::BatchGroup batch); /// Allocate constant memory for instance constants in this frame static CoreGraphics::ConstantBufferOffset AllocateInstanceConstants(const Graphics::GraphicsEntityId id, const IndexT nodeIndex, const Materials::BatchIndex batch); /// Allocate constant memory for instance constants in this frame diff --git a/code/render/models/nodes/shaderstatenode.cc b/code/render/models/nodes/shaderstatenode.cc index 979c43f07..cd81fe1ee 100644 --- a/code/render/models/nodes/shaderstatenode.cc +++ b/code/render/models/nodes/shaderstatenode.cc @@ -124,11 +124,7 @@ ShaderStateNode::DrawPacket::Apply(const CoreGraphics::CmdBufferId cmdBuf, Index // Set per-draw resource tables IndexT prevOffset = 0; - for (IndexT i = 0; i < this->numTables; i++) - { - CoreGraphics::CmdSetResourceTable(cmdBuf, this->tables[i], this->slots[i], CoreGraphics::GraphicsPipeline, this->numOffsets[i], this->offsets[prevOffset]); - prevOffset = this->numOffsets[i]; - } + CoreGraphics::CmdSetResourceTable(cmdBuf, this->table, this->slot, CoreGraphics::GraphicsPipeline, this->numOffsets, this->offsets); } } // namespace Models diff --git a/code/render/models/nodes/shaderstatenode.h b/code/render/models/nodes/shaderstatenode.h index 3e9b5ddfc..f8973df3a 100644 --- a/code/render/models/nodes/shaderstatenode.h +++ b/code/render/models/nodes/shaderstatenode.h @@ -24,22 +24,19 @@ class ShaderStateNode : public TransformNode virtual ~ShaderStateNode(); struct DrawPacket; - static const uint NumTables = 1; static const uint NumMaxOffsets = 4; // object, instancing, skeleton, particles struct DrawPacket { - Materials::MaterialInstanceId materialInstance; - SizeT numTables; - CoreGraphics::ResourceTableId tables[NumTables]; - uint32 numOffsets[NumTables]; - uint32 offsets[NumTables][NumMaxOffsets]; - IndexT slots[NumTables]; - #ifndef PUBLIC_BUILD - uint32_t nodeInstanceHash; Math::bbox boundingBox; + uint32_t nodeInstanceHash; #endif + Materials::MaterialInstanceId materialInstance; + CoreGraphics::ResourceTableId table; + uint32 offsets[NumMaxOffsets]; + uint8 numOffsets; + uint8 slot; /// Apply the resource table void Apply(const CoreGraphics::CmdBufferId cmdBuf, IndexT batchIndex, IndexT bufferIndex); diff --git a/code/render/visibility/visibilitycontext.cc b/code/render/visibility/visibilitycontext.cc index cfbd55c6f..7a1629b38 100644 --- a/code/render/visibility/visibilitycontext.cc +++ b/code/render/visibility/visibilitycontext.cc @@ -353,16 +353,15 @@ ObserverContext::RunVisibilityTests(const Graphics::FrameContext& ctx) // update packet and add to list Models::ShaderStateNode::DrawPacket* packet = reinterpret_cast(mem); - packet->numOffsets[0] = renderables->nodeStates[index].resourceTableOffsets.Size(); - packet->numTables = 1; - packet->tables[0] = renderables->nodeStates[index].resourceTables[CoreGraphics::GetBufferedFrameIndex()]; + packet->numOffsets = renderables->nodeStates[index].resourceTableOffsets.Size(); + packet->table = renderables->nodeStates[index].resourceTables[CoreGraphics::GetBufferedFrameIndex()]; packet->materialInstance = renderables->nodeStates[index].materialInstance; #ifndef PUBLIC_BUILD packet->boundingBox = renderables->nodeBoundingBoxes[index]; packet->nodeInstanceHash = index; #endif - memcpy(packet->offsets[0], renderables->nodeStates[index].resourceTableOffsets.Begin(), renderables->nodeStates[index].resourceTableOffsets.ByteSize()); - packet->slots[0] = NEBULA_DYNAMIC_OFFSET_GROUP; + memcpy(packet->offsets, renderables->nodeStates[index].resourceTableOffsets.Begin(), renderables->nodeStates[index].resourceTableOffsets.ByteSize()); + packet->slot = NEBULA_DYNAMIC_OFFSET_GROUP; drawList->drawPackets.Append(packet); cmd->numDrawPackets++; numDraws++; diff --git a/fips-files/generators/materialtemplatec.py b/fips-files/generators/materialtemplatec.py index d57d8cd7a..dbaa78775 100644 --- a/fips-files/generators/materialtemplatec.py +++ b/fips-files/generators/materialtemplatec.py @@ -218,12 +218,10 @@ def FormatHeader(self): }};\n'''.format(v.name, typeStr, accessorStr, varStr, self.interface.name, v.name, "nullptr" if len(v.desc) == 0 else '"{}"'.format(v.desc)) for p in self.passes: - ret += '\n\tEntry::Pass __{};\n'.format(p.batch) + ret += '\tEntry::Pass __{};\n'.format(p.batch) for v in self.variables: if v.type == 'texture2d': ret += '\tMaterials::ShaderConfigBatchTexture __{}_{};\n'.format(p.batch, v.name) - else: - ret += '\tMaterials::ShaderConfigBatchConstant __{}_{};\n'.format(p.batch, v.name) ret += '\n\tEntry entry = {{.name = "{}", .uniqueId = "{}"_hash, .properties = {}, .bufferName="_{}", .bufferSize=sizeof(MaterialInterfaces::{}Material), .vertexLayout = CoreGraphics::{}, .numTextures = {}}};\n'.format(self.name, self.name, self.interface.uniqueId, self.interface.name, self.interface.name, self.vertex, texCounter) ret += '\n\tvoid Setup();\n' @@ -274,7 +272,7 @@ def FormatSource(self): func += '\t\tIndexT bufferSlot = InvalidIndex;\n' func += '\t\tif (this->entry.bufferName != nullptr) bufferSlot = CoreGraphics::ShaderGetResourceSlot({}, this->entry.bufferName);\n'.format('shader') func += '\t\tthis->__{} = Entry::Pass{{.shader = shader, .program = program, .index = {}, .name = "{}", .bufferIndex=bufferSlot }};\n'.format(p.batch, passCounter, p.batch) - func += '\t\tthis->entry.passes.Add(CoreGraphics::BatchGroup::FromName("{}"), &this->__{});\n'.format(p.batch, p.batch) + func += '\t\tthis->entry.passes.Add(MaterialTemplates::BatchGroup::{}, &this->__{});\n'.format(p.batch, p.batch) func += '\t\tthis->entry.texturesPerBatch[{}].Resize({});\n'.format(passCounter, numTextures) texCounter = 0 for var in self.variables: @@ -341,6 +339,8 @@ def __init__(self): self.materialDict = {} self.interfaces = list() self.interfaceDict = {} + self.batchGroupCounter = 0 + self.batchGroupDict = {} self.name = "" #------------------------------------------------------------------------------ @@ -386,6 +386,10 @@ def Parse(self): if name == "Templates": for mat in node: matDef = MaterialTemplateDefinition(mat, self) + for p in matDef.passes: + if p.batch not in self.batchGroupDict: + self.batchGroupDict[p.batch] = self.batchGroupCounter + self.batchGroupCounter += 1 if matDef.inherits: matDef.variables = self.materialDict[matDef.inherits].variables + matDef.variables matDef.passes = self.materialDict[matDef.inherits].passes + matDef.passes @@ -420,7 +424,7 @@ def FormatHeader(self, f): f.WriteLine('\t{},\\'.format(int.name)) f.WriteLine("") - f.WriteLine('void SetupMaterialTemplates(Util::Dictionary& Lookup, Util::HashTable>& Configs);\n') + f.WriteLine('void SetupMaterialTemplates();\n') for mat in self.materials: f.WriteLine(mat.FormatHeader()) @@ -454,6 +458,7 @@ def BeginHeader(self, f): f.WriteLine('#include "math/vec4.h"') f.WriteLine('using namespace Util;') f.WriteLine('namespace MaterialTemplates\n{\n') + f.WriteLine('enum class BatchGroup;\n') #------------------------------------------------------------------------------ @@ -485,10 +490,10 @@ def FormatSource(self, f): setupStr += '\t__{}.Setup();\n'.format(mat.name) setupStr += '\tLookup.Add("{}"_hash, &__{}.entry);\n'.format(mat.name, mat.name) for p in mat.passes: - setupStr += '\tConfigs.Emplace(CoreGraphics::BatchGroup::FromName("{}")).Append(&__{}.entry);\n'.format(p.batch, mat.name) + setupStr += '\tConfigs[(uint)MaterialTemplates::BatchGroup::{}].Append(&__{}.entry);\n'.format(p.batch, mat.name) setupStr += '\n' f.WriteLine('struct {}::{} {}::__{};'.format(self.name, mat.name, self.name, mat.name)) - f.WriteLine('//------------------------------------------------------------------------------\n/**\n*/\nvoid\nSetupMaterialTemplates(Util::Dictionary& Lookup, Util::HashTable>& Configs)\n{{\n{}}}\n'.format(setupStr)) + f.WriteLine('//------------------------------------------------------------------------------\n/**\n*/\nvoid\nSetupMaterialTemplates()\n{{\n{}}}\n'.format(setupStr)) f.WriteLine('}} // namespace {}\n'.format(self.name)) @@ -567,109 +572,6 @@ def BeginShader(self, f): # def EndShader(self, f): f.WriteLine("") - - #------------------------------------------------------------------------------ - ## - # - def GenerateShader(self, outPath): - f = IDLC.filewriter.FileWriter() - f.Open(outPath) - self.BeginShader(f) - self.FormatShader(f) - self.EndShader(f) - f.Close() - - #------------------------------------------------------------------------------ - ## - # - def GenerateGlueHeader(self, files, outPath): - f = IDLC.filewriter.FileWriter() - f.Open(outPath) - f.WriteLine("// Material Template #version:{}#".format(self.version)) - f.WriteLine("#pragma once") - f.WriteLine("//------------------------------------------------------------------------------") - f.WriteLine("/**") - f.IncreaseIndent() - f.WriteLine("This file was generated with Nebula's Material Template compiler tool.") - f.WriteLine("DO NOT EDIT") - f.DecreaseIndent() - f.WriteLine("*/") - f.WriteLine('#include "materials/materialtemplatetypes.h"') - - enumStr = '' - for file in files: - name = Path(file).stem - enumStr += '\tENUM_{}\n'.format(name) - f.WriteLine('#include "{}"'.format(file)) - enumStr += '\tNum\n' - - f.WriteLine('namespace MaterialTemplates\n{\n') - f.WriteLine('enum class MaterialProperties\n{{\n{}}};'.format(enumStr)) - - f.WriteLine('extern Util::Dictionary Lookup;') - f.WriteLine('extern Util::HashTable> Configs;\n') - f.WriteLine('void SetupMaterialTemplates();\n') - - f.WriteLine('} // namespace MaterialTemplates\n') - - #------------------------------------------------------------------------------ - ## - # - def GenerateGlueSource(self, files, headerPath, outPath): - f = IDLC.filewriter.FileWriter() - f.Open(outPath) - f.WriteLine("// Material Template #version:{}#".format(self.version)) - f.WriteLine("#pragma once") - f.WriteLine("//------------------------------------------------------------------------------") - f.WriteLine("/**") - f.IncreaseIndent() - f.WriteLine("This file was generated with Nebula's Material Template compiler tool.") - f.WriteLine("DO NOT EDIT") - f.DecreaseIndent() - f.WriteLine("*/") - f.WriteLine('#include "{}"'.format(headerPath)) - - setupStr = '' - for file in files: - name = Path(file).stem - setupStr += '\t{}::SetupMaterialTemplates(Lookup, Configs);\n'.format(name) - f.WriteLine('#include "{}"'.format(file)) - - f.WriteLine('namespace MaterialTemplates\n{\n') - f.WriteLine('Util::Dictionary Lookup;') - f.WriteLine('Util::HashTable> Configs;\n') - - f.WriteLine('//------------------------------------------------------------------------------\n/**\n*/\nvoid\nSetupMaterialTemplates() \n{{\n{}}}'.format(setupStr)) - - f.WriteLine('} // namespace MaterialTemplates\n') - - #------------------------------------------------------------------------------ - ## - # - def GenerateGlueShader(self, files, outPath): - f = IDLC.filewriter.FileWriter() - f.Open(outPath) - f.WriteLine("// Material Template #version:{}#".format(self.version)) - f.WriteLine("#pragma once") - f.WriteLine("//------------------------------------------------------------------------------") - f.WriteLine("/**") - f.IncreaseIndent() - f.WriteLine("This file was generated with Nebula's Material Template compiler tool.") - f.WriteLine("DO NOT EDIT") - f.DecreaseIndent() - f.WriteLine("*/") - f.WriteLine("#define MATERIAL_BINDING group(BATCH_GROUP) binding(51)") - f.WriteLine("const uint MaterialBindingSlot = 51;") - f.WriteLine("const uint MaterialBufferSlot = 52;") - - bindingsContent = '' - for file in files: - fileName = Path(file).stem - f.WriteLine('#include <{}.fxh>'.format(fileName)) - bindingsContent += "\tMATERIAL_LIST_{}\n".format(fileName) - - f.WriteLine("MATERIAL_BINDING rw_buffer MaterialBindings\n{{\n{}}};".format(bindingsContent)) - # Entry point for generator if __name__ == '__main__': @@ -689,6 +591,9 @@ def GenerateGlueShader(self, files, outPath): sourceF.Open('{}/materialtemplates.cc'.format(outDir)) generator.BeginSource(sourceF) + sourceF.WriteLine('Util::Dictionary Lookup;') + sourceF.WriteLine('Util::Array Configs[(uint)MaterialTemplates::BatchGroup::Num];') + shaderF = IDLC.filewriter.FileWriter() shaderF.Open('{}/material_interfaces.fx'.format(outDir)) generator.BeginShader(shaderF) @@ -703,6 +608,23 @@ def GenerateGlueShader(self, files, outPath): generator.FormatSource(sourceF) generator.FormatShader(shaderF) + print(generator.batchGroupDict) + enumStr = '\tInvalid = -1,\n' + for batch in generator.batchGroupDict: + enumStr += '\t{} = {},\n'.format(batch, generator.batchGroupDict[batch]) + enumStr += '\tNum\n' + headerF.WriteLine('enum class BatchGroup\n{{\n{}}};'.format(enumStr)) + + conversionStr = '' + for batch in generator.batchGroupDict: + conversionStr += '\t\tcase "{}"_hash: return BatchGroup::{};\n'.format(batch, batch) + conversionStr += '\t\tdefault: return BatchGroup::Invalid;' + headerF.WriteLine(''' +//------------------------------------------------------------------------------ +/** +*/ +inline BatchGroup\nBatchGroupFromName(const char* name)\n{{\n\tuint code = Util::String::Hash(name, strlen(name));\n\tswitch(code)\n\t{{\n{}\n\t}}\n}}\n'''.format(conversionStr)) + # Finish header enumStr = '' for file in files: @@ -711,9 +633,8 @@ def GenerateGlueShader(self, files, outPath): enumStr += '\tNum\n' headerF.WriteLine('enum class MaterialProperties\n{{\n{}}};'.format(enumStr)) - headerF.WriteLine('extern Util::Dictionary Lookup;') - headerF.WriteLine('extern Util::HashTable> Configs;\n') + headerF.WriteLine('extern Util::Array Configs[(uint)MaterialTemplates::BatchGroup::Num];\n') headerF.WriteLine('void SetupMaterialTemplates();\n') generator.EndHeader(headerF) @@ -723,10 +644,8 @@ def GenerateGlueShader(self, files, outPath): setupStr = '' for file in files: name = Path(file).stem - setupStr += '\t{}::SetupMaterialTemplates(Lookup, Configs);\n'.format(name) + setupStr += '\t{}::SetupMaterialTemplates();\n'.format(name) - sourceF.WriteLine('Util::Dictionary Lookup;') - sourceF.WriteLine('Util::HashTable> Configs;\n') sourceF.WriteLine('//------------------------------------------------------------------------------\n/**\n*/\nvoid\nSetupMaterialTemplates() \n{{\n{}}}'.format(setupStr)) generator.EndSource(sourceF)