On Mon, Aug 10, 2015 at 12:41 AM, Oded Gabbay <oded.gab...@gmail.com> wrote: > On Mon, Aug 10, 2015 at 10:30 AM, Jason Ekstrand <ja...@jlekstrand.net> wrote: >> On Mon, Aug 10, 2015 at 12:07 AM, Oded Gabbay <oded.gab...@gmail.com> wrote: >>> On Mon, Aug 10, 2015 at 7:58 AM, Jason Ekstrand <ja...@jlekstrand.net> >>> wrote: >>>> On Sun, Aug 9, 2015 at 3:11 AM, Oded Gabbay <oded.gab...@gmail.com> wrote: >>>>> On Sun, Aug 9, 2015 at 2:43 AM, Jason Ekstrand <ja...@jlekstrand.net> >>>>> wrote: >>>>>> On Sat, Aug 8, 2015 at 3:14 PM, Oded Gabbay <oded.gab...@gmail.com> >>>>>> wrote: >>>>>>> On Sun, Aug 9, 2015 at 12:26 AM, Jason Ekstrand <ja...@jlekstrand.net> >>>>>>> wrote: >>>>>>> >>>>>>> If I understand your patch, instead of using the endian-dependent >>>>>>> defines, you use the LE defines all the time when converting >>>>>>> pipe<-->mesa formats >>>>>>> >>>>>>> I'm not saying its wrong, but these endian-dependent defines, e.g. >>>>>>> PIPE_FORMAT_ARGB8888_UNORM, are used in more places in the gallium >>>>>>> code than in the above two functions. Why change only here and not in >>>>>>> all places, i.e removing them ? >>>>>>> >>>>>>> Also, this fixes only llvmpipe/softpipe. It doesn't fix sw_rast. That >>>>>>> is still broken >>>>>> >>>>>> The fact that sw_rast is broken bothers me. The sw_rast code doesn't >>>>>> leave core mesa so it shouldn't be affected by any gallium changes. >>>>>> From that perspective, this makes sense. However, sw_rast should be >>>>>> using the auto-generated packing/unpacking functions in core mesa. >>>>>> Did sw_rast work prior to the readpixels changes? It's possible it >>>>>> was already broken. >>>>>> >>>>> I didn't check sw_rast status before readpixels changes. >>>>> However, from looking at the automatic pack/unpack functions, it seems >>>>> strange to me they don't take into account the endianness. >>>>> e.g on ppc64 machine, in file format_pack.c, there is the following >>>>> function: >>>>> >>>>> static inline void >>>>> pack_ubyte_a8b8g8r8_unorm(const GLubyte src[4], void *dst) >>>>> { >>>>> uint8_t a = _mesa_unorm_to_unorm(src[3], 8, 8); >>>>> uint8_t b = _mesa_unorm_to_unorm(src[2], 8, 8); >>>>> uint8_t g = _mesa_unorm_to_unorm(src[1], 8, 8); >>>>> uint8_t r = _mesa_unorm_to_unorm(src[0], 8, 8); >>>>> >>>>> uint32_t d = 0; >>>>> d |= PACK(a, 0, 8); >>>>> d |= PACK(b, 8, 8); >>>>> d |= PACK(g, 16, 8); >>>>> d |= PACK(r, 24, 8); >>>>> (*(uint32_t *) dst) = d; >>>>> } >>>>> >>>>> PACK is defined as: >>>>> #define PACK(SRC, OFFSET, BITS) (((SRC) & MAX_UINT(BITS)) << (OFFSET)) >>>>> >>>>> So, we see that 'R' is written to the most-significant byte of the >>>>> dword and 'A' is written to the least-significant byte of the dword, >>>>> although in BE, that should be reversed, since this is abgr format, >>>>> not rgba. >>>> >>>> No, what I've been trying to tell you this whole time is that this is >>>> how the a8r8g8b8 format is *defined*. It's defined in terms of >>>> carving up a single 32-bit word in native endianness. This is why we >>>> have to flip things based on endianness if we want to get it in terms >>>> of an array of 8-bit values. You're free to argue that that's a >>>> clumsy definition for a color format, but that's how it's defined none >>>> the less. >>>> >>>>> It's enough to see that the implementation of this function is the >>>>> same for LE and BE to suspect the code, unless I'm missing something. >>>>> >>>>> >>>>>>> I tested this patch on llvmpipe, combined with the previous patch you >>>>>>> sent on POWER8 machine running ppc64 (BE) >>>>>>> First of all, as I said above, it fixes the piglit sanity test. >>>>>>> Second, it seems that it improves piglit gpu.py results much more than >>>>>>> my patch. "Only" 1368 tests failed, vs. a bit more than 2000 with my >>>>>>> patch. Still a lot higher than the ~600 tests that fail on ppc64le >>>>>> >>>>>> I'm not surprised that it didn't get to zero regressions vs. ppc64le. >>>>>> This patch was just kind of thrown together and I didn't check all of >>>>>> the formats. Also, as per my conversation with rolland, I may be >>>>>> misunderstanding the PIPE_FORMAT enums. >>>>>> >>>>>> Really, this is a problem that is going to have to be chased by >>>>>> someone other than me. I have no BE hardware, so I can't really chase >>>>>> it down. I I also have very limited gallium knowledge so I'm probably >>>>>> not the best person to start chasing it through gallium. All I've >>>>>> done so far is throw darts at the wall. I'm sure this patch is >>>>>> incomplete and, to be honest, I didn't even compile-test it as I don't >>>>>> usually build gallium. What i do know is that, for the most part, the >>>>>> core mesa code is consistent with itself as far as endianness goes. >>>>> >>>>> So I'm not married to my patch, and your 2 patches seem to do a better >>>>> job (although sw-rast is still broken, but that's another issue and >>>>> frankly, it is of less importance for me atm), and I accept your >>>>> arguments for your solution. I would suggest that you upstream your >>>>> patches as a start and I will continue from there, based on my >>>>> schedule. >>>> >>>> Unfortunately, from what Marek and Rolland have said, this patch (the >>>> one to change the mesa format -> gallium format conversion) is also >>>> wrong. It seems like the code was doing it correct all along. This >>>> means that something else is wrong somewhere. Possibly in llvmpipe, >>>> possibly somewhere else. It's going to take some tracking. >>>> >>>> --Jason >>> >>> Jason, >>> From my debugging it seems as though the bug originates from the >>> mismatch between how llvmpipe handles BE and how mesa *expects* to >>> receive the information, i.e in BE machines, when llvmpipe converts >>> the pipe format to mesa format, it *changes* the format type, but mesa >>> does the same conversion, so we have a double conversion. >>> >>> e.g. when running piglit sanity, st_pipe_format_to_mesa_format >>> receives PIPE_FORMAT_R8G8B8A8_UNORM (because that what was chosen by >>> mesa for the texture image) and returns MESA_FORMAT_A8B8G8R8_UNORM (in >>> BE machine). Thus, the formats are *reversed* in order to represent >>> the *actual* order of bytes in the memory. >>> >>> Now, when arriving to _mesa_format_convert, src_format is >>> MESA_FORMAT_A8B8G8R8_UNORM (as passed by llvmpipe). >>> _mesa_format_convert again does the byte swapping, and therefore, >>> returns to the original format of RGBA. However, because the bytes are >>> written in memory in the format of ABGR, the result of >>> read_rgba_pixels (which calls _mesa_format_convert) are swapped and >>> piglit sanity fails. >>> >>> Because the auto-generated code in mesa format_pack/unpack is *always* >>> using little-endian format, you *must* have the formats reversed in >>> order for that code to work in BE machines. No other way around it. I >>> thought of generating a different set of format_pack/unpack for BE >>> machines, but at the end decided it was simpler and cleaner to remove >>> the extra swap in _mesa_format_convert. >> >> I'm not sure what you mean by "always using little-endian format". >> There are multiple different ways of packing 4 8-bit things into a >> 32-bit space. This one happens to be by packing them into a 32-bit >> integer and then storing it in native byte-order. It happens to be the >> same as using an array of 8-bit things on LE so I guess you could call >> that "little-endian format". In any case, format_as_array_format has >> to give you a format that's in terms of an array of 8-bit things so it >> has to swap on BE. If it didn't, then the different parts of the >> format conversion code would be out-of-sync. >> >> It seems like it might be a good idea to write a quick unit test for >> this (it would go in main/tests). In particular, we should verify >> that converting some known value to/from the packed 32-bit format >> yields the same values as converting to/from the array format. I >> don't know that we need to go over the top and test every format, but >> it should be thorough enough to make sure that endianness checks >> aren't getting out of sync. We should test both RGBA and RGBX style >> formats (see also the swizzle fixing patch I just sent). >> >> What really gets me here are two things 1) that classic sw_rast is >> broken and 2) that it broke when we started using >> _mesa_format_convert. Prior to the switch over toe >> _mesa_format_convert, it used the format_pack/unpack functions to >> convert to/from floats. If this really was a format mismatch issue >> between mesa and gallium, you'd think we would have seen it before. >> >> --Jason > > Prior to _mesa_format_convert, there was a function called > slow_read_rgba_pixels() which did the actual work. At least that's > what I saw when I tested piglit sanity on BE. Although I only skimmed > over that function, I don't see any byte-swapping there, so you didn't > have the double-conversion you have now.
It was calling pack_ubyte_a8b8g8r8_unorm() under the hood, so there was byte-swapping. It just wasn't as obvious. > Oded > >> >>> Could you please explain again why you think it is the wrong move ? As >>> I'm new to mesa, I'm still in the learning phase of the code. >>> >>> Oded >>> >>> >>>> >>>>>> >>>>>> If you want to see what a given format means in a more explicit >>>>>> fashion, just look at the auto-generated format_pack.c and >>>>>> format_unpack.c files. gallium has similar auto-generated format >>>>>> packing functions. If you can digest what each of them means on BE, >>>>>> then it should be pretty obvious how to match things up. >>>>>> --Jason >>>>> As I pointed above, I think the auto-generated code is not >>>>> endian-aware, which is a problem, IMO. >>>>> >>>>>> >>>>>> P.S. Thanks for bringing this up and taking the time to look into it. >>>>>> Mesa claims to work on BE but, as you've clearly demonstrated, it's >>>>>> completely broken. I'm sure we'd all like to see it working again. >>>>> >>>>> Although I'm focused more on ppc64le, I will probably be able to >>>>> squeeze some fixes in for ppc64, and fortunately I have the H/W to >>>>> check it. I appreciate your help and will be glad if you could take a >>>>> look at future patches I will send on the subject. >>>>> >>>>> Oded _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev