Good Performance test?

Started by
13 comments, last by noodleBowl 10 years, 4 months ago

Does the DISCARD flag not give me a new location in memory to use or am I thinking of this wrong?

Even if so, that means an extra allocation and free by the driver, which is a costly operation.

Even though that might be and I'm sure it is, because it makes tons of sense that the GPU would need to allocate more memory. But isn't that what the DISCARD flag and the use of Dynamic buffer is designed for?

But what I am a little confused about is, are you saying to only use the DISCARD flag. Does this not defeat the purpose of using a dynamic buffer and reusing buffer slots with NO OVERWRITE?

You still need the buffers to be D3D11_USAGE_DYNAMIC and update with D3D11_MAP_WRITE on the buffer that is not being used by the GPU.

I assume I need to be at the beginning of my buffer in order to use D3D11_MAP_WRITE correctly, also that this will always no matter what, overwrite the content in the buffers. Right?

If so how does this not create the issue where I'm writing to the buffer, send it to the GPU, and then I start writing to the buffer again before it is ready? Or does calling DrawIndexed send everything off to the GPU and the buffers get "flushed" in the sense that it does not matter if I overwrite the content because the GPU gets a copy or etc to use

Advertisement

I assume I need to be at the beginning of my buffer in order to use D3D11_MAP_WRITE correctly, also that this will always no matter what, overwrite the content in the buffers. Right?

No, you can write to any part of the buffer, but if that part of the buffer is in use by the GPU then the GPU has to flush all commands before allowing you to write.
But thanks to double-buffering you should write to the start of the buffer.


If so how does this not create the issue where I'm writing to the buffer, send it to the GPU, and then I start writing to the buffer again before it is ready?

I don’t know how else I can explain what I have already explained before.
You aren’t writing to it while it is in use by the GPU. You are writing to the other buffer while it is in use by the GPU. Hence the term: Double Buffer.
If you have further questions on what double-buffering is and how it works there are plenty of resources on Google (rather on the Internet; Google just helps you find them).


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid


If so how does this not create the issue where I'm writing to the buffer, send it to the GPU, and then I start writing to the buffer again before it is ready?

I don’t know how else I can explain what I have already explained before.
You aren’t writing to it while it is in use by the GPU. You are writing to the other buffer while it is in use by the GPU. Hence the term: Double Buffer.
If you have further questions on what double-buffering is and how it works there are plenty of resources on Google (rather on the Internet; Google just helps you find them).

I should explain myself a little better. I understand that the double buffer is supposed to mitigate the GPU stalls, but I guess what I'm trying to get at is. Since the GPU and CPU are asynchronous, how well does double buffering essentially guarantee that the GPU won’t stall?

Let just say that my CPU is going so fast around that the GPU just cannot keep up. Even when using double buffers.

The CPU will keep going, where I assume the GPU will start using ‘invalid’ data at some point right?

So I'm assuming, because the chance is so small that the above will happen and the fact that you will already have an exact needed size

(The buffers will always have enough room to hold everything) those are the major benefits over the DISCARD / OVERWRITE method.

Although that maybe the case, is the DISCARD/OVERWRITE method not safer or is it that safety does not come at a great price?

Let just say that my CPU is going so fast around that the GPU just cannot keep up. Even when using double buffers.
The CPU will keep going, where I assume the GPU will start using ‘invalid’ data at some point right?

There are certain flush points that cause the GPU to perform all queued render commands. Clearing the bound buffer. Changing render targets. Presenting to the screen.
When these flushes are complete, any resources sent to the GPU until that point are no longer in use by the GPU.
If you are so worried about it, use triple-buffering or quadruple-buffering.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

There are certain flush points that cause the GPU to perform all queued render commands. Clearing the bound buffer. Changing render targets. Presenting to the screen.
When these flushes are complete, any resources sent to the GPU until that point are no longer in use by the GPU.
If you are so worried about it, use triple-buffering or quadruple-buffering.

I was thinking that this would be the solution, also I assume the growable buffers would prevent this as well

Speaking of which, how do these work on a technical level? I understand you said they should grow when you run out of room.

But if I release it and then create a new one of the appropriate size I would assume its content is just gone. So then I guess this check has to be made from the start of a draw call right? So something like this


void SpriteBatcher::drawCall()
{
	//If the buffer is full
	if(currentBufferPosition + vertexperQuad > maxBufferSize)
	{
		unmapCurrentBuffers(); //Unmaps the buffers
		drawContent(); //Draws the data in the buffer [ DrawIndexed Call]
		
		releaseBufferAB(); //Releases buffer A and B
		
		constructBufferAB(currentSize + quadIncreaseAmount); //Recreate the vertex buffers A and B; With there new sizes
		switchBuffer(); //Changes the current buffer to the next Buffer that should be used
		
                currentBufferPosition = 0; //Reset the buffer position
		mapCurrentBuffer(); //maps the current buffer; Uses NO OVERWRiTE FLAG
                

	}
	
	/* Code to place the data into the Current Buffer; Increase the current buffer position*/
}

Also when using Dynamic buffers the map flag must be DISCARD or NO OVERWRITE. If I choose to use double buffers and with that in mind I should (or will have to) always use the NO OVERWRITE flag right? Seeing as using DISCARD would defeat the purpose of the double buffer technique

This topic is closed to new replies.

Advertisement