Texture Serialization Issue



I rebased against the main bsf branch today and I run into troubles when running the bsfImportTool executable. As an example a simple 40x40 PNG file ButtonNormal.png in encoded into ButtonNormal.png.asset and has lots of weird data that does not belong in the source image:

float3 hitPos;
if(hiZSearch(depth, samp, params.bufferSize, params.numMips, rayPos, uvStep, hitPos))
	return float4(hitPos.xy * params.HiZUVToScreenUV.xy, hitPos.z, 0);
// Plain linear search
if(linearSearch(depth, samp, uvStart, uvStep, NUM_STEPS, stepIncrement, compareTolerance, t))
	return float4(uvStart + uvStep * t, t);

I noticed the issue when loading my custom editor which has a completely broken skin now.
I will still look around to find the bug, but any help will be much appreciated.

NB: I run the code with the Vulkan API under Linux.


I also have an error that seems to be related to texture read back:

[ERROR] Cannot convert pixels between buffers of different sizes.
		 in static void bs::PixelUtil::bulkPixelConversion(const bs::PixelData &, bs::PixelData &) [/home/code/extern/bsf/Source/Foundation/bsfCore/Image/BsPixelUtil.cpp:1927]

When tracking down the issue it appears that VulkanTexture::lockImpl always returns an empty PixelData, thus PixelData myData passed on to PixelUtil::bulkPixelConversion triggers the error.

void VulkanTexture::readDataImpl(PixelData& dest, UINT32 mipLevel, UINT32 face, UINT32 deviceIdx, UINT32 queueIdx)
		if (mProperties.getNumSamples() > 1)
			BS_LOG(Error, RenderBackend, "Multisampled textures cannot be accessed from the CPU directly.");

		PixelData myData = lock(GBL_READ_ONLY, mipLevel, face, deviceIdx, queueIdx);
		PixelUtil::bulkPixelConversion(myData, dest);

		BS_INC_RENDER_STAT_CAT(ResRead, RenderStatObject_Texture);

Don’t know if it’s related to my first issue though…


Did you rebuild the import tool after the rebase? If not, then doing that and reimporting all assets might solve some or all of your problems. ‘Row pitch’ and ‘slice pitch’ properties of ‘PixelData’ have recently changed their meaning (from number of pixels to number of bytes).


Yes, I did rebuild it. This is not a Vulkan related issue either (I tried falling back to older versions). So basically when loading the skin the PNG files are imported from the raw folder with the function importAssets from the file BsBuiltinResourcesHelper.cpp. At some point it imports a PNG file which is 15x19 in size, creates a texture from it, serializes the texture and writes it to the disk as a 1,433 bytes file. Is this normal ? My first guess was that it would be approximately the same size as the PNG file with a few more metadata.


It won’t be the same size as PNG, size depends on the chosen pixel format and non-lossy compression options, and for the importer tool those are both non-compressed.

I suggest calling gImporter().import() manually on the texture file, and see if the same issue happens in that case. If it does, then you have a simple test case I can check out.


Hey, I tried some tests with the importer and it works fine. It seems to have to do with this error:

[ERROR] Cannot convert pixels between buffers of different sizes.
		 in static void bs::PixelUtil::bulkPixelConversion(const bs::PixelData &, bs::PixelData &) [/home/code/extern/bsf/Source/Foundation/bsfCore/Image/BsPixelUtil.cpp:1927]

After importing the PNG file and when saving it as an asset fil on the disk the image in VulkanImage* image = mImages[deviceIdx]; in the funtion lockImpl() is nullptr. The function then returns an empty PixelData, which is then passed as the source data for PixelUtil::bulkPixelConversion which returns without copying any data.


There were some issues with import introduced recently, that caused textures not to be initialized properly before they’re attempted to be saved. It has been fixed yesterday, perhaps try and update and check if that was your issue as well.


Yep, I saw the fix. Thanks a lot !
The error is resolved and the texture assets seem to be correctly saved.