Копирование буфера глубины с неблокируемым форматом (D24S8) в системную память с Direct3D9, Win 8.1

РЕДАКТИРОВАТЬ: Как указывает ozeanix в комментариях, невозможно скопировать поверхность D24S8 в системную память. К сожалению, вы также не можете привязать поверхность (или, скорее, содержащую ее текстуру) к пиксельному шейдеру.

В итоге я пошел по пути повторной реализации, перехватывая все вызовы D3D9. Если видеокарта поддерживает это — все карты с DX10 + должны делать — иногда возможно обменять формат D24S8 с FOURCC INTZ, который имеет ту же схему памяти, но может быть связан с образцом текстуры пиксельного шейдера и, таким образом, скопирован в другой текстура в видеопамяти. Содержимое этой текстуры затем можно скопировать в текстуру системной памяти с помощью GetRenderTargetData.


Исходное сообщение:

Я разрабатываю плагин, который должен вычислять мировое положение каждого пикселя, содержащегося в поверхности Direct3D. Плагин вызывается с помощью обратного вызова, когда в заднем буфере находится вновь отрендеренное изображение.

Даны два указателя (IDirect3DSurface9 *) на целевую поверхность рендеринга (D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE) и буферную поверхность глубины (D3DFMT_D24S8, D3DMULTISAMPLE_NONMASKABLE). Режим отображения связанного устройства также установлен на «D3DFMT_X8R8G8B8»

Указанные выше настройки не могут быть изменены!

Чтобы иметь возможность рассчитать мировую позицию, мне также нужен доступ к значениям буфера глубины.
Поэтому моей первой попыткой было создать в системной памяти неэкранную плоскую поверхность с форматом «D24S8», использовать «GetRenderTargetData», чтобы скопировать данные, а затем заблокировать эту неэкранную поверхность (с помощью LockRect).
К сожалению, самая первая команда уже потерпела неудачу — очевидно, этот формат не разрешен в системной памяти (нет проблем с созданием такой неэкранной поверхности в пуле по умолчанию). Так что я использовал DirectX Caps Viewer

D3D Device Type "HAL" and Adapter Format "D3DFMT_X8R8G8B8":

Depth/Stencil Formats:
"D3DFMT_D24S8", "D3DFMT_D24X8", "D3DFMT_D16", "D3DFMT_D32F_LOCKABLE"
Texture Formats (only mentioning the depth/stencil & depth formats):
"D3DFMT_D24S8", "D3DFMT_D24X8", "D3DFMT_D16", "D3DFMT_D32F_LOCKABLE",
"DXT1" through "DXT5"- but all are only supported in conjunction with usage type "0 (Plain)".

Plain Surface Formats: No depth stencil formats at all are listed.

Что я тоже пробовал:

  1. Создайте текстуру только с одним уровнем и форматом D3DFMT_D24S8, помещенным в D3DPOOL_SYSTEMMEM (также не удалось)

  2. Создайте поверхность типа D32F_LOCKABLE в D3DPOOL_DEFAULT (успешно) и используйте D3DXLoadSurfaceFromSurface для преобразования и копирования данных, чтобы последующий вызов LockRect предоставил дескриптор данных (не удалось)

  3. Создайте поверхность глубины / трафарета с отключенным мультисэмплированием (успешно) и используйте StretchRect для копирования из источника в место назначения (не удалось) и проверьте, является ли мультисэмплинг частью проблемы

Мои вопросы

  1. Согласно DirectX Caps Viewer D24S8 должен поддерживаться на текстурах. Эти списки применимы только для ресурсов в пуле памяти по умолчанию?

  2. Можно ли вообще как-то скопировать значения глубины в системную память?

  3. Есть ли возможность включить расширенные отчеты об ошибках для вызовов DirectX в Windows 8.1? Я знаю, что начиная с Win8.1, сама ОС использует тот же API, и поэтому среда выполнения DirectX не может быть переведена в режим отладки, но, возможно, я пропустил соответствующую опцию


Кстати, с D3DDevice Type «REF» есть несколько форматов глубины и трафарета, перечисленных для простых поверхностей (D16_LOCKABLE, D16, D32F_LOCKABLE, D32_LOCKABLE, S8_LOCKABLE) и нет записей глубины / трафарета, доступных в списке форматов текстур, но мне нужно использовать аппаратное ускорение, иначе мое приложение будет работать слишком медленно.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector