Vulkan: Enable mipmapping
This commit is contained in:
parent
8a62724316
commit
84e649f74b
3 changed files with 38 additions and 52 deletions
|
@ -1455,9 +1455,7 @@ void VulkanTexture::CreateDirect(int w, int h, int numMips, VkFormat format) {
|
|||
assert(res == VK_SUCCESS);
|
||||
|
||||
vkGetImageMemoryRequirements(vulkan_->GetDevice(), image, &mem_reqs);
|
||||
VkMemoryAllocateInfo mem_alloc = {};
|
||||
mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
mem_alloc.pNext = NULL;
|
||||
VkMemoryAllocateInfo mem_alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
mem_alloc.memoryTypeIndex = 0;
|
||||
mem_alloc.allocationSize = mem_reqs.size;
|
||||
|
||||
|
@ -1498,13 +1496,13 @@ void VulkanTexture::CreateDirect(int w, int h, int numMips, VkFormat format) {
|
|||
assert(res == VK_SUCCESS);
|
||||
}
|
||||
|
||||
void VulkanTexture::UploadMip(int mip, VkBuffer buffer, size_t offset, size_t rowLength) {
|
||||
void VulkanTexture::UploadMip(int mip, int mipWidth, int mipHeight, VkBuffer buffer, size_t offset, size_t rowLength) {
|
||||
VkBufferImageCopy copy_region = {};
|
||||
copy_region.bufferOffset = offset;
|
||||
copy_region.bufferRowLength = (uint32_t)rowLength;
|
||||
copy_region.bufferImageHeight = tex_height;
|
||||
copy_region.imageExtent.width = tex_width;
|
||||
copy_region.imageExtent.height = tex_height;
|
||||
copy_region.bufferImageHeight = 0; // 2D
|
||||
copy_region.imageExtent.width = mipWidth;
|
||||
copy_region.imageExtent.height = mipHeight;
|
||||
copy_region.imageExtent.depth = 1;
|
||||
copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copy_region.imageSubresource.mipLevel = mip;
|
||||
|
|
|
@ -347,7 +347,7 @@ class VulkanTexture {
|
|||
public:
|
||||
VulkanTexture(VulkanContext *vulkan)
|
||||
: vulkan_(vulkan), image(VK_NULL_HANDLE), mem(VK_NULL_HANDLE), view(VK_NULL_HANDLE),
|
||||
tex_width(0), tex_height(0), format_(VK_FORMAT_UNDEFINED),
|
||||
tex_width(0), tex_height(0), numMips_(1), format_(VK_FORMAT_UNDEFINED),
|
||||
mappableImage(VK_NULL_HANDLE), mappableMemory(VK_NULL_HANDLE), needStaging(false) {
|
||||
memset(&mem_reqs, 0, sizeof(mem_reqs));
|
||||
}
|
||||
|
@ -366,9 +366,9 @@ public:
|
|||
|
||||
// Fast uploads from buffer. Mipmaps supported.
|
||||
void CreateDirect(int w, int h, int numMips, VkFormat format);
|
||||
void UploadMip(int mip, VkBuffer buffer, size_t offset, size_t rowLength); // rowLength is in pixels
|
||||
void UploadMip(int mip, int mipWidth, int mipHeight, VkBuffer buffer, size_t offset, size_t rowLength); // rowLength is in pixels
|
||||
void EndCreate();
|
||||
|
||||
int GetNumMips() const { return numMips_; }
|
||||
void Destroy();
|
||||
|
||||
VkImageView GetImageView() const { return view; }
|
||||
|
|
|
@ -87,23 +87,28 @@ VkSampler SamplerCache::GetOrCreateSampler(const SamplerCacheKey &key) {
|
|||
return iter->second;
|
||||
}
|
||||
|
||||
VkSamplerCreateInfo samp = {};
|
||||
samp.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samp.pNext = nullptr;
|
||||
VkSamplerCreateInfo samp = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
||||
samp.addressModeU = key.sClamp ? VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.addressModeV = key.tClamp ? VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
samp.compareEnable = false;
|
||||
samp.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
samp.flags = 0;
|
||||
samp.magFilter = key.magFilt ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
samp.minFilter = key.minFilt ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; // TODO: Aniso
|
||||
samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; // key.4) ? ((key.magFilt & 2) ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST) : VK_SAMPLER_MIPMAP_MODE_BASE;
|
||||
samp.minFilter = key.minFilt ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
samp.mipmapMode = key.mipFilt ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
|
||||
// TODO: Need to check for device support before enabling aniso
|
||||
/*
|
||||
if (g_Config.iAnisotropyLevel > 1) {
|
||||
samp.maxAnisotropy = g_Config.iAnisotropyLevel;
|
||||
samp.anisotropyEnable = true;
|
||||
}
|
||||
*/
|
||||
samp.maxAnisotropy = 1.0f;
|
||||
samp.maxLod = 0.0f; // 1000.0f;
|
||||
samp.anisotropyEnable = false;
|
||||
samp.maxLod = key.maxLevel;
|
||||
samp.minLod = 0.0f;
|
||||
samp.unnormalizedCoordinates = false;
|
||||
samp.mipLodBias = 0.0f;
|
||||
|
||||
VkSampler sampler;
|
||||
|
@ -604,6 +609,7 @@ void TextureCacheVulkan::UpdateSamplingParams(TexCacheEntry &entry, SamplerCache
|
|||
key.magFilt = magFilt & 1;
|
||||
key.sClamp = sClamp;
|
||||
key.tClamp = tClamp;
|
||||
key.maxLevel = entry.vkTex->texture_->GetNumMips() - 1;
|
||||
/*
|
||||
if (entry.maxLevel != 0) {
|
||||
if (force || entry.lodBias != lodBias) {
|
||||
|
@ -1390,10 +1396,13 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
|||
}
|
||||
|
||||
// In addition, simply don't load more than level 0 if g_Config.bMipMap is false.
|
||||
if (!g_Config.bMipMap) {
|
||||
if (!g_Config.bMipMap || badMipSizes) {
|
||||
maxLevel = 0;
|
||||
}
|
||||
|
||||
// Disable mipmapping. Something is wrong.
|
||||
// maxLevel = 0;
|
||||
|
||||
// If GLES3 is available, we can preallocate the storage, which makes texture loading more efficient.
|
||||
VkFormat dstFmt = GetDestFormat(format, gstate.getClutPaletteFormat());
|
||||
|
||||
|
@ -1453,47 +1462,26 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
|||
entry->vkTex = new CachedTextureVulkan();
|
||||
entry->vkTex->texture_ = new VulkanTexture(vulkan_);
|
||||
VulkanTexture *image = entry->vkTex->texture_;
|
||||
image->CreateDirect(w, h, 1, dstFmt);
|
||||
image->CreateDirect(w, h, maxLevel + 1, dstFmt);
|
||||
}
|
||||
lastBoundTexture = entry->vkTex;
|
||||
|
||||
// In Vulkan, fortunately, we have full control over mipmapping.
|
||||
// For now, we only load the base texture. More to come.
|
||||
|
||||
// Upload the texture data.
|
||||
int bpp = dstFmt == VULKAN_8888_FORMAT ? 4 : 2;
|
||||
int stride = (w * bpp + 15) & ~15;
|
||||
int size = stride * h;
|
||||
size_t bufferOffset;
|
||||
void *data = uploadBuffer->Push(size, &bufferOffset);
|
||||
LoadTextureLevel(*entry, (uint8_t *)data, stride, 0, replaceImages, scaleFactor, dstFmt);
|
||||
entry->vkTex->texture_->UploadMip(0, uploadBuffer->GetVkBuffer(), bufferOffset, stride / bpp);
|
||||
|
||||
// Mipmapping only enable when texture scaling disable
|
||||
/*
|
||||
if (maxLevel > 0 && scaleFactor == 1) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) {
|
||||
if (badMipSizes) {
|
||||
// WARN_LOG(G3D, "Bad mipmap for texture sized %dx%dx%d - autogenerating", w, h, (int)format);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
} else {
|
||||
for (int i = 1; i <= maxLevel; i++) {
|
||||
LoadTextureLevel(*entry, i, replaceImages, scaleFactor, dstFmt);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)maxLevel);
|
||||
}
|
||||
} else {
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
} else if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
for (int i = 0; i <= maxLevel; i++) {
|
||||
int mipWidth = gstate.getTextureWidth(i);
|
||||
int mipHeight = gstate.getTextureHeight(i);
|
||||
int bpp = dstFmt == VULKAN_8888_FORMAT ? 4 : 2;
|
||||
int stride = (mipWidth * bpp + 15) & ~15;
|
||||
int size = stride * mipHeight;
|
||||
size_t bufferOffset;
|
||||
void *data = uploadBuffer->Push(size, &bufferOffset);
|
||||
LoadTextureLevel(*entry, (uint8_t *)data, stride, i, replaceImages, scaleFactor, dstFmt);
|
||||
entry->vkTex->texture_->UploadMip(i, mipWidth, mipHeight, uploadBuffer->GetVkBuffer(), bufferOffset, stride / bpp);
|
||||
}
|
||||
*/
|
||||
|
||||
gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL;
|
||||
gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN;
|
||||
|
||||
// TODO: Refactor away nextTexture_. Not needed on Vulkan.
|
||||
nextTexture_ = entry;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue