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:
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user