renderer_vulkan: Use combined image samplers

* Less descriptors = good
This commit is contained in:
GPUCode
2023-02-23 17:18:15 +02:00
parent 52683adedd
commit 8e8097e7c0
19 changed files with 96 additions and 162 deletions

View File

@ -47,7 +47,7 @@ template <typename T>
template <typename T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool IsPow2(T value) {
return std::has_single_bit(value);
return value != 0 && (value & (value - 1)) == 0;
}
template <typename T>

View File

@ -64,7 +64,6 @@ bool DecodePNG(std::span<const u8> png_data, std::span<u8> out_data) {
if (spng_decoded_image_size(ctx.get(), format, &decoded_len)) {
return false;
}
ASSERT(out_data.size() == decoded_len);
if (spng_decode_image(ctx.get(), out_data.data(), decoded_len, format, 0)) {
return false;

View File

@ -18,9 +18,8 @@ layout (push_constant, std140) uniform DrawInfo {
int reverse_interlaced;
};
layout (set = 0, binding = 0) uniform texture2D screen_textures[3];
layout (set = 0, binding = 1) uniform sampler screen_sampler;
layout (set = 0, binding = 0) uniform sampler2D screen_textures[3];
void main() {
color = texture(sampler2D(screen_textures[screen_id_l], screen_sampler), frag_tex_coord);
}
color = texture(screen_textures[screen_id_l], frag_tex_coord);
}

View File

@ -30,11 +30,10 @@ layout (push_constant, std140) uniform DrawInfo {
int reverse_interlaced;
};
layout (set = 0, binding = 0) uniform texture2D screen_textures[3];
layout (set = 0, binding = 1) uniform sampler screen_sampler;
layout (set = 0, binding = 0) uniform sampler2D screen_textures[3];
void main() {
vec4 color_tex_l = texture(sampler2D(screen_textures[screen_id_l], screen_sampler), frag_tex_coord);
vec4 color_tex_r = texture(sampler2D(screen_textures[screen_id_r], screen_sampler), frag_tex_coord);
vec4 color_tex_l = texture(screen_textures[screen_id_l], frag_tex_coord);
vec4 color_tex_r = texture(screen_textures[screen_id_r], frag_tex_coord);
color = vec4(color_tex_l.rgb*l+color_tex_r.rgb*r, color_tex_l.a);
}
}

View File

@ -18,13 +18,12 @@ layout (push_constant, std140) uniform DrawInfo {
int reverse_interlaced;
};
layout (set = 0, binding = 0) uniform texture2D screen_textures[3];
layout (set = 0, binding = 1) uniform sampler screen_sampler;
layout (set = 0, binding = 0) uniform sampler2D screen_textures[3];
void main() {
float screen_row = o_resolution.x * frag_tex_coord.x;
if (int(screen_row) % 2 == reverse_interlaced)
color = texture(sampler2D(screen_textures[screen_id_l], screen_sampler), frag_tex_coord);
color = texture(screen_textures[screen_id_l], frag_tex_coord);
else
color = texture(sampler2D(screen_textures[screen_id_r], screen_sampler), frag_tex_coord);
}
color = texture(screen_textures[screen_id_r], frag_tex_coord);
}

View File

@ -204,7 +204,7 @@ void CustomTexManager::DecodeToStaging(const Texture& texture, const StagingData
}
if (compatibility_mode) {
const u32 stride = texture.width * 4;
// FlipTexture(staging.mapped, texture.width, texture.height, stride);
FlipTexture(staging.mapped, texture.width, texture.height, stride);
}
break;
case CustomFileFormat::DDS:

View File

@ -1538,7 +1538,7 @@ do {
}
out += '}';
LOG_INFO(Render_OpenGL, "{}", out);
return {std::move(out)};
}

View File

@ -226,11 +226,11 @@ void RendererVulkan::BeginRendering(Frame* frame) {
for (std::size_t i = 0; i < screen_infos.size(); i++) {
const auto& info = screen_infos[i];
present_textures[i] = vk::DescriptorImageInfo{
.sampler = present_samplers[current_sampler],
.imageView = info.image_view,
.imageLayout = vk::ImageLayout::eGeneral,
};
}
present_textures[3].sampler = present_samplers[current_sampler];
vk::DescriptorSet set = desc_manager.AllocateSet(present_descriptor_layout);
instance.GetDevice().updateDescriptorSetWithTemplate(set, present_update_template,
@ -320,51 +320,33 @@ void RendererVulkan::CompileShaders() {
}
void RendererVulkan::BuildLayouts() {
const std::array present_layout_bindings = {
vk::DescriptorSetLayoutBinding{
.binding = 0,
.descriptorType = vk::DescriptorType::eSampledImage,
.descriptorCount = 3,
.stageFlags = vk::ShaderStageFlagBits::eFragment,
},
vk::DescriptorSetLayoutBinding{
.binding = 1,
.descriptorType = vk::DescriptorType::eSampler,
.descriptorCount = 1,
.stageFlags = vk::ShaderStageFlagBits::eFragment,
},
const vk::DescriptorSetLayoutBinding present_layout_binding = {
.binding = 0,
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
.descriptorCount = 3,
.stageFlags = vk::ShaderStageFlagBits::eFragment,
};
const vk::DescriptorSetLayoutCreateInfo present_layout_info = {
.bindingCount = static_cast<u32>(present_layout_bindings.size()),
.pBindings = present_layout_bindings.data(),
.bindingCount = 1,
.pBindings = &present_layout_binding,
};
const vk::Device device = instance.GetDevice();
present_descriptor_layout = device.createDescriptorSetLayout(present_layout_info);
const std::array update_template_entries = {
vk::DescriptorUpdateTemplateEntry{
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 3,
.descriptorType = vk::DescriptorType::eSampledImage,
.offset = 0,
.stride = sizeof(vk::DescriptorImageInfo),
},
vk::DescriptorUpdateTemplateEntry{
.dstBinding = 1,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = vk::DescriptorType::eSampler,
.offset = 3 * sizeof(vk::DescriptorImageInfo),
.stride = 0,
},
const vk::DescriptorUpdateTemplateEntry update_template_entry = {
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 3,
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
.offset = 0,
.stride = sizeof(vk::DescriptorImageInfo),
};
const vk::DescriptorUpdateTemplateCreateInfo template_info = {
.descriptorUpdateEntryCount = static_cast<u32>(update_template_entries.size()),
.pDescriptorUpdateEntries = update_template_entries.data(),
.descriptorUpdateEntryCount = 1,
.pDescriptorUpdateEntries = &update_template_entry,
.templateType = vk::DescriptorUpdateTemplateType::eDescriptorSet,
.descriptorSetLayout = present_descriptor_layout,
};

View File

@ -165,7 +165,7 @@ private:
/// Display information for top and bottom screens respectively
std::array<ScreenInfo, 3> screen_infos{};
std::array<vk::DescriptorImageInfo, 4> present_textures{};
std::array<vk::DescriptorImageInfo, 3> present_textures{};
PresentUniformData draw_info{};
vk::ClearColorValue clear_color{};
};

View File

@ -31,21 +31,10 @@ constexpr static std::array RASTERIZER_SETS = {
// Texture set
.bindings =
{
vk::DescriptorType::eSampledImage,
vk::DescriptorType::eSampledImage,
vk::DescriptorType::eSampledImage,
vk::DescriptorType::eSampledImage,
},
.binding_count = 4,
},
Bindings{
// Sampler set
.bindings =
{
vk::DescriptorType::eSampler,
vk::DescriptorType::eSampler,
vk::DescriptorType::eSampler,
vk::DescriptorType::eSampler,
vk::DescriptorType::eCombinedImageSampler,
vk::DescriptorType::eCombinedImageSampler,
vk::DescriptorType::eCombinedImageSampler,
vk::DescriptorType::eCombinedImageSampler,
},
.binding_count = 4,
},
@ -76,6 +65,7 @@ constexpr vk::ShaderStageFlags ToVkStageFlags(vk::DescriptorType type) {
switch (type) {
case vk::DescriptorType::eSampler:
case vk::DescriptorType::eSampledImage:
case vk::DescriptorType::eCombinedImageSampler:
case vk::DescriptorType::eUniformTexelBuffer:
case vk::DescriptorType::eStorageImage:
flags = vk::ShaderStageFlagBits::eFragment;

View File

@ -9,8 +9,8 @@
namespace Vulkan {
constexpr u32 MAX_DESCRIPTORS = 8;
constexpr u32 MAX_DESCRIPTOR_SETS = 4;
constexpr u32 MAX_DESCRIPTORS = 7;
constexpr u32 MAX_DESCRIPTOR_SETS = 3;
union DescriptorData {
vk::DescriptorImageInfo image_info;

View File

@ -635,8 +635,9 @@ void PipelineCache::UseFragmentShader(const Pica::Regs& regs) {
shader_hashes[ProgramType::FS] = config.Hash();
}
void PipelineCache::BindTexture(u32 binding, vk::ImageView image_view) {
void PipelineCache::BindTexture(u32 binding, vk::ImageView image_view, vk::Sampler sampler) {
const vk::DescriptorImageInfo image_info = {
.sampler = sampler,
.imageView = image_view,
.imageLayout = vk::ImageLayout::eGeneral,
};
@ -648,7 +649,7 @@ void PipelineCache::BindStorageImage(u32 binding, vk::ImageView image_view) {
.imageView = image_view,
.imageLayout = vk::ImageLayout::eGeneral,
};
desc_manager.SetBinding(3, binding, DescriptorData{image_info});
desc_manager.SetBinding(2, binding, DescriptorData{image_info});
}
void PipelineCache::BindBuffer(u32 binding, vk::Buffer buffer, u32 offset, u32 size) {
@ -670,16 +671,6 @@ void PipelineCache::BindTexelBuffer(u32 binding, vk::BufferView buffer_view) {
desc_manager.SetBinding(0, binding, data);
}
void PipelineCache::BindSampler(u32 binding, vk::Sampler sampler) {
const DescriptorData data = {
.image_info =
vk::DescriptorImageInfo{
.sampler = sampler,
},
};
desc_manager.SetBinding(2, binding, data);
}
void PipelineCache::ApplyDynamic(const PipelineInfo& info, bool is_dirty) {
scheduler.Record([is_dirty, current_dynamic = current_info.dynamic,
dynamic = info.dynamic](vk::CommandBuffer cmdbuf) {

View File

@ -204,7 +204,7 @@ public:
void UseFragmentShader(const Pica::Regs& regs);
/// Binds a texture to the specified binding
void BindTexture(u32 binding, vk::ImageView image_view);
void BindTexture(u32 binding, vk::ImageView image_view, vk::Sampler sampler);
/// Binds a storage image to the specified binding
void BindStorageImage(u32 binding, vk::ImageView image_view);
@ -215,9 +215,6 @@ public:
/// Binds a buffer to the specified binding
void BindTexelBuffer(u32 binding, vk::BufferView buffer_view);
/// Binds a sampler to the specified binding
void BindSampler(u32 binding, vk::Sampler sampler);
private:
/// Applies dynamic pipeline state to the current command buffer
void ApplyDynamic(const PipelineInfo& info, bool is_dirty);

View File

@ -129,8 +129,7 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory,
const Sampler& null_sampler = res_cache.GetSampler(VideoCore::NULL_SAMPLER_ID);
for (u32 i = 0; i < 4; i++) {
pipeline_cache.BindTexture(i, null_surface.ImageView());
pipeline_cache.BindSampler(i, null_sampler.Handle());
pipeline_cache.BindTexture(i, null_surface.ImageView(), null_sampler.Handle());
}
for (u32 i = 0; i < 7; i++) {
@ -629,12 +628,10 @@ void RasterizerVulkan::SyncTextureUnits(const Framebuffer& framebuffer) {
auto surface = res_cache.GetTextureCube(config);
if (surface) {
pipeline_cache.BindTexture(3, surface->ImageView());
pipeline_cache.BindTexture(3, surface->ImageView(), sampler.Handle());
} else {
pipeline_cache.BindTexture(3, null_surface.ImageView());
pipeline_cache.BindTexture(3, null_surface.ImageView(), sampler.Handle());
}
pipeline_cache.BindSampler(3, sampler.Handle());
continue; // Texture unit 0 setup finished. Continue to next unit
}
default:
@ -642,8 +639,6 @@ void RasterizerVulkan::SyncTextureUnits(const Framebuffer& framebuffer) {
}
}
pipeline_cache.BindSampler(texture_index, sampler.Handle());
auto surface = res_cache.GetTextureSurface(texture);
if (surface) {
if (color_view == surface->ImageView()) {
@ -658,9 +653,10 @@ void RasterizerVulkan::SyncTextureUnits(const Framebuffer& framebuffer) {
.extent = {temp.GetScaledWidth(), temp.GetScaledHeight()},
};
runtime.CopyTextures(static_cast<Surface&>(*framebuffer.Color()), temp, copy);
pipeline_cache.BindTexture(texture_index, temp.ImageView());
pipeline_cache.BindTexture(texture_index, temp.ImageView(), sampler.Handle());
} else {
pipeline_cache.BindTexture(texture_index, surface->ImageView());
pipeline_cache.BindTexture(texture_index, surface->ImageView(),
sampler.Handle());
}
} else {
@ -671,12 +667,13 @@ void RasterizerVulkan::SyncTextureUnits(const Framebuffer& framebuffer) {
// the geometry in question.
// For example: a bug in Pokemon X/Y causes NULL-texture squares to be drawn
// on the male character's face, which in the OpenGL default appear black.
pipeline_cache.BindTexture(texture_index, null_surface.ImageView());
pipeline_cache.BindTexture(texture_index, null_surface.ImageView(),
sampler.Handle());
}
} else {
const Sampler& null_sampler = res_cache.GetSampler(VideoCore::NULL_SAMPLER_ID);
pipeline_cache.BindTexture(texture_index, null_surface.ImageView());
pipeline_cache.BindSampler(texture_index, null_sampler.Handle());
pipeline_cache.BindTexture(texture_index, null_surface.ImageView(),
null_sampler.Handle());
}
}
}

View File

@ -128,11 +128,10 @@ void DescriptorPool::Allocate(std::size_t begin, std::size_t end) {
vk::DescriptorPool& pool = pools.emplace_back();
// Choose a sane pool size good for most games
static constexpr std::array<vk::DescriptorPoolSize, 5> pool_sizes = {{
{vk::DescriptorType::eUniformBuffer, 4096},
{vk::DescriptorType::eSampledImage, 4096},
{vk::DescriptorType::eSampler, 4096},
{vk::DescriptorType::eUniformTexelBuffer, 2048},
static constexpr std::array<vk::DescriptorPoolSize, 4> pool_sizes = {{
{vk::DescriptorType::eUniformBuffer, 1024},
{vk::DescriptorType::eCombinedImageSampler, 2048},
{vk::DescriptorType::eUniformTexelBuffer, 1024},
{vk::DescriptorType::eStorageImage, 1024},
}};

View File

@ -289,13 +289,13 @@ static std::string SampleTexture(const PicaFSConfig& config, unsigned texture_un
// Only unit 0 respects the texturing type
switch (state.texture0_type) {
case TexturingRegs::TextureConfig::Texture2D:
return "textureLod(sampler2D(tex0, tex0_sampler), texcoord0, getLod(texcoord0 * "
"vec2(textureSize(sampler2D(tex0, tex0_sampler), 0))) + tex_lod_bias[0])";
return "textureLod(tex0, texcoord0, getLod(texcoord0 * "
"vec2(textureSize(tex0, 0))) + tex_lod_bias[0])";
case TexturingRegs::TextureConfig::Projection2D:
// TODO (wwylele): find the exact LOD formula for projection texture
return "textureProj(sampler2D(tex0, tex0_sampler), vec3(texcoord0, texcoord0_w))";
return "textureProj(tex0, vec3(texcoord0, texcoord0_w))";
case TexturingRegs::TextureConfig::TextureCube:
return "texture(samplerCube(tex_cube, tex_cube_sampler), vec3(texcoord0, texcoord0_w))";
return "texture(tex_cube, vec3(texcoord0, texcoord0_w))";
case TexturingRegs::TextureConfig::Shadow2D:
return "shadowTexture(texcoord0, texcoord0_w)";
case TexturingRegs::TextureConfig::ShadowCube:
@ -305,18 +305,18 @@ static std::string SampleTexture(const PicaFSConfig& config, unsigned texture_un
default:
LOG_CRITICAL(HW_GPU, "Unhandled texture type {:x}", state.texture0_type);
UNIMPLEMENTED();
return "texture(sampler2D(tex0, tex0_sampler), texcoord0)";
return "texture(tex0, texcoord0)";
}
case 1:
return "textureLod(sampler2D(tex1, tex1_sampler), texcoord1, getLod(texcoord1 * "
"vec2(textureSize(sampler2D(tex1, tex1_sampler), 0))) + tex_lod_bias[1])";
return "textureLod(tex1, texcoord1, getLod(texcoord1 * "
"vec2(textureSize(tex1, 0))) + tex_lod_bias[1])";
case 2:
if (state.texture2_use_coord1)
return "textureLod(sampler2D(tex2, tex2_sampler), texcoord1, getLod(texcoord1 * "
"vec2(textureSize(sampler2D(tex2, tex2_sampler), 0))) + tex_lod_bias[2])";
return "textureLod(tex2, texcoord1, getLod(texcoord1 * "
"vec2(textureSize(tex2, 0))) + tex_lod_bias[2])";
else
return "textureLod(sampler2D(tex2, tex2_sampler), texcoord2, getLod(texcoord2 * "
"vec2(textureSize(sampler2D(tex2, tex2_sampler), 0))) + tex_lod_bias[2])";
return "textureLod(tex2, texcoord2, getLod(texcoord2 * "
"vec2(textureSize(tex2, 0))) + tex_lod_bias[2])";
case 3:
if (state.proctex.enable) {
return "ProcTex()";
@ -1217,23 +1217,18 @@ layout(set = 0, binding = 2) uniform samplerBuffer texture_buffer_lut_lf;
layout(set = 0, binding = 3) uniform samplerBuffer texture_buffer_lut_rg;
layout(set = 0, binding = 4) uniform samplerBuffer texture_buffer_lut_rgba;
layout(set = 1, binding = 0) uniform texture2D tex0;
layout(set = 1, binding = 1) uniform texture2D tex1;
layout(set = 1, binding = 2) uniform texture2D tex2;
layout(set = 1, binding = 3) uniform textureCube tex_cube;
layout(set = 1, binding = 0) uniform sampler2D tex0;
layout(set = 1, binding = 1) uniform sampler2D tex1;
layout(set = 1, binding = 2) uniform sampler2D tex2;
layout(set = 1, binding = 3) uniform samplerCube tex_cube;
layout(set = 2, binding = 0) uniform sampler tex0_sampler;
layout(set = 2, binding = 1) uniform sampler tex1_sampler;
layout(set = 2, binding = 2) uniform sampler tex2_sampler;
layout(set = 2, binding = 3) uniform sampler tex_cube_sampler;
layout(set = 3, binding = 0, r32ui) uniform readonly uimage2D shadow_texture_px;
layout(set = 3, binding = 1, r32ui) uniform readonly uimage2D shadow_texture_nx;
layout(set = 3, binding = 2, r32ui) uniform readonly uimage2D shadow_texture_py;
layout(set = 3, binding = 3, r32ui) uniform readonly uimage2D shadow_texture_ny;
layout(set = 3, binding = 4, r32ui) uniform readonly uimage2D shadow_texture_pz;
layout(set = 3, binding = 5, r32ui) uniform readonly uimage2D shadow_texture_nz;
layout(set = 3, binding = 6, r32ui) uniform uimage2D shadow_buffer;
layout(set = 2, binding = 0, r32ui) uniform readonly uimage2D shadow_texture_px;
layout(set = 2, binding = 1, r32ui) uniform readonly uimage2D shadow_texture_nx;
layout(set = 2, binding = 2, r32ui) uniform readonly uimage2D shadow_texture_py;
layout(set = 2, binding = 3, r32ui) uniform readonly uimage2D shadow_texture_ny;
layout(set = 2, binding = 4, r32ui) uniform readonly uimage2D shadow_texture_pz;
layout(set = 2, binding = 5, r32ui) uniform readonly uimage2D shadow_texture_nz;
layout(set = 2, binding = 6, r32ui) uniform uimage2D shadow_buffer;
)";
out += UniformBlockDef;

View File

@ -667,10 +667,8 @@ Id FragmentModule::SampleTexture(u32 texture_unit) {
// This LOD formula is the same as the LOD lower limit defined in OpenGL.
// f(x, y) >= max{m_u, m_v, m_w}
// (See OpenGL 4.6 spec, 8.14.1 - Scale Factor and Level-of-Detail)
const auto SampleLod = [this, texture_unit](Id tex_id, Id tex_sampler_id, Id texcoord_id) {
const Id tex{OpLoad(image2d_id, tex_id)};
const Id tex_sampler{OpLoad(sampler_id, tex_sampler_id)};
const Id sampled_image{OpSampledImage(TypeSampledImage(image2d_id), tex, tex_sampler)};
const auto SampleLod = [this, texture_unit](Id tex_id, Id texcoord_id) {
const Id sampled_image{OpLoad(TypeSampledImage(image2d_id), tex_id)};
const Id tex_image{OpImage(image2d_id, sampled_image)};
const Id tex_size{OpImageQuerySizeLod(ivec_ids.Get(2), tex_image, ConstS32(0))};
const Id texcoord{OpLoad(vec_ids.Get(2), texcoord_id)};
@ -687,11 +685,9 @@ Id FragmentModule::SampleTexture(u32 texture_unit) {
spv::ImageOperandsMask::Lod, biased_lod);
};
const auto Sample = [this](Id tex_id, Id tex_sampler_id, bool projection) {
const auto Sample = [this](Id tex_id, bool projection) {
const Id image_type = tex_id.value == tex_cube_id.value ? image_cube_id : image2d_id;
const Id tex{OpLoad(image_type, tex_id)};
const Id tex_sampler{OpLoad(sampler_id, tex_sampler_id)};
const Id sampled_image{OpSampledImage(TypeSampledImage(image_type), tex, tex_sampler)};
const Id sampled_image{OpLoad(TypeSampledImage(image_type), tex_id)};
const Id texcoord0{OpLoad(vec_ids.Get(2), texcoord0_id)};
const Id texcoord0_w{OpLoad(f32_id, texcoord0_w_id)};
const Id coord{OpCompositeConstruct(vec_ids.Get(3),
@ -709,11 +705,11 @@ Id FragmentModule::SampleTexture(u32 texture_unit) {
// Only unit 0 respects the texturing type
switch (state.texture0_type) {
case Pica::TexturingRegs::TextureConfig::Texture2D:
return SampleLod(tex0_id, tex0_sampler_id, texcoord0_id);
return SampleLod(tex0_id, texcoord0_id);
case Pica::TexturingRegs::TextureConfig::Projection2D:
return Sample(tex0_id, tex0_sampler_id, true);
return Sample(tex0_id, true);
case Pica::TexturingRegs::TextureConfig::TextureCube:
return Sample(tex_cube_id, tex_cube_sampler_id, false);
return Sample(tex_cube_id, false);
case Pica::TexturingRegs::TextureConfig::Shadow2D:
return SampleShadow();
// case Pica::TexturingRegs::TextureConfig::ShadowCube:
@ -726,12 +722,12 @@ Id FragmentModule::SampleTexture(u32 texture_unit) {
return zero_vec;
}
case 1:
return SampleLod(tex1_id, tex1_sampler_id, texcoord1_id);
return SampleLod(tex1_id, texcoord1_id);
case 2:
if (state.texture2_use_coord1) {
return SampleLod(tex2_id, tex2_sampler_id, texcoord1_id);
return SampleLod(tex2_id, texcoord1_id);
} else {
return SampleLod(tex2_id, tex2_sampler_id, texcoord2_id);
return SampleLod(tex2_id, texcoord2_id);
}
case 3:
if (state.proctex.enable) {
@ -1445,15 +1441,11 @@ void FragmentModule::DefineInterface() {
texture_buffer_lut_lf_id = DefineUniformConst(TypeSampledImage(image_buffer_id), 0, 2);
texture_buffer_lut_rg_id = DefineUniformConst(TypeSampledImage(image_buffer_id), 0, 3);
texture_buffer_lut_rgba_id = DefineUniformConst(TypeSampledImage(image_buffer_id), 0, 4);
tex0_id = DefineUniformConst(image2d_id, 1, 0);
tex1_id = DefineUniformConst(image2d_id, 1, 1);
tex2_id = DefineUniformConst(image2d_id, 1, 2);
tex_cube_id = DefineUniformConst(image_cube_id, 1, 3);
tex0_sampler_id = DefineUniformConst(sampler_id, 2, 0);
tex1_sampler_id = DefineUniformConst(sampler_id, 2, 1);
tex2_sampler_id = DefineUniformConst(sampler_id, 2, 2);
tex_cube_sampler_id = DefineUniformConst(sampler_id, 2, 3);
shadow_texture_px_id = DefineUniformConst(image_r32_id, 3, 0, true);
tex0_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 0);
tex1_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 1);
tex2_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 2);
tex_cube_id = DefineUniformConst(TypeSampledImage(image_cube_id), 1, 3);
shadow_texture_px_id = DefineUniformConst(image_r32_id, 2, 0, true);
// Define built-ins
gl_frag_coord_id = DefineVar(vec_ids.Get(4), spv::StorageClass::Input);

View File

@ -240,10 +240,6 @@ private:
Id tex1_id{};
Id tex2_id{};
Id tex_cube_id{};
Id tex0_sampler_id{};
Id tex1_sampler_id{};
Id tex2_sampler_id{};
Id tex_cube_sampler_id{};
Id texture_buffer_lut_lf_id{};
Id texture_buffer_lut_rg_id{};
Id texture_buffer_lut_rgba_id{};

View File

@ -730,7 +730,6 @@ bool TextureRuntime::BlitTextures(Surface& source, Surface& dest,
}
void TextureRuntime::GenerateMipmaps(Surface& surface) {
return;
if (surface.custom_format != VideoCore::CustomPixelFormat::RGBA8) {
LOG_ERROR(Render_Vulkan, "Generating mipmaps for compressed formats unsupported!");
return;
@ -1338,8 +1337,8 @@ Sampler::Sampler(TextureRuntime& runtime, VideoCore::SamplerParams params)
.maxAnisotropy = properties.limits.maxSamplerAnisotropy,
.compareEnable = false,
.compareOp = vk::CompareOp::eAlways,
.minLod = 0.f * lod_min,
.maxLod = 0.f * lod_max,
.minLod = lod_min,
.maxLod = lod_max,
.borderColor =
use_border_color ? vk::BorderColor::eFloatCustomEXT : vk::BorderColor::eIntOpaqueBlack,
.unnormalizedCoordinates = false,