Jump to content

Anders Melander

Members
  • Content Count

    2946
  • Joined

  • Last visited

  • Days Won

    166

Everything posted by Anders Melander

  1. Anders Melander

    MAP2PDB - Profiling with VTune

    Ew! It looks like they have done a complete rewrite. No wonder it's broken. So I guess this is an example of the main problem with the PDB format: Microsoft considers it their own internal format to do with what they like. They have their own (undocumented) writer, their own reader, and no documentation.
  2. Anders Melander

    MAP2PDB - Profiling with VTune

    Excellent! A few quick observations: First of all, it's strange that the error isn't logged. That would StrmTbl::internalSerializeBigMsf Lots of calls to this. I'm guessing it's reading MSF blocks and deblocking them into linear memory streams. This is probably the new code that supports the 8192-byte "big" MSF block size. MSF_HB::load Probably the code that loads the PDB tables from the memory streams. StrmTbl::~StrmTbl Lots of calls to this. Probably clean up after the load has been aborted. PortablePDB::PortablePDB Something wrong here. "Portable PDB" is the .NET PDB format. It's a completely different file format. I'm guessing it's falling back to that format after failing to validate the file as PDB.
  3. Anders Melander

    MAP2PDB - Profiling with VTune

    If the block size being 4096 is the only problem (I somehow doubt that I'm that lucky) then this is the line that needs to be changed to write 8192-byte blocks: https://bitbucket.org/anders_melander/map2pdb/src/2341200827af24f7dd75cb695a668dfa9564bcf5/Source/debug.info.writer.pdb.pas#lines-225 constructor TDebugInfoPdbWriter.Create; begin Create(4096); end;
  4. Anders Melander

    MAP2PDB - Profiling with VTune

    Neat. If you can spot where it gives up on the pdb file and returns an error that would be suuuuper nice. Does it produce any debug output while loading?
  5. Anders Melander

    MAP2PDB - Profiling with VTune

    Yeah... Not too keen on that as a first approach. The last time I tried using the llvm pdb support as a reference I wasted a lot of time before I found out that it was very incomplete to the point of being unusable by VTune. It has probably improved but since then it's hard to tell what state it's in. https://github.com/llvm/llvm-project/issues/37279 https://github.com/llvm/llvm-project/issues/28528 I will try to see if I can reproduce and spot the problem in the source before I go down that road. Thanks anyway.
  6. Anders Melander

    MAP2PDB - Profiling with VTune

    Looks like it. Ooooh, interesting. Maybe they've accidentally broken support for the older format and not noticed it because they're only testing the new format now. The article Stefan linked to makes me think that even though the PDB format supported large PDB files, the PDB reader (msdia140.dll) didn't. Otherwise, they would only have had to update their PDB writer to support large PDB files.
  7. Anders Melander

    Unicode normalization

    Doesn't really matter:
  8. Anders Melander

    MAP2PDB - Profiling with VTune

    That means the bug is most likely in map2pdb because that DLL is Microsoft's API for reading PDB files.
  9. Anders Melander

    MAP2PDB - Profiling with VTune

    I think that is a generic error message meaning "Something went wrong and our error handling sucks". As far as I remember you get a message like that regardless of what problem VTune encounters when resolving through the PDB file.
  10. Anders Melander

    MAP2PDB - Profiling with VTune

    I meant what do you mean by this ^ Do you mean 32- vs 64-bit addresses? AFAIR there's no choice or ambiguities in the PDB format with regard to the size of an address value, relative or absolute, but I would have to take a look at the source to make sure.
  11. Anders Melander

    Fast Base64 encode/decode

    Maybe at least reformat it into two distinct columns {$IFDEF DELPHIAVX}vpshufb ymm1, ymm0, [r9 + TAVXEncodeConst.Lut0];{$ELSE}db $C4,$C2,$7D,$00,$49,$20;{$ENDIF} {$IFDEF DELPHIAVX}vpand ymm2, ymm1, [r9 + TAVXEncodeConst.Mask0];{$ELSE}db $C4,$C1,$75,$DB,$51,$60;{$ENDIF} {$IFDEF DELPHIAVX}vpand ymm1, ymm1, [r9 + TAVXEncodeConst.Mask2];{$ELSE}db $C4,$C1,$75,$DB,$89,$A0,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX}vpmulhuw ymm2, ymm2, [r9 + TAVXEncodeConst.Mask1];{$ELSE}db $C4,$C1,$6D,$E4,$91,$80,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX}vpmullw ymm1, ymm1, [r9 + TAVXEncodeConst.Mask3];{$ELSE}db $C4,$C1,$75,$D5,$89,$C0,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX}vpor ymm1, ymm1, ymm2;{$ELSE}db $C5,$F5,$EB,$CA;{$ENDIF} Like this: {$IFDEF DELPHIAVX} vpshufb ymm1, ymm0, [r9 + TAVXEncodeConst.Lut0]; {$ELSE}db $C4,$C2,$7D,$00,$49,$20;{$ENDIF} {$IFDEF DELPHIAVX} vpand ymm2, ymm1, [r9 + TAVXEncodeConst.Mask0]; {$ELSE}db $C4,$C1,$75,$DB,$51,$60;{$ENDIF} {$IFDEF DELPHIAVX} vpand ymm1, ymm1, [r9 + TAVXEncodeConst.Mask2]; {$ELSE}db $C4,$C1,$75,$DB,$89,$A0,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX} vpmulhuw ymm2, ymm2, [r9 + TAVXEncodeConst.Mask1]; {$ELSE}db $C4,$C1,$6D,$E4,$91,$80,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX} vpmullw ymm1, ymm1, [r9 + TAVXEncodeConst.Mask3]; {$ELSE}db $C4,$C1,$75,$D5,$89,$C0,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX} vpor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EB,$CA;{$ENDIF} or even better: {$IFDEF DELPHIAVX} vpshufb ymm1, ymm0, [r9 + TAVXEncodeConst.Lut0]; {$ELSE}db $C4,$C2,$7D,$00,$49,$20;{$ENDIF} {$IFDEF DELPHIAVX} vpand ymm2, ymm1, [r9 + TAVXEncodeConst.Mask0]; {$ELSE}db $C4,$C1,$75,$DB,$51,$60;{$ENDIF} {$IFDEF DELPHIAVX} vpand ymm1, ymm1, [r9 + TAVXEncodeConst.Mask2]; {$ELSE}db $C4,$C1,$75,$DB,$89,$A0,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX} vpmulhuw ymm2, ymm2, [r9 + TAVXEncodeConst.Mask1]; {$ELSE}db $C4,$C1,$6D,$E4,$91,$80,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX} vpmullw ymm1, ymm1, [r9 + TAVXEncodeConst.Mask3]; {$ELSE}db $C4,$C1,$75,$D5,$89,$C0,$00,$00,$00;{$ENDIF} {$IFDEF DELPHIAVX} vpor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EB,$CA;{$ENDIF} Unreadable code is unmaintainable.
  12. Anders Melander

    MAP2PDB - Profiling with VTune

    Please elaborate
  13. Anders Melander

    MAP2PDB - Profiling with VTune

    This might help: https://www.intel.com/content/www/us/en/developer/articles/troubleshooting/older-version-product.html Please create an issue at the repository: https://bitbucket.org/anders_melander/map2pdb/issues/new The problem is most likely caused by msdia140.dll; The library VTune uses to read pdb files. You can try replacing the one that VTune installs with an older version. See:
  14. Anders Melander

    Label: Dashed Line Flow (animated) possible?

    There are many ways. What have you tried so far?
  15. Anders Melander

    Change "FadeOut" code to "FadeIn" code

    It doesn't matter. You are still not blending anything. Look, please forget about the alpha and just set it to 255. Even if alpha was somehow involved in what you are doing you are really not ready to deal with that part yet. Yes, but the code you posted does nothing in itself. It may very well be that you removed some parts that actually do something before you posted it, but I'm not a psychic and I can't guess what it originally did. Anyhow, moving on... Yes, it does. You are using the TImage32 control from the Graphics32 library to display the bitmaps. One approach would be to keep a copy of the bitmap you are fading from or to and then construct the bitmap to be displayed from that. However, I think we have by now established that you can't figure out how to do that. So I suggest you simply do this instead: // Set these values somewhere. // For example the place where you create the TImage32. // Make the background black fScreenImg.Color := clBlack; // Have the bitmap blend with the background color fScreenImg.Bitmap.DrawMode := dmBlend; ... // Fade out for var i := 255 downto 0 do begin fScreenImg.Bitmap.MasterAlpha := i; fScreenImg.Update; Sleep(50); end; // Load the new bitmap here fScreenImg.Bitmap.LoadFromFile(...); // or whatever... // Fade in for var i := 0 to 255 do begin fScreenImg.Bitmap.MasterAlpha := i; fScreenImg.Update; Sleep(50); end;
  16. Anders Melander

    Change "FadeOut" code to "FadeIn" code

    You don't need the alpha channel. The alpha is only needed when you later have to blend stuff together and that is not what you are doing. You are just "removing color" until only black is left. You haven't shown how exactly you draw stuff onto the screen so that is hard to answer. Generally, I would say that you need a temporary bitmap since it's dead slow to draw individual pixels one at a time. I don't know what this is supposed to illustrate since it doesn't do anything but once again: TColor32 is a DWORD (4 bytes) which is meant to contain the R, G, B and A channels simultaneously. You seem to think it represents a single channel.
  17. Btw, I don't know if the following is relevant to what you're doing: https://blog.grijjy.com/2021/01/14/shader-programming/
  18. GDI+ is generally not a fast library... Okay. I guess I'll take your word on that since you've actually tried it and I'm only speculating, but I would really expect a significantly higher FPS (on a "reasonably" sized screen) to be possible without hardware assist. I mean, what did we do before we got access to the GPU? Again, I'm not arguing that the GPU isn't the faster solution. I'm just surprised that it's necessary. Can you remember what bitmap size and resampler type you used when you tried this with Graphics32 (if that was what you used)? Now that I think of it, that was a brain fart on my part; It's OR-ing. I was thinking that since it's dropping black pixels it must be AND-ing but of course, since black isn't a color but rather the absence of color, it's the other way round. It's OR-ing so white $xxFFFFFF is replacing black $xx000000.
  19. Anders Melander

    Change "FadeOut" code to "FadeIn" code

    A, R, G and B are bytes. TColor32 is a dword (i.e. 4 bytes). It can be cast to a TColor32Entry, which is a record containing the 4 ARGB bytes. Value needs to be a "floating point" type. E.g. Single or Double. And the you cannot use Inc() on it. If you want to iterate using an integer value then you need to do a division somewhere so you get a value between 0 and 1 that you can multiply the RGB values with. Like I did here: This doesn't do anything. What did you expect it to do?
  20. Anders Melander

    Change "FadeOut" code to "FadeIn" code

    That's the ColorModulate function; It "fades" from any color to any color. In your case, you would fade each pixel from black to the color of your new image. Or if you absolutely must have a FadeFromBlack function: // Value = 0: Black // Value = 1: Color function FadeFromBlack(Color: TColor32Entry; Value: Single): TColor32Entry; begin Result.A := Color.A; // Probably 255 Result.R := Round(Color.R * Value); Result.G := Round(Color.G * Value); Result.B := Round(Color.B * Value); end; Apply this to each pixel of your "to" bitmap and draw the resulting bitmap on top of whatever you have on the screen.
  21. Anders Melander

    Change "FadeOut" code to "FadeIn" code

    Yes. As I stated: Right now you only have one bitmap, which is black because you faded it out, so you only have one color. If you don't have a copy of the image you're supposed to be fading in to, you need to code a time machine that goes back in time and gets it - or maybe save a copy somewhere before you destroy the color information by fading it to black.
  22. Anders Melander

    Change "FadeOut" code to "FadeIn" code

    No. The Value specifies how far you are between fade-in and fade-out. In my example it's a float value between 0 and 1, inclusive, so 0.5 is halfway faded in/out. I would probably use integer math for performance instead of floats, but it's easier to explain with a float. The two code snippets I gave you should be ready to use for what you're trying: // "Fade" from blue to red for i := 0 to 100 do Color := ColorModulate(clBlue32, clRed32, i / 100); // "Fade" from green to black for i := 0 to 100 do Color := ColorModulate(clGreen32, clBlack32, i / 100); // or... for i := 0 to 100 do Color := FadeToBlack(clGreen32, i / 100); Actually, in my FadeToBlack example, I modulate the Alpha channel too. You probably should leave the Alpha alone in that case. Otherwise, the result will end up being transparent.
  23. Confirmation bias, most likely. It's a common trap that I find myself in more often than I'd like to admit. Well, I guess I just did 🙂 I doubt it. Unless you're running this on a potato you shouldn't really need the GPU for something as simple as this. Of course, the GPU will be faster but the CPU should be fast enough. Rotation, translation, and scaling can be done in one go with a 3x3 (well, 2x3 actually) affine transformation. You "just" need to find a library that does that (or write it yourself). Graphics32 can do it but it doesn't support FMX. I'm guessing Image32 can too.
  24. I think it's just a bug in their implementation. They appear to be AND'ing the pixels instead or OR'ing them. Even the GDI's COLORONCOLOR or STRETCH_DELETESCAN methods, which are just about the fastest methods there are, with the worst quality, would produce a better result. Possibly, but the examples on that page are cooked to show the result you want; They only really demonstrate the effect of a downsample followed by a cubic upsample followed by a linear downsample (you've let the browser shrink the final bitmap). A fair comparison would be to compare the unscaled, downsampled results. What the results would look like when upsampled again with a cubic resampler is not relevant to the downsample quality. Original Downsampled, box filter Downsampled, linear filter Downsampled, cubic filter
  25. Anders Melander

    Change "FadeOut" code to "FadeIn" code

    Yes. For the "fade in" you need two bitmaps, giving you three color values: 1) the source color (black), 2) the target color (your original bitmap), and 3) the current color (the display bitmap). For the "fade out", the way you've implemented it, you only need one bitmap because the source and the current color are the same (the display bitmap) and the target color value is implicit (black). You can modulate/mix linearly between two colors, ColorFrom and ColorTo, by a value going from 0 to 1 with this formula: Color := ColorFrom * (1 - Value) + ColorTo * Value or in other words: // Value = 0: ColorFrom // Value = 1: ColorTo function ColorModulate(ColorFrom, ColorTo: TColor32Entry; Value: Single): TColor32Entry; begin Result.A := Round(ColorFrom.A * (1 - Value)) + Round(ColorTo.A * Value); Result.R := Round(ColorFrom.R * (1 - Value)) + Round(ColorTo.R * Value); Result.G := Round(ColorFrom.G * (1 - Value)) + Round(ColorTo.G * Value); Result.B := Round(ColorFrom.B * (1 - Value)) + Round(ColorTo.B * Value); end; This can both be used to fade in and fade out. When you're fading to black it follows that you are actually just doing this: // Value = 0: Color // Value = 1: Black function FadeToBlack(Color: TColor32Entry; Value: Single): TColor32Entry; begin Result.A := Round(Color.A * (1 - Value)); Result.R := Round(Color.R * (1 - Value)); Result.G := Round(Color.G * (1 - Value)); Result.B := Round(Color.B * (1 - Value)); end;
×