• subtract and divide instruction

    From Robert Finch@[email protected] to comp.arch on Thu Oct 15 02:40:46 2026
    From Newsgroup: comp.arch

    Added the SUBDIV (subtract and divide) instruction to Qupls4, used
    mainly with pointer arithmetic. The integer divider shortcuts divisions
    by powers of two. This was previously called PTRDIF which only did a
    right shift instead of a divide.

    SUBDIV Rd, Rs1, Rs2, Rs3 ; Rd = (Rs1-Rs2)/Rs3

    At work again on Qupls4. Certain aspects seem to be stabilizing, like
    the use of 48-bit instructions. The CPU currently has 64 GPRs. 8 GPRs
    may be selected as carry registers and are selected by three-bit code in
    some instructions.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Thomas Koenig@[email protected] to comp.arch on Thu Oct 15 14:42:04 2026
    From Newsgroup: comp.arch

    Robert Finch <[email protected]> schrieb:
    Added the SUBDIV (subtract and divide) instruction to Qupls4, used
    mainly with pointer arithmetic. The integer divider shortcuts divisions
    by powers of two. This was previously called PTRDIF which only did a
    right shift instead of a divide.

    SUBDIV Rd, Rs1, Rs2, Rs3 ; Rd = (Rs1-Rs2)/Rs3

    Wise man once wrote "On many computers, division is very time consuming
    and is to be avoided when possible."

    This could only become relevant if the size of your objects are
    unknown, and even then, a good optimizing compiler should be able
    to chose a good induction variable to avoid division.

    At work again on Qupls4. Certain aspects seem to be stabilizing, like
    the use of 48-bit instructions. The CPU currently has 64 GPRs. 8 GPRs
    may be selected as carry registers and are selected by three-bit code in some instructions.

    That is an interesting approach if one does not want to copy Mitch's
    CARRY modifier.
    --
    This USENET posting was made without artificial intelligence,
    artificial impertinence, artificial arrogance, artificial stupidity,
    artificial flavorings or artificial colorants.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Thu Oct 15 19:21:35 2026
    From Newsgroup: comp.arch


    Robert Finch <[email protected]> posted:

    Added the SUBDIV (subtract and divide) instruction to Qupls4, used
    mainly with pointer arithmetic. The integer divider shortcuts divisions
    by powers of two. This was previously called PTRDIF which only did a
    right shift instead of a divide.

    SUBDIV Rd, Rs1, Rs2, Rs3 ; Rd = (Rs1-Rs2)/Rs3

    Is this seen/used often enough to save useful amounts of instructions ?
    It does not appear to save execution time (except for power of 2 cases).

    In My 66000, DIV is down near 0.5% seldom following a subtract.

    At work again on Qupls4. Certain aspects seem to be stabilizing, like
    the use of 48-bit instructions. The CPU currently has 64 GPRs. 8 GPRs
    may be selected as carry registers and are selected by three-bit code in some instructions.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Robert Finch@[email protected] to comp.arch on Thu Oct 15 20:13:02 2026
    From Newsgroup: comp.arch

    On 2026-10-15 3:21 p.m., MitchAlsup wrote:

    Robert Finch <[email protected]> posted:

    Added the SUBDIV (subtract and divide) instruction to Qupls4, used
    mainly with pointer arithmetic. The integer divider shortcuts divisions
    by powers of two. This was previously called PTRDIF which only did a
    right shift instead of a divide.

    SUBDIV Rd, Rs1, Rs2, Rs3 ; Rd = (Rs1-Rs2)/Rs3

    Is this seen/used often enough to save useful amounts of instructions ?
    It does not appear to save execution time (except for power of 2 cases).

    In My 66000, DIV is down near 0.5% seldom following a subtract.

    Maybe, it showed up less than 1% but more than 0.1% IIRC. It does not
    save execution time, but it saves code space. Probably would not be
    worth supporting except that it is for free.

    It is a 3r instruction and provides DIV as well by subtracting zero. DIV
    was a 3r instruction format with one unused r.

    At work again on Qupls4. Certain aspects seem to be stabilizing, like
    the use of 48-bit instructions. The CPU currently has 64 GPRs. 8 GPRs
    may be selected as carry registers and are selected by three-bit code in
    some instructions.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Robert Finch@[email protected] to comp.arch on Sat Oct 17 18:45:52 2026
    From Newsgroup: comp.arch

    Adding some graphics instructions to Q+. While doing so, it seems to me
    like 24-bit load and store operations to handle RGB888 data might be handy.

    It is a toss-up deciding to use single precision floats or 18.18 fixed
    point arithmetic for graphics. The fixed point is about 3x faster
    latency and a lot smaller. I am leaning towards using single precision
    floats though.

    TEX - calculate texture index, TEX Rd, Rs1, Rs2, Rs3 ; Rs1 = U, Rs2 = V,
    and Rs3 contains the texture width,height and bytes per pixel. The
    texture cannot be more than 64k pixels high or wide.

    RGBCVT - convert between RGB formats: eg. RGBCVT r2,r1,10,8 converts
    RGB8.8.8 to RGB10.10.10

    BLEND - blend colors

    TRANSFORM - transform point, performs matrix multiply for point
    transformation using coefficients that may be set prior to calc.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Sun Oct 18 17:50:42 2026
    From Newsgroup: comp.arch

    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me
    like 24-bit load and store operations to handle RGB888 data might be handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code.

    It is a toss-up deciding to use single precision floats or 18.18 fixed
    point arithmetic for graphics. The fixed point is about 3x faster
    latency and a lot smaller. I am leaning towards using single precision floats though.

    TEX - calculate texture index, TEX Rd, Rs1, Rs2, Rs3 ; Rs1 = U, Rs2 = V,
    and Rs3 contains the texture width,height and bytes per pixel. The
    texture cannot be more than 64k pixels high or wide.

    RGBCVT - convert between RGB formats: eg. RGBCVT r2,r1,10,8 converts RGB8.8.8 to RGB10.10.10

    BLEND - blend colors

    TRANSFORM - transform point, performs matrix multiply for point transformation using coefficients that may be set prior to calc.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Robert Finch@[email protected] to comp.arch on Sun Oct 18 22:46:06 2026
    From Newsgroup: comp.arch

    On 2026-10-18 1:50 p.m., MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me
    like 24-bit load and store operations to handle RGB888 data might be handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code.

    It is a toss-up deciding to use single precision floats or 18.18 fixed
    point arithmetic for graphics. The fixed point is about 3x faster
    latency and a lot smaller. I am leaning towards using single precision
    floats though.

    TEX - calculate texture index, TEX Rd, Rs1, Rs2, Rs3 ; Rs1 = U, Rs2 = V,
    and Rs3 contains the texture width,height and bytes per pixel. The
    texture cannot be more than 64k pixels high or wide.

    RGBCVT - convert between RGB formats: eg. RGBCVT r2,r1,10,8 converts
    RGB8.8.8 to RGB10.10.10

    BLEND - blend colors

    TRANSFORM - transform point, performs matrix multiply for point
    transformation using coefficients that may be set prior to calc.



    I have seen a 64-bit masked store operation in another architecture that allows suppressing the storage of bytes that match a condition like the transparent color or color mixing bits. It seems to me that architecture
    has very application specific instruction. But I had sought to do this
    using generic SIMD or vector instructions.

    ; vector set not equal, generate mask in r4 for elements of r1 that are
    not equal to r5. R5 would contain the transparent color.
    VSNE r4,r1,r5
    ; do a masked vector store
    VSTORE r1,(r2+r3),r4

    I wonder if it would be possible to have the element/lane size for
    vectors specified in bits.

    I forgot that the frame buffer expects pixels packed into 256-bit wide
    strips, without allowing a pixel to span strips. The only raw pixel data
    that will map well is 8, 16, or 32 bits per pixel. Other sizes leave
    unused bits in the strip.

    Calculating a memory address for a pixel is not as simple as I thought.
    It requires providing a bit offset as well. The video hardware supports
    odd numbers of bits per pixel like 12 or 9 with each color component
    specified separately. It might be better to support pixel fetch and
    store instructions.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@[email protected] to comp.arch on Mon Oct 19 16:46:12 2026
    From Newsgroup: comp.arch

    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me
    like 24-bit load and store operations to handle RGB888 data might be handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code.


    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard, differing
    mostly as an unresolved fight over element ordering:
    "R, G, B, A" vs "B, G, R, A".


    24-bit is mostly a weird/awkward thing that is sometimes used but mostly
    not really worth it; vs just ignoring the last 8 bits in a 32-bit word
    when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually overkill.
    3x E5.M5 does seem semi-popular here for HDR.
    3x E4.M4 also works, and allows treating it like RGBA32.
    And seems to match the look/behavior of HDR on a Radeon HD 4xxx.
    3x E4.M6: No one uses it but would give better fidelity.


    Personally, I use RGB555 a lot:
    Mostly good enough for many uses;
    Generally manages to look better than RGB565.

    Here, 16 bits is a convenient size:
    Nice space savings over 32 bit;
    Works easily with 16 bit load/store ops, unlike 24 bits;
    In practice the loss of visual fidelity isn't often that noticeable.
    It is mostly obvious as banding in non-dithered gradients.


    565 has an ugly issue that it introduces noisy greenish/purplish tints, whereas 555 at least provides proper grays and is more free of chromatic noise.

    Depends on the up-conversion algo for 565 though, say:
    Traditional:
    R: Copy high 3 bits to low 3;
    G: Copy high 2 bits to low 2;
    B: Copy high 3 bits to low 3.
    Result, chromatic noise.
    Better visually:
    R: Copy high 2 bits to low 2, bit 2 is LSB of G;
    G: Copy high 2 bits to low 2;
    B: Copy high 2 bits to low 2, bit 2 is LSB of G.
    Avoids chromatic effect, but, this is non-traditional.


    Though, often for 555 to look good some level of dithering is still
    needed in many cases when down-converting from a higher bit-depth.

    Personally, I have usually had best results with 2x2 or 4x4 Bayer.
    People often argue that Floyd-Stanberg or Blue-Noise is better.
    But, visually, 4x4 Bayer often seems to give the best results for me.

    Dithering is also usually needed when down-converting to indexed color; otherwise bad posterization like effects may occur.


    There are cases where it shouldn't be used, like SDF fonts:
    Dithering an SDF makes it actively worse than posterizing it;
    Also SDFs survive fairly well to indexed-color if the palette fits well
    (but, generally needs either palette optimization, or a generalized
    palette optimized to SDFs; generic palettes don't really work).

    Better to avoid using color-cell though, as traditional color-cell seems
    to be more destructive to SDFs. So, was mostly having best results
    storing them as 256-color (then applying LZ compression).

    Have noted that there is another trick I have become aware of that can
    boost compression of these sorts of images:
    Encode the pixels in Hilbert (or maybe Morton) order rather than raster;
    This seems to increase the effectiveness of the LZ compression even when
    not using delta-filtering or entropy coding (and, unlike delta
    filtering, does not derive its value from entropy coding;
    delta-filtering without entropy-coding makes compression worse).

    Theoretically, could do Hilbert-8 or Hilbert-16, but these patterns are
    more complicated, and seemingly 2-levels of Hilbert-4 over a 16x16 block
    would achieve mostly the same effect. Computational cost is modest (and generally still notably less than that of using PNG style filters and
    entropy coding).

    Though, an intermediate compromise here being to store pixels in Morton
    order; which mostly gives similar benefits for plain LZ (in the absence
    of delta-filtering; Morton being notably worse for delta-filtering than Hilbert).


    Even if, yes, this is mostly falling into wackiness.


    Why not Vector / True-Type style fonts?
    Mostly that these have higher computational cost.

    And, for best results, need to render vector glyphs internally at a
    somewhat higher resolution internally and then downsample them to the
    target size (with many algos, trying to render them directly at the
    target scale looks like broken crap).

    However, bulk storage size for vector glyphs is less than that of SDFs,
    and they are still better for dynamic scaling (SDFs usually have a
    maximum useful size above which weirdness gets more obvious).

    Say:
    16x16 pixels SDF glyphs:
    Effective range, ~ 8 to 32 pixels.
    Below 8, need true mipmaps to avoid aliasing issues.
    Above 32, jank is obvious.
    32x32 glyphs could cover 5 to 64 pixels via mipmaps.

    There is one trick I had found that works in both 3D rendering and SDFs:
    Rather than using true trilinear filtering, it is possible to use the
    scale fraction mostly to pull the interpolation closer to the center in
    a bilinear filter to mimic the effects of a trilinear filter at lower cost.

    Or, basically, as it is about to jump to the next smaller mip-level, it
    sees the average of the 4 texels, or basically, roughly the value it
    would (presumably) have gotten from the next mip-level (if one assumes
    each mip-level is offset at 1/2 texel relative to the one above).

    Though, thinking, this does effectively have the property of going nearest-neighbor on the lower virtual mipmap level, rather than
    accurately mimic the effect of trilinear, but usually doesn't matter.






    Meanwhile, I have been having a weird experience recently mostly in that
    my own long term memory seems to be garbled in some areas.

    What was the trigger? A few old games, Myst and Riven.
    Actually, it was more specifically catching some streams of someone
    playing a modern remake of Riven; they were on one of the islands, had a response like "Wow, this looks a lot more immersive than the fixed view
    points in the original.", then was left questioning myself, like
    "What?", part of my mind saying I had played it, another part not
    recognizing it.

    I then had thought at first that they were games I was aware of when I
    was much younger, but had mostly overlooked.

    Downloaded them on GOG, started playing them.

    First Riven, but was making unreasonably fast progress, like I kept just knowing where to go and what to do. Got a little weirded out.

    Then went and did Myst, initially it was slow going (it didn't
    immediately seem as familiar), but seemingly once I realized how to get
    into the tower (by clicking one of the paintings to turn a bookshelf
    into stairs), it was like I then knew the whole rest of the game (apart
    from a few temporary snags). Like, once I got to each area, I somehow
    already knew what to do (well, except Stoneship, where I couldn't find
    the compass at first and had mostly forgotten about it, it being a
    necessary part of being able to return to the main island).

    Got through the game in roughly 7 hours.


    Then partly returned to Riven, have seemingly made it through much of
    the game in roughly about 3 hours (remaining steps: Go visit the rebels through an animal ordering puzzle, to get back a trap-book, needed
    before doing a fire-marble puzzle and facing off with the main villain).

    Well, also need to fetch the code for opening the inner part of the dome (think it is in the notebook in the lab, need to go back there and look
    at it more carefully... but they wrote it in cursive, so trying to read
    it is "teh suck"). Well, and after the villain face-off, getting some
    notes from a small music box to free someone, and crashing a telescope
    into a window to end the game.

    More or less... Trying to do any of these out-of-order leading to one of
    the bad endings.


    But, yeah, it is like the part of my mind that seemingly remembers the
    game is winning this particular fight. If I hadn't played the game (or
    if it were merely "contamination" from elsewhere, *2), I should have run
    into some major roadblock already. But, if I have, why don't I have
    consistent memories of the experience?... (The original memories I have
    are fragmentary and garbled...).

    *2: Well, say, if one sees parts of the game or knows plot spoilers,
    this may allow cheating on some things, but wouldn't likely continue
    carrying someone through the whole game. Main reason I stopped when I
    did, was because if I go through that animal-sequence puzzle, there was
    a longish series of cutscenes on the other side. So, was more of a "will
    stop here, cutscenes some other day" thing. Then a few remaining things,
    then probably on to the endgame.


    Like, I could probably do this for Half-Life, but, well, I actually
    remember playing through Half-Life.


    Well, among other things: Once, decades ago, I had a GF for a while. She
    is seemingly tied in with these memories (mostly in that I think it was
    her that had the game). But, this is where memories are most unstable (I
    don't really know if this is real or not). These memories also seem to characterize her somewhat different than in other memories.

    But, it would seem in any case, this is not my first encounter with this
    game.

    But, in some way, it is more a case of trying to figure out what exactly happened to my memory here. Most of the rest of my memory doesn't seem
    quite to badly chewed.



    It is a toss-up deciding to use single precision floats or 18.18 fixed
    point arithmetic for graphics. The fixed point is about 3x faster
    latency and a lot smaller. I am leaning towards using single precision
    floats though.


    In TKRA-GL, the internal rasterizer is mostly using 16 bit fixed point.
    Or, 8.8, generally mapped to packed-16-bit SIMD vectors.

    Ironically, for a while, I had thought that the reason TKRA-GL's
    software rasterization was as fast as it was, was because of epic
    properties of my ASM based span-drawing functions.

    After the move to XG3, which goes back to using the same basic C based versions as used when building for other targets, it is more obvious it
    is not.


    Or, what seeming performance advantages exist for my ISA design,
    relative to RV64G and x86, exist independent of any special merit of highly-tuned ASM code. But, then again, BGBCC has reached a point of
    (mostly) not producing horribly inefficient compiler output, so...


    There was a false start, where I was wondering why a build of TKRA-GL + GLQuake for native Win10+X64 was performing so badly (barely much faster
    at 640x480 than for my own ISA). But, then realized it is was because I
    had misunderstood the meaning of an MSVC command-line option and then
    left and forgot about it, so I was essentially comparing against an unoptimized debug build, and hence the lame performance.

    Still weird in a way though that the gulf between 3.7 GHz and 50 MHz
    manages to still be small enough that the effects of a debug build are obvious.



    But, results do still seem my ISA is "punching above its weight class",
    in being able to give any level of semi-usable OpenGL on a 50 MHz CPU.

    Well, never-mind the seemingly impossible demand that I would seemingly
    either need 200 MHz or 4 cores working in parallel to be able to give
    playable results for Quake 3.


    Though, if I was targeting mainly the XC7A200T, could try to do a setup
    like, maybe:
    1 control core (full ISA);
    4 render cores (more limited ISA);
    2 rasterizer modules, probably dividing the screen in half.
    Would need to split requests that cross halves though.

    The most likely idea for the render cores being, say:
    XG3+RV64G only (no RV-C or XG1/XG2 support);
    Omits the Double-Precision FPU (saves a few kLUT);
    Omits 64-bit integer multiply/divide (also another kLUT);
    L1 D$ is aligned-only (also saves a big chunk of LUTs).

    Missing functionality either being unsupported entirely, or faked via emulation traps. This is less bad though if one were to assume such
    cores only exist to run the TKRA-GL transform and rendering pipeline.

    Though, if all 4 cores are working on the same shared framebuffers,
    would need cache coherence. Or some way to divide up geometry by
    location, but can't know where geometry is on-screen until after the projection stage; which is one of the places one would want to split up.

    Well, unless maybe:
    Main CPU:
    Runs GLQuake / Quake2 / Quake3
    Deals with OpenGL;
    Does initial projection;
    Adds projected primitives to a global work list.
    Worker Cores:
    Grab a primitive, and check for need to subdivide;
    If needs subdivision:
    Subdivide primitive;
    Keeps any pieces that belong to its area;
    Others, pushed back to shared list.
    If local to this cores region?
    Process it.
    Else:
    Push it back to the list.

    Though, in this case, the shared list is likely to become a bottleneck.
    Could maybe reduce overhead by giving each core its own work queue, with
    the main CPU having a push-back queue.

    Each core only looks in its own list for new work, but may push work
    over to other cores (if in their area), or back to the main CPU (if it
    needs work there, like splitting a primitive between two workers).

    For sake of sanity, the main CPU can wait around until it and all the
    workers complete the draw-call.

    Though, another (maybe simpler) option in this case being to invest in a memory-coherence mechanism, which would allow simply dividing up the primitives sequentially hand handing each off to one of the cores (which
    may then draw anywhere in the framebuffer).

    Would mean the L2 cache or similar would need to track who "owns each
    dirty cache line" and has the ability to issue "please write back this
    line" requests to the cores.

    Maybe this is optional, and so may only need to apply to specific memory mappings (via the TLB):
    Default: Weak coherence only;
    If enabled per-page: Memory access needs to be cache-coherent.


    Then again, may also make sense to still have a single rasterizer module
    for its MMIO interface, but if needed, the rasterizer could have
    multiple "worker units" internally.

    Would also need to add a step to the MMIO interface though to deal with multiple cores firing requests at is, say:
    Core checks if unit is ready to accept work (status register);
    Core writes a request requesting ability to use the interface;
    Reads back status, seeing if its request was granted;
    If not, retry until success.
    (This overlaps with the existing busy / flow-control handling).
    Core writes its request's content registers;
    Core writes to status register to submit work to the FIFO.

    This trying to avoid the situation where the cores step on each other by
    both trying to write to the registers for the MMIO interface at the same
    time.

    There is already a flow-control mechanism (for busy signaling), but for muliple cores would need to add a "request in progress" mechanism to
    this (submitting a request to this module basically involves setting up
    a bunch of parameters to describe the part of the primitive to be
    rasterized).


    Note that TKRA-GL uses a hybrid process, where simple tasks are handled
    by the rasterizer module, but more advanced tasks use software
    rasterization.

    At present, the software-rasterization seems to be managing
    alpha-testing, may need to change this though.

    Well, also software manages GL_LINES, GL_POINTS, and drawing primitives
    as outlines (with these cases being annoyingly inefficient; as it takes
    almost as much computationally to draw a point or line as it does to
    draw a small triangle or quad).


    ...


    TEX - calculate texture index, TEX Rd, Rs1, Rs2, Rs3 ; Rs1 = U, Rs2 = V,
    and Rs3 contains the texture width,height and bytes per pixel. The
    texture cannot be more than 64k pixels high or wide.


    I did this via an LDTEX instruction.

    It passed U/V as 2x 16.16 though.
    With the register understood as 2x 32-bit.


    Also it used the tag-bits to encode texture resolution as a combined
    log-2, with a few bits to encode the encoding format:
    RGB555 (A.R5.R5.R5);
    RGBA32 (A8.R8.G8.B8);
    RGBA64 (A16.R16.G16.B16);
    UTX2 (2x RGB555, 4x4x2 selector bits)
    Functional stand-in for DXT1 / BC1
    UTX3 (2x RGBA32, 4x4x2 RGB, 4x4x2 A)
    Functional stand-in for DXT5 / BC3
    Overlaps with BC7 in slightly higher color fidelity.
    Or, with BC6H in the HDR mode.
    Using E4.M4 per component...


    There was UTX1, but it mostly isn't used much, as it packed both
    endpoints into 16 bits (D4, RGB444), and used 4x4x1 selector bits.
    Quality is worse than UTX1, so isn't usually a good option.


    There is a restriction on LDTEX (and the rasterizer module) that only
    certain ranges of texture sizes are allowed, eg:
    1x1, 2x1, 2x2, 4x2, 4x4, 8x4, 8x8, ..., 256x256, 512x256, 512x512, ...
    Though, with 5 bits, will max out at 65536x32768.
    But, 64k x 64k is impractically huge.
    TKRA-GL currently maxes out at around 1024x1024 IIRC.
    But, better to not exceed 256x256 without good reason.

    While it doesn't directly support 256x512 or similar, it can fake it by swapping U and V.

    Any textures further off from this will need to be resampled to one of
    the valid sizes.

    In this case, it is possible to pass off-size and NPOT images to
    glTexImage2D or similar, but they will be auto-resized internally, as it doesn't actually support NPOT internally.

    Part of the quirk also is that the textures internally all use
    Morton-Order, and this size progression is what one gets by performing
    the Morton shuffle and masking the result.

    One other interesting/useful property of Morton order is that nearby
    texels are more likely to be in-cache.

    Morton order is also a lot simpler/cheaper to deal with than Hilbert
    Order here, but Hilbert is better for locality.


    The LDTEX instruction only does nearest-neighbor by default, though
    there is a 64-bit encoding that allows also specifying which corner one
    wants.

    Say:
    LDTEX (R10, R11, 4), R28 //bottom left
    LDTEX (R10, R11, 5), R29 //bottom right
    LDTEX (R10, R11, 6), R30 //top left
    LDTEX (R10, R11, 7), R31 //top right
    Assuming a coordinate space where (0,0) is in the bottom-left corner and
    V points upwards.

    With the 32-bit encoding giving Nearest by default.

    In this case, the span-drawing function needs to do its own
    interpolation. Well, and for sake of speed, had often used 3 points and simplified interpolation, which was partly inspired by the GPU in the
    N64, but differs in that I use a slightly different approach so the
    result looks different.

    In my case, interpolate along U and V, then a weighted difference to interpolate along the diagonal; the N64 version apparently mirrors the interpolation if it would fall near the far corner, essentially dividing
    it into 2 triangular regions. Doing a little bit of mental grinding, I
    think the behavior of the N64 style interpolation might be to simply
    take (V-U) as the diagonal and let it wrap on overflow (as opposed to essentially (V-U)*0.5+0.5).



    In this case, the low 48 bits of the texture encode the base address of
    the image.

    For the rasterizer module, the address requires an alignment. I forget
    if 16 or 64 bytes at the moment; may have been 64 to match the L2
    cache's internal cache-line size (this being because the module mostly
    uses bare cache lines for its memory access to the RGB/Z buffers and textures).

    In the RGA32 mode, as noted:
    Framebuffer format: RGBA32
    Z buffer format: Z24.S8

    But, also has a 16-bit mode:
    RGB: RGB5A (A.R5.G5.B5)
    Z: Z16 | Z12.S4

    TKRA-GL is currently often using things in 16-bit mode with Z12, which admittedly isn't great for Z-fighting (even my GLQuake port has some significant Z fighting with this).

    The Z16 mode basically requires the program to swear that it will never
    enable stencil testing though.

    A 4-bit stencil buffer is basically enough to handle things like stencil shadows and similar; though stencil shadowing is slow on TKRA-GL so not
    a good idea. 2-bit would have given less Z-fighting, but is near useless
    for stencil effects.

    An RGB555 color buffer though does impact the allowed blending
    operations (pretty much nothing that uses DEST_ALPHA will work
    correctly). But, then again, it is pretty much never used as such
    (things like light-mapping typically using DEST_COLOr instead).


    Or, one can use the 32-bit mode for higher visual fidelity, but in this
    case it uses more memory and is slower (and the final output stages
    still require a conversion to RGB555).

    ...


    RGBCVT - convert between RGB formats: eg. RGBCVT r2,r1,10,8 converts
    RGB8.8.8 to RGB10.10.10

    BLEND - blend colors

    TRANSFORM - transform point, performs matrix multiply for point
    transformation using coefficients that may be set prior to calc.


    I didn't go this far.

    Would make sense if defining a shader-ASM language, but probably not for
    a CPU.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Robert Finch@[email protected] to comp.arch on Tue Oct 20 05:27:37 2026
    From Newsgroup: comp.arch

    On 2026-10-19 5:46 p.m., BGB wrote:
    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me
    like 24-bit load and store operations to handle RGB888 data might be
    handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code.


    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard, differing mostly as an unresolved fight over element ordering:
      "R, G, B, A" vs "B, G, R, A".

    Figures. I use ARGB, putting the alpha in the MSBs.

    24-bit is mostly a weird/awkward thing that is sometimes used but mostly
    not really worth it; vs just ignoring the last 8 bits in a 32-bit word
    when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually overkill.
      3x E5.M5 does seem semi-popular here for HDR.
      3x E4.M4 also works, and allows treating it like RGBA32.
        And seems to match the look/behavior of HDR on a Radeon HD 4xxx.
      3x E4.M6: No one uses it but would give better fidelity.

    Most people cannot see color beyond RGB777 so 10.10.10 is overkill but I
    had worried about rounding of colors and figure a few extra bits would
    not hurt. ARGB3777 is 24-bit. Some of the very early display adapters
    only supported 18 bits for color. So, ARGB6666 - fits nicely in 24 bits.

    The video hardware uses a 32-bit color bus. I had it at 40-bits (To
    support ARGB10.10.10.10) but figured it would never get used. Really
    needed to trim the bus size down to save LUTs. It is tempting to go to ARGB3777 for the display hardware. The RGB to HDMI converter only
    supports 8.8.8.


    Personally, I use RGB555 a lot:
      Mostly good enough for many uses;
      Generally manages to look better than RGB565.

    Here, 16 bits is a convenient size:
      Nice space savings over 32 bit;
      Works easily with 16 bit load/store ops, unlike 24 bits;
      In practice the loss of visual fidelity isn't often that noticeable.
        It is mostly obvious as banding in non-dithered gradients.

    I like the RGB555, it is the default format for my video hardware IIRC.
    But I made the hardware completely programmable for just about any format.>

    565 has an ugly issue that it introduces noisy greenish/purplish tints, whereas 555 at least provides proper grays and is more free of chromatic noise.

    Depends on the up-conversion algo for 565 though, say:
      Traditional:
        R: Copy high 3 bits to low 3;
        G: Copy high 2 bits to low 2;
        B: Copy high 3 bits to low 3.
      Result, chromatic noise.
      Better visually:
        R: Copy high 2 bits to low 2, bit 2 is LSB of G;
        G: Copy high 2 bits to low 2;
        B: Copy high 2 bits to low 2, bit 2 is LSB of G.
      Avoids chromatic effect, but, this is non-traditional.


    Though, often for 555 to look good some level of dithering is still
    needed in many cases when down-converting from a higher bit-depth.

    Personally, I have usually had best results with 2x2 or 4x4 Bayer.
      People often argue that Floyd-Stanberg or Blue-Noise is better.
      But, visually, 4x4 Bayer often seems to give the best results for me.

    Dithering is also usually needed when down-converting to indexed color; otherwise bad posterization like effects may occur.

    What about 3x3 alternating? I tried dithering but could not get the
    quality of results satisfactory. I could see the dither, figured it was
    better just to change the video resolution.>

    There are cases where it shouldn't be used, like SDF fonts:
    Dithering an SDF makes it actively worse than posterizing it;
    Also SDFs survive fairly well to indexed-color if the palette fits well (but, generally needs either palette optimization, or a generalized
    palette optimized to SDFs; generic palettes don't really work).

    Better to avoid using color-cell though, as traditional color-cell seems
    to be more destructive to SDFs. So, was mostly having best results
    storing them as 256-color (then applying LZ compression).

    Have noted that there is another trick I have become aware of that can
    boost compression of these sorts of images:
    Encode the pixels in Hilbert (or maybe Morton) order rather than raster;
    This seems to increase the effectiveness of the LZ compression even when
    not using delta-filtering or entropy coding (and, unlike delta
    filtering, does not derive its value from entropy coding; delta-
    filtering without entropy-coding makes compression worse).

    Theoretically, could do Hilbert-8 or Hilbert-16, but these patterns are
    more complicated, and seemingly 2-levels of Hilbert-4 over a 16x16 block would achieve mostly the same effect. Computational cost is modest (and generally still notably less than that of using PNG style filters and entropy coding).

    Though, an intermediate compromise here being to store pixels in Morton order; which mostly gives similar benefits for plain LZ (in the absence
    of delta-filtering; Morton being notably worse for delta-filtering than Hilbert).


    Even if, yes, this is mostly falling into wackiness.


    Why not Vector / True-Type style fonts?
    Mostly that these have higher computational cost.

    And, for best results, need to render vector glyphs internally at a
    somewhat higher resolution internally and then downsample them to the
    target size (with many algos, trying to render them directly at the
    target scale looks like broken crap).

    However, bulk storage size for vector glyphs is less than that of SDFs,
    and they are still better for dynamic scaling (SDFs usually have a
    maximum useful size above which weirdness gets more obvious).

    Say:
      16x16 pixels SDF glyphs:
        Effective range, ~ 8 to 32 pixels.
          Below 8, need true mipmaps to avoid aliasing issues.
        Above 32, jank is obvious.
      32x32 glyphs could cover 5 to 64 pixels via mipmaps.

    There is one trick I had found that works in both 3D rendering and SDFs: Rather than using true trilinear filtering, it is possible to use the
    scale fraction mostly to pull the interpolation closer to the center in
    a bilinear filter to mimic the effects of a trilinear filter at lower cost.

    Or, basically, as it is about to jump to the next smaller mip-level, it
    sees the average of the 4 texels, or basically, roughly the value it
    would (presumably) have gotten from the next mip-level (if one assumes
    each mip-level is offset at 1/2 texel relative to the one above).

    Though, thinking, this does effectively have the property of going nearest-neighbor on the lower virtual mipmap level, rather than
    accurately mimic the effect of trilinear, but usually doesn't matter.






    Meanwhile, I have been having a weird experience recently mostly in that
    my own long term memory seems to be garbled in some areas.

    What was the trigger? A few old games, Myst and Riven.
    Actually, it was more specifically catching some streams of someone
    playing a modern remake of Riven; they were on one of the islands, had a response like "Wow, this looks a lot more immersive than the fixed view points in the original.", then was left questioning myself, like
    "What?", part of my mind saying I had played it, another part not recognizing it.

    I played MYST. I got lost in the subway. It turns out my hearing was not
    good enough to hear the beeps, so I had no clues to go by. I had to
    resort to looking up how to escape on the internet. Once I got out of
    the subway I was able to finish the game.>
    I then had thought at first that they were games I was aware of when I
    was much younger, but had mostly overlooked.

    Downloaded them on GOG, started playing them.

    First Riven, but was making unreasonably fast progress, like I kept just knowing where to go and what to do. Got a little weirded out.

    Then went and did Myst, initially it was slow going (it didn't
    immediately seem as familiar), but seemingly once I realized how to get
    into the tower (by clicking one of the paintings to turn a bookshelf
    into stairs), it was like I then knew the whole rest of the game (apart
    from a few temporary snags). Like, once I got to each area, I somehow already knew what to do (well, except Stoneship, where I couldn't find
    the compass at first and had mostly forgotten about it, it being a
    necessary part of being able to return to the main island).

    Got through the game in roughly 7 hours.


    Then partly returned to Riven, have seemingly made it through much of
    the game in roughly about 3 hours (remaining steps: Go visit the rebels through an animal ordering puzzle, to get back a trap-book, needed
    before doing a fire-marble puzzle and facing off with the main villain).

    Well, also need to fetch the code for opening the inner part of the dome (think it is in the notebook in the lab, need to go back there and look
    at it more carefully... but they wrote it in cursive, so trying to read
    it is "teh suck"). Well, and after the villain face-off, getting some
    notes from a small music box to free someone, and crashing a telescope
    into a window to end the game.

    More or less... Trying to do any of these out-of-order leading to one of
    the bad endings.


    But, yeah, it is like the part of my mind that seemingly remembers the
    game is winning this particular fight. If I hadn't played the game (or
    if it were merely "contamination" from elsewhere, *2), I should have run into some major roadblock already. But, if I have, why don't I have consistent memories of the experience?... (The original memories I have
    are fragmentary and garbled...).

    *2: Well, say, if one sees parts of the game or knows plot spoilers,
    this may allow cheating on some things, but wouldn't likely continue carrying someone through the whole game. Main reason I stopped when I
    did, was because if I go through that animal-sequence puzzle, there was
    a longish series of cutscenes on the other side. So, was more of a "will stop here, cutscenes some other day" thing. Then a few remaining things, then probably on to the endgame.


    Like, I could probably do this for Half-Life, but, well, I actually
    remember playing through Half-Life.


    Well, among other things: Once, decades ago, I had a GF for a while. She
    is seemingly tied in with these memories (mostly in that I think it was
    her that had the game). But, this is where memories are most unstable (I don't really know if this is real or not). These memories also seem to characterize her somewhat different than in other memories.

    But, it would seem in any case, this is not my first encounter with this game.

    But, in some way, it is more a case of trying to figure out what exactly happened to my memory here. Most of the rest of my memory doesn't seem
    quite to badly chewed.



    It is a toss-up deciding to use single precision floats or 18.18 fixed
    point arithmetic for graphics. The fixed point is about 3x faster
    latency and a lot smaller. I am leaning towards using single precision
    floats though.

    Switched this to 16.16>
    In TKRA-GL, the internal rasterizer is mostly using 16 bit fixed point.
    Or, 8.8, generally mapped to packed-16-bit SIMD vectors.

    Ironically, for a while, I had thought that the reason TKRA-GL's
    software rasterization was as fast as it was, was because of epic
    properties of my ASM based span-drawing functions.

    After the move to XG3, which goes back to using the same basic C based versions as used when building for other targets, it is more obvious it
    is not.


    Or, what seeming performance advantages exist for my ISA design,
    relative to RV64G and x86, exist independent of any special merit of highly-tuned ASM code. But, then again, BGBCC has reached a point of (mostly) not producing horribly inefficient compiler output, so...


    There was a false start, where I was wondering why a build of TKRA-GL + GLQuake for native Win10+X64 was performing so badly (barely much faster
    at 640x480 than for my own ISA). But, then realized it is was because I
    had misunderstood the meaning of an MSVC command-line option and then
    left and forgot about it, so I was essentially comparing against an unoptimized debug build, and hence the lame performance.

    Still weird in a way though that the gulf between 3.7 GHz and 50 MHz
    manages to still be small enough that the effects of a debug build are obvious.

    That is quite a difference in clock rate. I wonder what the difference
    is in memory performance. Maybe being able to execute a whole bunch more instructions does not make as much difference as one might think because
    of the memory access time.>

    But, results do still seem my ISA is "punching above its weight class",
    in being able to give any level of semi-usable OpenGL on a 50 MHz CPU.

    Well, never-mind the seemingly impossible demand that I would seemingly either need 200 MHz or 4 cores working in parallel to be able to give playable results for Quake 3.


    Though, if I was targeting mainly the XC7A200T, could try to do a setup like, maybe:
      1 control core (full ISA);
      4 render cores (more limited ISA);
      2 rasterizer modules, probably dividing the screen in half.
        Would need to split requests that cross halves though.

    The most likely idea for the render cores being, say:
      XG3+RV64G only (no RV-C or XG1/XG2 support);
      Omits the Double-Precision FPU (saves a few kLUT);
      Omits 64-bit integer multiply/divide (also another kLUT);
      L1 D$ is aligned-only (also saves a big chunk of LUTs).

    Missing functionality either being unsupported entirely, or faked via emulation traps. This is less bad though if one were to assume such
    cores only exist to run the TKRA-GL transform and rendering pipeline.

    Though, if all 4 cores are working on the same shared framebuffers,
    would need cache coherence. Or some way to divide up geometry by
    location, but can't know where geometry is on-screen until after the projection stage; which is one of the places one would want to split up.

    Well, unless maybe:
      Main CPU:
        Runs GLQuake / Quake2 / Quake3
        Deals with OpenGL;
        Does initial projection;
        Adds projected primitives to a global work list.
      Worker Cores:
        Grab a primitive, and check for need to subdivide;
          If needs subdivision:
            Subdivide primitive;
            Keeps any pieces that belong to its area;
            Others, pushed back to shared list.
          If local to this cores region?
            Process it.
          Else:
            Push it back to the list.

    Though, in this case, the shared list is likely to become a bottleneck.
    Could maybe reduce overhead by giving each core its own work queue, with
    the main CPU having a push-back queue.

    Each core only looks in its own list for new work, but may push work
    over to other cores (if in their area), or back to the main CPU (if it
    needs work there, like splitting a primitive between two workers).

    For sake of sanity, the main CPU can wait around until it and all the workers complete the draw-call.

    Though, another (maybe simpler) option in this case being to invest in a memory-coherence mechanism, which would allow simply dividing up the primitives sequentially hand handing each off to one of the cores (which
    may then draw anywhere in the framebuffer).

    Would mean the L2 cache or similar would need to track who "owns each
    dirty cache line" and has the ability to issue "please write back this
    line" requests to the cores.

    Maybe this is optional, and so may only need to apply to specific memory mappings (via the TLB):
      Default: Weak coherence only;
      If enabled per-page: Memory access needs to be cache-coherent.


    Then again, may also make sense to still have a single rasterizer module
    for its MMIO interface, but if needed, the rasterizer could have
    multiple "worker units" internally.

    Would also need to add a step to the MMIO interface though to deal with multiple cores firing requests at is, say:
      Core checks if unit is ready to accept work (status register);
      Core writes a request requesting ability to use the interface;
        Reads back status, seeing if its request was granted;
        If not, retry until success.
        (This overlaps with the existing busy / flow-control handling).
      Core writes its request's content registers;
      Core writes to status register to submit work to the FIFO.

    This trying to avoid the situation where the cores step on each other by both trying to write to the registers for the MMIO interface at the same time.

    There is already a flow-control mechanism (for busy signaling), but for muliple cores would need to add a "request in progress" mechanism to
    this (submitting a request to this module basically involves setting up
    a bunch of parameters to describe the part of the primitive to be rasterized).


    Note that TKRA-GL uses a hybrid process, where simple tasks are handled
    by the rasterizer module, but more advanced tasks use software rasterization.

    At present, the software-rasterization seems to be managing alpha-
    testing, may need to change this though.

    Well, also software manages GL_LINES, GL_POINTS, and drawing primitives
    as outlines (with these cases being annoyingly inefficient; as it takes almost as much computationally to draw a point or line as it does to
    draw a small triangle or quad).


    ...


    TEX - calculate texture index, TEX Rd, Rs1, Rs2, Rs3 ; Rs1 = U, Rs2 = V, >>> and Rs3 contains the texture width,height and bytes per pixel. The
    texture cannot be more than 64k pixels high or wide.


    I did this via an LDTEX instruction.

    I figured it was better to separate the address calculation from the
    data load. TEX then a load. Teh TEX instruction has a fairly high
    latency about 5 cycles for fixed point or 20 for floats. The pixels surrounding the source pixel could be fetched using displacements from
    the TEX address avoiding multiple TEX instructions.
    Might need to be able to load / store data based on a data size stored
    in a register. I may change the 24-bit load/stores into variable data
    size load/stores. There is also a 72-bit load/store for register values including an 8-bit tag. I would also like 48-bit load/stores for instructions.>
    It passed U/V as 2x 16.16 though.
      With the register understood as 2x 32-bit.


    Also it used the tag-bits to encode texture resolution as a combined
    log-2, with a few bits to encode the encoding format:
      RGB555 (A.R5.R5.R5);
      RGBA32 (A8.R8.G8.B8);
      RGBA64 (A16.R16.G16.B16);
      UTX2 (2x RGB555, 4x4x2 selector bits)
        Functional stand-in for DXT1 / BC1
      UTX3 (2x RGBA32, 4x4x2 RGB, 4x4x2 A)
        Functional stand-in for DXT5 / BC3
        Overlaps with BC7 in slightly higher color fidelity.
        Or, with BC6H in the HDR mode.
          Using E4.M4 per component...


    There was UTX1, but it mostly isn't used much, as it packed both
    endpoints into 16 bits (D4, RGB444), and used 4x4x1 selector bits.
    Quality is worse than UTX1, so isn't usually a good option.


    There is a restriction on LDTEX (and the rasterizer module) that only certain ranges of texture sizes are allowed, eg:
      1x1, 2x1, 2x2, 4x2, 4x4, 8x4, 8x8, ..., 256x256, 512x256, 512x512, ...
      Though, with 5 bits, will max out at 65536x32768.
        But, 64k x 64k is impractically huge.
        TKRA-GL currently maxes out at around 1024x1024 IIRC.
          But, better to not exceed 256x256 without good reason.

    Most GPUs are like this, so I have read. It allows a trick to be used
    with the float arithmetic. The exponent can be scaled instead of doing multiplies.

    While it doesn't directly support 256x512 or similar, it can fake it by swapping U and V.

    Any textures further off from this will need to be resampled to one of
    the valid sizes.

    In this case, it is possible to pass off-size and NPOT images to glTexImage2D or similar, but they will be auto-resized internally, as it doesn't actually support NPOT internally.

    Part of the quirk also is that the textures internally all use Morton- Order, and this size progression is what one gets by performing the
    Morton shuffle and masking the result.

    What is Morton or Hilbert order? I would think raster order may be
    better as it would allow one to read multiple pixels at a time.>
    One other interesting/useful property of Morton order is that nearby
    texels are more likely to be in-cache.

    Morton order is also a lot simpler/cheaper to deal with than Hilbert
    Order here, but Hilbert is better for locality.


    The LDTEX instruction only does nearest-neighbor by default, though
    there is a 64-bit encoding that allows also specifying which corner one wants.

    Say:
      LDTEX (R10, R11, 4), R28  //bottom left
      LDTEX (R10, R11, 5), R29  //bottom right
      LDTEX (R10, R11, 6), R30  //top left
      LDTEX (R10, R11, 7), R31  //top right
    Assuming a coordinate space where (0,0) is in the bottom-left corner and
    V points upwards.

    I would think that the load should be able to load bottom-left,
    bottom-middle, and bottom-top pixels with a single load operation. Then extract the pixels using a second instruction. Same for top and middle.
    I have TEX calculating the address of the centre, then use displacements
    from that address in the loads.>
    With the 32-bit encoding giving Nearest by default.

    In this case, the span-drawing function needs to do its own
    interpolation. Well, and for sake of speed, had often used 3 points and simplified interpolation, which was partly inspired by the GPU in the
    N64, but differs in that I use a slightly different approach so the
    result looks different.

    In my case, interpolate along U and V, then a weighted difference to interpolate along the diagonal; the N64 version apparently mirrors the interpolation if it would fall near the far corner, essentially dividing
    it into 2 triangular regions. Doing a little bit of mental grinding, I
    think the behavior of the N64 style interpolation might be to simply
    take (V-U) as the diagonal and let it wrap on overflow (as opposed to essentially (V-U)*0.5+0.5).



    In this case, the low 48 bits of the texture encode the base address of
    the image.

    For the rasterizer module, the address requires an alignment. I forget
    if 16 or 64 bytes at the moment; may have been 64 to match the L2
    cache's internal cache-line size (this being because the module mostly
    uses bare cache lines for its memory access to the RGB/Z buffers and textures).

    In the RGA32 mode, as noted:
      Framebuffer format: RGBA32
      Z buffer format: Z24.S8

    But, also has a 16-bit mode:
      RGB: RGB5A (A.R5.G5.B5)
        Z: Z16 | Z12.S4

    TKRA-GL is currently often using things in 16-bit mode with Z12, which admittedly isn't great for Z-fighting (even my GLQuake port has some significant Z fighting with this).

    The Z16 mode basically requires the program to swear that it will never enable stencil testing though.

    A 4-bit stencil buffer is basically enough to handle things like stencil shadows and similar; though stencil shadowing is slow on TKRA-GL so not
    a good idea. 2-bit would have given less Z-fighting, but is near useless
    for stencil effects.

    An RGB555 color buffer though does impact the allowed blending
    operations (pretty much nothing that uses DEST_ALPHA will work
    correctly). But, then again, it is pretty much never used as such
    (things like light-mapping typically using DEST_COLOr instead).


    Or, one can use the 32-bit mode for higher visual fidelity, but in this
    case it uses more memory and is slower (and the final output stages
    still require a conversion to RGB555).

    ...


    RGBCVT - convert between RGB formats: eg. RGBCVT r2,r1,10,8 converts
    RGB8.8.8 to RGB10.10.10

    BLEND - blend colors

    TRANSFORM - transform point, performs matrix multiply for point
    transformation using coefficients that may be set prior to calc.


    I didn't go this far.

    Would make sense if defining a shader-ASM language, but probably not for
    a CPU.


    Things are memory limited in my system, there being only a single DDRRAM
    so I want to put as much of the shader and other graphics into the CPU
    as possible. Rather than arbitrate between an external shader the CPU.
    Why have two sets of caches etc. when one set can offer the same
    performance?



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Tue Oct 20 16:47:51 2026
    From Newsgroup: comp.arch

    Robert Finch <[email protected]> posted:

    On 2026-10-19 5:46 p.m., BGB wrote:
    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me >>> like 24-bit load and store operations to handle RGB888 data might be
    handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code.


    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard, differing mostly as an unresolved fight over element ordering:
      "R, G, B, A" vs "B, G, R, A".

    Figures. I use ARGB, putting the alpha in the MSBs.

    24-bit is mostly a weird/awkward thing that is sometimes used but mostly not really worth it; vs just ignoring the last 8 bits in a 32-bit word when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually overkill.
      3x E5.M5 does seem semi-popular here for HDR.
      3x E4.M4 also works, and allows treating it like RGBA32.
        And seems to match the look/behavior of HDR on a Radeon HD 4xxx.
      3x E4.M6: No one uses it but would give better fidelity.

    Most people cannot see color beyond RGB777 so 10.10.10 is overkill but I
    had worried about rounding of colors and figure a few extra bits would
    not hurt. ARGB3777 is 24-bit. Some of the very early display adapters
    only supported 18 bits for color. So, ARGB6666 - fits nicely in 24 bits.

    And then there are those of us who edit photographs and hate it when
    a change to gamma results in posterization of the "sky" or any other recognizable color with a small gradient. We also worry about gamut.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Terje Mathisen@[email protected] to comp.arch on Tue Oct 20 20:43:46 2026
    From Newsgroup: comp.arch

    MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    On 2026-10-19 5:46 p.m., BGB wrote:
    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me >>>>> like 24-bit load and store operations to handle RGB888 data might be >>>>> handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code.>>>> >>>
    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard, differing
    mostly as an unresolved fight over element ordering:
      "R, G, B, A" vs "B, G, R, A".

    Figures. I use ARGB, putting the alpha in the MSBs.

    24-bit is mostly a weird/awkward thing that is sometimes used but mostly >>> not really worth it; vs just ignoring the last 8 bits in a 32-bit word
    when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually overkill.
      3x E5.M5 does seem semi-popular here for HDR.
      3x E4.M4 also works, and allows treating it like RGBA32.
        And seems to match the look/behavior of HDR on a Radeon HD 4xxx.
      3x E4.M6: No one uses it but would give better fidelity.

    Most people cannot see color beyond RGB777 so 10.10.10 is overkill but I
    had worried about rounding of colors and figure a few extra bits would>> not hurt. ARGB3777 is 24-bit. Some of the very early display adapters
    only supported 18 bits for color. So, ARGB6666 - fits nicely in 24 bits.

    And then there are those of us who edit photographs and hate it when
    a change to gamma results in posterization of the "sky" or any other recognizable color with a small gradient. We also worry about gamut.
    3x8-bit RGB is typically OK for finished photos, but for anything that's going to be edited, you want a _lot_ more.
    Terje
    --
    - <Terje.Mathisen at tmsw.no>
    "almost all programming can be viewed as an exercise in caching"
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Tue Oct 20 18:56:10 2026
    From Newsgroup: comp.arch

    Terje Mathisen <[email protected]> posted:

    MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    On 2026-10-19 5:46 p.m., BGB wrote:
    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me >>>>> like 24-bit load and store operations to handle RGB888 data might be >>>>> handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code. >>>>

    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard, differing >>> mostly as an unresolved fight over element ordering:
      "R, G, B, A" vs "B, G, R, A".

    Figures. I use ARGB, putting the alpha in the MSBs.

    24-bit is mostly a weird/awkward thing that is sometimes used but mostly >>> not really worth it; vs just ignoring the last 8 bits in a 32-bit word >>> when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually overkill. >>>   3x E5.M5 does seem semi-popular here for HDR.
      3x E4.M4 also works, and allows treating it like RGBA32.
        And seems to match the look/behavior of HDR on a Radeon HD 4xxx.
      3x E4.M6: No one uses it but would give better fidelity.

    Most people cannot see color beyond RGB777 so 10.10.10 is overkill but I >> had worried about rounding of colors and figure a few extra bits would
    not hurt. ARGB3777 is 24-bit. Some of the very early display adapters
    only supported 18 bits for color. So, ARGB6666 - fits nicely in 24 bits.

    And then there are those of us who edit photographs and hate it when
    a change to gamma results in posterization of the "sky" or any other recognizable color with a small gradient. We also worry about gamut.

    3x8-bit RGB is typically OK for finished photos, but for anything that's going to be edited, you want a _lot_ more.

    While 8-bits is sufficient for almost any viewing of an image
    For editing::
    10-bits is nowhere close to being enough
    12-bits is pretty reasonable for gentle editing (old RAW circa 2005)
    14-bits is very good for significant editing (new RAW circa 2015)
    16-bits seems to be enough for all sensor types.


    Terje

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@[email protected] to comp.arch on Tue Oct 20 18:24:46 2026
    From Newsgroup: comp.arch

    On 10/20/2026 1:56 PM, MitchAlsup wrote:
    Terje Mathisen <[email protected]> posted:

    MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    On 2026-10-19 5:46 p.m., BGB wrote:
    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me >>>>>>> like 24-bit load and store operations to handle RGB888 data might be >>>>>>> handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code. >>>>>>

    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard, differing >>>>> mostly as an unresolved fight over element ordering:
      "R, G, B, A" vs "B, G, R, A".

    Figures. I use ARGB, putting the alpha in the MSBs.

    24-bit is mostly a weird/awkward thing that is sometimes used but mostly >>>>> not really worth it; vs just ignoring the last 8 bits in a 32-bit word >>>>> when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually overkill. >>>>>   3x E5.M5 does seem semi-popular here for HDR.
      3x E4.M4 also works, and allows treating it like RGBA32.
        And seems to match the look/behavior of HDR on a Radeon HD 4xxx.
      3x E4.M6: No one uses it but would give better fidelity.

    Most people cannot see color beyond RGB777 so 10.10.10 is overkill but I >>>> had worried about rounding of colors and figure a few extra bits would >>>> not hurt. ARGB3777 is 24-bit. Some of the very early display adapters
    only supported 18 bits for color. So, ARGB6666 - fits nicely in 24 bits. >>>
    And then there are those of us who edit photographs and hate it when
    a change to gamma results in posterization of the "sky" or any other
    recognizable color with a small gradient. We also worry about gamut.

    3x8-bit RGB is typically OK for finished photos, but for anything that's
    going to be edited, you want a _lot_ more.

    While 8-bits is sufficient for almost any viewing of an image
    For editing::
    10-bits is nowhere close to being enough
    12-bits is pretty reasonable for gentle editing (old RAW circa 2005)
    14-bits is very good for significant editing (new RAW circa 2015)
    16-bits seems to be enough for all sensor types.


    To note, in my case I was not thinking of photo editing...

    Well, and in TKRA-GL motivation was less "quality" and more so
    "hopefully try to get things to stay mostly in double-digit frame-rates".


    But, yeah, personally I would also like it if cameras and monitors could
    match the way I see colors IRL, rather than a sort of
    muted/flattened/tinted version of reality.

    Sometimes, there is a difference between "perfect" and "good enough".

    Can someone see a difference between RGB555 and RGB24? Yes.
    Does it matter: Not usually.

    Kinda similar for 16 kHz audio vs 44.1 kHz.

    Usually, stuff being "good enough" when the loss of quality is not
    "painfully obvious".



    And, should cameras capture images in something other than JPEG, or photo-editors use more than 8 bits/component for editing? Probably.

    Can mostly just try to convince people to not do multi-stage editing/saving/reloading via JPEG, since every time they do so, the
    quality gets worse.

    But, people do so anyways, because "JPEG is the Photo format".

    Could be like, "You know, maybe photos should ideally be captured edited
    in something more like EXR".

    Then people will likely be like, "WTF is EXR?".

    ...



    Terje


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@[email protected] to comp.arch on Wed Oct 21 00:42:32 2026
    From Newsgroup: comp.arch

    On 10/20/2026 4:27 AM, Robert Finch wrote:
    On 2026-10-19 5:46 p.m., BGB wrote:
    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me >>>> like 24-bit load and store operations to handle RGB888 data might be
    handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code.


    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard,
    differing mostly as an unresolved fight over element ordering:
       "R, G, B, A" vs "B, G, R, A".

    Figures. I use ARGB, putting the alpha in the MSBs.

    Usually Alpha is in the MSB, it is mostly the endless fight over whether
    Red or Blue goes in the LSB.

    Though, more common for OS's is to put Blue in the LSB, so seen as bytes
    it is: B, G, R, A, ...

    But, many graphics APIs (particularly those working with OpenGL) prefer
    the reverse, as the default scheme used by glTexImage2D and similar was R,G,B,A; though they later added an option to accept the other ordering.



    24-bit is mostly a weird/awkward thing that is sometimes used but
    mostly not really worth it; vs just ignoring the last 8 bits in a 32-
    bit word when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually overkill.
       3x E5.M5 does seem semi-popular here for HDR.
       3x E4.M4 also works, and allows treating it like RGBA32.
         And seems to match the look/behavior of HDR on a Radeon HD 4xxx.
       3x E4.M6: No one uses it but would give better fidelity.

    Most people cannot see color beyond RGB777 so 10.10.10 is overkill but I
    had worried about rounding of colors and figure a few extra bits would
    not hurt. ARGB3777 is 24-bit. Some of the very early display adapters
    only supported 18 bits for color. So, ARGB6666 - fits nicely in 24 bits.


    A lot also depends on the monitor, and a lot of monitors seemingly can't really reproduce colors more accurately than around 5 or 6 bits per
    component.

    On such a monitor, RGB555 would be adequate and RGB24 offers little or
    no real advantage. Even when it does, the visual difference is mostly
    subtle, and the banding (usually the main "obvious" artifact) can be
    reduced by dither.

    With cheap monitors (using a cheap LCD TV as a monitor), also,
    intentional dither to RGB555 can actually look better for gradients than
    pure 24/32 bit RGB, as the monitor itself may introduce visible banding
    (as a lot of the people making these monitors don't seem to bother with
    doing the dithering in hardware).


    The video hardware uses a 32-bit color bus. I had it at 40-bits (To
    support ARGB10.10.10.10) but figured it would never get used. Really
    needed to trim the bus size down to save LUTs. It is tempting to go to ARGB3777 for the display hardware. The RGB to HDMI converter only
    supports 8.8.8.


    OK.

    The boards I was using typically use a VGA output, but generally with
    only a 3 or 4 bit per component DAC (typically implemented via a blob of surface mount resistors next to the VGA connector).

    So, even with HW, needed to dither in HW (from the RGB555).

    Had tried various strategies, but simple screen-space Bayer dither
    mostly worked out best. Trying to get more elaborate, like using noisy
    or temporal dither, had very mixed results with the monitors tested.


    One gave weird distortions with temporal dither, the other will simply
    regard the last version as "close enough" and hold the last version of
    an on-screen block until it changed sufficiently.

    Well, say, rather than actually redrawing the image as it came over the
    VGA cable at 60Hz or similar, it would seemingly digitize it into a grid
    of on-screen blocks and redraw each block once it changed beyond a
    certain threshold; this effect becoming much more obvious when trying to
    use temporal dither, as the dither pattern would not move, just change abruptly whenever there was a more significant change within the block.


    On this monitor, in this case seemingly unless the top few bits of a few
    of the pixels changed, it was like "meh, close enough".

    Well, either this or the monitor only had a fixed budget for redrawing
    parts of the screen, and would "triage" the redrawing when faced with full-screen temporal dither, and/or interpret it as some sort of noise
    or interference over the VGA cable.

    But, in this case, the monitor started acting like it was playing
    through a poorly compressed YouTube video, effectively with a bunch of
    obvious blocking artifacts.


    Though, this was mostly on monitors from the 2000s.

    Well, and at one point was using a VGA to component-video cable to use
    an LCD TV as a monitor, as it lacked a native VGA input, but did at
    least have component.

    Admittedly, not entirely sure how the cable worked. Seems like
    RGB->YPbPr would need at least some active components, not sure how they
    are powered (well, unless maybe using the HSync/VSync as a power
    source). Maybe a few transistors as drivers and some resistor bridges
    could work.

    Well, maybe could be sufficient to just wing it and use resistors
    between R-G and B-G, pulling G towards the Luma and R/B towards a
    difference. Would still need a way to pull Y down to ground for sync
    pulses, as VGA signals don't (necessarily) encode the sync pulses in the
    G signal in the same way as component video expects for Luma (so, would presumably need a transistor for this). Ironically, if the driver is
    powered off of H and V sync, it would (naturally) drop out at just the
    times it would need to encode the sync pulses into Y (NTSC, VGA, and
    compoent all using a "very similar" timing structure, except for NTSC
    assuming a fixed timing, and VGA and Component pulling the timing from
    the signal).


    Well, and say, an annoyance of having a monitor with a DVI input, and
    for a while using a DVI/HDMI adapter, but then needing to get a new
    graphics card, which seemingly only had DisplayPort, but then seemingly
    while DP<->HDMI works in theory, and HDMI<->DVI worked in the past, the
    DP -> HDMI -> DVI adapter combo didn't appear to work.



    Personally, I use RGB555 a lot:
       Mostly good enough for many uses;
       Generally manages to look better than RGB565.

    Here, 16 bits is a convenient size:
       Nice space savings over 32 bit;
       Works easily with 16 bit load/store ops, unlike 24 bits;
       In practice the loss of visual fidelity isn't often that noticeable.
         It is mostly obvious as banding in non-dithered gradients.

    I like the RGB555, it is the default format for my video hardware IIRC.
    But I made the hardware completely programmable for just about any format.>

    Yeah.

    Most of my TestKern OS pipeline also ended up being built around RGB555.

    Early on, was using YUV655 at one point, but it mostly died off; apart
    from some lingering weirdness in my port of Quake which was originally
    written to assume YUV655 rather than RGB555.



    565 has an ugly issue that it introduces noisy greenish/purplish
    tints, whereas 555 at least provides proper grays and is more free of
    chromatic noise.

    Depends on the up-conversion algo for 565 though, say:
       Traditional:
         R: Copy high 3 bits to low 3;
         G: Copy high 2 bits to low 2;
         B: Copy high 3 bits to low 3.
       Result, chromatic noise.
       Better visually:
         R: Copy high 2 bits to low 2, bit 2 is LSB of G;
         G: Copy high 2 bits to low 2;
         B: Copy high 2 bits to low 2, bit 2 is LSB of G.
       Avoids chromatic effect, but, this is non-traditional.


    Though, often for 555 to look good some level of dithering is still
    needed in many cases when down-converting from a higher bit-depth.

    Personally, I have usually had best results with 2x2 or 4x4 Bayer.
       People often argue that Floyd-Stanberg or Blue-Noise is better.
       But, visually, 4x4 Bayer often seems to give the best results for me. >>
    Dithering is also usually needed when down-converting to indexed
    color; otherwise bad posterization like effects may occur.

    What about 3x3 alternating? I tried dithering but could not get the
    quality of results satisfactory. I could see the dither, figured it was better just to change the video resolution.>

    Not tried 3x3.

    Usually patters like:
    1 3
    4 2
    Or:
    1 9 3 11
    13 5 15 7
    4 12 2 10
    16 7 14 6

    Or similar.

    The great problem with 3 is that at no point does it align with a power
    of 2.

    Could get more elaborate, say a 3x3 pattern combined with a 5x5 pattern
    and then padded up to 16x16.

    But, as noted, going to patterns larger than 4x4, the problem is that
    the effect quickly becomes diluted (and spatial accuracy drops).


    Though, once did a half-way interesting experiment, noting that it was possible to encode color into 8x8 or 16x16 blocks in 1-bit monochrome by encoding chroma via the dither pattern.

    If one assumes that the chroma for each block is the average of the neighboring blocks, it could do reasonably well for natural images even despite the limitations of being very crude chroma encoded via the
    dithering (with a very low effective bandwidth).

    Not yet used this for much.

    The main option would be to allow color within a display mode that can
    only encode 1 bit per pixel; though visually far inferior to a 1.25 bpp color-cell variant at this task (8x8x1 pixel bits with 16-bits for RGBD
    at 4b per component).

    Well, and one doesn't really have enough effective bandwidth to encode
    16 bits of RGBD or RGBY in an 8x8 block via the dither pattern.




    There are cases where it shouldn't be used, like SDF fonts:
    Dithering an SDF makes it actively worse than posterizing it;
    Also SDFs survive fairly well to indexed-color if the palette fits
    well (but, generally needs either palette optimization, or a
    generalized palette optimized to SDFs; generic palettes don't really
    work).

    Better to avoid using color-cell though, as traditional color-cell
    seems to be more destructive to SDFs. So, was mostly having best
    results storing them as 256-color (then applying LZ compression).

    Have noted that there is another trick I have become aware of that can
    boost compression of these sorts of images:
    Encode the pixels in Hilbert (or maybe Morton) order rather than raster;
    This seems to increase the effectiveness of the LZ compression even
    when not using delta-filtering or entropy coding (and, unlike delta
    filtering, does not derive its value from entropy coding; delta-
    filtering without entropy-coding makes compression worse).

    Theoretically, could do Hilbert-8 or Hilbert-16, but these patterns
    are more complicated, and seemingly 2-levels of Hilbert-4 over a 16x16
    block would achieve mostly the same effect. Computational cost is
    modest (and generally still notably less than that of using PNG style
    filters and entropy coding).

    Though, an intermediate compromise here being to store pixels in
    Morton order; which mostly gives similar benefits for plain LZ (in the
    absence of delta-filtering; Morton being notably worse for delta-
    filtering than Hilbert).


    Even if, yes, this is mostly falling into wackiness.


    Why not Vector / True-Type style fonts?
    Mostly that these have higher computational cost.

    And, for best results, need to render vector glyphs internally at a
    somewhat higher resolution internally and then downsample them to the
    target size (with many algos, trying to render them directly at the
    target scale looks like broken crap).

    However, bulk storage size for vector glyphs is less than that of
    SDFs, and they are still better for dynamic scaling (SDFs usually have
    a maximum useful size above which weirdness gets more obvious).

    Say:
       16x16 pixels SDF glyphs:
         Effective range, ~ 8 to 32 pixels.
           Below 8, need true mipmaps to avoid aliasing issues.
         Above 32, jank is obvious.
       32x32 glyphs could cover 5 to 64 pixels via mipmaps.

    There is one trick I had found that works in both 3D rendering and SDFs:
    Rather than using true trilinear filtering, it is possible to use the
    scale fraction mostly to pull the interpolation closer to the center
    in a bilinear filter to mimic the effects of a trilinear filter at
    lower cost.

    Or, basically, as it is about to jump to the next smaller mip-level,
    it sees the average of the 4 texels, or basically, roughly the value
    it would (presumably) have gotten from the next mip-level (if one
    assumes each mip-level is offset at 1/2 texel relative to the one above).

    Though, thinking, this does effectively have the property of going
    nearest-neighbor on the lower virtual mipmap level, rather than
    accurately mimic the effect of trilinear, but usually doesn't matter.






    Meanwhile, I have been having a weird experience recently mostly in
    that my own long term memory seems to be garbled in some areas.

    What was the trigger? A few old games, Myst and Riven.
    Actually, it was more specifically catching some streams of someone
    playing a modern remake of Riven; they were on one of the islands, had
    a response like "Wow, this looks a lot more immersive than the fixed
    view points in the original.", then was left questioning myself, like
    "What?", part of my mind saying I had played it, another part not
    recognizing it.

    I played MYST. I got lost in the subway. It turns out my hearing was not good enough to hear the beeps, so I had no clues to go by. I had to
    resort to looking up how to escape on the internet. Once I got out of
    the subway I was able to finish the game.>


    Yeah, I was a little afraid of facing that section...


    My experience was along the lines of:
    Starts playing the game, initially feels a little lost, puzzles don't
    really seem familiar, like maybe I hadn't played it before. Wanders
    around for a while, doesn't make much progress...

    Until I was reminded of the "clicking on the picture opens the path to
    the tower" part, and then it was like, suddenly I knew basically the
    whole rest of the game.

    Main challenges I ran into:
    Had an issue raising the boat for access to Stoneship, messed up
    entering one of the dates and had misidentified a constellation, and
    then left one of the posts in the wrong state (and felt unsure about the polarity of the red-vs-green signals for on/off).

    Going there, I initially forgot about the compass or where to find it,
    which delayed my ability to return back to the main island.

    In Channelwood, mostly got caught up on the elevator door (and needing
    to close it before the elevator works).

    As for me, the subway/train/tram/whatever thing went easily, once I got
    to it. It was a little long, and kinda started to want it to be over
    already, but didn't have much difficulty as it was basically just using
    the sounds to turn the tram.

    I went to the Mechanical age first, as it was an easier/refresher to the sounds used in the tram section (and by that point I remembered these
    puzzles and the sound-keying connection).


    At least according to my dad, we had that game when I was in elementary school, and I used to play it back then for a while. I just don't
    remember having done so.



    For Riven, it was basically the issue that I saw something, and was put
    into a weird state of not remembering having played the game, but
    seemingly knowing stuff about the game.

    Looked at a few videos talking about it (so, "mental contamination" is possible), got the game, and started playing it. And, then it is weirdly
    like, when I play the game, I know basically the whole game (where
    things are, how to progress things, what the endings are, etc); but then
    when I stop it starts fading away again.


    Though, this time around I have seemingly held onto it a little better,
    like after my second second session, I still remember basically the rest
    of the game, and the paths from where I am at to the various possible
    endings:
    Going visit the villain without getting the trap book back first;
    Crashing the telescope into the window first;
    Whether or not one frees the lady on the island;
    ...

    Well, and how to get some of the various optional things (well, say, I
    didn't get to see the guy running away on the survey island this time,
    but more because I came in from the wrong way and also didn't provoke
    the fish to hit its head on the window).

    Well, say, goes the long-way around and comes to the island from the lab
    for the first time, he is encountered. If one instead comes over from
    the village and goes up through the golden elevator first, not
    encountered; but can be seen instead if one gets the fish (or 'whark')
    to hit its head on the glass.


    Seemingly, if I were merely operating on "contamination", I would have
    hit roadblocks where something is encountered or seen outside the scope
    of what I had seen, and which would be unexpected. I instead just sort
    of found myself (after roughly 3 hours of game time) roughly about ready
    to face the end-game (where the point-and-click parts give way to a lot
    of cutscenes).


    I am seemingly not as in-tune with the lore of the setting, but mostly
    because the lore is in notebooks, and these are mostly in the form of
    cursive handwriting, and it rather sucks trying to read cursive. I
    suspect my younger self also had a similar feeling about this part.


    These memories are fragmentary, but are seemingly from around the time I
    was in high-school.

    Still kind of a weird experience though.


    I am usually more used to my memories being more consistent, but this
    sort of thing is like stumbling onto big holes where things had
    seemingly happened but most of the actual memories are missing.



    I then had thought at first that they were games I was aware of when I
    was much younger, but had mostly overlooked.

    Downloaded them on GOG, started playing them.

    First Riven, but was making unreasonably fast progress, like I kept
    just knowing where to go and what to do. Got a little weirded out.

    Then went and did Myst, initially it was slow going (it didn't
    immediately seem as familiar), but seemingly once I realized how to
    get into the tower (by clicking one of the paintings to turn a
    bookshelf into stairs), it was like I then knew the whole rest of the
    game (apart from a few temporary snags). Like, once I got to each
    area, I somehow already knew what to do (well, except Stoneship, where
    I couldn't find the compass at first and had mostly forgotten about
    it, it being a necessary part of being able to return to the main
    island).

    Got through the game in roughly 7 hours.


    Then partly returned to Riven, have seemingly made it through much of
    the game in roughly about 3 hours (remaining steps: Go visit the
    rebels through an animal ordering puzzle, to get back a trap-book,
    needed before doing a fire-marble puzzle and facing off with the main
    villain).

    Well, also need to fetch the code for opening the inner part of the
    dome (think it is in the notebook in the lab, need to go back there
    and look at it more carefully... but they wrote it in cursive, so
    trying to read it is "teh suck"). Well, and after the villain face-
    off, getting some notes from a small music box to free someone, and
    crashing a telescope into a window to end the game.

    More or less... Trying to do any of these out-of-order leading to one
    of the bad endings.


    But, yeah, it is like the part of my mind that seemingly remembers the
    game is winning this particular fight. If I hadn't played the game (or
    if it were merely "contamination" from elsewhere, *2), I should have
    run into some major roadblock already. But, if I have, why don't I
    have consistent memories of the experience?... (The original memories
    I have are fragmentary and garbled...).

    *2: Well, say, if one sees parts of the game or knows plot spoilers,
    this may allow cheating on some things, but wouldn't likely continue
    carrying someone through the whole game. Main reason I stopped when I
    did, was because if I go through that animal-sequence puzzle, there
    was a longish series of cutscenes on the other side. So, was more of a
    "will stop here, cutscenes some other day" thing. Then a few remaining
    things, then probably on to the endgame.


    Like, I could probably do this for Half-Life, but, well, I actually
    remember playing through Half-Life.


    Well, among other things: Once, decades ago, I had a GF for a while.
    She is seemingly tied in with these memories (mostly in that I think
    it was her that had the game). But, this is where memories are most
    unstable (I don't really know if this is real or not). These memories
    also seem to characterize her somewhat different than in other memories.

    But, it would seem in any case, this is not my first encounter with
    this game.

    But, in some way, it is more a case of trying to figure out what
    exactly happened to my memory here. Most of the rest of my memory
    doesn't seem quite to badly chewed.



    It is a toss-up deciding to use single precision floats or 18.18 fixed >>>> point arithmetic for graphics. The fixed point is about 3x faster
    latency and a lot smaller. I am leaning towards using single precision >>>> floats though.

    Switched this to 16.16>
    In TKRA-GL, the internal rasterizer is mostly using 16 bit fixed point.
    Or, 8.8, generally mapped to packed-16-bit SIMD vectors.

    Ironically, for a while, I had thought that the reason TKRA-GL's
    software rasterization was as fast as it was, was because of epic
    properties of my ASM based span-drawing functions.

    After the move to XG3, which goes back to using the same basic C based
    versions as used when building for other targets, it is more obvious
    it is not.


    Or, what seeming performance advantages exist for my ISA design,
    relative to RV64G and x86, exist independent of any special merit of
    highly-tuned ASM code. But, then again, BGBCC has reached a point of
    (mostly) not producing horribly inefficient compiler output, so...


    There was a false start, where I was wondering why a build of TKRA-GL
    + GLQuake for native Win10+X64 was performing so badly (barely much
    faster at 640x480 than for my own ISA). But, then realized it is was
    because I had misunderstood the meaning of an MSVC command-line option
    and then left and forgot about it, so I was essentially comparing
    against an unoptimized debug build, and hence the lame performance.

    Still weird in a way though that the gulf between 3.7 GHz and 50 MHz
    manages to still be small enough that the effects of a debug build are
    obvious.

    That is quite a difference in clock rate. I wonder what the difference
    is in memory performance. Maybe being able to execute a whole bunch more instructions does not make as much difference as one might think because
    of the memory access time.>


    My CPU core seems to get speeds of roughly:
    300 MB/s for L1 memcpy;
    70 MB/s for L2 memcpy;
    35 MB/s for DRAM.

    My main PC seems to get for memcpy:
    ~ 15 GB/s for L1;
    ~ 7 GB/s for L2;
    ~ 3.6 GB/s for DRAM;

    So, seemingly, memory bandwidth fall-off for my CPU is steeper.
    With around a 90x difference in RAM bandwidth, vs the 74x clock-speed difference.


    For my custom CPU core, memset roughly doubles the values vs memcpy,
    whereas for my Xen, memset runs at around the same speed as memcpy.

    Seemingly it has a faster Load bandwidth available, but seems to be
    primarily limited by how fast it can fill the destination memory (and
    doesn't appear to care that much whether one uses 64-bit stores or SSE
    for doing so; seemingly both giving roughly around the same speed).


    I seem to be seeing different limits for the newer i7 based laptop,
    which seems to have notably higher limits for L1 local memcpy and memset
    (but not fully investigated).

    This may also be correlated with the laptop's seeming stronger
    preference (speed-wise) for LZ4 over my own RP2 compressor.



    Though, it is a very different situation with my early 2000s laptop,
    which has proportionally not that much slower RAM.

    Well, say, the DDR1 RAM sticks running at 100 MHz being not *that* much
    faster than a DDR2 chip running at 50MHz.

    While the DDR2 chip is meant to be run faster (via SERDES), when I was
    looking at it, CAS/RAS would still have ate much of the gain here.

    The actual intent was that people would use Xilinx MIG and then
    interface with the generated glue logic over AXI, but still haven't done
    so (and had just written/used my own logic for the RAM chip, and not
    changed it yet).


    But, even with all of this, the difference in OpenGL software rasterizer performance still falls below the expectation of the 74x clock-speed difference (or 90x RAM speed difference).



    But, results do still seem my ISA is "punching above its weight
    class", in being able to give any level of semi-usable OpenGL on a 50
    MHz CPU.

    Well, never-mind the seemingly impossible demand that I would
    seemingly either need 200 MHz or 4 cores working in parallel to be
    able to give playable results for Quake 3.


    Though, if I was targeting mainly the XC7A200T, could try to do a
    setup like, maybe:
       1 control core (full ISA);
       4 render cores (more limited ISA);
       2 rasterizer modules, probably dividing the screen in half.
         Would need to split requests that cross halves though.

    The most likely idea for the render cores being, say:
       XG3+RV64G only (no RV-C or XG1/XG2 support);
       Omits the Double-Precision FPU (saves a few kLUT);
       Omits 64-bit integer multiply/divide (also another kLUT);
       L1 D$ is aligned-only (also saves a big chunk of LUTs).

    Missing functionality either being unsupported entirely, or faked via
    emulation traps. This is less bad though if one were to assume such
    cores only exist to run the TKRA-GL transform and rendering pipeline.

    Though, if all 4 cores are working on the same shared framebuffers,
    would need cache coherence. Or some way to divide up geometry by
    location, but can't know where geometry is on-screen until after the
    projection stage; which is one of the places one would want to split up.

    Well, unless maybe:
       Main CPU:
         Runs GLQuake / Quake2 / Quake3
         Deals with OpenGL;
         Does initial projection;
         Adds projected primitives to a global work list.
       Worker Cores:
         Grab a primitive, and check for need to subdivide;
           If needs subdivision:
             Subdivide primitive;
             Keeps any pieces that belong to its area;
             Others, pushed back to shared list.
           If local to this cores region?
             Process it.
           Else:
             Push it back to the list.

    Though, in this case, the shared list is likely to become a bottleneck.
    Could maybe reduce overhead by giving each core its own work queue,
    with the main CPU having a push-back queue.

    Each core only looks in its own list for new work, but may push work
    over to other cores (if in their area), or back to the main CPU (if it
    needs work there, like splitting a primitive between two workers).

    For sake of sanity, the main CPU can wait around until it and all the
    workers complete the draw-call.

    Though, another (maybe simpler) option in this case being to invest in
    a memory-coherence mechanism, which would allow simply dividing up the
    primitives sequentially hand handing each off to one of the cores
    (which may then draw anywhere in the framebuffer).

    Would mean the L2 cache or similar would need to track who "owns each
    dirty cache line" and has the ability to issue "please write back this
    line" requests to the cores.

    Maybe this is optional, and so may only need to apply to specific
    memory mappings (via the TLB):
       Default: Weak coherence only;
       If enabled per-page: Memory access needs to be cache-coherent.


    Then again, may also make sense to still have a single rasterizer
    module for its MMIO interface, but if needed, the rasterizer could
    have multiple "worker units" internally.

    Would also need to add a step to the MMIO interface though to deal
    with multiple cores firing requests at is, say:
       Core checks if unit is ready to accept work (status register);
       Core writes a request requesting ability to use the interface;
         Reads back status, seeing if its request was granted;
         If not, retry until success.
         (This overlaps with the existing busy / flow-control handling).
       Core writes its request's content registers;
       Core writes to status register to submit work to the FIFO.

    This trying to avoid the situation where the cores step on each other
    by both trying to write to the registers for the MMIO interface at the
    same time.

    There is already a flow-control mechanism (for busy signaling), but
    for muliple cores would need to add a "request in progress" mechanism
    to this (submitting a request to this module basically involves
    setting up a bunch of parameters to describe the part of the primitive
    to be rasterized).


    Note that TKRA-GL uses a hybrid process, where simple tasks are
    handled by the rasterizer module, but more advanced tasks use software
    rasterization.

    At present, the software-rasterization seems to be managing alpha-
    testing, may need to change this though.

    Well, also software manages GL_LINES, GL_POINTS, and drawing
    primitives as outlines (with these cases being annoyingly inefficient;
    as it takes almost as much computationally to draw a point or line as
    it does to draw a small triangle or quad).


    ...


    TEX - calculate texture index, TEX Rd, Rs1, Rs2, Rs3 ; Rs1 = U, Rs2
    = V,
    and Rs3 contains the texture width,height and bytes per pixel. The
    texture cannot be more than 64k pixels high or wide.


    I did this via an LDTEX instruction.

    I figured it was better to separate the address calculation from the
    data load. TEX then a load. Teh TEX instruction has a fairly high
    latency about 5 cycles for fixed point or 20 for floats. The pixels surrounding the source pixel could be fetched using displacements from
    the TEX address avoiding multiple TEX instructions.
    Might need to be able to load / store data based on a data size stored
    in a register. I may change the 24-bit load/stores into variable data
    size load/stores. There is also a 72-bit load/store for register values including an 8-bit tag. I would also like 48-bit load/stores for instructions.>

    In my case, LDTEX and FMOV.S / FMOV.H have a 4-cycle latency.

    Say:
    Normal Loads: 3 cycle;
    LDTEX / FMOV.S: 4 cycle (converter bolted on the end).

    With Morton order, this can be sort of handled via the AGU without too
    much added latency.

    It mostly needs to interleave the bits and mask by the texture size.


    It passed U/V as 2x 16.16 though.
       With the register understood as 2x 32-bit.


    Also it used the tag-bits to encode texture resolution as a combined
    log-2, with a few bits to encode the encoding format:
       RGB555 (A.R5.R5.R5);
       RGBA32 (A8.R8.G8.B8);
       RGBA64 (A16.R16.G16.B16);
       UTX2 (2x RGB555, 4x4x2 selector bits)
         Functional stand-in for DXT1 / BC1
       UTX3 (2x RGBA32, 4x4x2 RGB, 4x4x2 A)
         Functional stand-in for DXT5 / BC3
         Overlaps with BC7 in slightly higher color fidelity.
         Or, with BC6H in the HDR mode.
           Using E4.M4 per component...


    There was UTX1, but it mostly isn't used much, as it packed both
    endpoints into 16 bits (D4, RGB444), and used 4x4x1 selector bits.
    Quality is worse than UTX1, so isn't usually a good option.


    There is a restriction on LDTEX (and the rasterizer module) that only
    certain ranges of texture sizes are allowed, eg:
       1x1, 2x1, 2x2, 4x2, 4x4, 8x4, 8x8, ..., 256x256, 512x256, 512x512, ... >>    Though, with 5 bits, will max out at 65536x32768.
         But, 64k x 64k is impractically huge.
         TKRA-GL currently maxes out at around 1024x1024 IIRC.
           But, better to not exceed 256x256 without good reason.

    Most GPUs are like this, so I have read. It allows a trick to be used
    with the float arithmetic. The exponent can be scaled instead of doing multiplies.


    This is one merit.

    Also the Morton + Masking approach only really works along this range of texture sizes.


    While it doesn't directly support 256x512 or similar, it can fake it
    by swapping U and V.

    Any textures further off from this will need to be resampled to one of
    the valid sizes.

    In this case, it is possible to pass off-size and NPOT images to
    glTexImage2D or similar, but they will be auto-resized internally, as
    it doesn't actually support NPOT internally.

    Part of the quirk also is that the textures internally all use Morton-
    Order, and this size progression is what one gets by performing the
    Morton shuffle and masking the result.

    What is Morton or Hilbert order? I would think raster order may be
    better as it would allow one to read multiple pixels at a time.>

    Morton Order (as a 4x4 example):
    0 1 4 5
    2 3 6 7
    8 9 12 13
    10 11 14 15

    Or, expanding to 8x8:
    0 ... 16
    ...
    32 ... 48
    ...

    And so on.

    Basic idea being that the two X/Y coords are turning into a linear
    coordinate by interleaving the bits.

    Then just mask it off by however big the texture is.

    Though, as noted, a single LDTEX only loads a single texel in my case.



    Hilbert is more complicated:
    2x2:
    0 3
    1 2
    4x4:
    0 1 14 15
    3 2 13 12
    4 7 8 11
    5 6 9 10

    Or, ASCII art:
    2x2:
    -+ +-
    | |
    +--+
    4x4:
    -+--+ +--+-
    | |
    +--+ +--+
    | |
    + +--+ +
    | | | |
    +--+ +--+

    ...

    With Hilbert, pixels are always followed/preceded by an adjacent pixel
    and with longer runs within a single area, which makes it much better
    for things like naive delta filtering if compared with raster ordering.

    Likewise, unlike something like Paeth, you don't need a buffer to keep
    track of a previous scanline or similar.


    In contrast, Morton ordering is good for spatial locality, but things
    are not adjacent; so it is a fairly poor option option for delta-coding.

    However, as noted, Morton order still provides an advantage for the
    ability to use LZ77 compression on images.


    Can note that one of my recent experimental color-cell codecs did make
    use of Hilbert order by grouping the 4x4 pixel blocks into a larger
    16x16 macroblock; which increased the effectiveness of being able to
    predict or reuse color-endpoints between blocks and the common
    properties of said blocks (such as what block type works best, etc).


    One other interesting/useful property of Morton order is that nearby
    texels are more likely to be in-cache.

    Morton order is also a lot simpler/cheaper to deal with than Hilbert
    Order here, but Hilbert is better for locality.


    The LDTEX instruction only does nearest-neighbor by default, though
    there is a 64-bit encoding that allows also specifying which corner
    one wants.

    Say:
       LDTEX (R10, R11, 4), R28  //bottom left
       LDTEX (R10, R11, 5), R29  //bottom right
       LDTEX (R10, R11, 6), R30  //top left
       LDTEX (R10, R11, 7), R31  //top right
    Assuming a coordinate space where (0,0) is in the bottom-left corner
    and V points upwards.

    I would think that the load should be able to load bottom-left, bottom- middle, and bottom-top pixels with a single load operation. Then extract
    the pixels using a second instruction. Same for top and middle.
    I have TEX calculating the address of the centre, then use displacements from that address in the loads.>


    I think the typical option is to load 4 points and do an H shaped interpolation:

    0 -+- 1
    |
    2 -+- 3

    Or, Interpolate 0/1 and 2/3 horizontally, then interpolate vertically.

    For trilinear, it is done on 2 miplevels, and then interpolate between
    the result for each mip-level.

    Except I cut some corners in TKRA-GL in the name of making it faster.


    If one can do 3 points and make something that resembles trilinear,
    better maybe than 8 points for true trilinear; or 4 points for normal bilinear.

    Or:
    0--1
    | /
    2/


    With the 32-bit encoding giving Nearest by default.

    In this case, the span-drawing function needs to do its own
    interpolation. Well, and for sake of speed, had often used 3 points
    and simplified interpolation, which was partly inspired by the GPU in
    the N64, but differs in that I use a slightly different approach so
    the result looks different.

    In my case, interpolate along U and V, then a weighted difference to
    interpolate along the diagonal; the N64 version apparently mirrors the
    interpolation if it would fall near the far corner, essentially
    dividing it into 2 triangular regions. Doing a little bit of mental
    grinding, I think the behavior of the N64 style interpolation might be
    to simply take (V-U) as the diagonal and let it wrap on overflow (as
    opposed to essentially (V-U)*0.5+0.5).



    In this case, the low 48 bits of the texture encode the base address
    of the image.

    For the rasterizer module, the address requires an alignment. I forget
    if 16 or 64 bytes at the moment; may have been 64 to match the L2
    cache's internal cache-line size (this being because the module mostly
    uses bare cache lines for its memory access to the RGB/Z buffers and
    textures).

    In the RGA32 mode, as noted:
       Framebuffer format: RGBA32
       Z buffer format: Z24.S8

    But, also has a 16-bit mode:
       RGB: RGB5A (A.R5.G5.B5)
         Z: Z16 | Z12.S4

    TKRA-GL is currently often using things in 16-bit mode with Z12, which
    admittedly isn't great for Z-fighting (even my GLQuake port has some
    significant Z fighting with this).

    The Z16 mode basically requires the program to swear that it will
    never enable stencil testing though.

    A 4-bit stencil buffer is basically enough to handle things like
    stencil shadows and similar; though stencil shadowing is slow on TKRA-
    GL so not a good idea. 2-bit would have given less Z-fighting, but is
    near useless for stencil effects.

    An RGB555 color buffer though does impact the allowed blending
    operations (pretty much nothing that uses DEST_ALPHA will work
    correctly). But, then again, it is pretty much never used as such
    (things like light-mapping typically using DEST_COLOr instead).


    Or, one can use the 32-bit mode for higher visual fidelity, but in
    this case it uses more memory and is slower (and the final output
    stages still require a conversion to RGB555).

    ...


    RGBCVT - convert between RGB formats: eg. RGBCVT r2,r1,10,8 converts
    RGB8.8.8 to RGB10.10.10

    BLEND - blend colors

    TRANSFORM - transform point, performs matrix multiply for point
    transformation using coefficients that may be set prior to calc.


    I didn't go this far.

    Would make sense if defining a shader-ASM language, but probably not
    for a CPU.


    Things are memory limited in my system, there being only a single DDRRAM
    so I want to put as much of the shader and other graphics into the CPU
    as possible. Rather than arbitrate between an external shader the CPU.
    Why have two sets of caches etc. when one set can offer the same performance?


    I was also kinda facing against RAM limits, but can stretch RAM further
    with a lot of compression type stuff...

    Less bandwidth needed when things are RGB555 and Color-Cell compressed.





    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Robert Finch@[email protected] to comp.arch on Thu Oct 22 19:43:31 2026
    From Newsgroup: comp.arch

    Done it now. Added another type of branches – masked value branches. For example, branching on comparison of ARGB16.16.16.16 colors. Colors may
    be compared according to an accuracy spec. For example: "MBEQ Rs1, Rs2,
    Rm, label" will branch if two colors are the same according to a mask
    value in register Rm. Rm is a carry register. Rm is an eight register
    subset. The instruction requires reading three registers.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Terje Mathisen@[email protected] to comp.arch on Fri Oct 23 18:28:41 2026
    From Newsgroup: comp.arch

    MitchAlsup wrote:
    Terje Mathisen <[email protected]> posted:

    MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    On 2026-10-19 5:46 p.m., BGB wrote:
    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it seems to me >>>>>>> like 24-bit load and store operations to handle RGB888 data might be >>>>>>> handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code. >>>>>>

    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard, differing >>>>> mostly as an unresolved fight over element ordering:
      "R, G, B, A" vs "B, G, R, A".

    Figures. I use ARGB, putting the alpha in the MSBs.

    24-bit is mostly a weird/awkward thing that is sometimes used but mostly >>>>> not really worth it; vs just ignoring the last 8 bits in a 32-bit word >>>>> when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually overkill. >>>>>   3x E5.M5 does seem semi-popular here for HDR.
      3x E4.M4 also works, and allows treating it like RGBA32. >>>>>     And seems to match the look/behavior of HDR on a Radeon HD 4xxx.
      3x E4.M6: No one uses it but would give better fidelity. >>>>>
    Most people cannot see color beyond RGB777 so 10.10.10 is overkill but I >>>> had worried about rounding of colors and figure a few extra bits would >>>> not hurt. ARGB3777 is 24-bit. Some of the very early display adapters
    only supported 18 bits for color. So, ARGB6666 - fits nicely in 24 bits. >>>
    And then there are those of us who edit photographs and hate it when
    a change to gamma results in posterization of the "sky" or any other
    recognizable color with a small gradient. We also worry about gamut.

    3x8-bit RGB is typically OK for finished photos, but for anything that's
    going to be edited, you want a _lot_ more.

    While 8-bits is sufficient for almost any viewing of an image
    For editing::
    10-bits is nowhere close to being enough
    12-bits is pretty reasonable for gentle editing (old RAW circa 2005)
    14-bits is very good for significant editing (new RAW circa 2015)
    16-bits seems to be enough for all sensor types.
    If you have a log format sensor, then you can make do with a few less bits. Terje
    --
    - <Terje.Mathisen at tmsw.no>
    "almost all programming can be viewed as an exercise in caching"
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@[email protected] to comp.arch on Fri Oct 23 15:02:35 2026
    From Newsgroup: comp.arch

    On 10/23/2026 11:28 AM, Terje Mathisen wrote:
    MitchAlsup wrote:
    Terje Mathisen <[email protected]> posted:

    MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    On 2026-10-19 5:46 p.m., BGB wrote:
    On 10/18/2026 12:50 PM, MitchAlsup wrote:
    Robert Finch <[email protected]> posted:

    Adding some graphics instructions to Q+. While doing so, it
    seems to me
    like 24-bit load and store operations to handle RGB888 data
    might be
    handy.

    A lot of GPUs use the other 8-bits as a mixing or transparency code. >>>>>>>

    Yeah, 32-bit RGBA (RGBA32 / RGB8888) is pretty much standard,
    differing
    mostly as an unresolved fight over element ordering:
         "R, G, B, A" vs "B, G, R, A".

    Figures. I use ARGB, putting the alpha in the MSBs.

    24-bit is mostly a weird/awkward thing that is sometimes used but >>>>>> mostly
    not really worth it; vs just ignoring the last 8 bits in a 32-bit >>>>>> word
    when alpha isn't needed.

    Some 10.10.10 formats exist, but are rarely used, and usually
    overkill.
         3x E5.M5 does seem semi-popular here for HDR.
         3x E4.M4 also works, and allows treating it like RGBA32. >>>>>>        And seems to match the look/behavior of HDR on a
    Radeon HD 4xxx.
         3x E4.M6: No one uses it but would give better fidelity. >>>>>>
    Most people cannot see color beyond RGB777 so 10.10.10 is overkill
    but I
    had worried about rounding of colors and figure a few extra bits would >>>>> not hurt. ARGB3777 is 24-bit. Some of the very early display adapters >>>>> only supported 18 bits for color. So, ARGB6666 - fits nicely in 24
    bits.

    And then there are those of us who edit photographs and hate it when
    a change to gamma results in posterization of the "sky" or any other
    recognizable color with a small gradient. We also worry about gamut.

    3x8-bit RGB is typically OK for finished photos, but for anything that's >>> going to be edited, you want a _lot_ more.

    While 8-bits is sufficient for almost any viewing of an image
    For editing::
    10-bits is nowhere close to being enough
    12-bits is pretty reasonable for gentle editing (old RAW circa 2005)
    14-bits is very good for significant editing    (new RAW circa 2015)
    16-bits seems to be enough for all sensor types.

    If you have a log format sensor, then you can make do with a few less bits.


    FWIW:
    Pretty much all the cameras I have used have only offered T.81 JPEG as
    the option for storage (though often with options to tweak image size
    and quality, but not format).

    High resolution, yes, but no options for RAW capture or similar.
    I think this requires much more expensive cameras though.


    Though, an annoyance is that many I have used also need fairly bright
    lighting to avoid significant noise in the images (say, lighting levels
    that seem fine in person giving a noisy mess on a camera, and the light
    level needs to be painfully bright before the image sensors give a clean image; or enable the use of a camera flash).

    Well, or some cameras apparently internally take multiple images at
    different exposure levels and then combine them for better results.


    Otherwise:

    Something like E5.M7 would probably be pretty OK as a storage format, as
    for the range of 0.5 to 1.0 would have basically the same accuracy as
    8-bit LDR.

    Could argue that something like Binary16 could make sense as a working
    format for HDR photo editing. Relatively few formats natively support
    this though (excluding things like EXR).

    Many of the other formats that claim HDR support do so instead by
    storing a "tone mapped" image and an exponent image or similar (or, essentially, more like RGBE rather than by storing FP values directly).


    Editing is also more of an issue as most normal editing software (say,
    GIMP or Paint.NET or similar) don't really support much beyond normal
    8-bit LDR.


    ...


    Terje



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From George Neuner@[email protected] to comp.arch on Fri Oct 23 17:53:09 2026
    From Newsgroup: comp.arch

    On Fri, 23 Oct 2026 15:02:35 -0500, BGB <[email protected]> wrote:

    FWIW:
    Pretty much all the cameras I have used have only offered T.81 JPEG as
    the option for storage (though often with options to tweak image size
    and quality, but not format).

    High resolution, yes, but no options for RAW capture or similar.
    I think this requires much more expensive cameras though.

    The camera captures a raw image - so all that is required is that the
    camera let you save the data as a bitmap. Unfortunately, many "smart"
    cameras just won't let you do that.

    You can pair a high resolution dumb camera with a framegrabber, but
    even so, anything [the generic] you can afford likely will limit you
    to RGB or RGBA at 8-bits per channel.

    I've seen cameras and framegrabbers with more depth, but they tend to
    be ridiculously expensive if you want color. Grayscale hardware is
    somewhat more affordable [though still high if you want deep pixels].


    MMV. I used to work in image processing, but that was several years
    ago and I'll admit I haven't kept up. I know there are a few others
    with image processing experience here who may know better.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Sat Oct 24 01:04:31 2026
    From Newsgroup: comp.arch

    BGB <[email protected]> posted:
    --------------
    FWIW:
    Pretty much all the cameras I have used have only offered T.81 JPEG as
    the option for storage (though often with options to tweak image size
    and quality, but not format).

    I have never owned a digital camera that did not allow RAW.
    I have owned numerous film cameras (no bit depth or spatial array)

    High resolution, yes, but no options for RAW capture or similar.
    I think this requires much more expensive cameras though.


    Though, an annoyance is that many I have used also need fairly bright lighting to avoid significant noise in the images (say, lighting levels
    that seem fine in person giving a noisy mess on a camera, and the light level needs to be painfully bright before the image sensors give a clean image; or enable the use of a camera flash).

    Well, or some cameras apparently internally take multiple images at different exposure levels and then combine them for better results.


    Otherwise:

    Something like E5.M7 would probably be pretty OK as a storage format, as
    for the range of 0.5 to 1.0 would have basically the same accuracy as
    8-bit LDR.

    Could argue that something like Binary16 could make sense as a working format for HDR photo editing. Relatively few formats natively support
    this though (excluding things like EXR).

    Many of the other formats that claim HDR support do so instead by
    storing a "tone mapped" image and an exponent image or similar (or, essentially, more like RGBE rather than by storing FP values directly).


    Editing is also more of an issue as most normal editing software (say,
    GIMP or Paint.NET or similar) don't really support much beyond normal
    8-bit LDR.


    ...


    Terje



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Terje Mathisen@[email protected] to comp.arch on Sat Oct 24 17:25:44 2026
    From Newsgroup: comp.arch

    MitchAlsup wrote:
    BGB <[email protected]> posted:
    --------------
    FWIW:
    Pretty much all the cameras I have used have only offered T.81 JPEG as
    the option for storage (though often with options to tweak image size
    and quality, but not format).

    I have never owned a digital camera that did not allow RAW.

    Not even a cell phone camera?

    Terje
    --
    - <Terje.Mathisen at tmsw.no>
    "almost all programming can be viewed as an exercise in caching"
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Sat Oct 24 19:36:44 2026
    From Newsgroup: comp.arch

    Terje Mathisen <[email protected]> posted:

    MitchAlsup wrote:
    BGB <[email protected]> posted:
    --------------
    FWIW:
    Pretty much all the cameras I have used have only offered T.81 JPEG as
    the option for storage (though often with options to tweak image size
    and quality, but not format).

    I have never owned a digital camera that did not allow RAW.

    Not even a cell phone camera?

    While cell phones can take pictures, and while cell phones record pictures using digital technology, unless you CAN set the aperture, shutter speed,
    and focus; it is not a camera--just a picture taking device.

    Terje

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From BGB@[email protected] to comp.arch on Sat Oct 24 16:02:10 2026
    From Newsgroup: comp.arch

    On 10/24/2026 10:25 AM, Terje Mathisen wrote:
    MitchAlsup wrote:
    BGB <[email protected]> posted:
    --------------
    FWIW:
    Pretty much all the cameras I have used have only offered T.81 JPEG as
    the option for storage (though often with options to tweak image size
    and quality, but not format).

    I have never owned a digital camera that did not allow RAW.

    Not even a cell phone camera?


    Cellphone cameras are often most limited in this way.

    In my case, seemingly, even among the "actual cameras", with a camera
    form factor and (sometimes) removable/replaceable lenses, they still
    often don't give an option for RAW capture.


    Goes and checks...

    Ironically in my case, my cellphone camera is one of the few that does
    allow RAW capture (in DNG format). Also allows switching to a manual
    mode without automatic exposure control or white balance.

    Looks like in this mode, it is apparently using a 4096x3072 resolution.


    Terje


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Sat Oct 24 22:40:39 2026
    From Newsgroup: comp.arch

    On 10/23/2026 6:04 PM, MitchAlsup wrote:
    BGB <[email protected]> posted:
    --------------
    FWIW:
    Pretty much all the cameras I have used have only offered T.81 JPEG as
    the option for storage (though often with options to tweak image size
    and quality, but not format).

    I have never owned a digital camera that did not allow RAW.
    I have owned numerous film cameras (no bit depth or spatial array)

    High resolution, yes, but no options for RAW capture or similar.
    I think this requires much more expensive cameras though.
    [...]

    We need the RAW data.



    --- Synchronet 3.22a-Linux NewsLink 1.2