renderer_vulkan: Don't sample from mipmaps when using texture cubes

* Mipmaps for texture cubes are unimplemented in the rasterizer cache, so sampling from mipmaps will return nothing
This commit is contained in:
GPUCode
2022-10-03 13:39:27 +03:00
parent 177c7de4f9
commit 70c2376fd0
2 changed files with 24 additions and 17 deletions

View File

@ -650,17 +650,24 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
}; };
const auto BindSampler = [&](u32 binding, SamplerInfo& info, const auto BindSampler = [&](u32 binding, SamplerInfo& info,
const Pica::TexturingRegs::FullTextureConfig& texture) { const Pica::TexturingRegs::TextureConfig& config) {
// TODO(GPUCode): Cubemaps don't contain any mipmaps for now, so sampling from them returns nothing
// Always sample from the base level until mipmaps for texture cubes are implemented
// NOTE: There are no Vulkan filter modes that directly correspond to OpenGL minification filters
// GL_LINEAR/GL_NEAREST so emulate them by setting
// minLod = 0, and maxLod = 0.25, and using minFilter = VK_FILTER_LINEAR or minFilter = VK_FILTER_NEAREST
const bool skip_mipmap =
config.type == Pica::TexturingRegs::TextureConfig::TextureCube;
info = SamplerInfo{ info = SamplerInfo{
.mag_filter = texture.config.mag_filter, .mag_filter = config.mag_filter,
.min_filter = texture.config.min_filter, .min_filter = config.min_filter,
.mip_filter = texture.config.mip_filter, .mip_filter = config.mip_filter,
.wrap_s = texture.config.wrap_s, .wrap_s = config.wrap_s,
.wrap_t = texture.config.wrap_t, .wrap_t = config.wrap_t,
.border_color = texture.config.border_color.raw, .border_color = config.border_color.raw,
.lod_min = texture.config.lod.min_level, .lod_min = skip_mipmap ? 0.f : static_cast<float>(config.lod.min_level),
.lod_max = texture.config.lod.max_level, .lod_max = skip_mipmap ? 0.25f : static_cast<float>(config.lod.max_level),
.lod_bias = texture.config.lod.bias .lod_bias = static_cast<float>(config.lod.bias)
}; };
// Search the cache and bind the appropriate sampler // Search the cache and bind the appropriate sampler
@ -726,7 +733,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
pipeline_cache.BindTexture(3, default_texture.image_view); pipeline_cache.BindTexture(3, default_texture.image_view);
} }
BindSampler(3, texture_cube_sampler, texture); BindSampler(3, texture_cube_sampler, texture.config);
continue; // Texture unit 0 setup finished. Continue to next unit continue; // Texture unit 0 setup finished. Continue to next unit
} }
default: default:
@ -735,7 +742,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
} }
// Update sampler key // Update sampler key
BindSampler(texture_index, texture_samplers[texture_index], texture); BindSampler(texture_index, texture_samplers[texture_index], texture.config);
auto surface = res_cache.GetTextureSurface(texture); auto surface = res_cache.GetTextureSurface(texture);
if (surface != nullptr) { if (surface != nullptr) {
@ -1580,8 +1587,8 @@ vk::Sampler RasterizerVulkan::CreateSampler(const SamplerInfo& info) {
.maxAnisotropy = properties.limits.maxSamplerAnisotropy, .maxAnisotropy = properties.limits.maxSamplerAnisotropy,
.compareEnable = false, .compareEnable = false,
.compareOp = vk::CompareOp::eAlways, .compareOp = vk::CompareOp::eAlways,
.minLod = static_cast<float>(info.lod_min), .minLod = info.lod_min,
.maxLod = static_cast<float>(info.lod_max), .maxLod = info.lod_max,
.borderColor = vk::BorderColor::eIntOpaqueBlack, .borderColor = vk::BorderColor::eIntOpaqueBlack,
.unnormalizedCoordinates = false .unnormalizedCoordinates = false
}; };

View File

@ -35,9 +35,9 @@ struct SamplerInfo {
TextureConfig::WrapMode wrap_s; TextureConfig::WrapMode wrap_s;
TextureConfig::WrapMode wrap_t; TextureConfig::WrapMode wrap_t;
u32 border_color = 0; u32 border_color = 0;
u32 lod_min = 0; float lod_min = 0;
u32 lod_max = 0; float lod_max = 0;
s32 lod_bias = 0; float lod_bias = 0;
// TODO(wwylele): remove this once mipmap for cube is implemented // TODO(wwylele): remove this once mipmap for cube is implemented
bool supress_mipmap_for_cube = false; bool supress_mipmap_for_cube = false;