Page 1 of 1

Direct color RGB memory model

Posted: Mon Oct 19, 2015 12:40 pm
by iamnoob
Hello guys. Sorry for noob, but this stuff confuses me. So I've set the video mode with grub and got this back in my VBE mode info:

Code: Select all

segmentA: a000
pitch: 1280
Xres: 640
Yres: 480
planes: 1
bpp: 16
banks: 1
memory_model: 6
bank_size: 0
red_mask_size: 5
red_position: 11
green_mask_size: 6
green_position: 5
blue_mask_size: 5
blue_position: 0
physbase: fd000000
I know that I don't have to do bank switching, and that a memory model of 6 means "Direct color RGB memory model". Which means I have to somehow use the mask and position variables. I'm having difficulty getting started. Here are my questions.

1. Do I use segmentA or physbase? I don't have paging yet. Do I need to manipulate segment A in any way (far pointer; if so, how do I do that?) or can I just do segmentA[location] = color

2. Which is correct? y * pitch + x = color or y * pitch + x * bpp = color

3. How do I use the mask and position variables to properly make a color? What's the range of colors I can use?

Thank you for your help, it's very much appreciated.

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 1:03 pm
by madanra
iamnoob wrote:1. Do I use segmentA or physbase? I don't have paging yet. Do I need to manipulate segment A in any way (far pointer; if so, how do I do that?) or can I just do segmentA[location] = color
physbase, if you are using a linear framebuffer. Linear framebuffer is the right choice, but as I haven't used GRUB myself, I don't know for certain that it does this.
iamnoob wrote:2. Which is correct? y * pitch + x = color or y * pitch + x * bpp = color
Neither, quite - x needs to be multiplied by the number of bytes per pixel, not bits per pixel.
iamnoob wrote:3. How do I use the mask and position variables to properly make a color? What's the range of colors I can use?
Depends on the video mode and what input format you are using.

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 1:10 pm
by iamnoob
madanra wrote:physbase, if you are using a linear framebuffer. Linear framebuffer is the right choice, but as I haven't used GRUB myself, I don't know for certain that it does this.
I've read that you're supposed to check if LFB is present. And I'm assuming it is since physbase isn't 0. But it's a weird address, which makes me wary about using it.
madanra wrote:Neither, quite - x needs to be multiplied by the number of bytes per pixel, not bits per pixel.
OK, but what is "bytes per pixel"? I don't see it in VBE mode info, or any place on the internet.
madanra wrote:Depends on the video mode and what input format you are using.
I put that information in the question.

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 1:37 pm
by madanra
iamnoob wrote:I've read that you're supposed to check if LFB is present. And I'm assuming it is since physbase isn't 0. But it's a weird address, which makes me wary about using it.
Looking at the Multiboot Specification, GRUB tells you the VBE mode it has used in vbe_mode, which should have bit 13 set for LFB modes according to RBIL
iamnoob wrote:OK, but what is "bytes per pixel"? I don't see it in VBE mode info, or any place on the internet.
How many bits are there in a byte?
iamnoob wrote:I put that information in the question.
Where? You mention that the format of the video mode is "Direct color RGB memory model", but nowhere what the input format is.

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 2:29 pm
by iamnoob
madanra wrote:Looking at the Multiboot Specification, GRUB tells you the VBE mode it has used in vbe_mode, which should have bit 13 set for LFB modes according to RBIL
Do you mean bit 14? Either way, it seems to be set.
madanra wrote:How many bits are there in a byte?
So (8 * bpp)? I remember in another thread that (8 * bpp) and (bpp / 8) is wrong. Excuse me for misunderstanding.
madanra wrote:Where? You mention that the format of the video mode is "Direct color RGB memory model", but nowhere what the input format is.
What do you mean by input format?

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 2:41 pm
by madanra
iamnoob wrote:Do you mean bit 14? Either way, it seems to be set.
Yes, sorry!
iamnoob wrote:So (8 * bpp)?
No - there are 8 bits to a byte, not 8 bytes to a bit. If it's 24bpp, then each pixel takes up 3 bytes, not 192 bytes. Does that make sense? Bear in mind that the bpp might not be a multiple of 8, eg 15bpp. I think that in that case, the bytes per pixel should be rounded up, but I'm not 100% sure. See http://wiki.osdev.org/Getting_VBE_Mode_ ... Are_Unused
iamnoob wrote:What do you mean by input format?
A common input format might be 32bpp RGBA or 24bpp sRGB. Or, it might be something much more general. If you're just trying to write anything to the screen to test you can do it at all, you probably haven't decided this yet, which is fair enough. Perhaps a better question for me to have asked would be "What are you trying to write to the screen?".

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 3:16 pm
by iamnoob
madnra wrote:No - there are 8 bits to a byte, not 8 bytes to a bit. If it's 24bpp, then each pixel takes up 3 bytes, not 192 bytes. Does that make sense? Bear in mind that the bpp might not be a multiple of 8, eg 15bpp. I think that in that case, the bytes per pixel should be rounded up, but I'm not 100% sure. See http://wiki.osdev.org/Getting_VBE_Mode_ ... Are_Unused
OK makes sense. VBE 3 spec says the same thing. So for 16 BPP it'd be 2 bytes per pixel, right?
madnra wrote:A common input format might be 32bpp RGBA or 24bpp sRGB.
You mean something like g_color_argb?
madnra wrote:Perhaps a better question for me to have asked would be "What are you trying to write to the screen?".
In the past, I threw together ad-hoc code that looked something like this (the lack of bytes per pixel sic):

Code: Select all

            position[x] = color & 0xFF;
            position[x + 1] = (color >> 8) & 0xFF;
            position[x + 2] = (color >> 16) & 0xFF;
I had a font, colored backgrounds, and for the most part it "worked". But it didn't seem "correct". I'm trying to ensure I understand things from the ground up to avoid subtle bugs.

Also the spec says I should use the "linear" equivalent of the fields, and it does give me slightly different information:

Code: Select all

LinBytesPerScanLine: 1280
BnkNumberofImagePages: 0
LinNumberofImagePages: 0
LinRedMaskSize: 5
LinRedFieldPosition: 11
LinGreenMaskSize: 6
LinGreenFieldPosition: 5
LinBlueMaskSize: 5
LinBlueMaskPosition: 0
LinRsvdMaskSize: 0
LinRsvdFieldPosition: 0

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 3:26 pm
by madanra
iamnoob wrote:OK makes sense. VBE 3 spec says the same thing. So for 16 BPP it'd be 2 bytes per pixel, right?
Yes.
iamnoob wrote:You mean something like g_color_argb?
Google only returns 6 results for g_color_argb - it looks like it was a type used by someone on the OSDev forums, but it's not a standard C type.
iamnoob wrote:In the past, I threw together ad-hoc code that looked something like this (the lack of bytes per pixel sic):

Code: Select all

position[x] = color & 0xFF;
position[x + 1] = (color >> 8) & 0xFF;
position[x + 2] = (color >> 16) & 0xFF;
That will be correct for some video modes, assuming you set/increment x correctly, and the format in color matches the format the video card is expecting (ie. if color contains RGB and the video card is expecting RGB). Am I right in thinking your main question is how to generalize this to cope with different video modes where these assumptions are incorrect?

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 3:27 pm
by iamnoob
OK I kinda understand now. This http://www.fourcc.org/rgb.php seems to give some information:
16bpp

Things were pretty simple up to now but some confusion is introduced by the 16bpp format. It's actually 15bpp since the default format is actually RGB 5:5:5 with the top bit of each u_int16 being unused. In this format, each of the red, green and blue colour components is represented by a 5 bit number giving 32 different levels of each and 32786 possible different colours in total (true 16bpp would be RGB 5:6:5 where there are 65536 possible colours). No palette is used for 16bpp RGB images - the red, green and blue values in the pixel are used to define the colours directly.

As an aside, most display drivers handle both RGB 5:5:5 and 5:6:5 formats but several video codecs get confused when asked to decompress to a 5:6:5 desktop so using 5:5:5 as the default is generally safer.

24bpp

We get back to predictable ground with 24bpp. Here a pixel is represented by 3 BYTES containing a red, blue and green sample (with blue stored at the lowest address, green next then red). No padding bytes are added between pixels. Although I can't find the information in any spec I have on my machine currently, I get the feeling that 24bpp images should be stored with each line padded to a u_int32 boundary. Information on http://www.mediatel.lu/workshop/graphic ... h_bmp.html also suggests that this is true.
Which makes sense. For 24BPP, I get the following info:

Code: Select all

red_mask_size: 8
red_position: 16
green_mask_size: 8
green_position: 8
blue_mask_size: 8
And that explains why we shift by 8 and 16 (I hope.)

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 3:28 pm
by Ready4Dis
You are correct, 15bpp needs to be rounded up to 2 bytes. From his post, the information is say 16-bits per pixel.

If you look at the bit masks and sizes, you can see it's 5 for red, 6 for green, and 5 for blue (the most common 16-bit mode). It says blue position is 0, so it looks like this
rrrrrggggggbbbbb.

So, in order to display a pixel on the screen using RGB...

Code: Select all


//+7/8 will cause this to round up...
uint32_t vbe_bytes_per_pixel = (vbe_bits_per_pixel + 7) / 8;

void PutPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b)
{
  uint16_t *p_buffer = (uint16_t*)(vbe_buffer + y * vbe_bytes_per_scanline + x * vbe_bytes_per_pixel);
  *p_buffer = (r>>3);   //Remove 3 bits from red
  *p_buffer <<= 6;      //Move over 6 bits to make room for green
  *p_buffer += (g>>2); //6-bits green
  *p_buffer <<= 5;     //Move over to make room for blue
  *p_buffer += (b>>3); //And finally add 5 bits of blue...
}
Of course, this is hard coded, you could make this non-hard coded if you'd like so it actually used the bit info, but that is the basic idea. I know this can be optimized, but this is hopefully enough to get you started.
vbe_buffer comes from the video information, which is physbase in your info.
vbe_bytes_per_scanline is also part of the information, which appears to be pitch in your info

Re: Direct color RGB memory model

Posted: Mon Oct 19, 2015 5:05 pm
by iamnoob
Thanks a lot for your help guys. I've tested these web-safe colors and it seems to work fine.

Image