#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