Почему Map() не работает с текстурой по умолчанию, несмотря на UnifiedMemoryArchitecture и MapOnDefaultTextures

Документы предполагает, что текстуры использования по умолчанию могут быть сопоставлены с архитектурами UMA, такими как интегрированная графика Intel с Direct3D 11.3.

Я пытался добиться этого, но Map() всегда терпит неудачу с E_INVALIDARG.

Я новичок в C++ и DirectX, но ниже приведен минимальный тестовый пример. Пожалуйста, не стесняйтесь указывать на любую глупость, которую я совершаю.

Я запускаю это на ноутбуке с Windows 10 1809, Intel Skylake i5-6300U с HD Graphics 520.

#include "pch.h"
#include <iostream>
#include <dxgi1_6.h>
#include <d3d.h>
#include <d3d11_4.h>
#include <assert.h>

int main()
{
    HRESULT res = S_OK;
    ID3D11Device *Dev = nullptr;
    ID3D11DeviceContext *Ctx = nullptr;
    D3D_FEATURE_LEVEL Fl;
    D3D_FEATURE_LEVEL fls[1] = { D3D_FEATURE_LEVEL_11_1 };

    res = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_BGRA_SUPPORT, fls, 1, D3D11_SDK_VERSION, &Dev, &Fl, &Ctx);
    assert(res == S_OK);
    assert(Fl == D3D_FEATURE_LEVEL_11_1);

    ID3D11Device5 *Dev5 = nullptr;
    res = Dev->QueryInterface<ID3D11Device5>(&Dev5);
    assert(res == S_OK);
    Dev->Release();
    Dev = nullptr;

    ID3D11DeviceContext4 *Ctx4;
    res = Ctx->QueryInterface<ID3D11DeviceContext4>(&Ctx4);
    assert(res == S_OK);
    Ctx->Release();
    Ctx = nullptr;

    D3D11_FEATURE_DATA_D3D11_OPTIONS2 opts2;
    res = Dev5->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &opts2, sizeof(opts2));
    assert(res == S_OK);
    assert(opts2.MapOnDefaultTextures);
    assert(opts2.UnifiedMemoryArchitecture);

    D3D11_TEXTURE2D_DESC1 texDesc = { 0 };
    texDesc.ArraySize = 1;
    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
    texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
    texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    texDesc.Height = 256;
    texDesc.Width = 256;
    texDesc.MipLevels = 1;
    texDesc.MiscFlags = 0;
    texDesc.SampleDesc.Count = 1;
    texDesc.SampleDesc.Quality = 0;
    texDesc.TextureLayout = D3D11_TEXTURE_LAYOUT_UNDEFINED;
    texDesc.Usage = D3D11_USAGE_DEFAULT;

    byte mem[256 * 256 * 4];
    ZeroMemory(mem, 256 * 256 * 4);

    D3D11_SUBRESOURCE_DATA data = { 0 };
    data.pSysMem = mem;
    data.SysMemPitch = 256 * 4;

    ID3D11Texture2D1 *tex2d;
    res = Dev5->CreateTexture2D1(&texDesc, &data, &tex2d);
    assert(res == S_OK);

    D3D11_MAPPED_SUBRESOURCE map = { 0 };
    // I believe at least one of these should succeed, but all fail
    res = Ctx4->Map(tex2d, 0, D3D11_MAP_READ, 0, &map);
    //res = Ctx4->Map(tex2d, 0, D3D11_MAP_WRITE, 0, &map);
    //res = Ctx4->Map(tex2d, 0, D3D11_MAP_READ_WRITE, 0, &map);
    assert(res == S_OK); // E_INVALIDARG
}

Я считаю, что вызов Map() должен завершиться успешно, но он не работает с E_INVALIDARG.

Обновлено: Я пробовал D3D11_TEXTURE_LAYOUT_ROW_MAJOR и D3D11_TEXTURE_LAYOUT_64K_STANDARD_SWIZZLE тоже, но потом CreateTexture2D1() не работает с E_INVALIDARG. Может мое железо не поддерживает эти режимы?

Включите уровень отладки Direct3D, и вы, скорее всего, получите больше информации в окне вывода отладки. См. этот пост в блоге. Тем не менее, общий ответ здесь: «Сопоставьте промежуточную текстуру, скопируйте ее в текстуру по умолчанию». В противном случае используйте USAGE_DYNAMIC.

Chuck Walbourn 26.07.2019 23:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
150
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что проблема описана в документация:

It is illegal to set CPU access flags on default textures without also setting TextureLayout to a value other than D3D11_TEXTURE_LAYOUT_UNDEFINED.

Спасибо. Я этого не видел. К сожалению, если я укажу один из двух других вариантов, на этот раз CreateTexture2D1() произойдет сбой с E_INVALIDARG.

cgi 26.07.2019 13:10

@cgi В случае D3D11_TEXTURE_LAYOUT_ROW_MAJOR использование ненулевых флагов привязки является незаконным, в случае D3D11_TEXTURE_LAYOUT_64K_STANDARD_SWIZZLE вы должны проверить, поддерживается ли это графическим драйвером, запросив D3D11_FEATURE_DATA_D3D11_OPTIONS2

user7860670 26.07.2019 17:27

Я думал, что смогу сохранить операцию копирования при стриминге кадров на видеокарту, но теперь, кажется, то, что я хотел сделать, не может быть сделано, а то, что можно было сделать, вроде бы не помогло...

cgi 29.07.2019 02:26

Другие вопросы по теме