1
\$\begingroup\$

Hi^^ i am trying to read data in resource, which i used to do well without any problems. but suddenly it is not working.

  1. first i made immutable resource that has data in it, which is XMFLOAT4(1,1,1,1) here.
  2. next i made staging resource for reading.
  3. lastly, i called map/unmap to read and store data into outputArr.
//(all HRESULT checked already)
    int WIDTH = 10, HEIGHT = 2;

    ID3D11Texture2D* resource; // create texture------------------------------
    D3D11_TEXTURE2D_DESC texDesc;
    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    texDesc.Usage = D3D11_USAGE_IMMUTABLE;
    texDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    texDesc.Width = WIDTH;
    texDesc.Height = HEIGHT;
    texDesc.CPUAccessFlags = 0;
    texDesc.ArraySize = 1;
    texDesc.MipLevels = 1;
    texDesc.SampleDesc.Count = 1;
    texDesc.SampleDesc.Quality = 0;
    texDesc.MiscFlags = 0;

    XMFLOAT4* initValues = new XMFLOAT4[WIDTH * HEIGHT];
    for (int i = 0; i < WIDTH * HEIGHT; ++i) {
        initValues[i] = XMFLOAT4(1,1,1,1);
    }
    D3D11_SUBRESOURCE_DATA data;
    data.pSysMem = initValues;
    data.SysMemPitch = sizeof(XMFLOAT4)*WIDTH;
    data.SysMemSlicePitch = 0;
    device->CreateTexture2D(
        &texDesc,
        &data,
        &resource);

    ID3D11Texture2D* staging; // create texture for reading --------------------
    D3D11_TEXTURE2D_DESC stgDesc;
    stgDesc.BindFlags = 0;
    stgDesc.Usage = D3D11_USAGE_STAGING;
    stgDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    stgDesc.Width = WIDTH;
    stgDesc.Height = HEIGHT;
    stgDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    stgDesc.ArraySize = 1;
    stgDesc.MipLevels = 1;
    stgDesc.SampleDesc.Count = 1;
    stgDesc.SampleDesc.Quality = 0;
    stgDesc.MiscFlags = 0;
    device->CreateTexture2D(
        &stgDesc,
        nullptr,
        &staging);

    XMFLOAT4* outputArr = new XMFLOAT4[WIDTH*HEIGHT]; // READ-------------------
    dContext->CopyResource(staging, resource);
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));
    dContext->Map(staging, 0, D3D11_MAP_READ, 0, &mappedResource);

    outputArr = reinterpret_cast<XMFLOAT4*>(mappedResource.pData);
    std::vector<XMFLOAT4> testV;
    for (int y = 0; y < HEIGHT; ++y)
    {
        for (int x = 0; x < WIDTH; ++x)
        {
            int idx = y * WIDTH + x;

            testV.push_back(outputArr[idx]);
        }
    }

    dContext->Unmap(staging, 0);

and it turns out, only when WIDTH is multiple of 16(HEIGHT doesn't seem to be matter here), it copies the data well into ALL element of array, otherwise it fill out just 0 into array until next 16 element.

For example, if width/height is 10/2, first 10 elements of outputArr will have proper data and next 6 elements have just 0, and next another 10 elements with data, and 6 elements with 0, so on.

i haven't had any problem on dealing with resources. and struggle still. just my humble assumption is that there might be specific alignment in number of width of resource that i miss. Or silly mistake in my process.

Hope anyone can find something from this question. thanks

\$\endgroup\$
  • \$\begingroup\$ You need to check all functions that return HRESULT with the SUCCEEDED or FAILED macros. Map returns an HRESULT. You should also have the Direct3D Debug Layer enabled which will give you additional information. \$\endgroup\$ – Chuck Walbourn Aug 29 at 18:48
  • \$\begingroup\$ Oops thanks. i forgot that i should mention that i checked it already. just removed that to make easier to read my code. i put the comment in first line of code now;) \$\endgroup\$ – KIM CHANGJUN Aug 29 at 18:53
1
\$\begingroup\$

i have found the solution. it looks even so pretty.

testV.push_back(outputArr[idx]) should have been edited like

testV.push_back(((XMFLOAT4*)((char*)mappedResource.pData + (y* mappedResource.RowPitch) + (x*sizeof(XMFLOAT4))))->y)

i thought at first time that when i make a 2dTexture(xmfloat4) with WIDTH * HEIGHT, its size will be 16*WIDTH*HEIGHT. But it was wrong !!!. it has some automatic padding in it. so the actual size would be (16*WIDTH + padding)*HEIGHT. i have no idea why, just guessing because a texture can cover a lot of different type, so it makes different padding for types automatically??? maybe

if anyone know why, plz let me know.

thanks

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.