mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-13 23:50:08 +00:00
Merge branch 'master' of https://github.com/KhronosGroup/SPIRV-Cross
This commit is contained in:
commit
6236cc79f0
24
Makefile
24
Makefile
@ -1,27 +1,37 @@
|
||||
TARGET := spirv-cross
|
||||
SOURCES := $(wildcard *.cpp)
|
||||
|
||||
SOURCES := $(wildcard spirv_*.cpp)
|
||||
CLI_SOURCES := main.cpp
|
||||
|
||||
OBJECTS := $(SOURCES:.cpp=.o)
|
||||
DEPS := $(OBJECTS:.o=.d)
|
||||
CLI_OBJECTS := $(CLI_SOURCES:.cpp=.o)
|
||||
|
||||
STATIC_LIB := lib$(TARGET).a
|
||||
|
||||
DEPS := $(OBJECTS:.o=.d) $(CLI_OBJECTS:.o=.d)
|
||||
|
||||
CXXFLAGS += -std=c++11 -Wall -Wextra
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CXXFLAGS += -O0 -gdwarf-2
|
||||
CXXFLAGS += -O0
|
||||
else
|
||||
CXXFLAGS += -O2 -gdwarf-2
|
||||
CXXFLAGS += -O2
|
||||
endif
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CXX) -o $@ $(OBJECTS) $(LDFLAGS)
|
||||
$(TARGET): $(CLI_OBJECTS) $(STATIC_LIB)
|
||||
$(CXX) -o $@ $(CLI_OBJECTS) $(STATIC_LIB) $(LDFLAGS)
|
||||
|
||||
$(STATIC_LIB): $(OBJECTS)
|
||||
$(AR) rcs $@ $(OBJECTS)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) -c -o $@ $< $(CXXFLAGS) -MMD
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJECTS) $(DEPS)
|
||||
rm -f $(TARGET) $(OBJECTS) $(CLI_OBJECTS) $(STATIC_LIB) $(DEPS)
|
||||
|
||||
.PHONY: clean
|
||||
|
53
README.md
53
README.md
@ -33,6 +33,59 @@ MinGW-w64 based compilation works with `make`, and an MSVC 2013 solution is also
|
||||
|
||||
## Usage
|
||||
|
||||
### Using the C++ API
|
||||
|
||||
To perform reflection and convert to other shader languages you can use the SPIRV-Cross API.
|
||||
For example:
|
||||
|
||||
```
|
||||
#include "spirv_glsl.hpp"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
extern std::vector<uint32_t> load_spirv_file();
|
||||
|
||||
int main()
|
||||
{
|
||||
// Read SPIR-V from disk or similar.
|
||||
std::vector<uint32_t> spirv_binary = load_spirv_file();
|
||||
|
||||
spirv_cross::CompilerGLSL glsl(std::move(spirv_binary));
|
||||
|
||||
// The SPIR-V is now parsed, and we can perform reflection on it.
|
||||
spirv_cross::ShaderResources resources = glsl.get_shader_resources();
|
||||
|
||||
// Get all sampled images in the shader.
|
||||
for (auto &resource : resources.sampled_images)
|
||||
{
|
||||
unsigned set = glsl.get_decoration(resource.id, spv::DecorationDescriptorSet);
|
||||
unsigned binding = glsl.get_decoration(resource.id, spv::DecorationBinding);
|
||||
printf("Image %s at set = %u, binding = %u\n", resource.name.c_str(), set, binding);
|
||||
|
||||
// Modify the decoration to prepare it for GLSL.
|
||||
glsl.unset_decoration(resource.id, spv::DecorationDescriptorSet);
|
||||
|
||||
// Some arbitrary remapping if we want.
|
||||
glsl.set_decoration(resource.id, spv::DecorationBinding, set * 16 + binding);
|
||||
}
|
||||
|
||||
// Set some options.
|
||||
spirv_cross::CompilerGLSL::Options options;
|
||||
options.version = 310;
|
||||
options.es = true;
|
||||
glsl.set_options(options);
|
||||
|
||||
// Compile to GLSL, ready to give to GL driver.
|
||||
std::string source = glsl.compile();
|
||||
}
|
||||
```
|
||||
|
||||
#### Integrating SPIRV-Cross in a custom build system
|
||||
|
||||
To add SPIRV-Cross to your own codebase, just copy the source and header files from root directory
|
||||
and build the relevant .cpp files you need. Make sure to build with C++11 support, e.g. `-std=c++11` in GCC and Clang.
|
||||
Alternatively, the Makefile generates a libspirv-cross.a static library during build that can be linked in.
|
||||
|
||||
### Creating a SPIR-V file from GLSL with glslang
|
||||
|
||||
```
|
||||
|
@ -60,7 +60,7 @@ bool Compiler::block_is_pure(const SPIRBlock &block)
|
||||
{
|
||||
for (auto &i : block.ops)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
switch (op)
|
||||
@ -119,7 +119,7 @@ void Compiler::register_global_read_dependencies(const SPIRBlock &block, uint32_
|
||||
{
|
||||
for (auto &i : block.ops)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
switch (op)
|
||||
@ -458,11 +458,11 @@ static string extract_string(const vector<uint32_t> &spirv, uint32_t offset)
|
||||
void Compiler::parse()
|
||||
{
|
||||
auto len = spirv.size();
|
||||
auto s = stream(0);
|
||||
|
||||
if (len < 5)
|
||||
throw CompilerError("SPIRV file too small.");
|
||||
|
||||
auto s = spirv.data();
|
||||
|
||||
// Endian-swap if we need to.
|
||||
if (s[0] == swap_endian(MagicNumber))
|
||||
transform(begin(spirv), end(spirv), begin(spirv), [](uint32_t c) { return swap_endian(c); });
|
||||
@ -793,7 +793,7 @@ void Compiler::unset_decoration(uint32_t id, Decoration decoration)
|
||||
|
||||
void Compiler::parse(const Instruction &i)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
|
||||
@ -1666,7 +1666,7 @@ bool Compiler::traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHand
|
||||
// inside dead blocks ...
|
||||
for (auto &i : block.ops)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
if (!handler.handle(op, ops, i.length))
|
||||
|
@ -173,11 +173,17 @@ namespace spirv_cross
|
||||
ShaderResources get_shader_resources() const;
|
||||
|
||||
protected:
|
||||
const uint32_t* stream(uint32_t offset) const
|
||||
const uint32_t* stream(const Instruction &instr) const
|
||||
{
|
||||
if (offset > spirv.size())
|
||||
// If we're not going to use any arguments, just return nullptr.
|
||||
// We want to avoid case where we return an out of range pointer
|
||||
// that trips debug assertions on some platforms.
|
||||
if (!instr.length)
|
||||
return nullptr;
|
||||
|
||||
if (instr.offset + instr.length > spirv.size())
|
||||
throw CompilerError("Compiler::stream() out of range.");
|
||||
return &spirv[offset];
|
||||
return &spirv[instr.offset];
|
||||
}
|
||||
std::vector<uint32_t> spirv;
|
||||
|
||||
|
@ -1353,7 +1353,7 @@ void CompilerGLSL::emit_mix_op(uint32_t result_type, uint32_t id,
|
||||
|
||||
void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
|
||||
@ -2274,7 +2274,7 @@ string CompilerGLSL::build_composite_combiner(const uint32_t *elems, uint32_t le
|
||||
|
||||
void CompilerGLSL::emit_instruction(const Instruction &i)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
|
||||
@ -3615,7 +3615,7 @@ void CompilerGLSL::emit_function(SPIRFunction &func, uint64_t return_flags)
|
||||
auto &b = get<SPIRBlock>(block);
|
||||
for (auto &i : b.ops)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
if (op == OpFunctionCall)
|
||||
|
Loading…
Reference in New Issue
Block a user