DirectX 11 ID3DDevice :: CreateTexture2D с исходной ошибкой данных - PullRequest
0 голосов
/ 01 декабря 2018

до тех пор, пока я следую учебному пособию, что CreateTexture2D() с начальными данными NULL, а затем с помощью UpdateSubresource() для загрузки данных, все работает нормально.Но UpdateSubResource() - это контекстная функция устройства, поэтому я пытаюсь использовать CreateTexture2D() с начальными данными за один раз, но это не получается.

Код ниже показывает оригинал, который работает нормально.

tex_desc.Height = h;
tex_desc.Width = w;
tex_desc.MipLevels = 0;
tex_desc.ArraySize = 1;
tex_desc.Format= DXGI_FORMAT_R8G8B8A8_UNORM;
tex_desc.SampleDesc.Count = 1;
tex_desc.SampleDesc.Quality = 0;
tex_desc.Usage= D3D11_USAGE_DEFAULT;
tex_desc.BindFlags= D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET;
tex_desc.CPUAccessFlags= 0;
tex_desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

row_pitch = (w * 4) * sizeof(unsigned char);
hres = _dv->CreateTexture2D(&tex_desc, NULL, &m_tex);
HR_FAIL(hres,  "create 2D texture");

_dc->UpdateSubresource(m_tex, 0, NULL, data, row_pitch, 0);

затем я изменяю его на

tex_desc.Height = h;
tex_desc.Width = w;
tex_desc.MipLevels = 0;
tex_desc.ArraySize = 1;
tex_desc.Format= DXGI_FORMAT_R8G8B8A8_UNORM;
tex_desc.SampleDesc.Count = 1;
tex_desc.SampleDesc.Quality = 0;
tex_desc.Usage= D3D11_USAGE_DEFAULT;
tex_desc.BindFlags= D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET;
tex_desc.CPUAccessFlags= 0;
tex_desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

row_pitch = (w * 4) * sizeof(unsigned char);

D3D11_SUBRESOURCE_DATA sdata;            // <<===changed
sdata.pSysMem = data;                  // <<===changed
sdata.SysMemPitch = row_pitch;                 // <<===changed
sdata.SysMemSlicePitch = (w*h*4)*sizeof(unsigned char);       // <<===changed
hres = _dv->CreateTexture2D(&tex_desc, &sdata, &m_tex);       // <<===changed
HR_FAIL(hres, "testing create texture 2d");

, затем он генерирует ошибку

testing create texture 2d fail
E_INVALIDARG : An invalid parameter was passed to the returning function.

он говорит, что какой-то параметр недопустим, но я не понимаю, почему переданный мною аргумент недействителен


ОБНОВЛЕНИЕ:
, поэтому я пытаюсь перейти по ссылкам для настройки устройства отладки для DirectX.Вот что я получил:

D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[4].SysMemPitch cannot be 0 [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]
D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[6].pSysMem cannot be NULL. [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]
D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[7].pSysMem cannot be NULL. [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]
D3D11 ERROR: ID3D11Device::CreateTexture2D: Returning E_INVALIDARG, meaning invalid parameters were passed. [ STATE_CREATION ERROR #104: CREATETEXTURE2D_INVALIDARG_RETURN]
Exception thrown at 0x750BC54F in directx11_test.exe: Microsoft C++ exception: _com_error at memory location 0x002BF3D0.
D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[2].pSysMem cannot be NULL. [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]
D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[4].SysMemPitch cannot be 0 [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]
D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[6].pSysMem cannot be NULL. [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]
D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[7].pSysMem cannot be NULL. [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]
D3D11 ERROR: ID3D11Device::CreateTexture2D: Returning E_INVALIDARG, meaning invalid parameters were passed. [ STATE_CREATION ERROR #104: CREATETEXTURE2D_INVALIDARG_RETURN]

, поэтому он сказал, что функция Create пытается получить доступ к InitialData как массиву, в то время как у меня есть только один элемент в качестве аргумента передачи.Стоит заметить, что я получаю только выходные данные отладки в конфигурации выпуска (я вручную определяю _DEBUG в коде).В конфигурации отладки я получаю триггер исключения прав доступа, поэтому я не получаю сообщение отладки D3D.

поэтому я могу обойти это, получив массив подресурсов, достаточно большой, чтобы хранить все виды уровней mipmap для предотвращения нарушения доступа.

D3D11_SUBRESOURCE_DATA sdata[20];
    int idx = 0;
    while (row_pitch > 0)
    {

        sdata[idx].pSysMem = data;
        sdata[idx].SysMemPitch = row_pitch;
        row_pitch >>= 1;
        idx++;
    }

    hres = _dv->CreateTexture2D(&tex_desc, sdata, &m_tex);
    HR_FAIL(hres, "testing create texture 2d");

но я думаю, что это неразумнотак как мне все еще нужно сгенерировать mipmap и эта функция находится в контексте устройства

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Я полагаю, что причина его неудачи в том, что вы запросили автоматические мип-карты (D3D11_RESOURCE_MISC_GENERATE_MIPS), которые вы не можете использовать для настройки исходных данных.Вместо этого вы должны загрузить верхний уровень через контекст устройства.

Для полной реализации мипмапов auto-gen, а также для использования initData для других сценариев см. WICTextureLoader в DirectX Tool Kit

Если бы вы использовали отладочное устройство Direct3D, оно предоставило бы намного больше деталей в окне вывода при возврате E_INVALIDARG.

0 голосов
/ 01 декабря 2018

Думаю, проблема в том, что вы присваиваете ненулевое значение полю D3D11_SUBRESOURCE_DATA::SysMemSlicePitch, которое имеет значение только для 3d-текстур и должно быть установлено равным 0 для других типов текстур.В первом примере вы правильно передаете 0 как значение аналогичного параметра при вызове UpdateSubresource.

...