2
\$\begingroup\$

How does one create a Texture2D Array in DirectX11? The texture I am trying to create is not multisampled, and I want only one mip level. I can't find a working example of a Texture2D Array. I have a buffer of 2D images that I want to use as a Texture2DArray in a shader.

The following code snippet works when sTexDesc.ArraySize=1 (as a Texture2D). With sTexDesc.ArraySize=2 the subsequent call to CreateTexture2D crashes with this Access violation inside DirectX:

Unhandled exception at 0x000007fef5d6771a in test.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.

With larger values of ArraySize CreateTexture2D returns E_INVALIDARG. ubImageStorage contains valid data. As a Texture2D I can add multiples of the slice offset to this buffer address when assigning pSysMem and read each slice from a shader. What am I missing? I have tried all combinations of bind and usage flags and various values for MipLevels with no success.

D3D11_TEXTURE2D_DESC sTexDesc;
sTexDesc.Width = 1024;
sTexDesc.Height = 1024;
sTexDesc.MipLevels = 1;
sTexDesc.ArraySize = 2;
sTexDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sTexDesc.SampleDesc.Count = 1;
sTexDesc.SampleDesc.Quality = 0;
sTexDesc.Usage = D3D11_USAGE_IMMUTABLE;
sTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
sTexDesc.CPUAccessFlags = 0;
sTexDesc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA sSubData;
sSubData.pSysMem = ubImageStorage;
sSubData.SysMemPitch = (UINT) (1024 * 4);
sSubData.SysMemSlicePitch = (UINT) (1024 * 1024 * 4);

ID3D11Texture2D* pTexture;

hr = m_pd3dDevice->CreateTexture2D(&sTexDesc,&sSubData,&pTexture);

Here are the relevant pages from MSDN:
ID3D11Device::CreateTexture2D Method
D3D11_TEXTURE2D_DESC Structure

\$\endgroup\$
3
  • 5
    \$\begingroup\$ You may want to put your solution in an answer and accept that, so that the question is marked answered \$\endgroup\$
    – Hasturkun
    Commented Jul 4, 2011 at 11:23
  • \$\begingroup\$ As a new member, I was not able to answer my own question before some time limit (1 day?). \$\endgroup\$
    – matth
    Commented Jul 21, 2011 at 18:16
  • \$\begingroup\$ You can answer the question whenever you like. You just can't accept your answer for 1 day (or so). (I realize this is very old now, but hey, now you know!) \$\endgroup\$
    – anon
    Commented Nov 12, 2019 at 16:16

1 Answer 1

5
\$\begingroup\$

(Note: This is the answer originally provided in the question body by the OP).

Problem solved. I needed to create an array of D3D11_SUBRESOURCE_DATA elements, one for each element in the Texture2DArray. Like this:

D3D11_TEXTURE2D_DESC sTexDesc;
sTexDesc.Width = m_uTextureWidth;
sTexDesc.Height = m_uTextureHeight;
sTexDesc.MipLevels = 1;
sTexDesc.ArraySize = 16;
sTexDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sTexDesc.SampleDesc.Count = 1;
sTexDesc.SampleDesc.Quality = 0;
sTexDesc.Usage = D3D11_USAGE_IMMUTABLE;
sTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
sTexDesc.CPUAccessFlags = 0;
sTexDesc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA *sSubData = new D3D11_SUBRESOURCE_DATA[16];
for(int i=0; i<16; i++) {
    sSubData[i].pSysMem = ubImageStorage;
    sSubData[i].SysMemPitch = (UINT) (1024 * 4);
    sSubData[i].SysMemSlicePitch = (UINT) (1024 * 1024 * 4);
}

ID3D11Texture2D* pTexture;

hr = m_pd3dDevice->CreateTexture2D(&sTexDesc,sSubData,&pTexture);

delete [] sSubData;

Note that I've replaced the variables in the code above with constants, but allocated the D3D11_SUBRESOURCE_DATA array dynamically because its size is unknown at compile time.

Why would you ever have different slices with different pitches? Is that even really supported? That seems really strange.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .