mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-11-20 08:10:08 +00:00
gl_shader_decompiler: Implement image binding settings
This commit is contained in:
parent
9097301d92
commit
1bf4154e7d
5 changed files with 52 additions and 24 deletions
|
@ -190,6 +190,10 @@ CachedProgram SpecializeShader(const std::string& code, const GLShader::ShaderEn
|
||||||
source += fmt::format("#define SAMPLER_BINDING_{} {}\n", sampler.GetIndex(),
|
source += fmt::format("#define SAMPLER_BINDING_{} {}\n", sampler.GetIndex(),
|
||||||
base_bindings.sampler++);
|
base_bindings.sampler++);
|
||||||
}
|
}
|
||||||
|
for (const auto& image : entries.images) {
|
||||||
|
source +=
|
||||||
|
fmt::format("#define IMAGE_BINDING_{} {}\n", image.GetIndex(), base_bindings.image++);
|
||||||
|
}
|
||||||
|
|
||||||
// Transform 1D textures to texture samplers by declaring its preprocessor macros.
|
// Transform 1D textures to texture samplers by declaring its preprocessor macros.
|
||||||
for (std::size_t i = 0; i < texture_buffer_usage.size(); ++i) {
|
for (std::size_t i = 0; i < texture_buffer_usage.size(); ++i) {
|
||||||
|
|
|
@ -235,6 +235,9 @@ public:
|
||||||
for (const auto& sampler : ir.GetSamplers()) {
|
for (const auto& sampler : ir.GetSamplers()) {
|
||||||
entries.samplers.emplace_back(sampler);
|
entries.samplers.emplace_back(sampler);
|
||||||
}
|
}
|
||||||
|
for (const auto& image : ir.GetImages()) {
|
||||||
|
entries.images.emplace_back(image);
|
||||||
|
}
|
||||||
for (const auto& gmem_pair : ir.GetGlobalMemory()) {
|
for (const auto& gmem_pair : ir.GetGlobalMemory()) {
|
||||||
const auto& [base, usage] = gmem_pair;
|
const auto& [base, usage] = gmem_pair;
|
||||||
entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset,
|
entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset,
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct ShaderEntries;
|
||||||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||||
using ProgramResult = std::pair<std::string, ShaderEntries>;
|
using ProgramResult = std::pair<std::string, ShaderEntries>;
|
||||||
using SamplerEntry = VideoCommon::Shader::Sampler;
|
using SamplerEntry = VideoCommon::Shader::Sampler;
|
||||||
|
using ImageEntry = VideoCommon::Shader::Image;
|
||||||
|
|
||||||
class ConstBufferEntry : public VideoCommon::Shader::ConstBuffer {
|
class ConstBufferEntry : public VideoCommon::Shader::ConstBuffer {
|
||||||
public:
|
public:
|
||||||
|
@ -74,6 +75,7 @@ struct ShaderEntries {
|
||||||
std::vector<ConstBufferEntry> const_buffers;
|
std::vector<ConstBufferEntry> const_buffers;
|
||||||
std::vector<SamplerEntry> samplers;
|
std::vector<SamplerEntry> samplers;
|
||||||
std::vector<SamplerEntry> bindless_samplers;
|
std::vector<SamplerEntry> bindless_samplers;
|
||||||
|
std::vector<ImageEntry> images;
|
||||||
std::vector<GlobalMemoryEntry> global_memory_entries;
|
std::vector<GlobalMemoryEntry> global_memory_entries;
|
||||||
std::array<bool, Maxwell::NumClipDistances> clip_distances{};
|
std::array<bool, Maxwell::NumClipDistances> clip_distances{};
|
||||||
std::size_t shader_length{};
|
std::size_t shader_length{};
|
||||||
|
|
|
@ -34,11 +34,11 @@ enum class PrecompiledEntryKind : u32 {
|
||||||
Dump,
|
Dump,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr u32 NativeVersion = 2;
|
constexpr u32 NativeVersion = 3;
|
||||||
|
|
||||||
// Making sure sizes doesn't change by accident
|
// Making sure sizes doesn't change by accident
|
||||||
static_assert(sizeof(BaseBindings) == 12);
|
static_assert(sizeof(BaseBindings) == 16);
|
||||||
static_assert(sizeof(ShaderDiskCacheUsage) == 32);
|
static_assert(sizeof(ShaderDiskCacheUsage) == 40);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -285,8 +285,7 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
|
||||||
if (!LoadObjectFromPrecompiled(code_size)) {
|
if (!LoadObjectFromPrecompiled(code_size)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
std::vector<u8> code(code_size);
|
||||||
std::string code(code_size, '\0');
|
|
||||||
if (!LoadArrayFromPrecompiled(code.data(), code.size())) {
|
if (!LoadArrayFromPrecompiled(code.data(), code.size())) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -298,7 +297,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
|
||||||
if (!LoadObjectFromPrecompiled(const_buffers_count)) {
|
if (!LoadObjectFromPrecompiled(const_buffers_count)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < const_buffers_count; ++i) {
|
for (u32 i = 0; i < const_buffers_count; ++i) {
|
||||||
u32 max_offset{};
|
u32 max_offset{};
|
||||||
u32 index{};
|
u32 index{};
|
||||||
|
@ -314,7 +312,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
|
||||||
if (!LoadObjectFromPrecompiled(samplers_count)) {
|
if (!LoadObjectFromPrecompiled(samplers_count)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < samplers_count; ++i) {
|
for (u32 i = 0; i < samplers_count; ++i) {
|
||||||
u64 offset{};
|
u64 offset{};
|
||||||
u64 index{};
|
u64 index{};
|
||||||
|
@ -332,11 +329,28 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
|
||||||
static_cast<Tegra::Shader::TextureType>(type), is_array, is_shadow, is_bindless);
|
static_cast<Tegra::Shader::TextureType>(type), is_array, is_shadow, is_bindless);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 images_count{};
|
||||||
|
if (!LoadObjectFromPrecompiled(images_count)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
for (u32 i = 0; i < images_count; ++i) {
|
||||||
|
u64 offset{};
|
||||||
|
u64 index{};
|
||||||
|
u32 type{};
|
||||||
|
u8 is_bindless{};
|
||||||
|
if (!LoadObjectFromPrecompiled(offset) || !LoadObjectFromPrecompiled(index) ||
|
||||||
|
!LoadObjectFromPrecompiled(type) || !LoadObjectFromPrecompiled(is_bindless)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
entry.entries.images.emplace_back(
|
||||||
|
static_cast<std::size_t>(offset), static_cast<std::size_t>(index),
|
||||||
|
static_cast<Tegra::Shader::ImageType>(type), is_bindless != 0);
|
||||||
|
}
|
||||||
|
|
||||||
u32 global_memory_count{};
|
u32 global_memory_count{};
|
||||||
if (!LoadObjectFromPrecompiled(global_memory_count)) {
|
if (!LoadObjectFromPrecompiled(global_memory_count)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < global_memory_count; ++i) {
|
for (u32 i = 0; i < global_memory_count; ++i) {
|
||||||
u32 cbuf_index{};
|
u32 cbuf_index{};
|
||||||
u32 cbuf_offset{};
|
u32 cbuf_offset{};
|
||||||
|
@ -360,7 +374,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
|
||||||
if (!LoadObjectFromPrecompiled(shader_length)) {
|
if (!LoadObjectFromPrecompiled(shader_length)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.entries.shader_length = static_cast<std::size_t>(shader_length);
|
entry.entries.shader_length = static_cast<std::size_t>(shader_length);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -400,6 +413,18 @@ bool ShaderDiskCacheOpenGL::SaveDecompiledFile(u64 unique_identifier, const std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SaveObjectToPrecompiled(static_cast<u32>(entries.images.size()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const auto& image : entries.images) {
|
||||||
|
if (!SaveObjectToPrecompiled(static_cast<u64>(image.GetOffset())) ||
|
||||||
|
!SaveObjectToPrecompiled(static_cast<u64>(image.GetIndex())) ||
|
||||||
|
!SaveObjectToPrecompiled(static_cast<u32>(image.GetType())) ||
|
||||||
|
!SaveObjectToPrecompiled(static_cast<u8>(image.IsBindless() ? 1 : 0))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!SaveObjectToPrecompiled(static_cast<u32>(entries.global_memory_entries.size()))) {
|
if (!SaveObjectToPrecompiled(static_cast<u32>(entries.global_memory_entries.size()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,11 @@ struct BaseBindings {
|
||||||
u32 cbuf{};
|
u32 cbuf{};
|
||||||
u32 gmem{};
|
u32 gmem{};
|
||||||
u32 sampler{};
|
u32 sampler{};
|
||||||
|
u32 image{};
|
||||||
|
|
||||||
bool operator==(const BaseBindings& rhs) const {
|
bool operator==(const BaseBindings& rhs) const {
|
||||||
return std::tie(cbuf, gmem, sampler) == std::tie(rhs.cbuf, rhs.gmem, rhs.sampler);
|
return std::tie(cbuf, gmem, sampler, image) ==
|
||||||
|
std::tie(rhs.cbuf, rhs.gmem, rhs.sampler, rhs.image);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const BaseBindings& rhs) const {
|
bool operator!=(const BaseBindings& rhs) const {
|
||||||
|
@ -91,8 +93,11 @@ namespace std {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct hash<OpenGL::BaseBindings> {
|
struct hash<OpenGL::BaseBindings> {
|
||||||
std::size_t operator()(const OpenGL::BaseBindings& bindings) const noexcept {
|
std::size_t operator()(const OpenGL::BaseBindings& bindings) const {
|
||||||
return bindings.cbuf | bindings.gmem << 8 | bindings.sampler << 16;
|
return static_cast<std::size_t>(bindings.cbuf) ^
|
||||||
|
(static_cast<std::size_t>(bindings.gmem) << 8) ^
|
||||||
|
(static_cast<std::size_t>(bindings.sampler) << 16) ^
|
||||||
|
(static_cast<std::size_t>(bindings.image) << 24);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -300,19 +305,8 @@ private:
|
||||||
return LoadArrayFromPrecompiled(&object, 1);
|
return LoadArrayFromPrecompiled(&object, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadObjectFromPrecompiled(bool& object) {
|
|
||||||
u8 value;
|
|
||||||
const bool read_ok = LoadArrayFromPrecompiled(&value, 1);
|
|
||||||
if (!read_ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
object = value != 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Core system
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
// Stores whole precompiled cache which will be read from or saved to the precompiled chache
|
// Stores whole precompiled cache which will be read from or saved to the precompiled chache
|
||||||
// file
|
// file
|
||||||
FileSys::VectorVfsFile precompiled_cache_virtual_file;
|
FileSys::VectorVfsFile precompiled_cache_virtual_file;
|
||||||
|
|
Loading…
Reference in a new issue