mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-27 05:04:17 +01:00
Implement Graphics Shader Compilation in ShaderManager
Graphics shaders can now be compiled using the shader compiler and emit SPIR-V that can be used on the host. The binding state isn't currently handled alongside constant buffers and textures support in `GraphicsEnvironment` yet.
This commit is contained in:
parent
353ca8ec84
commit
08afda6ac4
@ -4,6 +4,8 @@
|
|||||||
#include <gpu.h>
|
#include <gpu.h>
|
||||||
#include <shader_compiler/common/settings.h>
|
#include <shader_compiler/common/settings.h>
|
||||||
#include <shader_compiler/common/log.h>
|
#include <shader_compiler/common/log.h>
|
||||||
|
#include <shader_compiler/frontend/maxwell/translate_program.h>
|
||||||
|
#include <shader_compiler/backend/spirv/emit_spirv.h>
|
||||||
#include "shader_manager.h"
|
#include "shader_manager.h"
|
||||||
|
|
||||||
namespace Shader::Log {
|
namespace Shader::Log {
|
||||||
@ -75,4 +77,73 @@ namespace skyline::gpu {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A shader environment for all graphics pipeline stages
|
||||||
|
*/
|
||||||
|
class GraphicsEnvironment : public Shader::Environment {
|
||||||
|
private:
|
||||||
|
std::vector<u8> binary;
|
||||||
|
u32 baseOffset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit GraphicsEnvironment(std::vector<u8> pBinary, u32 baseOffset, Shader::Stage pStage) : binary(std::move(pBinary)), baseOffset(baseOffset) {
|
||||||
|
sph = *reinterpret_cast<Shader::ProgramHeader *>(binary.data());
|
||||||
|
start_address = baseOffset;
|
||||||
|
stage = pStage;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u64 ReadInstruction(u32 address) final {
|
||||||
|
address -= baseOffset;
|
||||||
|
if (binary.size() < (address + sizeof(u64)))
|
||||||
|
throw exception("Out of bounds instruction read: 0x{:X}", address);
|
||||||
|
return *reinterpret_cast<u64 *>(binary.data() + address);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u32 ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) final {
|
||||||
|
throw exception("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] Shader::TextureType ReadTextureType(u32 raw_handle) final {
|
||||||
|
throw exception("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u32 TextureBoundBuffer() const final {
|
||||||
|
throw exception("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u32 LocalMemorySize() const final {
|
||||||
|
return static_cast<u32>(sph.LocalMemorySize()) + sph.common3.shader_local_memory_crs_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u32 SharedMemorySize() const final {
|
||||||
|
return 0; // Shared memory size is only relevant for compute shaders
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::array<u32, 3> WorkgroupSize() const final {
|
||||||
|
return {0, 0, 0}; // Workgroup size is only relevant for compute shaders
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::raii::ShaderModule ShaderManager::CompileGraphicsShader(const std::vector<u8> &binary, Shader::Stage stage, u32 baseOffset, Shader::RuntimeInfo& runtimeInfo) {
|
||||||
|
GraphicsEnvironment environment{binary, baseOffset, stage};
|
||||||
|
Shader::Maxwell::Flow::CFG cfg(environment, flowBlockPool, Shader::Maxwell::Location{static_cast<u32>(baseOffset + sizeof(Shader::ProgramHeader))});
|
||||||
|
|
||||||
|
auto program{Shader::Maxwell::TranslateProgram(instPool, blockPool, environment, cfg, hostTranslateInfo)};
|
||||||
|
|
||||||
|
Shader::Backend::Bindings bindings{};
|
||||||
|
auto spirv{Shader::Backend::SPIRV::EmitSPIRV(profile, runtimeInfo, program, bindings)};
|
||||||
|
|
||||||
|
runtimeInfo.previous_stage_stores = program.info.stores;
|
||||||
|
if (program.is_geometry_passthrough)
|
||||||
|
runtimeInfo.previous_stage_stores.mask |= program.info.passthrough.mask;
|
||||||
|
|
||||||
|
vk::ShaderModuleCreateInfo createInfo{
|
||||||
|
.pCode = spirv.data(),
|
||||||
|
.codeSize = spirv.size() * sizeof(u32),
|
||||||
|
};
|
||||||
|
vk::raii::ShaderModule shaderModule(gpu.vkDevice, createInfo);
|
||||||
|
|
||||||
|
return shaderModule;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
#include <shader_compiler/object_pool.h>
|
||||||
|
#include <shader_compiler/frontend/maxwell/control_flow.h>
|
||||||
|
#include <shader_compiler/frontend/ir/value.h>
|
||||||
|
#include <shader_compiler/frontend/ir/basic_block.h>
|
||||||
|
#include <shader_compiler/runtime_info.h>
|
||||||
#include <shader_compiler/host_translate_info.h>
|
#include <shader_compiler/host_translate_info.h>
|
||||||
#include <shader_compiler/profile.h>
|
#include <shader_compiler/profile.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
@ -15,10 +20,18 @@ namespace skyline::gpu {
|
|||||||
class ShaderManager {
|
class ShaderManager {
|
||||||
private:
|
private:
|
||||||
GPU &gpu;
|
GPU &gpu;
|
||||||
|
Shader::ObjectPool<Shader::Maxwell::Flow::Block> flowBlockPool;
|
||||||
|
Shader::ObjectPool<Shader::IR::Inst> instPool;
|
||||||
|
Shader::ObjectPool<Shader::IR::Block> blockPool;
|
||||||
Shader::HostTranslateInfo hostTranslateInfo;
|
Shader::HostTranslateInfo hostTranslateInfo;
|
||||||
Shader::Profile profile;
|
Shader::Profile profile;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShaderManager(const DeviceState& state, GPU &gpu);
|
ShaderManager(const DeviceState& state, GPU &gpu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @note `runtimeInfo::previous_stage_stores` will automatically be updated for the next stage
|
||||||
|
*/
|
||||||
|
vk::raii::ShaderModule CompileGraphicsShader(const std::vector<u8> &binary, Shader::Stage stage, u32 baseOffset, Shader::RuntimeInfo& runtimeInfo);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user