[swift-evolution] [Proposal] Introduces endianness specific type

Jens Persson jens at bitcycle.com
Sun Jul 9 15:48:55 CDT 2017


Sorry for making so much off topic noise in this thread, but I made a
mistake regarding the Metal tutorial:
Looking more carefully I see now that they rebuild a vertedData: [Float]
from their vertices: [Vertex] using the floatBuffer() method of the Vertex
struct, which returns an Array with the stored properties of Vertex in
correct order.

While searching the internet about this I saw Joe Groff mentioning on
Twitter that:
"We plan to sort fields in padding order to minimize size, and may also
automatically pack bools and enums in bitfields."

So AFAICS my current image processing code is making the possibly invalid
assumption that eg
struct S {
    var a, b, c, d: Float
}
will have a memory layout of 4*4=16 bytes (stride and size == 16) and an
alignment of 4, and most importantly that a, b, c, d will be in that order.

It looks like I should be defining my structs (the ones for which memory
layout is important) in C and import them.

Although I would be surprised if a Swift-struct containing only same-sized
fields (all of the same primitive type) would be reordered, and such
changes to the language would probably include some per-struct way to
express some sort of layout control (since being able to define structs to
be used for low level data manipulation is important in a systems language).

/Jens


On Sun, Jul 9, 2017 at 7:01 PM, Jens Persson via swift-evolution <
swift-evolution at swift.org> wrote:

> I should perhaps add that in my image processing code, I use code like
> this:
>
> func withVImageBuffer<Data, R>(for table: Table<Data>, body:
> (vImage_Buffer) -> R) -> R
>     where
>     Data.Coordinate.Index == VectorIndex2
> {
>     let vib = vImage_Buffer(
>         data: table.baseAddress,
>         height: vImagePixelCount(table.size.e1),
>         width: vImagePixelCount(table.size.e0),
>         rowBytes: table.stride.e1
>     )
>     return withExtendedLifetime(table) { body(vib) }
> }
>
> Here, Table<Data> is the raster image. Data.Coordinate == VectorIndex2
> makes it a 2D table, and a Table's Data also has a type parameter
> Data.Value which can be eg one of the "pixel"-struct I showed before.
> This works without any problems (I've tested and used the some variant of
> this type of code for years) but it would surely break if the memory layout
> of simple structs changed.
>
> I can't see how this usage is much different from the one in the Metal
> tutorial. It too uses pointers to point into a data created using the
> (Swift) struct "Vertex", and the GPU hardware has its expectations on the
> memory layout of that data, so the code would break if the memory layout of
> the Vertex struct changed.
>
> /Jens
>
>
> On Sun, Jul 9, 2017 at 6:35 PM, Jens Persson <jens at bitcycle.com> wrote:
>
>> I don't think I'm misunderstanding you, but I might be, so I'll add more
>> detail:
>>
>> If you look at the Metal article, you'll see that the (Swift) struct
>> "Vertex" is used to specify the data that is sent to Metal for creating a
>> buffer (using MTLDevice.makeBuffer). The result that the GPU will
>> produce surely depends on the fields of the Vertex struct (x, y, z, r, g,
>> b, a) being in the specified order (ie swapping the red channel with the x
>> coordinate would produce an unexpected result).
>>
>> And regarding the second example, pixel structs used for manipulating
>> raster image data. Manipulating raster image data presumably includes stuff
>> like displaying to screen, loading and saving raster images.
>> I currently use this way of doing this right now without any problems,
>> but if the order of the fields (eg a, r, g, b) should change in the future,
>> then my code would break (the colors of the images would at least not come
>> out as expected).
>>
>> /Jens
>>
>>
>>
>>
>>
>>
>> On Sun, Jul 9, 2017 at 5:53 PM, Chris Lattner <clattner at nondot.org>
>> wrote:
>>
>>>
>>> On Jul 9, 2017, at 12:23 AM, Jens Persson <jens at bitcycle.com> wrote:
>>>
>>>
>>> On Sat, Jul 8, 2017 at 6:28 PM, Chris Lattner via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>>> Hi Susan,
>>>>
>>>> Swift does not currently specify a layout for Swift structs.  You
>>>> shouldn’t be using them for memory mapped i/o or writing to a file, because
>>>> their layout can change.  When ABI stability for fragile structs lands, you
>>>> will be able to count on it, but until then something like this is probably
>>>> a bad idea.
>>>>
>>>> -Chris
>>>>
>>>
>>> Does this imply that you should never use Swift structs to eg interact
>>> with Metal?
>>>
>>>
>>> No.
>>>
>>> This seems to be a very common practice. Here is a typical example (from
>>> a Metal tutorial at raywenderlich.com):
>>>
>>> struct Vertex {
>>>   var x,y,z: Float     // position data
>>>   var r,g,b,a: Float   // color data
>>>
>>>   func floatBuffer() -> [Float] {
>>>     return [x,y,z,r,g,b,a]
>>>   }
>>> }
>>>
>>>
>>> This doesn’t appear to expose the layout of the struct.
>>>
>>> Also, does it imply that we cannot use structs (of only primitive types)
>>> like:
>>>
>>> struct RgbaFloatsLinearGamma {
>>>     var r, g, b, a: Float
>>>>>> }
>>> struct BgraBytesSrgbGamma {
>>>     var b, g, r, a: UInt8
>>> }
>>>
>>> for manipulating raster image data?
>>>
>>>
>>> I don’t see why that would be a problem.
>>>
>>> I vaguely remember a swift evo discussion where it was concluded that
>>> such usage was considered OK provided the stored properties of the structs
>>> was only primitive types, but I can't find it now.
>>>
>>> Perhaps it could be considered OK at least when the intended platforms
>>> are known to be only iOS devices?
>>>
>>>
>>> I think you’re misunderstanding what I’m saying.  It isn’t correct to
>>> take (e.g.) an unsafepointer to the beginning of a struct, and serialize
>>> that out to disk, and expect that the fields are emitted in some order with
>>> some specific padding between them.  None of the uses above try to do this.
>>>
>>> -Chris
>>>
>>>
>>>
>>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170709/634c1d73/attachment.html>


More information about the swift-evolution mailing list