Jump to content
  • Advertisement
Sign in to follow this  
a2ps

DX11 [DX11] change square color every second, CPU or GPU work?

This topic is 2436 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

hi,
im educating myself about D3D11 and shader development.

i have a small framework that does all the initialization work as well as buffer and shader creation. for a small test i build a small square (2 triangles) where every vertex has a different color on the original buffer.

this is my initialization code:

array <string, 2> tmpInputLayout =
{
string("POSITION"),
string("COLOR")
};

array <D3DEngine::ColorVertex, 4> tmpVertexBuffer =
{
XMFLOAT3(-0.5, 0.5f, 0.5f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f),
XMFLOAT3(0.5, 0.5f, 0.5f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f),
XMFLOAT3(-0.5, -0.5f, 0.5f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f),
XMFLOAT3(0.5, -0.5f, 0.5f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)
};

array <unsigned short, 6> tmpIndexBuffer =
{
0, 1, 2,
2, 1, 3
};

inst.CreateBuffer(D3DEngine::Vertex, tmpVertexBuffer, &vertexBuffer);
inst.CreateBuffer(D3DEngine::Index, tmpIndexBuffer, &indexBuffer);

inst.CreateVertexShader(vsBlob, tmpInputLayout, &inputLayout, &vertexShader);
inst.CreatePixelShader(psBlob, &pixelShader);

pretty simple right? and it works fine.

now i want to add a simple effect, change those vertex colors every second. using a constant buffer its easy, i just see if a second has passed and if it has i just set a new color and pass it to the shader using a constant buffer.

now my question is, is there a way i can calculate if a second has passed and calculate the new color on the shader itself? it seems to me that im doing work on the CPU that i should be doing on the GPU. with the way im doing things the shader doesnt do anything but apply the new color (that is on a constant buffer) and thats it.

problem is, if i pass my timeDelta to the shader so it can calculate if a second has passed how can i save persistant data between shader calls? the way i do it on the CPU is add timeDelta until its addedTimeDelta == 1.0f, and then i know a second has passed. but on the shader such a variable would reset every shader call (or im i wrong about this?), also global variables are constant so i dont really know how to change that.

also the shader always receives the same input right? the data that has been originally set to the buffer? that means he always receives the initial color and NOT the color from the previous shader call (previous frame that is), so how can i deal with that?

on a sidenote, the only way i can pass data between the CPU and GPU is by using constant buffers? or is there a another way? the reason i ask is because constant buffers need more work to initialize and have to be minimum 16 bytes long. if i want to pass just one float i would have to create at least a float4.

thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement

now my question is, is there a way i can calculate if a second has passed and calculate the new color on the shader itself? it seems to me that im doing work on the CPU that i should be doing on the GPU. with the way im doing things the shader doesnt do anything but apply the new color (that is on a constant buffer) and thats it.

Well, in order to find out in a shader whether a second has past, you need the elapsed time. This means, you need a constant buffer that stores that elapsed time and have to update it every frame. Moreover you have the overhead of checking, whether the second has passed, on the GPU (all the time). You're CPU is probably much less busy, so I'd rather to the test there and write the color to a constant buffer, since then you need to update the buffer only once a second. The updating of constant buffers is an expensive task, by the way.


how can i save persistant data between shader calls?

That's only possible in pixel shaders since Dx11 (it will likely be available for all shader stages in Dx11.1). But it is an expensive operation, since you write to global memory. In your case this won't be a wise way to go.


also the shader always receives the same input right? the data that has been originally set to the buffer? that means he always receives the initial color and NOT the color from the previous shader call (previous frame that is), so how can i deal with that?

That's right. Unless you change the data in the original buffer. Particle systems, for instance store the particle positions in vertices, drag them through the vertex shader, modify the positions there and stream them then via stream out into another vertex buffer, which is bound in the next frame as input. (Thats called the ping-pong paradigm.) Doing this here might be a little overkill and is probably slower. Besides you still need the elapsed time. (So the main problem isn't solved.)


but on the shader such a variable would reset every shader call (or im i wrong about this?)

Yes, you're right. Variables are not persistent. The memory in which the variables were stored might be used by some other draw call later, so we can't make any assumptions whether the variables are still in that memory.


on a sidenote, the only way i can pass data between the CPU and GPU is by using constant buffers? or is there a another way? the reason i ask is because constant buffers need more work to initialize and have to be minimum 16 bytes long. if i want to pass just one float i would have to create at least a float4.

If you have data that is different for each vertex you can consider updating the content of a vertex buffer and feed this one in as well. Actually, you use a second buffer, called staging buffer in which you copy the data from the CPU and then copy on the GPU the staging buffer to the buffer you use for rendering.
If all your shader threads need the same value you are much faster when letting them read from a constant buffer. (It is not a good idea to let each thread read from a different position in a constant buffer, since the memory accesses are serialized. That's called constant waterfalling.)

So, in conclusion: You do it already right. :)

Hope this helps you a little. :)

Share this post


Link to post
Share on other sites

So, in conclusion: You do it already right. :)

Hope this helps you a little. :)

it helped a lot!
thanks so much for taking time to read my answer and reply to it :)

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!