Browse Source

Added shader disassembler.

Branimir Karadžić 9 years ago
parent
commit
91e8751bab
3 changed files with 153 additions and 0 deletions
  1. 1 0
      src/bgfx_p.h
  2. 131 0
      src/shader.cpp
  3. 21 0
      src/shader.h

+ 1 - 0
src/bgfx_p.h

@@ -137,6 +137,7 @@ namespace bgfx
 
 #include <bgfx/bgfxplatform.h>
 #include "image.h"
+#include "shader.h"
 
 #define BGFX_CHUNK_MAGIC_CSH BX_MAKEFOURCC('C', 'S', 'H', 0x2)
 #define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', 0x4)

+ 131 - 0
src/shader.cpp

@@ -0,0 +1,131 @@
+/*
+ * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "bgfx_p.h"
+#include "shader_dxbc.h"
+#include "shader_dx9bc.h"
+#include "shader_spirv.h"
+
+namespace bgfx
+{
+	static bool printAsm(uint32_t, const DxbcInstruction& _instruction, void* _userData)
+	{
+		bx::WriterI* writer = reinterpret_cast<bx::WriterI*>(_userData);
+		char temp[512];
+		toString(temp, sizeof(temp), _instruction);
+		bx::write(writer, temp, (int32_t)strlen(temp) );
+		return true;
+	}
+
+	static bool printAsm(uint32_t, const Dx9bcInstruction& _instruction, void* _userData)
+	{
+		bx::WriterI* writer = reinterpret_cast<bx::WriterI*>(_userData);
+		char temp[512];
+		toString(temp, sizeof(temp), _instruction);
+		bx::write(writer, temp, (int32_t)strlen(temp) );
+		return true;
+	}
+
+	static bool printAsm(uint32_t, const SpvInstruction& _instruction, void* _userData)
+	{
+		bx::WriterI* writer = reinterpret_cast<bx::WriterI*>(_userData);
+		char temp[512];
+		toString(temp, sizeof(temp), _instruction);
+		bx::write(writer, temp, (int32_t)strlen(temp) );
+		return true;
+	}
+
+	void disassembleByteCode(bx::WriterI* _writer, bx::ReaderSeekerI* _reader, bx::Error* _err)
+	{
+		uint32_t magic;
+		bx::peek(_reader, magic);
+
+		if (magic == 0x07230203)
+		{
+			SpirV spirv;
+			read(_reader, spirv, _err);
+			parse(spirv.shader, printAsm, _writer, _err);
+		}
+		else if (magic != BX_MAKEFOURCC('D', 'X', 'B', 'C') )
+		{
+			Dx9bc dx9bc;
+			read(_reader, dx9bc, _err);
+			parse(dx9bc.shader, printAsm, _writer, _err);
+		}
+		else
+		{
+			DxbcContext dxbc;
+			read(_reader, dxbc, _err);
+			parse(dxbc.shader, printAsm, _writer, _err);
+		}
+	}
+
+	void disassemble(bx::WriterI* _writer, bx::ReaderSeekerI* _reader, bx::Error* _err)
+	{
+		BX_ERROR_SCOPE(_err);
+
+		uint32_t magic;
+		bx::peek(_reader, magic);
+
+		if (BGFX_CHUNK_MAGIC_CSH == magic
+		||  BGFX_CHUNK_MAGIC_FSH == magic
+		||  BGFX_CHUNK_MAGIC_VSH == magic)
+		{
+			bx::read(_reader, magic);
+
+			uint32_t iohash;
+			bx::read(_reader, iohash, _err);
+
+			uint16_t count;
+			bx::read(_reader, count, _err);
+
+			for (uint32_t ii = 0; ii < count; ++ii)
+			{
+				uint8_t nameSize;
+				bx::read(_reader, nameSize, _err);
+
+				char name[256];
+				bx::read(_reader, &name, nameSize, _err);
+				name[nameSize] = '\0';
+
+				uint8_t type;
+				bx::read(_reader, type, _err);
+
+				uint8_t num;
+				bx::read(_reader, num, _err);
+
+				uint16_t regIndex;
+				bx::read(_reader, regIndex, _err);
+
+				uint16_t regCount;
+				bx::read(_reader, regCount, _err);
+			}
+
+			uint16_t shaderSize;
+			bx::read(_reader, shaderSize, _err);
+
+			uint8_t* shaderCode = (uint8_t*)BX_ALLOC(g_allocator, shaderSize);
+			bx::read(_reader, shaderCode, shaderSize, _err);
+
+			bx::MemoryReader reader(shaderCode, shaderSize);
+			disassembleByteCode(_writer, &reader, _err);
+
+			bx::write(_writer, '\0');
+
+			BX_FREE(g_allocator, shaderCode);
+		}
+		else
+		{
+			disassembleByteCode(_writer, _reader, _err);
+		}
+	}
+
+	void disassemble(bx::WriterI* _writer, const void* _data, uint32_t _size, bx::Error* _err)
+	{
+		bx::MemoryReader reader(_data, _size);
+		disassemble(_writer, &reader, _err);
+	}
+
+} // namespace bgfx

+ 21 - 0
src/shader.h

@@ -0,0 +1,21 @@
+/*
+ * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
+ */
+
+#ifndef BGFX_SHADER_H
+#define BGFX_SHADER_H
+
+#include <bx/readerwriter.h>
+
+namespace bgfx
+{
+	///
+	void disassemble(bx::WriterI* _writer, bx::ReaderSeekerI* _reader, bx::Error* _err = NULL);
+
+	///
+	void disassemble(bx::WriterI* _writer, const void* _data, uint32_t _size, bx::Error* _err = NULL);
+
+} // namespace bgfx
+
+#endif // BGFX_SHADER_H