From 91e8751bab27cc59a5aebe3b4c018685218c6ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 10 Mar 2016 21:09:32 -0800 Subject: [PATCH] Added shader disassembler. --- src/bgfx_p.h | 1 + src/shader.cpp | 131 +++++++++++++++++++++++++++++++++++++++++++++++++ src/shader.h | 21 ++++++++ 3 files changed, 153 insertions(+) create mode 100644 src/shader.cpp create mode 100644 src/shader.h diff --git a/src/bgfx_p.h b/src/bgfx_p.h index c56d86917..34106718e 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -137,6 +137,7 @@ namespace bgfx #include #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) diff --git a/src/shader.cpp b/src/shader.cpp new file mode 100644 index 000000000..c895c91b9 --- /dev/null +++ b/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(_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(_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(_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 diff --git a/src/shader.h b/src/shader.h new file mode 100644 index 000000000..5ddde589d --- /dev/null +++ b/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 + +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