Sign in to follow this  
schupf

DX10: Write to parts of a texture

Recommended Posts

Hello, just a little question about textures in DX10: I have created a dynamic texture with write access:
D3D10_TEXTURE2D_DESC alphaMapDesc;
//...
alphaMapDesc.Usage	    = D3D10_USAGE_DYNAMIC;
alphaMapDesc.BindFlags	    = D3D10_BIND_SHADER_RESOURCE;
alphaMapDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
alphaMapDesc.MiscFlags	    = 0;


But if I try to map this texture to update some texels with this line:
alphaMap->Map(D3D10CalcSubresource(0, 0, 1), D3D10_MAP_WRITE, 0, &mappedAlphaMap);


I get this error:
Quote:
D3D10: ERROR: ID3D10Texture2D::Map: Map cannot be called with MAP_WRITE access, because the Resource was created as D3D10_USAGE_DYNAMIC. D3D10_USAGE_DYNAMIC Resources must use either MAP_WRITE_DISCARD or MAP_WRITE_NO_OVERWRITE with Map.
To me this is a little bit strange. I thought by using the flag D3D10_CPU_ACCESS_WRITE I can map the texture and write to it however I want to. Did I do something wrong or is it really impossible to update some parts of a texture per Map()? (because DX10 only always DISCARD, so I always have to update ALL texels)

Share this post


Link to post
Share on other sites
The purpose of dynamic resources is to fully update them often (multiple times per frame). If you only want to modify a part of a texture, you'd be better served by creating a new smaller texture with the data you need to update, and copy the data in with CopySubresourceRegion.

Share this post


Link to post
Share on other sites
Hm, ok.
I just made some test with DX10 resources and now I have some additional questions.
A DYNAMIC resource can only be mapped with Flags D3D10_MAP_WRITE_DISCARD or D3D10_MAP_WRITE_NO_OVERWRITE. So I created a DYNAMIC 2D texture with D3D10_CPU_ACCESS_WRITE, called Map() on this texture with flag D3D10_MAP_WRITE_DISCARD and updated only some texels. But when I checked the texture the texels which I did not update were still the same! I thought DISCARD means: the whole resource is cleared and you have to refill the WHOLE resource.
1. So is it save to assume that the non-updated parts of a resource stay the same if I call Map() with D3D10_MAP_WRITE_DISCARD?

I dont really understand the use of D3D10_MAP_WRITE_NO_OVERWRITE. So this means I write to the resource but only to parts where the resource isnt initialized (so where no values are)? Currently I can only see one use of NO_OVERWRITE: you write 100 bytes to a buffer with NO_OVERWRITE, in the next frame you write from byte 101 to byte 200, then from 201 to 300 and so on. But eventually the resource will be full and what should I do then?
2. So when do I need NO_OVERWRITE?

Last one: I tried to create a STAGING vertexbuffer. So I set Usage = D3D10_USAGE_STAGING, BindFlags = D3D10_BIND_VERTEX_BUFFER and CPUAccessFlags = D3D10_CPU_ACCESS_WRITE. But I try to create the buffer I get this error:
Quote:
A D3D10_USAGE_STAGING Resource cannot be bound to any parts of the graphics pipeline, so therefore cannot have any BindFlags bits set

I dont get this. So I can only create a STAGING resource if I set BindFlags = 0?
But how does DX10 then know what kind of resource this is? (It could be a vertexbuffer, indexbuffer, ...)
3. So you ALWAYS have to set BindFlags = 0 (and basically create a typeless resource) if you create a staging resource?

Share this post


Link to post
Share on other sites
Quote:
Original post by schupf
1. So is it save to assume that the non-updated parts of a resource stay the same if I call Map() with D3D10_MAP_WRITE_DISCARD?

2. So when do I need NO_OVERWRITE?

3. So you ALWAYS have to set BindFlags = 0 (and basically create a typeless resource) if you create a staging resource?


1. No, that's not a safe assumption.

2. Your usage pattern is essentially correct. When it's full, use discard and start from the beginning again. Expect everything to be garbled trash after using discard.

3. Staging resources exist in system memory, so you can't bind them to any GPU pipeline stage. They're used to copy data between GPU and system memory, so wherever you copy it to or from is what should have the bindflags set.

Share this post


Link to post
Share on other sites
Thanks for your answers!

One last question: You said Staging resource exist in system memory. But what about the other 3 resource types Default, Dynamic and Immutable? I guess I can't assume that Default, Dynamic and Immutuable are ALWAYS in video memory (VRAM) and only Staging resources are ALWAYS in sys mem (the reason why I am asking: I would like to calculate the VRAM and SYSMEM requirements of my application)

Share this post


Link to post
Share on other sites
You can't really assume that any of them will be in any particular memory. The only real requirement is that you have enough system memory to hold everything (in case your app gets evicted from the GPU, everything in vidmem has a sysmem backing store). You need enough vidmem to complete your most intensive render operation, because everything that is bound to a shader resource, vertex buffer, etc must all fit in video memory so the GPU can access it. There may be a couple of exceptions for certain hardware and drivers, but that's pretty much your minimum requirement. Ideally you'd be able to fit everything for 1 or more whole rendering frames into video memory for smooth operation.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this