Too many D3D11 Map calls when using VPP and Encoder

Too many D3D11 Map calls when using VPP and Encoder

I have a program using Intel Media SDK which uses VPP and Encoder with D3D surfaces (similar to: http://software.intel.com/en-us/articles/intel-media-sdk-tutorial-simple...) and also using the D3D memory allocator routines provided in the tutorial.

However, I observe that in the debug output, there are too many D3D Map calls and not enough Unmap calls being made: D3D11 ERROR: ID3D11DeviceContext::Map: This resource is already mapped! [ RESOURCE_MANIPULATION ERROR #2097213: RESOURCE_MAP_ALREADYMAPPED].  Is this behavior normal?  It would seem to me that the number of Map and Unmap calls should be equal.

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Also, it would help if there is an explanation about when Lock and Unlock should be getting called.

Hi Richard,

I ran some quick tests using the "simple_6_encode - d3d - vpp_preproc" sample from the tutorial. I do not encounter any DX11 debug errors or warnings like the ones you describe.

Do you see these debug messages for each frame or at specific frame or at the end of the workload? If you can you provide some details about your workload it would help us understand your setup better.

Lock/Unlock should be called if you intend to manually access the "bits" in the surface for reading or writing. This is exemplified in the code by  the file read/write operations.

Regards,
Petter 

Petter,

Some trial and error has revealed that the error is related to what display my test machine is connected to.  In certain display configurations, the error does not appear.  Will investigate further...

In the meantime, I had a question about loading D3D input data for consumption by VPP.  The examples I saw in the tutorial examples and SDK samples copied data from a file using fread.  I used memcpy to achieve a similar result:

memcpy(m_pmfxSurfacesVPPIn[nVPPSurfIdx]->Data.B, pData, pLen);

However, I already have my input data in video memory. Is this the right way to load it:

CustomMemId* cmid = (CustomMemId*)(m_pmfxSurfacesVPPIn[nVPPSurfIdx]->Data.MemId);
ID3D11Texture2D* dstFrame = reinterpret_cast<ID3D11Texture2D *>(cmid->memId);
g_pD3D11Ctx->CopyResource(dstFrame, srcFrame); // srcFrame is a pointer to ID3D11Texture2D which holds the input

I didn't see any examples of how to accomplish direct load from video memory otherwise, so your advice would be appreciated.  Thanks.

Also, I am unclear how I should be indicating to QuickSync to use the video memory from srcFrame.  I saw in the media sdk documentation:

MfxFrameData.MemId: Memory ID of the data buffers; if any of the preceding data pointers is non-zero then the SDK ignores MemId.

Therefore, I tried to clear the data pointers with memset:

memset(m_pmfxSurfacesVPPIn[nVPPSurfIdx]->Data.B, 0, pLen); // pLen is rowpitch * height as defined in post above

CustomMemId* cmid = (CustomMemId*)(m_pmfxSurfacesVPPIn[nVPPSurfIdx]->Data.MemId);
ID3D11Texture2D* dstFrame = reinterpret_cast<ID3D11Texture2D *>(cmid->memId);
g_pD3D11Ctx->CopyResource(dstFrame, srcFrame); // srcFrame is a pointer to ID3D11Texture2D which holds the input

However, the result of rendering is a black screen, making me think that VPP is still trying to use the R,G,B, etc. system memory data pointers.  How can I check whether VPP is using MemId/ID3D11Texture2D or the data pointers?  I made sure that the formats and dimensions of dstFrame and srcFrame are compatible (no D3D11 Errors during the CopyResource).  There must be something I am missing with how video memory is passed in as input to VPP?

Hi Richard,

First, make sure that your D3D11 2D texture surfaces are allocated with the same set of attributes as illustrated in the Media SDK samples (sample_common/d3d11_allocator.cpp) or like in the tutorial samples (common/common_directx11.cpp).

If your surfaces are allocated in the same way you should be able to use them with Media SDK Also make sure they have been allocated using the same DirectX device as used by Media SDK.

Since you're using D3D surfaces you only need to lock and access the surface components (such as Data.B) if you plan to perform manual read and write to surface (such as in the file read/write case). If you use DirectX operations (eg. CopyResource) to copy to/from surface you should not invoke lock/unlock. MemId (which is the reference to Texture2D) is enough.

Since you're using D3D surfaces, please set Data.B/Y/... to zero at initialization. But note that these parameters will be set in case you do perform a lock on the surfaces via the Media SDK allocation interface.

Regards,
Petter 

Thanks.  I turned lock/unlock off when using CopyResource with MemId and also set Data.R/G/B/A to zero, and that solved the problem.

Leave a Comment

Please sign in to add a comment. Not a member? Join today