source: graphics/Nuclex.Graphics.Native/trunk/Source/Introspection/HlslShaderReflector.cpp

Last change on this file was 1803, checked in by cygon, 4 years ago

Updated copyright statement for the year 2013

File size: 4.6 KB
Line 
1#pragma region CPL License
2/*
3Nuclex Native Framework
4Copyright (C) 2002-2013 Nuclex Development Labs
5
6This library is free software; you can redistribute it and/or
7modify it under the terms of the IBM Common Public License as
8published by the IBM Corporation; either version 1.0 of the
9License, or (at your option) any later version.
10
11This library is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14IBM Common Public License for more details.
15
16You should have received a copy of the IBM Common Public
17License along with this library
18*/
19#pragma endregion // CPL License
20
21// If the library is compiled as a DLL, this ensures symbols are exported
22#define NUCLEX_GRAPHICS_SOURCE 1
23
24#include "HlslShaderReflector.h"
25#include "HlslResourceDefinitionSerializer.h"
26#include "HlslInputSignatureSerializer.h"
27
28namespace {
29
30  // ------------------------------------------------------------------------------------------- //
31
32  /// <summary>File id for HLSL files</summary>
33  const std::uint32_t HlslFileId = 'CBXD'; // DXBC converted to little endian
34
35  /// <summary>Id of the resource definition chunk</summary>
36  const std::uint32_t ResourceDefinition = 'FEDR'; // RDEF
37
38  /// <summary>Id of the shader inputs signature chunk</summary>
39  const std::uint32_t InputSignature = 'NGSI'; // ISGN
40
41  /// <summary>Id of the shader outputs signature chunk</summary>
42  const std::uint32_t OutputSignature = 'NGSO'; // OSGN
43
44  /// <summary>Id of the shader model 5 outputs signature chunk</summary>
45  const std::uint32_t OutputSignature5 = '5GSO'; // OSG5
46
47  // ------------------------------------------------------------------------------------------- //
48
49} // anonymous namespace
50
51namespace Nuclex { namespace Graphics { namespace Introspection {
52
53  // ------------------------------------------------------------------------------------------- //
54
55  bool HlslShaderReflector::IsHlslShader(const std::uint8_t *bytecode, std::size_t length) {
56    if(length < 4) {
57      return false;
58    }
59
60    std::uint32_t fileId = *reinterpret_cast<const std::uint32_t *>(bytecode);
61    return (fileId == HlslFileId);
62  }
63
64  // ------------------------------------------------------------------------------------------- //
65
66  void HlslShaderReflector::Read(
67    const std::uint8_t *bytecode, std::size_t length, ShaderMetadata &metadata
68  ) {
69    MiniReader reader(bytecode, length);
70
71    // Signature that identies the file type (identical for all shader types)
72    std::uint32_t fileId;
73    reader.Read(fileId);
74    if(fileId != HlslFileId) {
75      throw std::runtime_error("Not a compiled HLSL shader");
76    }
77
78    // GUID that is generated each time a shader is compiled
79    std::uint32_t guid[4];
80    reader.Read(guid[0]);
81    reader.Read(guid[1]);
82    reader.Read(guid[2]);
83    reader.Read(guid[3]);
84
85    // Version number of the shader file format
86    std::uint32_t fileFormatVersion;
87    reader.Read(fileFormatVersion);
88
89    // Total size of the shader in bytes
90    std::uint32_t totalLength;
91    reader.Read(totalLength);
92
93    // Number of chunks stored in the file
94    std::uint32_t chunkCount;
95    reader.Read(chunkCount);
96
97    // Array containing the absolute file offset of each chunk
98    for(std::size_t index = 0; index < chunkCount; ++index) {
99      std::uint32_t chunkOffset;
100      reader.Read(chunkOffset);
101
102      MiniReader chunkReader(bytecode + chunkOffset, length - chunkOffset);
103      readChunk(chunkReader, metadata);
104    }
105  }
106
107  // ------------------------------------------------------------------------------------------- //
108
109  void HlslShaderReflector::readChunk(MiniReader &reader, ShaderMetadata &metadata) {
110
111    // Type of chunk this is
112    std::uint32_t chunkType;
113    reader.Read(chunkType);
114
115    // Total length of the chunk in bytes
116    std::uint32_t chunkLength;
117    reader.Read(chunkLength);
118
119    // It's likely there will be more chunk types added in the future, so only parse
120    // those we're interested in and ignore the rest.
121    switch(chunkType) {
122      case ResourceDefinition: {
123        HlslResourceDefinitionSerializer::Read(reader, metadata);
124        break;
125      }
126      case InputSignature: {
127        HlslInputSignatureSerializer::Read(reader, metadata);
128        break;
129      }
130      default: {
131        // Other type of chunk we're not interested in
132        break;
133      }
134    }
135
136  }
137
138  // ------------------------------------------------------------------------------------------- //
139
140}}} // namespace Nuclex::Graphics::Introspection
Note: See TracBrowser for help on using the repository browser.