Sign in to follow this  

How to initialize Texture2DArray?

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

Hello.

 

I'm using DirectXTK for texture creation from *.dds. Thought documentation says that DDSTextureLoader supports texture arrays, I couldn't figure out how to create an array. So I'm loading textures with D3DReadFileToBlob() and creating texture from it with CreateDDSTextureFromMemory(). And now interesting part - this code works fine:

CreateDDSTextureFromMemory(device, static_cast<uint8_t*>(textureBlob1->GetBufferPointer()), textureBlob1->GetBufferSize(), texture.ReleaseAndGetAddressOf(), nullptr);

D3D11_TEXTURE2D_DESC texElementDesc;
texture->GetDesc(&texElementDesc);

D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
viewDesc.Format = texElementDesc.Format;
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
viewDesc.Texture2D.MostDetailedMip = 0;
viewDesc.Texture2D.MipLevels = 1;
    
hr = device->CreateShaderResourceView(texture.Get(), &viewDesc, textureView.ReleaseAndGetAddressOf());

But this is only single texture. Let's change it for an array:

CreateDDSTextureFromMemory(device, static_cast<uint8_t*>(textureBlob1->GetBufferPointer()), textureBlob1->GetBufferSize(), texture.ReleaseAndGetAddressOf(), nullptr);

D3D11_TEXTURE2D_DESC texElementDesc;
texture->GetDesc(&texElementDesc);

D3D11_TEXTURE2D_DESC texArrayDesc;
texArrayDesc.Width = texElementDesc.Width;
texArrayDesc.Height = texElementDesc.Height;
texArrayDesc.MipLevels = 1;
texArrayDesc.ArraySize = 1;
texArrayDesc.Format = texElementDesc.Format;
texArrayDesc.SampleDesc.Count = 1;
texArrayDesc.SampleDesc.Quality = 0;
texArrayDesc.Usage = D3D11_USAGE_DEFAULT;
texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texArrayDesc.CPUAccessFlags = 0;
texArrayDesc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA resourceData1{};
resourceData1.pSysMem = static_cast<uint8_t*>(textureBlob1->GetBufferPointer());
resourceData1.SysMemPitch = texElementDesc.Width * sizeof(uint8_t) * 4;
resourceData1.SysMemSlicePitch = texElementDesc.Width * texElementDesc.Height * sizeof(uint8_t) * 4;

ComPtr<ID3D11Texture2D> texArray;
hr = device->CreateTexture2D(&texArrayDesc, &resourceData1, texArray.ReleaseAndGetAddressOf());

D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
viewDesc.Format = texArrayDesc.Format;
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
viewDesc.Texture2DArray.MostDetailedMip = 0;
viewDesc.Texture2DArray.MipLevels = 1;
viewDesc.Texture2DArray.FirstArraySlice = 0;
viewDesc.Texture2DArray.ArraySize = 1;

hr = device->CreateShaderResourceView(texArray.Get(), &viewDesc, &textureView);

And, as you might guess, this doesn't work. Actually this work, but somewhat strange - some textures looks cutted, some become fully transparent. Personally me think that the problem is here:

D3D11_SUBRESOURCE_DATA resourceData1{};
resourceData1.pSysMem = static_cast<uint8_t*>(textureBlob1->GetBufferPointer());
resourceData1.SysMemPitch = texElementDesc.Width * sizeof(uint8_t) * 4;
resourceData1.SysMemSlicePitch = texElementDesc.Width * texElementDesc.Height * sizeof(uint8_t) * 4;

I know there's a way to update texture with context's update sub resource. But I'm interested in initializing texture on creation.

Share this post


Link to post
Share on other sites
You aren’t likely to have any success creating texture arrays when you are hard-coding it not to be an array.

 

 

I specified D3D11_SRV_DIMENSION_TEXTURE2DARRAY view dimension, so ArraySize = 1 is valid I think.

 

ALWAYS read the Remarks section on MSDN

 

 

I read this but it doesn't applies to my case - I don't have mips and my textures are the same size. And actually I'm testing with 1 texture.

Edited by nikitablack

Share this post


Link to post
Share on other sites

I figured it out. I was right, all the magic inside this lines:

D3D11_SUBRESOURCE_DATA resourceData1{};
resourceData1.pSysMem = static_cast<uint8_t*>(textureBlob1->GetBufferPointer());
resourceData1.SysMemPitch = texElementDesc.Width * sizeof(uint8_t) * 4;
resourceData1.SysMemSlicePitch = texElementDesc.Width * texElementDesc.Height * sizeof(uint8_t) * 4;

The blob holds ALL data. For *.dds file it's also information in header. I investigated DirectXTK sources and found that they take the header length into account when assign a data. This is fixed code that works:

ptrdiff_t offset = sizeof(uint32_t) + sizeof(DDS_HEADER);

D3D11_SUBRESOURCE_DATA resourceData1{};
resourceData1.pSysMem = (static_cast<uint8_t*>(textureBlob1->GetBufferPointer()) + offset);
resourceData1.SysMemPitch = texElementDesc.Width * sizeof(uint8_t) * 4;
resourceData1.SysMemSlicePitch = texElementDesc.Width * texElementDesc.Height * sizeof(uint8_t) * 4;

The DDS_HEADER definition can be found in dds.h header in toolkit sources.

Share this post


Link to post
Share on other sites

I specified D3D11_SRV_DIMENSION_TEXTURE2DARRAY view dimension, so ArraySize = 1 is valid I think.

int iAnt[1]; is valid too. An array with a single element isn’t actually an array though, aside from syntax.
 

I figured it out. I was right, all the magic inside this lines:

Since you hard-coded the array size to 1 and only passed a single D3D11_SUBRESOURCE_DATA pointer to ID3D11Device::CreateTexture2D(), I doubt very much that you’ve gotten anything working other than a single texture that you’re calling an “array” just because you managed to slap a “[1]” on it, even though that didn’t actually change anything about the texture being a single image like every other texture you’ve loaded.
You have nothing to celebrate until you can access texture-array indices [0] and [1], etc.

 

 

L. Spiro

Edited by L. Spiro

Share this post


Link to post
Share on other sites

L. Spiro, I can't agree with you, sorry.

 

What makes a resource view to act like texture array is exactly D3D11_SRV_DIMENSION_TEXTURE2DARRAY. And I'm so assured because my hardcoded values (i.e. ArraySize = 1) is a simple snippet for forum only. In my code I have more than 1 texture and texture array behaved bad in all cases despite the size.

 

Btw, your art on devianart is amazing. You're definitely a very talented person ).

Edited by nikitablack

Share this post


Link to post
Share on other sites

This topic is 1050 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.

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