Jump to content
  • Advertisement
Sign in to follow this  
Relfos

Difference between graphic cards

This topic is 3080 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I switched from a NVidia GTX 295 to a ATI HD 5870, and I noticed a very big difference during the loading.
I have a multthread loading system that load previously compressed DXT textures and pass the data to the main thread, to use with glCompressedTexImage2D.
In the Nvidia everything was smooth, now with the new ATI card it almost seems there's no multithreading, the loading part completly blocks everything else.
What could the cause be behind this?
(I've already recreated all texture files using the new graphic card, to make sure the data is exactly in the format the card expects and is not doing any conversion)

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Relfos
What could the cause be behind this?

Impossible to say from the very limited information you provided. It could be virtually anything from a bug in your code, over some thread sync problem, incorrect usage of multithreaded GL contexts, to a driver specific issue. You will need to provide a lot more information before we can even start guessing.

Share this post


Link to post
Share on other sites
First obvious question: are you creating a separate GL context for each thread, then calling wglShareLists()? (assuming Windows)

Share this post


Link to post
Share on other sites
Oh, sorry, I probably did not provide enough details.
I only have OpenGL in the main thread, the only thing the other threads do is load data from disk (either from PNG or raw DXT texture data).
They fill in a structure containing width + height + format + pixel data, and then they add this to a queue.

In the main thread I do this

Resource *resource;

if (!_resourceQueue.empty())
{
Thread::Lock();
do
{
resource = _resourceQueue.front();
_resourceQueue.pop();
resource->Update();
resource->SetStatus(RESOURCE_Ready);
}
while (!_resourceQueue.empty());
Thread::Unlock();
}


The Update method is the following

bool Texture::Update()
{
if (_pixels==NULL)
return false;

if (_handle==0)
glGenTextures(1, &_handle);


glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _handle);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, Renderer::Instance()->_maxAnisotrophy);

glCompressedTexImage2D(GL_TEXTURE_2D, 0, _internalformat, _width, _height, 0, _size, _pixels);
glDisable(GL_TEXTURE_2D);
return true;
}


And the code that runs in the loading threads is the following:

bool Texture::Load(Stream *stream)
{
stream->Read(&_width, 4);
stream->Read(&_height, 4);
stream->Read(&_internalformat, 4);
stream->Read(&_size, 4);
_pixels = (unsigned char*) malloc(_size);
stream->Read(_pixels, _size);
return true;
}


My textures are very big (most are 4096x4096), and I load about 20 or more at once. This is a big problem, as the product I am working requires specific output to three screens at the same time, and this ATI card seems to be the only one that fits our requirements.

Share this post


Link to post
Share on other sites
Anyone?
It seems that the call to the glCompressedTexImage2D blocks the main thread, until the texture is transfered to the graphic card. This didnt happen in the nVidia drivers it seems

Share this post


Link to post
Share on other sites
Quote:
Original post by Relfos
Anyone?
It seems that the call to the glCompressedTexImage2D blocks the main thread, until the texture is transfered to the graphic card. This didnt happen in the nVidia drivers it seems
Technically, it either has to block, or quickly make a copy of the input data before returning (because you could decallocate the data directly afterwards).

NVidia's drivers do have some fairly new multi-threading functionality, where they might try the latter option. If a driver chooses the former option, there's not much you can do about it (except maybe try to implement the treading yourself with shared contexts, but I doubt this will help much).

Share this post


Link to post
Share on other sites
Quote:
Original post by Hodgman
NVidia's drivers do have some fairly new multi-threading functionality, where they might try the latter option. If a driver chooses the former option, there's not much you can do about it (except maybe try to implement the treading yourself with shared contexts, but I doubt this will help much).


It might help quite a bit to use shared contexts if there's a bunch of other non-graphics setup that needs to be done, although it would probably make more sense to do that other setup in a separate thread spawned before loading textures, rather than using shared GL contexts.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shinkage
It might help quite a bit to use shared contexts if there's a bunch of other non-graphics setup that needs to be done, although it would probably make more sense to do that other setup in a separate thread spawned before loading textures, rather than using shared GL contexts.



There's no additional setup, everything is running, but as we move around in the 3d enviroment, new models need to be loaded. The geometry and textures are read from files and decoded to memory all in separate threads.
But the call to send the texture data to the graphic card stalls everything else, while with the nVidia card before, we could see the different textures layers being loaded, for example (diffuse, normal, specular, etc).
But now with this ATI card, every time a new model comes into view, everything blocks, and after some seconds, the model is already there, fully textured.

Share this post


Link to post
Share on other sites
I've not been using OpenGL in the last 5/6 years, but aren't you supposed to use PBO for async texture loading nowaday ?

Share this post


Link to post
Share on other sites
Quote:
Original post by Ingenu
I've not been using OpenGL in the last 5/6 years, but aren't you supposed to use PBO for async texture loading nowaday ?


Hmmm, PBOs. I tried that today.


glGenBuffers(1, &pboLoader);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboLoader);
glBufferData(GL_PIXEL_UNPACK_BUFFER, _size, _pixels, GL_STREAM_DRAW);

glCompressedTexImage2D(GL_TEXTURE_2D, 0, _internalformat, _width, _height, 0, _size, NULL);

glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
glDeleteBuffers(1, &pboLoader);


This works, but, now there's no mipmaps in the texture, so everything disappears unless I'm very close to the 3d models.

[Edited by - Relfos on July 6, 2010 11:54:22 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!