Having trouble plotting pixel color in 24 bit vesa modes
- beyondsociety
- Member
- Posts: 39
- Joined: Tue Oct 17, 2006 10:35 pm
- Location: Eagle, ID (USA)
- Contact:
Having trouble plotting pixel color in 24 bit vesa modes
I've started working on my boot loader again and wanted to finally have it switch to a high resolution mode at boot. So I wrote some test code that sets up a 800x600x24 vesa mode using a linearframebuffer and then switches to protected mode and plots pixels to the screen in red. Im using rgb red color 0xFF0000 which is a 8:8:8 rgb 24 bpp mode.
When I run my code in either bochs or qemu it switches the mode but displays white pixels instead of red which has me stumped. If I try and change the color of the pixel, I get a range of colors from black to grey to white and not the color I should have. If I use the same code and convert that red color to 16,15, or 8 bit modes I can see my pixels are red like they should be, I only have this issue in 24 bit modes and can't figure out why.
I know it's got to be something simple im not doing or assuming which is wrong. So im thinking 3 different possibilities:
A. There is some grayscale to trucolor bit in vesa im not setting. This could be a possibility but highly unlikely since I haven't read or seen anything to suggest this.
B. Im not converting the red rgb color correctly. Though the way I convert 0xFF0000 to different 16,15, or 8 bit modes work just fine for that color and as well as other different colors.
C. Im plotting the color code the right way but the hardware is in a different rgb combination mode which would make sense why I get white instead of red. Though to be sure I would need to display the modeinfo to be sure.
Hopefully someone has a good suggestion to the problem at hand. I'm at work atm so I cant postcode but let me know if I need to and can do so when I get home. Though I have to warn you my code is similar to every tutorial or post on this forum and yet I seem to be the only one that seems to be having this problem. When I get home, I plan to write a test kernel that prints pixels and displays debug info. I also plan to test in my current kernel that uses grub2 graphics and a bga driver I wrote for bochs to see if I can narrow down the problem as well.
Worst case, I could set code to 16 bpp and move onto other things and come back to this when I have more time. How common is 16bit for high res graphics? Most seem to use 24 or 32 bit modes but as I'm testing in bochs and qemu, they are limited to 24 bpp, 32 isn't mush different besides the alpha bit. If I ever get some time, I might try on real hardware as I have quite a bit of different hardware to test on. Thanks in advance, hopefully I have enough info, but if not feel free to ask.
When I run my code in either bochs or qemu it switches the mode but displays white pixels instead of red which has me stumped. If I try and change the color of the pixel, I get a range of colors from black to grey to white and not the color I should have. If I use the same code and convert that red color to 16,15, or 8 bit modes I can see my pixels are red like they should be, I only have this issue in 24 bit modes and can't figure out why.
I know it's got to be something simple im not doing or assuming which is wrong. So im thinking 3 different possibilities:
A. There is some grayscale to trucolor bit in vesa im not setting. This could be a possibility but highly unlikely since I haven't read or seen anything to suggest this.
B. Im not converting the red rgb color correctly. Though the way I convert 0xFF0000 to different 16,15, or 8 bit modes work just fine for that color and as well as other different colors.
C. Im plotting the color code the right way but the hardware is in a different rgb combination mode which would make sense why I get white instead of red. Though to be sure I would need to display the modeinfo to be sure.
Hopefully someone has a good suggestion to the problem at hand. I'm at work atm so I cant postcode but let me know if I need to and can do so when I get home. Though I have to warn you my code is similar to every tutorial or post on this forum and yet I seem to be the only one that seems to be having this problem. When I get home, I plan to write a test kernel that prints pixels and displays debug info. I also plan to test in my current kernel that uses grub2 graphics and a bga driver I wrote for bochs to see if I can narrow down the problem as well.
Worst case, I could set code to 16 bpp and move onto other things and come back to this when I have more time. How common is 16bit for high res graphics? Most seem to use 24 or 32 bit modes but as I'm testing in bochs and qemu, they are limited to 24 bpp, 32 isn't mush different besides the alpha bit. If I ever get some time, I might try on real hardware as I have quite a bit of different hardware to test on. Thanks in advance, hopefully I have enough info, but if not feel free to ask.
"I think it may be time for some guru meditation"
"Barbarians don't do advanced wizardry"
"Barbarians don't do advanced wizardry"
Re: Having trouble plotting pixel color in 24 bit vesa modes
Hi,
Cheers,
Brendan
There's no greyscale or anything - 24-bpp is just like 32-bpp except there's no extra reserved/padding byte.beyondsociety wrote:A. There is some grayscale to trucolor bit in vesa im not setting. This could be a possibility but highly unlikely since I haven't read or seen anything to suggest this.
If you had RGB around the wrong way you'd get blue instead of red (and not white instead of red). The only case I can think of where you'd get white (and some black pixels) instead of red is if you're in 8-bpp mode.beyondsociety wrote:B. Im not converting the red rgb color correctly. Though the way I convert 0xFF0000 to different 16,15, or 8 bit modes work just fine for that color and as well as other different colors.
C. Im plotting the color code the right way but the hardware is in a different rgb combination mode which would make sense why I get white instead of red. Though to be sure I would need to display the modeinfo to be sure.
As far as I know, Bochs supports 8-bpp, 15-bpp, 16-bpp, 24-bpp and 32-bpp; most (not all) real video cards tend to support 8-bpp, either 15-bpp or 16-bpp, and either 24-bpp or 32-bpp; and 24-bpp is less common on modern hardware and more common on old hardware (where there's much less, slower, video card memory).beyondsociety wrote:Worst case, I could set code to 16 bpp and move onto other things and come back to this when I have more time. How common is 16bit for high res graphics? Most seem to use 24 or 32 bit modes but as I'm testing in bochs and qemu, they are limited to 24 bpp, 32 isn't mush different besides the alpha bit. If I ever get some time, I might try on real hardware as I have quite a bit of different hardware to test on. Thanks in advance, hopefully I have enough info, but if not feel free to ask.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Having trouble plotting pixel color in 24 bit vesa modes
You might want to doublecheck that you are actually getting a linear frame buffer back from VESA.
Also, the math is easier in 32-bit color depth, so you might want to try that first.
Also, the math is easier in 32-bit color depth, so you might want to try that first.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
- beyondsociety
- Member
- Posts: 39
- Joined: Tue Oct 17, 2006 10:35 pm
- Location: Eagle, ID (USA)
- Contact:
Re: Having trouble plotting pixel color in 24 bit vesa modes
Thanks for clarifying what I originally thought Brendan. As for the 0xff0000 being white in 8 bpp mode, that I have checked for sure. I've checked and bochs is indeed setting a 24 bpp mode and prints the pixels white instead of red which is weird.
SpyderTL, I believe I am setting the lfb correctly but will make sure to check each vesa function and display debug info. I totally agree that the math in 32 bpp is easier, i just can't get bochs to display it as the highest I get is 24 bpp. I am setting the mode manually which is depreciated and not using a function to find the best mode with my desired mode. My thinking is this could be the problem as the boch s documentation does in fact say it supports 32 bpp modes.
SpyderTL, I believe I am setting the lfb correctly but will make sure to check each vesa function and display debug info. I totally agree that the math in 32 bpp is easier, i just can't get bochs to display it as the highest I get is 24 bpp. I am setting the mode manually which is depreciated and not using a function to find the best mode with my desired mode. My thinking is this could be the problem as the boch s documentation does in fact say it supports 32 bpp modes.
"I think it may be time for some guru meditation"
"Barbarians don't do advanced wizardry"
"Barbarians don't do advanced wizardry"
Re: Having trouble plotting pixel color in 24 bit vesa modes
Just a thought. The first thing that came to mind when you said that you were getting all white pixels is that you were not incrementing your pointer 24-bits at a time, but 8 bits at a time, in error of course.
Count the pixels you have on the screen. (Ya right, huh?).
What I mean is do you have the count of what you think you have or is it about a 1/3 of what you should have?
If it is a 1/3 of what you think you should have, *and* you are sending 0x00FF0000 to the memory, I think you might be sending
Which will be all white pixels.
Another idea is that you are not rotating your 24-bit pixel when writing to the screen. You are writing 0xFF, 0xFF, 0xFF, instead of 0xFF, 0x00, 0x00.
Change the pixel value to 0x800000 and see what happens. Is it straight gray color now? If yes, you are definitely only writing the high 8-bits, of course writing it three times.
Just a thought.
Also, what is the Memory Model (offset 0x1B) value of the Vesa Info returned. If it is 4, the bit masks are assumed as per the bits per pixel value. However, if it is 6, you need to extract the color masks from the info returned. Depending on the version, there are two places these masks are retrieved. If it is 7, you have a YUV decoder, though I am sure Bochs doesn't...
Speaking of version, versions before 2.0 don't even have a Linear Buffer, however, I think Bochs supports 2.0+.
Ben
Count the pixels you have on the screen. (Ya right, huh?).
What I mean is do you have the count of what you think you have or is it about a 1/3 of what you should have?
If it is a 1/3 of what you think you should have, *and* you are sending 0x00FF0000 to the memory, I think you might be sending
Code: Select all
(1st write) Offset 0: 0xFF 0x00 0x00
(2nd write) Offset 1: 0xFF 0x00 0x00
(3rd write) Offset 2: 0xFF 0x00 0x00
etc.
Another idea is that you are not rotating your 24-bit pixel when writing to the screen. You are writing 0xFF, 0xFF, 0xFF, instead of 0xFF, 0x00, 0x00.
Change the pixel value to 0x800000 and see what happens. Is it straight gray color now? If yes, you are definitely only writing the high 8-bits, of course writing it three times.
Just a thought.
Also, what is the Memory Model (offset 0x1B) value of the Vesa Info returned. If it is 4, the bit masks are assumed as per the bits per pixel value. However, if it is 6, you need to extract the color masks from the info returned. Depending on the version, there are two places these masks are retrieved. If it is 7, you have a YUV decoder, though I am sure Bochs doesn't...
Speaking of version, versions before 2.0 don't even have a Linear Buffer, however, I think Bochs supports 2.0+.
Ben
Re: Having trouble plotting pixel color in 24 bit vesa modes
Actually, just plot a single pixel. That should give you a clue what is going on. If it's white instead of red, then you know it's a problem with the pixel format. If it's red, then you know it's a problem with your stride calculation. If it's blue, then it's a problem with your pixel format, or your linear frame buffer.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
- beyondsociety
- Member
- Posts: 39
- Joined: Tue Oct 17, 2006 10:35 pm
- Location: Eagle, ID (USA)
- Contact:
Re: Having trouble plotting pixel color in 24 bit vesa modes
I've tried plotting a red pixel and sometimes I will get red and other times I will get blue or green depending on the x and y location I specify which seems weird to me. I only get white if I actually set it that color or if I try and filI the screen with pixels. I am currently trying to plot the pixel in protected mode in assembly language. I seem to be rusty when it comes to assembly and more experienced with c, so I'm going to see if I can get it to display correctly in c with a simple test kernel.
The other thing I see is if I plot more than one pixel, I sometimes will get all three rgb colors for the pixels. I have no issue in 16bpp or lower, it's just the 24bpp that I'm having this issue. All I want to do is set a high res and change the background color and plot text which should be simple.
The other thing I see is if I plot more than one pixel, I sometimes will get all three rgb colors for the pixels. I have no issue in 16bpp or lower, it's just the 24bpp that I'm having this issue. All I want to do is set a high res and change the background color and plot text which should be simple.
"I think it may be time for some guru meditation"
"Barbarians don't do advanced wizardry"
"Barbarians don't do advanced wizardry"
Re: Having trouble plotting pixel color in 24 bit vesa modes
Hi,
Maybe if you posted the code, we could see the code...
Cheers,
Brendan
That sounds like you're calculating the location for the pixel incorrectly - e.g. doing something like "address = x * 4 + y * bytes_per_line" instead of "address = x * 3 + y * bytes_per_line".beyondsociety wrote:I've tried plotting a red pixel and sometimes I will get red and other times I will get blue or green depending on the x and y location I specify which seems weird to me. I only get white if I actually set it that color or if I try and filI the screen with pixels. I am currently trying to plot the pixel in protected mode in assembly language. I seem to be rusty when it comes to assembly and more experienced with c, so I'm going to see if I can get it to display correctly in c with a simple test kernel.
The other thing I see is if I plot more than one pixel, I sometimes will get all three rgb colors for the pixels. I have no issue in 16bpp or lower, it's just the 24bpp that I'm having this issue. All I want to do is set a high res and change the background color and plot text which should be simple.
Maybe if you posted the code, we could see the code...
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- beyondsociety
- Member
- Posts: 39
- Joined: Tue Oct 17, 2006 10:35 pm
- Location: Eagle, ID (USA)
- Contact:
Re: Having trouble plotting pixel color in 24 bit vesa modes
Thanks for the help Brendan. I will post my code when I get home from work tonight.
"I think it may be time for some guru meditation"
"Barbarians don't do advanced wizardry"
"Barbarians don't do advanced wizardry"
- beyondsociety
- Member
- Posts: 39
- Joined: Tue Oct 17, 2006 10:35 pm
- Location: Eagle, ID (USA)
- Contact:
Re: Having trouble plotting pixel color in 24 bit vesa modes
So I managed to plot a pixel with the right color to different coordinates on the screen finally thanks to brendans help, I had the wrong pixel calculations. I'm now trying to print more than one pixel but can seem to figure out whats going on, Im figuring it has to do with how I am trying to do it in assembly language.
This is my vesa initialization code, it checks for each function and then sets up a 800*600*24 bit mode
Once I am in protected mode, I plot a red pixel to the screen with this code and works just fine:
If I try to plot more than one pixel, I get a red pixel followed by a bunch of white pixels, when I want all the pixels to be the same color
Thanks in advance for the help.
This is my vesa initialization code, it checks for each function and then sets up a 800*600*24 bit mode
Code: Select all
; Vesa start code.
mov dword [vesa_info_block.signature], 'VBE2'
mov ax, 0x4f00
mov di, vesa_info_block
int 0x10
cmp ax, 0x004f
jne near NoVesa2
cmp dword [vesa_info_block.signature], 'VESA'
jne near NoVesa2
cmp byte [vesa_info_block.version + 1], 2
jb Old_vesa
mov ax, 0x4f01
mov di, mode_info_block
mov cx, 0x4000|0x0115
int 0x10
mov ax, 0x4f02
mov bx, 0x4000|0x0115
int 0x10
Code: Select all
mov edi, [ModeInfo_PhysBasePtr]
add edi, 805 * 3 + 615 * 24 ; address = x * 3 + y * bytes_per_line".
mov eax, 0xFF0000
stosd
Code: Select all
mov edi, [ModeInfo_PhysBasePtr]
mov ecx, 815 * 3 + 615 * 24 ; address = x * 3 + y * bytes_per_line".
mov ecx, 100
mov eax, 0xFF0000
rep stosd
"I think it may be time for some guru meditation"
"Barbarians don't do advanced wizardry"
"Barbarians don't do advanced wizardry"
Re: Having trouble plotting pixel color in 24 bit vesa modes
Rep stosd will store 4 bytes and increment edi by 4 on each iteration. You want 3 bytes, not 4.
Re: Having trouble plotting pixel color in 24 bit vesa modes
well that is not going to work... you are overwriting ECX immediately, so those address calculations aren't going to work (I assume you wanted to put it in EDI rather than ECX?)beyondsociety wrote: If I try to plot more than one pixel, I get a red pixel followed by a bunch of white pixels, when I want all the pixels to be the same colorThanks in advance for the help.Code: Select all
mov edi, [ModeInfo_PhysBasePtr] mov ecx, 815 * 3 + 615 * 24 ; address = x * 3 + y * bytes_per_line". mov ecx, 100 mov eax, 0xFF0000 rep stosd
however that still wont work, since you are writing 32-bits per pixel, but you say you are in 24-bpp mode
since you are in 24bpp mode, you can't use rep stosd to store it -- because you need to store only 3 bytes instead of 4...
so you need something like: (note this is not working code)
Code: Select all
MOV ECX, number_of_adjacent_pixels
MOV EAX, offset_of_first_pixel_in_row ;x * 3
MOV EBP, address_of_start_of_row_containing_first_pixel ;y * bytes_per_row + LFB
.loop
;write pixel
MOV [EBP+EAX], WORD 0
ADD EAX, 2
MOV [EAX], BYTE 0xFF ;note I am simply copying your pixel layout from the code you posted, the actual layout might be different
;test end_of_row for end of row here (note row length might not be same as pixels_per_row * bytes_per_pixel)
;if row is ended, update EAX and EBP with new addresses
loop .loop
Re: Having trouble plotting pixel color in 24 bit vesa modes
In fact, we are probably surrounded by a dithered 16-color world of products, even for HD movies, clothes, cereal packages, furniture, and any other man-made thing. At most some things (the prettiest ones) could use dithered 256-color world of objects. And the rarest ones would use dithered 16, 24 or 32-bit colors.
So why not just learn advanced dithering and color/graphics algorithms with the lower resolution modes before relying too much on VESA? The standard VGA can look truly great if it's used with enough intelligence and using the brain enough.
Maybe it's time to use tweak16b.zip again to try to set mode 640x400 256-colors again:
Metropoli BBS files | unpacked/software/programm/general/tweak16b.zip/
http://files.mpoli.fi//software/programm/general/tweak16b.zip
By the way, try to understand how to use the graphics mode 640x480 256-colors. It's the most standard graphics mode even if it isn't included in the original VGA. Most graphics applications and games are expected to run great in this mode. Also, you could develop color dithering methods in real time that allow you to make it feel that things like live TV and most existing videos look as if they were using 24-bit color.
One of the VESA modes with that resolution is mode 101h. That's probably the most standard VESA mode of that kind.
I remember how I used Windows 98 and Windows XP in standard VGA 640x480 16-colors mode, and I used a PCI TV card (and I could still use it), a Lifeview FlyVideo. It looked as if it was using at least 256 colors for all of the channels and I could enjoy the TV without noticing the low color resolution.
Now, with 640x480 256-colors you should be able to use dithering algorithms to supply most color needs of the users. It would surely be truly worth it, as much as 640x480 24-bit color, but getting to handle properly-dithered 16 and 256-color modes will prove to be invaluable.
I guess that we could scale pixels using Mode X (320x240) although it's a planar mode that will require pixel writing functions more than being straightforward to write it directly. We could emulate a magnified quarter of 640x480 with it and show only the most important area of a game for example centered on screen, or make it necessary to resize video windows down to that resolution and using other tricks like marquees for the selected menus so that we can make the very most of this mode.
Also, it would probably be better to find out how to configure the standard VGA to reach 360x480 (or is it maybe 400x600?) 256-colors resolution. It seems that everything here goes down to making the very most of standard capabilities to enable them, and then the very most to learn to use them at advanced levels, before relying too much in using nonstandard capabilities like VESA.
So why not just learn advanced dithering and color/graphics algorithms with the lower resolution modes before relying too much on VESA? The standard VGA can look truly great if it's used with enough intelligence and using the brain enough.
Maybe it's time to use tweak16b.zip again to try to set mode 640x400 256-colors again:
Metropoli BBS files | unpacked/software/programm/general/tweak16b.zip/
http://files.mpoli.fi//software/programm/general/tweak16b.zip
By the way, try to understand how to use the graphics mode 640x480 256-colors. It's the most standard graphics mode even if it isn't included in the original VGA. Most graphics applications and games are expected to run great in this mode. Also, you could develop color dithering methods in real time that allow you to make it feel that things like live TV and most existing videos look as if they were using 24-bit color.
One of the VESA modes with that resolution is mode 101h. That's probably the most standard VESA mode of that kind.
I remember how I used Windows 98 and Windows XP in standard VGA 640x480 16-colors mode, and I used a PCI TV card (and I could still use it), a Lifeview FlyVideo. It looked as if it was using at least 256 colors for all of the channels and I could enjoy the TV without noticing the low color resolution.
Now, with 640x480 256-colors you should be able to use dithering algorithms to supply most color needs of the users. It would surely be truly worth it, as much as 640x480 24-bit color, but getting to handle properly-dithered 16 and 256-color modes will prove to be invaluable.
I guess that we could scale pixels using Mode X (320x240) although it's a planar mode that will require pixel writing functions more than being straightforward to write it directly. We could emulate a magnified quarter of 640x480 with it and show only the most important area of a game for example centered on screen, or make it necessary to resize video windows down to that resolution and using other tricks like marquees for the selected menus so that we can make the very most of this mode.
Also, it would probably be better to find out how to configure the standard VGA to reach 360x480 (or is it maybe 400x600?) 256-colors resolution. It seems that everything here goes down to making the very most of standard capabilities to enable them, and then the very most to learn to use them at advanced levels, before relying too much in using nonstandard capabilities like VESA.
Last edited by ~ on Fri Jun 03, 2016 6:06 pm, edited 1 time in total.
YouTube:
http://youtube.com/@AltComp126
My x86 OS/software:
https://sourceforge.net/projects/api-simple-completa/
Donate to get more food/programming resources/computers:
https://www.paypal.com/donate/?hosted_b ... QS2YTW3V64
http://youtube.com/@AltComp126
My x86 OS/software:
https://sourceforge.net/projects/api-simple-completa/
Donate to get more food/programming resources/computers:
https://www.paypal.com/donate/?hosted_b ... QS2YTW3V64
Re: Having trouble plotting pixel color in 24 bit vesa modes
Also, you have
There is all kinds of wrong with that
As noted earlier, you need EDI not ECX.
If you have 800 pixels wide, how are you going to place a pixel at X coordinate 815?
If you have 600 pixels tall, how are you going to place a pixel at Y coordinate 615?
If you have 800 pixels wide, how are you going to fit 800 24-bit pixels into 24 bytes per line?
Try that.
I don't remember if you mentioned why you wanted a 24-bit color mode. This is the slowest mode there is, not necessarily the video mode, but the way you write to the frame buffer.
In this mode, you have to either:
- write three bytes
- write a word then a byte
- read a dword, mask off the 24-bits, write the dword.
In 15- and 16-bit color modes, you only have to write once. Unless you are doing high-end graphics, there isn't much difference or need for 24-bit color.
In 15- and 16-bit color modes, you can write pixels to the screen, quickly:
Code: Select all
mov ecx, 815 * 3 + 615 * 24 ; address = x * 3 + y * bytes_per_line".
As noted earlier, you need EDI not ECX.
If you have 800 pixels wide, how are you going to place a pixel at X coordinate 815?
If you have 600 pixels tall, how are you going to place a pixel at Y coordinate 615?
If you have 800 pixels wide, how are you going to fit 800 24-bit pixels into 24 bytes per line?
Code: Select all
; X = X coordinate
; Y = Y coordinate
; bytes_per_line = well, bytes per line, and in this case should be (800 * 3)
mov edi, ((Y * bytes_per_line) + (X * 3))
I don't remember if you mentioned why you wanted a 24-bit color mode. This is the slowest mode there is, not necessarily the video mode, but the way you write to the frame buffer.
In this mode, you have to either:
- write three bytes
- write a word then a byte
- read a dword, mask off the 24-bits, write the dword.
In 15- and 16-bit color modes, you only have to write once. Unless you are doing high-end graphics, there isn't much difference or need for 24-bit color.
In 15- and 16-bit color modes, you can write pixels to the screen, quickly:
Code: Select all
mov eax,RRRRRGGGGGGBBBBB ; 16-bit mode
mov eax,0RRRRRGGGGGBBBBB ; 15-bit mode
mov edi, ((Y * bytes_per_line) + (X * 2))
mov ecx,count_of_pixels
rep stosw
Re: Having trouble plotting pixel color in 24 bit vesa modes
Hi,
The other problem (already mentioned by alexfru) is that "stosd" does 4 bytes, not 3 bytes. To do 3 bytes and avoid misaligned writes you'd want to do individual bytes - more like:
Of course this is much slower (it's better for performance to do less writes by doing larger aligned writes).
Also note that I would strongly recommend having a buffer in RAM where pixels are stored as 32-bpp and doing all the drawing in that buffer (because it avoids a huge amount of duplication in rendering code, and allows you to add support for things like dithering later); and then (except for 32-bpp) having a second buffer that contains what the video card actually wants. In this case you'd convert pixel formats when copying data from the first buffer to the second buffer, and then you'd blit the second buffer to display memory with a "rep movsd" for each line because you know it's already exactly what the video card wants. The main benefit here is that CPUs tend to optimise "rep movsd" to work on cache lines, so you can be doing 64 bytes per write most of the time (hopefully) and doing far less writes across the PCI bus (and the PCI bus is typically the single largest performance bottleneck). Note: It's best to think of a write on the PCI bus as a packet containing "address, length, data", where larger writes means less bandwidth wasted for the "address and length" packet headers).
Of course if you are using buffers like this, 24-bpp is faster than 32-bpp because it's less data being sent over the PCI bus.
Cheers,
Brendan
There's multiple problems here - not checking if the VBE function exists and worked, assuming that "mode 0x0115" exists and supports LFB, assuming that "mode 0x0115" is a 800*600, assuming that "mode 0x0115" is 24-bpp RGB (and not BGR or something funky), etc.beyondsociety wrote:This is my vesa initialization code, it checks for each function and then sets up a 800*600*24 bit mode
There's multiple problems here too. It's entirely possible for "bytes_per_line" to be larger than 800*3 (e.g. bytes_per_line might be 1024*3 or 1024*4 to make the start of each line nicely aligned, or anything else); and you'd need to get "bytes_per_line" from VBE's mode information structure and use that. Note that it can help to check if "bytes_per_line = bytes_per_pixel * horizontal_resolution" (the "no padding between lines" case) and write a special case for that, because for that case you can (e.g.) fill the screen or blit pixel data from a buffer without doing one line at a time.beyondsociety wrote:Once I am in protected mode, I plot a red pixel to the screen with this code and works just fine:
The other problem (already mentioned by alexfru) is that "stosd" does 4 bytes, not 3 bytes. To do 3 bytes and avoid misaligned writes you'd want to do individual bytes - more like:
Code: Select all
mov eax, 0xFF0000
mov ebx,eax
shr eax,16
mov [edi],bl
mov [edi+1],bh
mov [edi+2],al
add edi,3
For more than one pixel; you can do 4 pixels at a time as 3 aligned dwords. This is how you get decent performance in 24-bpp modes. For a simple example (making an entire line red):beyondsociety wrote:If I try to plot more than one pixel, I get a red pixel followed by a bunch of white pixels, when I want all the pixels to be the same color
Code: Select all
mov eax, 0x00FF0000 ;b1 r0 g0 b0
mov ebx, 0x0000FF00 ;g2 b2 r1 g1
mov edx, 0x000000FF ;r4 g4 b4 r3
mov ecx,800
.next:
mov [edi],eax
mov [edi+4],ebx
mov [edi+8],edx
add edi,12
sub ecx,4
jne .next
Of course if you are using buffers like this, 24-bpp is faster than 32-bpp because it's less data being sent over the PCI bus.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.