OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Nov 22, 2017 2:18 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: SVGA pixel drawing issue
PostPosted: Fri Oct 13, 2017 10:14 am 
Offline

Joined: Fri Oct 13, 2017 10:03 am
Posts: 2
Hi, i'm trying to draw pixels in SVGA mode 118 aka 1024x768 32bpp, i'm using this function in loop to clear the screen

Code:
uint32_t * screenBase = 0xA0000;
uint32_t  screenWidth = 1024;
uint32_t  screenHeight = 768;
void drawPixel(uint32_t x, uint32_t y, uint32_t rgbColor) {
     uint32_t * address = screenBase + screenWidth * y + x;
       *address = rgbColor;
}


but the only thing i get is this:
Image

the strange thing is that bochs recognize the video mode as 24 bpp instead of 32
Thank you in advance and sorry if my english is no the best :D


Last edited by tommasop on Fri Oct 13, 2017 11:37 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: SVGA pixel drawing issue
PostPosted: Fri Oct 13, 2017 10:33 am 
Offline

Joined: Thu Jun 30, 2016 12:04 pm
Posts: 10
The first thing i can notice is that you wrote Ax000 instead of 0xA0000.
Also 32bits x 1024 x 768 = 3072KiB , but in the x86 memory map the area starting from 0xA0000 is only 128KiB long,after that there's video BIOS ROM.
(See http://wiki.osdev.org/Memory_Map_(x86) )

However it would be better if you get information about things more accurately.
It also would be better if you don't use a function for setting pixels.
You can use a define with multiple lines...


Last edited by whellcome on Fri Oct 13, 2017 11:39 am, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: SVGA pixel drawing issue
PostPosted: Fri Oct 13, 2017 11:09 am 
Online
Member
Member
User avatar

Joined: Wed Oct 27, 2004 11:00 pm
Posts: 829
Location: WA
3 problems:

1) mode 0x118 on some systems is 1024 x 768 x 32
on other systems it is 1024 x 768 x 24

however it might be something completely different

... the standard states explicitly that mode numbers should not be assumed to be any particular resolution/bit depth

(you must enumerate modes and find one that matches what you want...)

however, this isn't your problem with bochs

2) some systems support 32 bbp, others use 24bbp, some systems support both (but not on a single mode, obviously) -- you must expect that not all systems will support 32bbp at all, and that all 32-bbp modes will be 24bbp on some systems

3) the LFB is never located at 0xA000 (as the previous poster stated) you probably meant 0xA0000 -- but this is still wrong

the region of memory located at 0xA0000 reserved for video memory is only 128KB in length (do the math: 1024 x 768 x 32bbp is 3MB... that is never going to fit in a 128KB hole)

there are 2 ways to get around this:
#1 - use banked or channeled modes: in these modes, the screen is divided into segments, and the region of memory located at 0xA000 will map to one of these segments at a time (you must call the video BIOS to change segments when you want to write to a different one)
#2 - (most common these days, though there are graphics controllers that don't support it, or only support it in specific modes) use the LFB located at a different location in memory (usually up above 1GB, often between 3GB and 4GB) -- to do this, you must specify that you want to use LFB (rather than banked modes), and then ask the graphics card where that LFB is located




now:
if you want your code to run on bochs and don't care if it fails on other emulators and real hardware, you can look up where bochs places its LFB (iirc its always the same location, and never 0xA0000), and switch to using 24bbp instead of 32bbp

if you want to work on almost all systems (all emulators, including bochs, and most real hardware) you should enumerate the modes, and look for one that matches what you want (most systems will support 1024 x 768 with either 32 or 24 bbp), and expect that you might need to use 32bbp on some computers, and 24bbp on other computers, and then ask the system where the LFB is located -- also be sure to check the line width properly (since on some systems in some modes there is extra gap between the end of one row and the start of the next), and the channel configuration (since not all system will have the channels in the same order, and some also have a different configuration rather than 8-bits per channel for all 3 channels)

if you want to fully support all real hardware, you must also consider 2 more things:
not all systems support LFB at all (or not for all modes) -- you must be prepared to use banked modes in this case
some rare (or very old) systems might not support 1024 x 768 with either 24 or 32 bbp (at least not through the video BIOS), and you must be prepared to use other resolutions/bit depths if it doesn't

_________________
## ---- ----- ------ Intel Manuals
OSdev wiki


Top
 Profile  
 
 Post subject: Re: SVGA pixel drawing issue
PostPosted: Fri Oct 13, 2017 11:32 am 
Offline

Joined: Fri Oct 13, 2017 10:03 am
Posts: 2
JAAman wrote:
3 problems:

1) mode 0x118 on some systems is 1024 x 768 x 32
on other systems it is 1024 x 768 x 24

however it might be something completely different

... the standard states explicitly that mode numbers should not be assumed to be any particular resolution/bit depth

(you must enumerate modes and find one that matches what you want...)

however, this isn't your problem with bochs

2) some systems support 32 bbp, others use 24bbp, some systems support both (but not on a single mode, obviously) -- you must expect that not all systems will support 32bbp at all, and that all 32-bbp modes will be 24bbp on some systems

3) the LFB is never located at 0xA000 (as the previous poster stated) you probably meant 0xA0000 -- but this is still wrong

the region of memory located at 0xA0000 reserved for video memory is only 128KB in length (do the math: 1024 x 768 x 32bbp is 3MB... that is never going to fit in a 128KB hole)

there are 2 ways to get around this:
#1 - use banked or channeled modes: in these modes, the screen is divided into segments, and the region of memory located at 0xA000 will map to one of these segments at a time (you must call the video BIOS to change segments when you want to write to a different one)
#2 - (most common these days, though there are graphics controllers that don't support it, or only support it in specific modes) use the LFB located at a different location in memory (usually up above 1GB, often between 3GB and 4GB) -- to do this, you must specify that you want to use LFB (rather than banked modes), and then ask the graphics card where that LFB is located




now:
if you want your code to run on bochs and don't care if it fails on other emulators and real hardware, you can look up where bochs places its LFB (iirc its always the same location, and never 0xA0000), and switch to using 24bbp instead of 32bbp

if you want to work on almost all systems (all emulators, including bochs, and most real hardware) you should enumerate the modes, and look for one that matches what you want (most systems will support 1024 x 768 with either 32 or 24 bbp), and expect that you might need to use 32bbp on some computers, and 24bbp on other computers, and then ask the system where the LFB is located -- also be sure to check the line width properly (since on some systems in some modes there is extra gap between the end of one row and the start of the next), and the channel configuration (since not all system will have the channels in the same order, and some also have a different configuration rather than 8-bits per channel for all 3 channels)

if you want to fully support all real hardware, you must also consider 2 more things:
not all systems support LFB at all (or not for all modes) -- you must be prepared to use banked modes in this case
some rare (or very old) systems might not support 1024 x 768 with either 24 or 32 bbp (at least not through the video BIOS), and you must be prepared to use other resolutions/bit depths if it doesn't

The address in my code was 0xA0000 but copying the code here i wrote 0xA000 :oops: , anyway i didn't know the space reserved for video memory was only 128Kb so thanks for the super complete answer, now i will try using LFB


Top
 Profile  
 
 Post subject: Re: SVGA pixel drawing issue
PostPosted: Fri Oct 13, 2017 8:51 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8149
Location: At his keyboard!
Hi,

There's another problem (not mentioned yet) - there can be unused padding at the end of each row of pixels. This padding is mostly used for alignment (e.g. to make "800*600 @ 32-bpp" use 4 KiB per row instead of 3200 bytes), but is also sometimes used for fast horizontal scrolling/panning (e.g. so you can adjust "display start" register to display any 1024*768 area within something much larger).

To fix that, VBE provides a "bytes per scanline" field in the mode information structure, and you'd do something like "uint32_t * address = (uint32_t *)( (uint8_t *)screenBase + bytesPerScanline * y) + x;".


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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group