diff --git a/src/engine/renderer/tr_image.c b/src/engine/renderer/tr_image.c index 33963c3..123f63e 100644 --- a/src/engine/renderer/tr_image.c +++ b/src/engine/renderer/tr_image.c @@ -135,6 +135,9 @@ void GL_TextureMode( const char *string ) { gl_filter_min = modes[i].minimize; gl_filter_max = modes[i].maximize; + // VULKAN + VK_CHECK(vkDeviceWaitIdle(vk.device)); + // change all the existing mipmap texture objects for ( i = 0 ; i < tr.numImages ; i++ ) { glt = tr.images[ i ]; @@ -142,6 +145,10 @@ void GL_TextureMode( const char *string ) { GL_Bind (glt); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + + // VULKAN + Vk_Image& image = vk_resources.images[i]; + vk_update_descriptor_set(image.descriptor_set, image.view, true, glt->wrapClampMode == GL_REPEAT); } } } diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index 7532571..e36d2a6 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -1020,30 +1020,9 @@ Vk_Image vk_create_image(int width, int height, int mip_levels, bool repeat_text desc.descriptorPool = vk.descriptor_pool; desc.descriptorSetCount = 1; desc.pSetLayouts = &vk.set_layout; - VK_CHECK(vkAllocateDescriptorSets(vk.device, &desc, &image.descriptor_set)); - Vk_Sampler_Def sampler_def; - sampler_def.repeat_texture = repeat_texture; - - VkDescriptorImageInfo image_info; - image_info.sampler = vk_find_sampler(sampler_def); - image_info.imageView = image.view; - image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkWriteDescriptorSet descriptor_write; - descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptor_write.dstSet = image.descriptor_set; - descriptor_write.dstBinding = 0; - descriptor_write.dstArrayElement = 0; - descriptor_write.descriptorCount = 1; - descriptor_write.pNext = nullptr; - descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptor_write.pImageInfo = &image_info; - descriptor_write.pBufferInfo = nullptr; - descriptor_write.pTexelBufferView = nullptr; - - vkUpdateDescriptorSets(vk.device, 1, &descriptor_write, 0, nullptr); + vk_update_descriptor_set(image.descriptor_set, image.view, mip_levels > 1, repeat_texture); } return image; @@ -1102,6 +1081,37 @@ void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, con }); } +void vk_update_descriptor_set(VkDescriptorSet set, VkImageView image_view, bool mipmap, bool repeat_texture) { + Vk_Sampler_Def sampler_def; + sampler_def.repeat_texture = repeat_texture; + if (mipmap) { + sampler_def.gl_mag_filter = gl_filter_max; + sampler_def.gl_min_filter = gl_filter_min; + } else { + sampler_def.gl_mag_filter = GL_LINEAR; + sampler_def.gl_min_filter = GL_LINEAR; + } + + VkDescriptorImageInfo image_info; + image_info.sampler = vk_find_sampler(sampler_def); + image_info.imageView = image_view; + image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkWriteDescriptorSet descriptor_write; + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.dstSet = set; + descriptor_write.dstBinding = 0; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorCount = 1; + descriptor_write.pNext = nullptr; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_write.pImageInfo = &image_info; + descriptor_write.pBufferInfo = nullptr; + descriptor_write.pTexelBufferView = nullptr; + + vkUpdateDescriptorSets(vk.device, 1, &descriptor_write, 0, nullptr); +} + static VkPipeline create_pipeline(const Vk_Pipeline_Def& def) { auto get_shader_stage_desc = [](VkShaderStageFlagBits stage, VkShaderModule shader_module, const char* entry) { VkPipelineShaderStageCreateInfo desc; @@ -1430,7 +1440,9 @@ VkSampler vk_find_sampler(const Vk_Sampler_Def& def) { for (int i = 0; i < vk_resources.num_samplers; i++) { const auto& cur_def = vk_resources.sampler_defs[i]; - if (cur_def.repeat_texture == def.repeat_texture) + if (cur_def.repeat_texture == def.repeat_texture && + cur_def.gl_mag_filter == def.gl_mag_filter && + cur_def.gl_min_filter == def.gl_min_filter) { return vk_resources.samplers[i]; } @@ -1443,13 +1455,49 @@ VkSampler vk_find_sampler(const Vk_Sampler_Def& def) { VkSamplerAddressMode address_mode = def.repeat_texture ? VK_SAMPLER_ADDRESS_MODE_REPEAT : VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + VkFilter mag_filter; + if (def.gl_mag_filter == GL_NEAREST) { + mag_filter = VK_FILTER_NEAREST; + } else if (def.gl_mag_filter == GL_LINEAR) { + mag_filter = VK_FILTER_LINEAR; + } else { + ri.Error(ERR_FATAL, "vk_find_sampler: invalid gl_mag_filter"); + } + + VkFilter min_filter; + VkSamplerMipmapMode mipmap_mode; + bool max_lod_0_25 = false; // used to emulate OpenGL's GL_LINEAR/GL_NEAREST minification filter + if (def.gl_min_filter == GL_NEAREST) { + min_filter = VK_FILTER_NEAREST; + mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + max_lod_0_25 = true; + } else if (def.gl_min_filter == GL_LINEAR) { + min_filter = VK_FILTER_LINEAR; + mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + max_lod_0_25 = true; + } else if (def.gl_min_filter == GL_NEAREST_MIPMAP_NEAREST) { + min_filter = VK_FILTER_NEAREST; + mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + } else if (def.gl_min_filter == GL_LINEAR_MIPMAP_NEAREST) { + min_filter = VK_FILTER_LINEAR; + mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + } else if (def.gl_min_filter == GL_NEAREST_MIPMAP_LINEAR) { + min_filter = VK_FILTER_NEAREST; + mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + } else if (def.gl_min_filter == GL_LINEAR_MIPMAP_LINEAR) { + min_filter = VK_FILTER_LINEAR; + mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + } else { + ri.Error(ERR_FATAL, "vk_find_sampler: invalid gl_min_filter"); + } + VkSamplerCreateInfo desc; desc.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; desc.pNext = nullptr; desc.flags = 0; - desc.magFilter = VK_FILTER_LINEAR; - desc.minFilter = VK_FILTER_LINEAR; - desc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + desc.magFilter = mag_filter; + desc.minFilter = min_filter; + desc.mipmapMode = mipmap_mode; desc.addressModeU = address_mode; desc.addressModeV = address_mode; desc.addressModeW = address_mode; @@ -1459,7 +1507,7 @@ VkSampler vk_find_sampler(const Vk_Sampler_Def& def) { desc.compareEnable = VK_FALSE; desc.compareOp = VK_COMPARE_OP_ALWAYS; desc.minLod = 0.0f; - desc.maxLod = 12.0f; + desc.maxLod = max_lod_0_25 ? 0.25f : 12.0f; desc.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; desc.unnormalizedCoordinates = VK_FALSE; diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index 0daa158..82528d5 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -29,13 +29,15 @@ enum class Vk_Shader_Type { struct Vk_Sampler_Def { bool repeat_texture = false; // clamp/repeat texture addressing mode + int gl_mag_filter = 0; // GL_XXX mag filter + int gl_min_filter = 0; // GL_XXX min filter }; struct Vk_Pipeline_Def { - Vk_Shader_Type shader_type = Vk_Shader_Type::single_texture; - unsigned int state_bits = 0; // GLS_XXX flags - int face_culling = 0;// cullType_t - bool polygon_offset = false; + Vk_Shader_Type shader_type = Vk_Shader_Type::single_texture; + unsigned int state_bits = 0; // GLS_XXX flags + int face_culling = 0;// cullType_t + bool polygon_offset = false; }; struct Vk_Image { @@ -59,6 +61,7 @@ void vk_destroy_resources(); // destroys Vk_Resources resources // Vk_Image vk_create_image(int width, int height, int mip_levels, bool repeat_texture); void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, const uint8_t* rgba_pixels); +void vk_update_descriptor_set(VkDescriptorSet set, VkImageView image_view, bool mipmap, bool repeat_texture); VkSampler vk_find_sampler(const Vk_Sampler_Def& def); VkPipeline vk_find_pipeline(const Vk_Pipeline_Def& def);