Vulkan swapchain format UNORM to SRGB using VK_KHR_swapchain_mutable_format? - vulkan

Creating swapchain images with wrong format result this obviously:
vkCreateImageView() format VK_FORMAT_B8G8R8A8_UNORM differs from VkImage
0x40000000004[] format VK_FORMAT_B8G8R8A8_SRGB. Formats MUST be IDENTICAL unless
VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation.
VK_KHR_swapchain_mutable_format Requires Vulkan 1.0
it result this:
The Vulkan spec states: If flags contains VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR
then the pNext chain must include a VkImageFormatListCreateInfo structure with a viewFormatCount
greater than zero and pViewFormats must have an element equal to imageFormat
VkImageFormatListCreateInfo Provided by VK_VERSION_1_2
Question - how Vulkan 1.0 extension require 1.2 structure? (maybe I'm missing something idk)
And as I see on https://vulkan.gpuinfo.org/listextensions.php VK_KHR_swapchain_mutable_format supported only by 60% of Vulkan GPUs... so better write "hand conversion"?

VkImageFormatListCreateInfo Provided by VK_VERSION_1_2
You linked to the Vulkan 1.2 specification. So of course it cites itself. The extension in question is a core part of 1.2, as is VkImageFormatListCreateInfo.
The actual extension cites another extension:
Requires VK_KHR_image_format_list
Which defines the VkImageFormatListCreateInfoKHR structure used by the swapchain format extension. This structure is of course equivalent to the core 1.2 structure VkImageFormatListCreateInfo, since "image_format_list" was promoted to core in Vulkan 1.2.

Related

Send heavy data through protobuf. Custom field

I'm developing the API for the application using protobuf and grpc.
I need to send the data with the arbitrary size. Sometimes it is small, sometimes huge. For example Nympy array. If the size is small I want to send it through protobuf, if the size if huge I want to dump data into file and send the filepath to this file through protobuf.
To do so I've created a following .proto messages:
message NumpyTroughProtobuf {
repeated int32 shape = 1;
repeated float array = 2;
}
message NumpyTroughfile {
string filepath = 1;
}
message NumpyTrough {
google.protobuf.Any data = 1;
}
The logic is simple: If the size is big I use data as NumpyTroughfile or if small data as NumpyTroughProtobuf.
Problem (what I want to avoid):
The mechanism of data transformation is the part of my app.
In the current approach I have to check and covert the data before I create the message NumpyTrough. So I have to add some logic into my application which will care of data check and cast. The same I have to do for any language which I use (for example if I send massages from Python to C++).
What I want to do:
The mechanism of data transformation is the part of customized protobuf.
I want to hide the data transformation. I want that my app to send a pure Numpy array into NumpyTrough.data field. All data transformation should be hided.
So I want that the logic of data transformation be the part of custom Protobuf field, not the part of my application.
Which meant that I would like to create a custom type of the field. I just implement the behavior of this filed (marshal/unmarshal) for any languages which I use. Then I can just directly send Numpy data into this custom field and this field will decide how to proceed: turn the data in into file or via other method, send trough Protobuf and restore on the receiver side.
Somethig like this https://github.com/gogo/protobuf/blob/master/custom_types.md but it seems this is not a part of protobuf ecosystem.
Protobuf only defines schema.
You can't add logic to a protobuf definition.
Protobug Any represents arbitrary binary data and so -- somewhere -- you'll need to explain to your users what it represents in order that they can ship data in the correct format to your service.
You get to decide how to distribute the processing of the data:
Either partly client-side functionality that performs preprocessing of the data and ships the output (either as structured data using non-Any types or, if still necessary as Any).
Or partly server-side that receives entirely unprocessed client-side data shipped through Any
Or some combination of the two
NOTE You may want to consider shipping the data regardless of size as file references to simplify your implementation. You're correct to bias protobuf to smaller message sizes but, depending on the file size distribution, does it make sense to complicate your implementation with 2 paths?

Vulkan ignoring GLSL image format qualifier

I have a compute shader that reads a signed normalized integer image using imageLoad.
The image itself (which contains both positive and negative values) is created as a R16G16_SNORM and is written by a fragment shader in a previous gpass.
The imageview bound to the descriptorsetlayout binding in the compute shader is also created with the same R16G16_SNORM format.
Everything works as expected.
Yesterday I realized that in the compute shader I used the wrong image format qualifier rg16.
A bit puzzled (I could not understand how it could work properly reading an unsigned normalized value) I corrected to rg16_snorm, and.. nothing changed.
I performed several tests (I even specified a rg16f) and always had the same (correct, [-1,1] signed) result.
It seems like Vulkan (at least my implementation) silently ignores any image format qualifier, and falls back (I guess) to the imageview format bound to the descriptorset.
This seems to be in line with the spec regarding format in imageview creation
format is a VkFormat describing the format and type used to interpret texel blocks in the image
but then in Appendix A (Vulkan Environment for SPIR-V - "Compatibility Between SPIR-V Image Formats And Vulkan Formats") there is a clear distinction between Rg16 and Rg16Snorm.. so:
is it a bug or a feature?
I am working with an Nvidia 2070 Super under ubuntu 20.04
UPDATE
The initial image writing operation happens as the result of a fragment shader color attachment output, and as such, there is no descriptorsetlayout binding declaration. The fragment shader outputs a vec2 to the R16G16_SNORM color attachment as specified by the active framebuffer and renderpass.
The resulting image (after the relevant barriers) is then read (correctly, despite the wrong layout qualifier) by a compute shader as an image/imageLoad operation.
Note that validation layers are enabled and silent.
Note also that the resulting values are far from random, and exactly match the expected values (both positive and negative), using either rg16, rg16f or rg16_snorm.
What you're getting is undefined behavior.
There is a validation check on Image Write Operations that prevents the OpTypeImage's format (equivalent to the layout format specifier in GLSL) from being incompatible with the backing VkImageView's format:
If the image format of the OpTypeImage is not compatible with the VkImageView’s format, the write causes the contents of the image’s memory to become undefined.
Note that when it says "compatible", it doesn't mean image view compatibility; it means "exactly match". Your OpTypeImage format did not exactly match that of the shader, so your writes were undefined. And "undefined" can mean "works as if you had specified the correct format".

What does packing nal packets mean?

I have been trying to use the information from this question to solve a similar problem.
However, from the answer; I am not sure what is meant by the following:
I was not packing the raw NAL data correctly (not sure where this is
documented, if anywhere).
or even the solution to this packing issue.
To solve #2, through trial and error I found that giving my NAL units
in the following form worked:
[7 8 5] [1] [1] [1]..... [7 8 5] [1] [1] [1]..... (repeating)
Where each NAL unit is prefixed by a 32-bit start code equaling
0x00000001.
I have seen similar expression concerning nal packets. The original post from the link above has a statement that says:
My stream of NALs contains only SPS/PPS/IDR/P NALs (1, 5, 7, 8)
Again, what does this mean? How would I pack raw NAL data correctly in objective-c?
Any help would be greatly appreciated.
It is called H.264 Annex B byte stream format (defined in ISO/IEC 14496-12).
http://wiki.multimedia.cx/?title=H.264
I think, below page has very good explanation:
http://gentlelogic.blogspot.kr/2011/11/exploring-h264-part-2-h264-bitstream.html
There are many open source implementations about this (not easily reusable though).
NAL AU is the unit of data to encapsulate an encoded frame data. It is consist of header (start code), type, length, and body part.
SPS/PPS/IDR/P are frame types.
SPS : config information about overall stream (encoding method, parameter, etc)
PPS : config information about pictures (width, height, etc)
IDR : special frame/packet to setup decoder
P : usual encoded frame data
Order of frame in ordinary movie files: SPS (once) PPS (once) IDR (periodically) P (actual picture) P P P P P IDR P P P P P P P ...
For annex B byte stream processing, Intel IPP code samples are very good reference (umc_h264_nal_spl.cpp).
Its currently free to download (latest version is free to evaluate 30 days).
https://software.intel.com/en-us/articles/code-samples-for-intel-integrated-performance-primitives-intel-ipp-library-71
Annex B byte stream format describes how to store H.264 encoded frame data in a media container (such as mp4, MPEG 2 TS). Handling the container format binary data also requires many hard works. Each container uses different mechanism to specify codec configuration. As mentioned related SO post (AVAssetWriterInput H.264 Passthrough to QuickTime (.mov) - Passing in SPS/PPS to create avcC atom?), mp4/mov uses avcc box format which is defined in other ISO/IEC document.

Determine internal format of given astc compressed image through its header?

I am writing a EbGL based HTML application that uses ASTC (Adaptive Scalable Texture Compression) compressed textures to be loaded on my triangle. I would like to know that does there exists a way to know whether the internal format of the compressed ASTC image(that in my case might be located on a remote web server) is "linear" or "srgb encoded", by parsing the ASTC header. I can then use that internalFormat information obtained to pass my ASTC texture to glCompressedTexImage2D(). In other words, for eg. I want to know whether my internal format is COMPRESSED_RGBA_ASTC_4x4_KHR or COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR from the header of any ASTC compressed image. Any clues?
It seems that ASTC file header indeed doesn't fully describe its contents. It has only dimensions and some strange 'magic number' which seems to be just a constant.
Information about file header: http://malideveloper.arm.com/downloads/Stacy_ASTC_white%20paper.pdf (pages 4-5, it also refers to code samples from Mali Developer Center for more clues).
'Magic number' explained here as a mere constant value 0x5CA1AB13:
http://community.arm.com/thread/3981
You should ask a question at Mali Developer Center forums - these guys are very helpful and usually respond quite fast.
EDIT: Header format in case external links go down:
struct astc_header
{
uint8_t magic [ 4 ];
uint8_t blockdim_x;
uint8_t blockdim_y;
uint8_t blockdim_z ;
uint8_t xsize [ 3 ];
uint8_t ysize [ 3 ];
uint8_t zsize [ 3 ];
};
The ASTC header has no such information. You could try a file name extension, perhaps, such as .srgb.astc. Using KTX, the Khronos alternative storage container for ASTC data, you can add key-value pair for whatever you like, though the glInternalFormat should be good enough in this case.
That said, if you store your data in the ASTC file as sRGB (non-linear gamma) then you can choose whether you want the data to be read as non-linear gamma or linear gamma by setting COMPRESSED_RGBA_ASTC_4x4_KHR or COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR when you read it. That is, the sRGB-ness probably shouldn't be considered a property of the file format but a property of the texel read operation and/or your graphics pipeline. Use the appropriate kind to produce the style of output you want.

Is this GPGSV sentence valid?

While parsing the NMEA output of a GPS receiver I get the following lines:
$GPGSV,4,1,16,02,17,228,35,03,04,048,37,05,59,285,29,06,02,030,34*73
$GPGSV,4,2,16,07,58,061,46,08,80,159,40,09,11,227,32,10,51,167,47*77
$GPGSV,4,3,16,13,15,089,38,15,00,279,,16,00,018,,26,34,279,42*7A
$GPGSV,4,4,16,28,20,154,39*4C
As I understand it, from various sources on the web (e.g. here), this is wrong. According to the 3rd number, there should be 16 satellites, which was true for all those GPS receivers I previously encountered, but the sentence from this one only contains the data for 13 satellites.
Is this an error? Or do I read the specification wrongly?
Nmea is a weakly specified file format. GPS chip manufactures provide documenttaion how they interpret the NMEA specification.
For example ublox and Sirf each have a chapter of about 40 pages describing how to interpret the NMEA format.
So if you write " Or do I read the specification wrongly?", then the question is which specification you are reading. That of the GPS chip manufacturer? The NMEA 0183 spec does not contain enough info to correctly parse the sentences.
Especially in your case: the NMEA protocol does not desribe how to handle empty values vs invalid ones.
In your case the receiver theretically expects to see 16 satellites, but found only 13.
I would expect that the missing 3 sats would have empty ",,,,,,,,". But obviously the manufacturer decided to just stop and append the checksum string. (Its simply not speciefied that it is mandatory to print out empty semicolons for the missing 3 sats.
Unfortunaetly you have to expect to write a NMEA parser for each CHPS chip manufacturer.
Therfore I always recommend to use the binary format of the Chip manufactureres protocol. (e,.g uBlox bianry or Sirf binary because these are exactly specified).
You can further look at the docu for GpsBable: they show how different manufacturres produce different GSV data sets.
Update:
As you now told that it is a ublox receiver:
The answer is, yes the NMEA sentences are valid. Look at the ublox protocol spec. i use spec for ublox 5:
On page where the GSV sentence is described look at the "Message Structure":
{,sv,elv,az,cno}*cs
the curly braces enclose the sequence that is repeated.
And below look at "1..4": this means 1,2,3 or 4 blocks. There is not written "4", its "1..4" therefore satelite info is optional, and has not to be empty.
If you further look at the example ublox gives, then you see, that the last GPGSV message contains less than 4 satellites, exactly as you are showing in your question.
Yes, it's inconsistent; the last message should have described more than one satellite (four, actually) so as to total the 16 advertised. The GPS receiver should have reported at least the satellite IDs (PRN), even if their viewing direction in the sky and SNR were unknown at the time, e.g.: {,01,,,}.
That being said, it's better to write programs tolerant against ill-formed messages; in this case, updating the number of satellites in view to 13, as counted.
(I've checked the checksums and they're okay.)