• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Tape_Worm

Questions about Map/UpdateSubResource

19 posts in this topic

I'm finding the whole change from Lock/Unlock to Map/Unmap and UpdateSubResource to be a little perplexing.

So, here's how I handle when to use Map and when to use UpdateSubResource:
For dynamic usage buffers, I use Map/Unmap (UpdateSubResource doesn't like dynamic from what I gather), and for default usage I use UpdateSubResource. Is this a good rule of thumb? Or does this change depending on the type of buffer? For constant buffers I tend to just use default usage and UpdateSubResource, but I've read that UpdateSubResource for Textures and Vertex/Index buffers is on the slow side.

Secondly, with Lock in D3D9, you can Lock a region of the buffer. Am I able to Map a region of a buffer? Or how about UpdateSubResource on a particular portion of the buffer? I've read that when you update a constant buffer, you have to do the entire buffer. For textures you can update a region of the buffer, and for vertex/index buffers... well, I've read about people suggesting to update a portion of those buffers, but I've not found any concrete examples of anyone actually doing it. So is it possible with Vertex/Index buffers? If you can, how in the hell do you map it out so that you map at an offset of 16 bytes in the buffer and a range of 32 bytes? This whole stride/index/rowpitch thing is a little weird for a linear buffer.

I'm not a big fan of the API layout thus far. Having the Map/UpdateSubResource on the context and not the object with the "kitchen sink" parameters is a little more than confusing and what I've found in the docs don't really explain in detail what applies to what, or more accurately, they don't seem to say what -not- to do.

Sorry if this all sounds really dumb, but I'm quite new to the API and trying to make sense of it. Thanks in advance for any insight.
0

Share this post


Link to post
Share on other sites
[quote name='Jason Z' timestamp='1327099831' post='4904714']
Map is used to map a complete [u][b]sub[/b][/u]resource - for buffers that means the whole buffer, and for textures that can mean a lot of different things depending on the dimension, array size, and mip levels. UpdateSubResource has the ability to update only a portion of a subresource, which can be an advantage in some cases.
[/quote]

How do you map a subresource into a position in an array of another?
0

Share this post


Link to post
Share on other sites
[quote name='jsedlak' timestamp='1327117203' post='4904749']
[quote name='Jason Z' timestamp='1327099831' post='4904714']
Map is used to map a complete [u][b]sub[/b][/u]resource - for buffers that means the whole buffer, and for textures that can mean a lot of different things depending on the dimension, array size, and mip levels. UpdateSubResource has the ability to update only a portion of a subresource, which can be an advantage in some cases.
[/quote]

How do you map a subresource into a position in an array of another?
[/quote]Sorry, I don't understand the question - do you mean mapping a texture subresource to another texture array subresource? If so, then for mapping you just map the two subresources and then copy the data directly. With UpdateSubResource you more or less specify the locations in the parameter arguments and the function does the copying for you.
0

Share this post


Link to post
Share on other sites
In general, I believe dynamic buffers are best if you want to use them the same frame as you update them. If you have a lot of data and want to update once and then use the same data multiple times on the GPU, default buffers with UpdateSubResource are probably better.
0

Share this post


Link to post
Share on other sites
[quote name='Jason Z' timestamp='1327128132' post='4904780']
[quote name='jsedlak' timestamp='1327117203' post='4904749']
[quote name='Jason Z' timestamp='1327099831' post='4904714']
Map is used to map a complete [u][b]sub[/b][/u]resource - for buffers that means the whole buffer, and for textures that can mean a lot of different things depending on the dimension, array size, and mip levels. UpdateSubResource has the ability to update only a portion of a subresource, which can be an advantage in some cases.
[/quote]

How do you map a subresource into a position in an array of another?
[/quote]Sorry, I don't understand the question - do you mean mapping a texture subresource to another texture array subresource? If so, then for mapping you just map the two subresources and then copy the data directly. With UpdateSubResource you more or less specify the locations in the parameter arguments and the function does the copying for you.
[/quote]

I'm probably not asking the right question... (and yes, sorry for the hijack)
http://www.gamedev.net/topic/618817-using-texture2darray-and-shaderresourceview/
0

Share this post


Link to post
Share on other sites
[quote name='Jason Z' timestamp='1327099831' post='4904714']
Map is used to map a complete [u][b]sub[/b][/u]resource - for buffers that means the whole buffer, and for textures that can mean a lot of different things depending on the dimension, array size, and mip levels. [i]UpdateSubResource has the ability to update only a portion of a subresource, which can be an advantage in some cases.[/i]

I personally use Map to update my constant buffers in Hieroglyph3, but I think either method can be used...
[/quote]

So, you can update a portion of a vertex buffer with UpdateSubResource then? I'm just wondering how I would pass the offset within the buffer and the number of bytes to update to the UpdateSubResource method? Can you use UpdateSubResource to update a portion of a constant buffer?
0

Share this post


Link to post
Share on other sites
You can also update just part of it with Map, if you use D3D11_MAP_WRITE instead of D3D11_MAP_WRITE_DISCARD. I'm not sure what restrictions apply to the usage and bind-flags for uncommon cases, but that is easy to look up or test.
[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476181%28v=vs.85%29.aspx"]http://msdn.microsoft.com/en-us/library/windows/desktop/ff476181%28v=vs.85%29.aspx[/url]
You probably don't want to do that for a constant-buffer, as they are usually relatively small. Doubtful it's ever worth it compared to overwriting the whole thing with a discarding map.
[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476259%28v=vs.85%29.aspx"]http://msdn.microsoft.com/en-us/library/windows/desktop/ff476259%28v=vs.85%29.aspx[/url] has additional discussion on dynamic usage.
0

Share this post


Link to post
Share on other sites
In the remarks on[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx"] this page[/url], it explicitly says that you can't update a portion of a constant buffer, but there is no mention of doing it for a vertex buffer (although it mentions updating vertex buffers in general, so it should be possible). I've never explicitly tried it, but I would assume that you use the same addressing concept for the destination box as you would for a 1D texture (there is also a sample of that on the link above).

It would probably be worth doing a quick test, where you create a vertex buffer that is all zeros, then update only the second element with all ones. If it works in that case (which can be verified with PIX) then you should be good to go.

As a side note, the two methods are similar enough that it shouldn't be too hard to build support for either method and dynamically decide which one to use. This would be ideal so that you can profile and see how fast one or the other is. In the end, they both end up doing the same thing - copying data from CPU memory to a resource in GPU memory. There is some difference in the way that the driver handles it, but I suspect there isn't much performance difference between the two methods. To be honest, I've never heard anyone say that one is better than the other...

And one final point - notice the comments about deferred contexts at the bottom of the linked page!

EDIT: I also found [url="http://www.gamedev.net/topic/570433-dx11updatesubresource-what-am-i-missing/"]this link[/url], which has some good discussion about the topic. In there it says that mapping a buffer uses bytes in the D3D11_BOX, while textures use pixels for the units...
1

Share this post


Link to post
Share on other sites
[quote name='Erik Rufelt' timestamp='1327189592' post='4904974']
You can also update just part of it with Map, if you use D3D11_MAP_WRITE instead of D3D11_MAP_WRITE_DISCARD. I'm not sure what restrictions apply to the usage and bind-flags for uncommon cases, but that is easy to look up or test.
[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476181%28v=vs.85%29.aspx"]http://msdn.microsof...v=vs.85%29.aspx[/url]
You probably don't want to do that for a constant-buffer, as they are usually relatively small. Doubtful it's ever worth it compared to overwriting the whole thing with a discarding map.
[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476259%28v=vs.85%29.aspx"]http://msdn.microsof...v=vs.85%29.aspx[/url] has additional discussion on dynamic usage.
[/quote]
Mapping with write will end up mapping the whole sub-resource too, as far as I know. There are some specialized cases where a vertex or index buffer can be partially updated with WRITE_DISCARD and WRITE_NO_OVERWRITE flags, but they are very special cases (building dynamic vertex / index buffers as opposed to dynamically updating the contents of the buffers).
0

Share this post


Link to post
Share on other sites
[quote name='Jason Z' timestamp='1327218837' post='4905051']
[quote name='Erik Rufelt' timestamp='1327189592' post='4904974']
You can also update just part of it with Map, if you use D3D11_MAP_WRITE instead of D3D11_MAP_WRITE_DISCARD. I'm not sure what restrictions apply to the usage and bind-flags for uncommon cases, but that is easy to look up or test.
[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476181%28v=vs.85%29.aspx"]http://msdn.microsof...v=vs.85%29.aspx[/url]
You probably don't want to do that for a constant-buffer, as they are usually relatively small. Doubtful it's ever worth it compared to overwriting the whole thing with a discarding map.
[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476259%28v=vs.85%29.aspx"]http://msdn.microsof...v=vs.85%29.aspx[/url] has additional discussion on dynamic usage.
[/quote]
Mapping with write will end up mapping the whole sub-resource too, as far as I know. There are some specialized cases where a vertex or index buffer can be partially updated with WRITE_DISCARD and WRITE_NO_OVERWRITE flags, but they are very special cases (building dynamic vertex / index buffers as opposed to dynamically updating the contents of the buffers).
[/quote]
[quote name='Erik Rufelt' timestamp='1327189592' post='4904974']
You can also update just part of it with Map, if you use D3D11_MAP_WRITE instead of D3D11_MAP_WRITE_DISCARD. I'm not sure what restrictions apply to the usage and bind-flags for uncommon cases, but that is easy to look up or test.
[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476181%28v=vs.85%29.aspx"]http://msdn.microsof...v=vs.85%29.aspx[/url]
You probably don't want to do that for a constant-buffer, as they are usually relatively small. Doubtful it's ever worth it compared to overwriting the whole thing with a discarding map.
[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476259%28v=vs.85%29.aspx"]http://msdn.microsof...v=vs.85%29.aspx[/url] has additional discussion on dynamic usage.
[/quote]

So, I did some investigation (boy, I wish they'd document this stuff more explicitly) and I found this:
I -can- update a portion of the vertex buffer when I use UpdateSubResource by defining the left and right fields of the destination box. So there's that.

I can't seem to do it for Map though. I tried using the Write flag and the debug gave me this:
[CODE]D3D11: ERROR: ID3D11DeviceContext::Map: Map cannot be called with MAP_WRITE access, because the Resource was created as D3D11_USAGE_DYNAMIC. D3D11_USAGE_DYNAMIC Resources must use either MAP_WRITE_DISCARD or MAP_WRITE_NO_OVERWRITE with Map. [ RESOURCE_MANIPULATION ERROR #2097210: RESOURCE_MAP_INVALIDMAPTYPE ][/CODE]
So, I changed it to default, with no CPU write access (can't use CPU write with default resources) and I got this:
[CODE]D3D11: ERROR: ID3D11DeviceContext::Map: Map cannot be called with MAP_WRITE access, because the Resource was not created with the D3D11_CPU_ACCESS_WRITE flag. [ RESOURCE_MANIPULATION ERROR #2097210: RESOURCE_MAP_INVALIDMAPTYPE ][/CODE]

Anyway, this has been extremely helpful, so thank you all.

I do have another question though... what is this Subresource parameter I'm seeing? What's its purpose and how is it used?

Thanks!
0

Share this post


Link to post
Share on other sites
Your first error is because your vertex buffer either didn't have a dynamic usage, or perhaps that you didn't indicate that you wanted write access with the CPU flags parameter. The second one makes sense, since you don't have any way to update a default resource with the CPU...

The sub-resource is a portion of a complete resource (obviously :) ) that is simply an index to point to that part of it. So for textures there is a separate subresource index for each mip level, each array slice, etc... For buffers, there is only one subresource - the whole buffer.

I dedicated quite a bit of time to researching each possibility and they are explicitly shown in our book (chapter 2, for each resource type) - but if you trawl through the online documentation you can also find the subresource information.
1

Share this post


Link to post
Share on other sites
[quote name='Jason Z' timestamp='1327472263' post='4906018']
Your first error is because your vertex buffer either didn't have a dynamic usage, or perhaps that you didn't indicate that you wanted write access with the CPU flags parameter. The second one makes sense, since you don't have any way to update a default resource with the CPU...

The sub-resource is a portion of a complete resource (obviously [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] ) that is simply an index to point to that part of it. So for textures there is a separate subresource index for each mip level, each array slice, etc... For buffers, there is only one subresource - the whole buffer.

I dedicated quite a bit of time to researching each possibility and they are explicitly shown in our book (chapter 2, for each resource type) - but if you trawl through the online documentation you can also find the subresource information.
[/quote]

Awesome.

As an additional thank you, I've purchased your book.
0

Share this post


Link to post
Share on other sites
On a related note, D3D11_MAP_WRITE_NO_OVERWRITE is not allowed with Structured Buffers, Raw Buffers, or regular buffers. This is unfortunate when you want to dynamically append data to what you've already written. DX 11.1 fixes this, but not sure when it'll be released, whether it'll be available on Windows 7, and whether existing DX11 graphics cards will support it.

Assuming that DX 11.1 isn't a possibility, the only ways we have of updating a Structured Buffer are either D3D11_MAP_WRITE_DISCARD or UpdateSubresource. For our app, DISCARD won't work because it makes all previously written data unavailable to further draw calls, and our shaders need access to the entire buffer. So that leaves UpdateSubresource as our only option, I believe. I'm unclear as to whether our Structured Buffer should be created as DEFAULT or DYNAMIC for best performance with UpdateSubresource.

Structured Buffers created as DYNAMIC reside permanently in system memory. The data is streamed to the graphics card over the bus as the shader needs it. I assume that when UpdateResource is called, the driver makes a copy of the data in temp memory and then simply copies it to the buffer in system memory when it's safe to. Contrast this with D3D11_MAP_WRITE_NO_OVERWRITE on vertex buffers, where the app can write directly to the destination memory location without the driver making a copy.

StructuredBuffers created as DEFAULT reside in video memory with faster access by the shader. When UpdateResource is called, I assume the driver still needs to make a copy of the data in temp memory and then upload it to video memory at a safe time. Still a lot of copying.

If anyone has experience with the fastest way to incrementally update Structured Buffers, would love to hear it!
0

Share this post


Link to post
Share on other sites
[quote name='360GAMZ' timestamp='1328051880' post='4908205']
I'm unclear as to whether our Structured Buffer should be created as DEFAULT or DYNAMIC for best performance with UpdateSubresource.
[/quote]

Update: UpdateSubresource requires that the resource have been created as DEFAULT without CPU write access.
0

Share this post


Link to post
Share on other sites
I've used MAP_WRITE_NO_OVERWRITE and MAP_WRITE_DISCARD and it doesn't seem to have had any adverse impact on performance (overall a good deal faster than D3D9, but I haven't benched this in isolation), but still ... it would be really nice to see some clear documentation or guidelines coming from MS on what you need to do in order to replicate the old NOOVERWRITE/DISCARD Locking pattern, because right now it's just as head-scratching as GL_ARB_vertex_buffer_object, and that's not a good thing.
0

Share this post


Link to post
Share on other sites
For vertex & index buffers, you should be able to use the NO_OVERWRITE/DISCARD locking pattern just as in the DX9 days. You'll just need to make sure you create the resources with DYNAMIC and CPU write access.

For Structured Buffers, Raw Buffers, and normal buffers, NO_OVERWRITE isn't supported which is very unfortunate. So, the only way to do incremental updating of one of these types of buffers is through UpdateSubresource(). In this case, the resource needs to be created with DEFAULT and no CPU write access.
0

Share this post


Link to post
Share on other sites
The key difference however is: with the old way, when locking with no overwrite, you specify a start offset and size to lock. When mapping you don't - you get the entire buffer contents. And that is the source of confusion: what assurance have you that your no overwrite map is going to stand a chance of actually doing what you asked it to do (and not stalling the pipeline)?

OK, I know that the old locking flags were hints, not absolute assurances, but that doesn't make the difference go away - how do you hint to D3D11 that this is the behaviour you want?

So right now I'm just casting the pData member of D3D11_MAPPED_SUBRESOURCE to my vertex structure type, incrementing the pointer by the required amount, and writing in. Like I said, that seems to work and it doesn't cause any performance loss, but in the absence of any documented description of what's happening (and it could be as simple as "yeah, do this" and "no, don't do that") it feels an awful lot like throwing magic pixie dust in the air and seeing what comes down. That's not fun. D3D9 had a clear and well-documented approach for this buffer usage pattern (and let's leave out buffer types to which it doesn't apply), D3D11 doesn't.

So I guess what's needed is a D3D11 equivalent of usage style 2 in the old "Using Dynamic Vertex and Index Buffers" SDK entry.
0

Share this post


Link to post
Share on other sites
[quote name='mhagain' timestamp='1328194547' post='4908717']
So right now I'm just casting the pData member of D3D11_MAPPED_SUBRESOURCE to my vertex structure type, incrementing the pointer by the required amount, and writing in. Like I said, that seems to work and it doesn't cause any performance loss, but in the absence of any documented description of what's happening (and it could be as simple as "yeah, do this" and "no, don't do that") it feels an awful lot like throwing magic pixie dust in the air and seeing what comes down. That's not fun. D3D9 had a clear and well-documented approach for this buffer usage pattern (and let's leave out buffer types to which it doesn't apply), D3D11 doesn't.
[/quote]

What you're describing sounds correct to me and consistent with the link provided by Erik above. The DX11 docs also suggest that you use NO_OVERWRITE along with DISCARD to insure you won't be overwriting any data the GPU may be using. Same as with DX9, but the DX9 docs explain it a lot better (i.e. use DISCARD when you reach the end of the buffer). As you pointed out, the difference between the DX9 and DX11 APIs are that you specified the region in DX9 whereas DX11 gives you a pointer to the start of the buffer, and then we must apply the offset afterwards. I agree that the docs could explain all of this better.
0

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  
Followers 0