Fast upload to GPU

Hi OpenGL forum.
I’m writing a graphics plugin for PS2 emulators and i’ve got to the point where I want to efficiently emulate textures. Before I ask the question, I just want to give a brief overview of what I’m trying to emulate.

PS2 programs can upload “image” data to the Graphics Synthesiser’s local memory, this uploaded data can then be used to texturise primitives.

Once the texture data is in the GS’s memory, various internal registers are used to specify the location (in local GS memory) and format of the texture data to be applied to a given primitive. Of course, the location and format of the data is arbitrary.

Now, to emulate this behaviour, i’m currently creating one large texture which, upon writes to the texture control registers (TEX0/TEX1), I am updating using glTexSubImage2. Since these registers are being updated regularly, this is extremely slow and not a feasable method. What I really need is a method which can allow me to upload the image data to my GPU’s memory when the PS2 prgrams actually upload the data themselves.

PS2 programs often upload small parts of textures at a time so I do not know how big the final texture will be in advanced. Therefor, I can’t just upoad textures into memory in advanced and simply bind the texture I want to use. The only time I know the exact format of the data is when the PS2 program has already uploaded the data and it is telling the PS2 what format the texture is going to be in using TEX0/TEX1.

Can anyone think of a very flexible and efficient way to do this?

I’ve looked into ARB_pixel_buffer_object’s, but do you think they will provide the efficiency I need?

I have to preface this by saying that this is only speculation as i don’t know exactly how you want this.
I can think of two ways.
The first one is using the big texture as you describe as a virtual memory of sorts, then you use a shader to transform the incoming texture coordinates in real time and doing all the sampling yourself according to the wishes of the ps2 software.

Second method is actually keeping track of any data written and textures used in case you could reuse some of it, this is probably harder to do.

ARB_pixel_buffer_object’s will probably help with efficiency.

The first method sounds perfect, and I believe that is actually how other plugins for PS2 emulators (such as ZeroGS) do it. However, I am not at all familier with OpenGL’s shaders, could someone point me in the right direction? I assume that what I should aim to do is to take the load off the CPU and give the GPU the work to do.

The only efficient way to work around this that I can think of is to buffer up the texture uploads into intermediate structures during the course of a frame, then run the uploads in a single batch at the end of the frame (or the start of the next frame). You’ll be able to figure out the parameters you need from the buffering, but the uploads will lag one frame behind what’s actually on screen (in practice you will probably have a difficult time even noticing the difference).

The only efficient way to work around this that I can think of is to buffer up the texture uploads into intermediate structures during the course of a frame, then run the uploads in a single batch at the end of the frame (or the start of the next frame). You’ll be able to figure out the parameters you need from the buffering, but the uploads will lag one frame behind what’s actually on screen (in practice you will probably have a difficult time even noticing the difference).

What I really need is a way to set aside an amount of memory in the GPU which will act as the PS2’s GS memory. This can easily be done with glTexImage, but the issue is that using this method that entire texture would have to be considered one format and one single texture, which is not what I want.

If only there was a simple way (using OpenGL) to have low level control over the GPU so that I could just upload data to the GPU at will, then specify its address and format. Is there a way to upload a texture with no regard for its format, then tell OpenGL how to interpret the data later time?

I have been reading about shaders and I have found an interesting article, here, as well as this. Both of which demonstrate the manipulation of textures using fragment shaders. I will need to learn how to use fragment shaders but I think that this is the key, it can be done.

Combine
http://www.opengl.org/registry/specs/ARB/texture_buffer_object.txt
and FlushMappedBufferRange from
http://www.opengl.org/registry/specs/ARB/map_buffer_range.txt

Do swizzling, format-conversion, bilinear-filtering (optionally the rare trilinear) in shader.