Difference between graphic cards

Started by
13 comments, last by Ashaman73 13 years, 9 months ago
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)
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.
First obvious question: are you creating a separate GL context for each thread, then calling wglShareLists()? (assuming Windows)
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.
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
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).
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.
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.
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 ?
-* So many things to do, so little time to spend. *-
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]

This topic is closed to new replies.

Advertisement