• Advertisement
Sign in to follow this  

Manually copying texture data from a loaded image

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

I was building a simple D3D12 app which load and display an image on screen.
 
As you are aware, D3D12 has no calls like CreateTexture2D which we have in D3D11 so that this process has to be done in the hard way.
So far I've loaded the image in memory using WIC with DXGI_FORMAT_R8G8B8A8_UNORM and got its width and height.
 
Created a 2D array to store the pixels.
 

BYTE ** pixels = new BYTE*[height];
for (int i = 0; i < height; i++) {
pixels[i] = new BYTE[width * 4];
}

Use CopyPixels to copy the pixels to the new array

UINT stride = width * 4;
hr = pSource->CopyPixels(nullptr, stride, (sizeof(BYTE)*4*height*width), *pixels);

Note : I'm getting 0x88982f8c: insufficient buffer allocation here!

My aim is to get the texture data so that I can copy it to the upload buffer.
For that I'm extracting the texture dat as follows,

D3D12_SUBRESOURCE_FOOTPRINT srFtprint;
srFtprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srFtprint.Depth = 1; // 0 or 1?
srFtprint.Width = width;
srFtprint.Height = height;
srFtprint.RowPitch = rowPitch;

D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedTexture2D = { 0 };
placedTexture2D.Offset = 0;
placedTexture2D.Footprint = srFtprint;

UINT8 * pScan;
for (UINT y = 0; y < height; y++)
{
pScan = m_pDataBegin + placedTexture2D.Offset // Now pScan stores the texture data
+ y * srFtprint.RowPitch;
memcpy(pScan, &(pixels[y * width]),
sizeof(BYTE) * width);
}

I'm unable to accomplish this correctly because I think I'm not able to create/copy the exact number of bytes in the same expected alignment.

Edited by ngub05

Share this post


Link to post
Share on other sites
Advertisement
pixels is not contiguous in memory; you have it as an array of pointers to rows.
Make it a single contiguous allocation.


L. Spiro

Share this post


Link to post
Share on other sites

pixels is not contiguous in memory; you have it as an array of pointers to rows.
Make it a single contiguous allocation.


L. Spiro

Thanks I made it like this : BYTE *pixels = new BYTE(height*width);

And do you think my stride calculation is correct?

Share this post


Link to post
Share on other sites

I changed the code to use this formula for stride: stride = ((((biWidth * biBitCount) + 31) & ~31) >> 3) from msdn

I'm not sure about biBitCount. Is it 32/8 = 4 if the bpp is 32?

Edited by ngub05

Share this post


Link to post
Share on other sites
If the bits-per-pixel (BPP) is 32 then biBitCount is 32.
Your new calculation for stride is correct.

BYTE *pixels = new BYTE(height*width); is not correct. It should be BYTE *pixels = new BYTE(height*stride);.


L. Spiro

Share this post


Link to post
Share on other sites

You're not supposed to fill out D3D12_SUBRESOURCE_FOOTPRINT and D3D12_PLACED_SUBRESOURCE_FOOTPRINT. You need to fill out your D3D12_RESOURCE_DESC for the 2D texture that you want to create, and then pass that to ID3D12Device::GetCopyableFootprints in order to get the array of footprints for each subresource. You can then use the footprints to fill in an UPLOAD buffer, and then use CopyTextureRegion to copy the subresources from your upload buffer to the actual 2D texture resource in a DEFAULT heap.

You may want to look at the HelloTexture sample on GitHub to use as a reference.

 

Thanks a lot pointing out that smile.png BTW your D3D11 book is awesome. Any plans on making one for D3D12? It's quite challenging to learn D3D12 only from msdn pages..

Edited by ngub05

Share this post


Link to post
Share on other sites

Hi MJP,

 

Minor clarification here:


You're not supposed to fill out D3D12_SUBRESOURCE_FOOTPRINT and D3D12_PLACED_SUBRESOURCE_FOOTPRINT

 

Apps can fill out these footprint structures themselves, but they must follow the documented alignment restrictions. The samples use GetCopyableFootprints, because its conciseness avoids distracting from the sample's true intention. Apps should take care to avoid GetCopyableFootprints from becoming a bottleneck. Once the restrictions are understood, applications can simplify the logic to fill out these structures. As an example, planar complications could be avoided, and the structure data could even be baked to disk.

 

-Brian Klamik

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement