X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Ftexture_backend.cpp;h=ec6d504732f9f0a13055eff1f42086d2fe4858a7;hb=eddb5cfd959eaa202ee6f95cd2049349ec920829;hp=06c4a622341955b1064539afe11b369c0620b9e6;hpb=a16145549dc87c3b12671f797bd77b14bcc7786b;p=libs%2Fgl.git diff --git a/source/backends/vulkan/texture_backend.cpp b/source/backends/vulkan/texture_backend.cpp index 06c4a622..ec6d5047 100644 --- a/source/backends/vulkan/texture_backend.cpp +++ b/source/backends/vulkan/texture_backend.cpp @@ -49,14 +49,14 @@ void VulkanTexture::allocate() image_info.extent.width = 1; image_info.extent.height = 1; image_info.extent.depth = 1; - image_info.mipLevels = 1; + image_info.mipLevels = self.n_levels; image_info.arrayLayers = 1; image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - image_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT; PixelComponents comp = get_components(self.storage_fmt); if(comp==DEPTH_COMPONENT || comp==STENCIL_INDEX) image_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -73,7 +73,7 @@ void VulkanTexture::allocate() memory_id = device.get_allocator().allocate(handle, DEVICE_MEMORY); // Trigger a layout transition if the image is used before uploading data. - synchronize(-1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); + change_layout(-1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); } VkImageViewCreateInfo view_info = { }; @@ -100,15 +100,82 @@ void VulkanTexture::allocate() set_vulkan_object_names(); } +void VulkanTexture::stage_pixels(void *staging, const void *data, size_t count) +{ + const Texture &self = *static_cast(this); + + if(self.swizzle==RGBA_TO_RGB) + { + const uint32_t *src = static_cast(data); + uint32_t *dst = static_cast(staging); + size_t i = 0; + for(; i+3>24)|(src[1]<<8)|0xFF000000; + dst[2] = (src[1]>>16)|(src[2]<<16)|0xFF000000; + dst[3] = (src[2]>>8)|0xFF000000; + src += 3; + dst += 4; + } + + if(i(src); + for(; i(data); + size_t data_size = count*get_pixel_size(self.storage_fmt); + copy(src, src+data_size, static_cast(staging)); + } +} + void VulkanTexture::generate_mipmap() { - throw logic_error("VulkanTexture::generate_mipmap is unimplemented"); + unsigned n_levels = static_cast(this)->n_levels; + + TransferQueue &tq = device.get_transfer_queue(); + for(unsigned i=0; i+1(this)->storage_fmt)); + region.srcSubresource.mipLevel = i; + region.srcSubresource.baseArrayLayer = 0; + region.srcSubresource.layerCount = 1; + region.dstSubresource = region.srcSubresource; + ++region.dstSubresource.mipLevel; + + fill_mipmap_blit(i, ®ion); + + vk.CmdBlitImage(cmd_buf, handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, ®ion, VK_FILTER_LINEAR); + }); + } } -void VulkanTexture::synchronize(int layer, unsigned layout, bool discard) const +void VulkanTexture::change_layout(int level, unsigned layout, bool discard) const { - unsigned aspect = get_vulkan_aspect(get_components(static_cast(this)->storage_fmt)); - device.get_synchronizer().access(handle, aspect, layer, layout, discard); + const Texture &self = *static_cast(this); + + unsigned aspect = get_vulkan_aspect(get_components(self.storage_fmt)); + if(level>=0) + device.get_synchronizer().split_image_mipmap(handle, aspect, self.n_levels); + device.get_synchronizer().change_image_layout(handle, aspect, level, layout, discard); } void VulkanTexture::set_debug_name(const string &name)