google/amber

Expected values not making sense for UINT color buffer

Opened this issue · 2 comments

I'm not sure if this is more of a bug report or a question.

When using UNORM color buffers, everything works as expected and storing 1.0 in a component value works with a subsequent EQ_RGB(A) check with value 255.

For example, this works:

#!amber

SHADER vertex vert PASSTHROUGH

SHADER fragment frag GLSL
#version 460
layout (location=0) out vec4 outColor;

void main()
{
    outColor = vec4(0.0, 1.0, 0.0, 0.0);
}

END

BUFFER position DATA_TYPE vec4<float> DATA
-1 -1 0 1
 1 -1 0 1
-1  1 0 1
 1  1 0 1
END

BUFFER framebuffer FORMAT R8G8B8A8_UNORM

PIPELINE graphics graphics_pipeline
  ATTACH vert
  ATTACH frag
  VERTEX_DATA position LOCATION 0
  FRAMEBUFFER_SIZE 1 1
  BIND BUFFER framebuffer AS color LOCATION 0
END

CLEAR_COLOR graphics_pipeline 255 255 255 255
CLEAR graphics_pipeline
RUN graphics_pipeline DRAW_ARRAY AS TRIANGLE_STRIP START_IDX 0 COUNT 4
EXPECT framebuffer IDX 0 0 SIZE 1 1 EQ_RGBA 0 255 0 0

But if we switch the framebuffer to UINT, this does not work. Note we're storing a 1 in the frag shader and expecting a 1 in the EQ_RGBA statement.

#!amber

SHADER vertex vert PASSTHROUGH

SHADER fragment frag GLSL
#version 460
layout (location=0) out uvec4 outColor;

void main()
{
    outColor = uvec4(0, 1, 0, 0);
}

END

BUFFER position DATA_TYPE vec4<float> DATA
-1 -1 0 1
 1 -1 0 1
-1  1 0 1
 1  1 0 1
END

BUFFER framebuffer FORMAT R8G8B8A8_UINT

PIPELINE graphics graphics_pipeline
  ATTACH vert
  ATTACH frag
  VERTEX_DATA position LOCATION 0
  FRAMEBUFFER_SIZE 1 1
  BIND BUFFER framebuffer AS color LOCATION 0
END

CLEAR_COLOR graphics_pipeline 255 255 255 255
CLEAR graphics_pipeline
RUN graphics_pipeline DRAW_ARRAY AS TRIANGLE_STRIP START_IDX 0 COUNT 4
EXPECT framebuffer IDX 0 0 SIZE 1 1 EQ_RGBA 0 1 0 0

I get the following:

Line 36: Probe failed at: 0, 0
  Expected: 0.000000, 0.003922, 0.000000, 0.000000
    Actual: 0.000000, 1.000000, 0.000000, 0.000000
Probe failed in 1 pixels
dj2 commented

The parser in amber treats all colour values as [0..1] floating point values. So, when it parses the EQ_RGBA 0 1 0 0 it divides each value by 255.f which is why the expected value ends up being 0.003922.

You'll either need to EXPECT on each index that the values are correct, or create a second buffer with the result values and EXPECT with an EQ_BUFFER.

We could potentially add a EQ_URGBA (or some better name) to specify the the RGBA values are [0-255] instead of [0..1] if this comes up a lot.

Understood, thanks! Reading that, my main complaint is that this is poorly documented. If I'm using UNORM framebuffers and store a 1.0 from the shader, I understand how that ends up being a 255 value in memory, so I can reason why EQ_RGBA may want me to say 255 by reading the documentation. However, it's not evident at all that I cannot apply this operation to UINT framebuffers (the expected value undergoes a floating point division, but the actual value does not), nor is it evident that we need to apply the workarounds you mention. So I ended up being quite lost. 😅