#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License // If the library is compiled as a DLL, this ensures symbols are exported #define NUCLEX_GRAPHICS_SOURCE 1 #include "HlslShaderReflector.h" #include "HlslResourceDefinitionSerializer.h" #include "HlslInputSignatureSerializer.h" namespace { // ------------------------------------------------------------------------------------------- // /// File id for HLSL files const std::uint32_t HlslFileId = 'CBXD'; // DXBC converted to little endian /// Id of the resource definition chunk const std::uint32_t ResourceDefinition = 'FEDR'; // RDEF /// Id of the shader inputs signature chunk const std::uint32_t InputSignature = 'NGSI'; // ISGN /// Id of the shader outputs signature chunk const std::uint32_t OutputSignature = 'NGSO'; // OSGN /// Id of the shader model 5 outputs signature chunk const std::uint32_t OutputSignature5 = '5GSO'; // OSG5 // ------------------------------------------------------------------------------------------- // } // anonymous namespace namespace Nuclex { namespace Graphics { namespace Introspection { // ------------------------------------------------------------------------------------------- // bool HlslShaderReflector::IsHlslShader(const std::uint8_t *bytecode, std::size_t length) { if(length < 4) { return false; } std::uint32_t fileId = *reinterpret_cast(bytecode); return (fileId == HlslFileId); } // ------------------------------------------------------------------------------------------- // void HlslShaderReflector::Read( const std::uint8_t *bytecode, std::size_t length, ShaderMetadata &metadata ) { MiniReader reader(bytecode, length); // Signature that identies the file type (identical for all shader types) std::uint32_t fileId; reader.Read(fileId); if(fileId != HlslFileId) { throw std::runtime_error("Not a compiled HLSL shader"); } // GUID that is generated each time a shader is compiled std::uint32_t guid[4]; reader.Read(guid[0]); reader.Read(guid[1]); reader.Read(guid[2]); reader.Read(guid[3]); // Version number of the shader file format std::uint32_t fileFormatVersion; reader.Read(fileFormatVersion); // Total size of the shader in bytes std::uint32_t totalLength; reader.Read(totalLength); // Number of chunks stored in the file std::uint32_t chunkCount; reader.Read(chunkCount); // Array containing the absolute file offset of each chunk for(std::size_t index = 0; index < chunkCount; ++index) { std::uint32_t chunkOffset; reader.Read(chunkOffset); MiniReader chunkReader(bytecode + chunkOffset, length - chunkOffset); readChunk(chunkReader, metadata); } } // ------------------------------------------------------------------------------------------- // void HlslShaderReflector::readChunk(MiniReader &reader, ShaderMetadata &metadata) { // Type of chunk this is std::uint32_t chunkType; reader.Read(chunkType); // Total length of the chunk in bytes std::uint32_t chunkLength; reader.Read(chunkLength); // It's likely there will be more chunk types added in the future, so only parse // those we're interested in and ignore the rest. switch(chunkType) { case ResourceDefinition: { HlslResourceDefinitionSerializer::Read(reader, metadata); break; } case InputSignature: { HlslInputSignatureSerializer::Read(reader, metadata); break; } default: { // Other type of chunk we're not interested in break; } } } // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Introspection