Форум программистов, компьютерный форум, киберфорум
DirectX
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
11 / 11 / 1
Регистрация: 31.03.2012
Сообщений: 29
1

DirectX 11. Прямой доступ к заднему буферу

18.06.2015, 16:20. Показов 1731. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Как организовать доступ к заднему буферу через указатель, более эффективно, чем:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ID3D11Device        *d3dDevice;
ID3D11DeviceContext *d3dDeviceContext;
IDXGISwapChain      *dxgiSwapChain;
 
void Graphics::SetDot(int x, int y, unsigned long color)
{
    ID3D11Texture2D *backBuffer = NULL;
    ID3D11Texture2D *tex = NULL;
    D3D11_TEXTURE2D_DESC texD;
    D3D11_MAPPED_SUBRESOURCE mappedResource;
 
    dxgiSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer);
    backBuffer->GetDesc(&texD);
 
    texDesc.BindFlags = 0;
    texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    texDesc.Usage = D3D11_USAGE_STAGING;
 
    d3dDevice->CreateTexture2D(&texDesc, NULL, &tex);
 
    d3dDeviceContext->CopyResource(tex, backBuffer);
    d3dDeviceContext->Map(tex, 0, D3D11_MAP_WRITE, 0, &mappedResource);
 
    ((unsigned long*)mappedResource.pData)[x + (mappedResource.RowPitch >> 2) * y] = color;
 
    d3dDeviceContext->Unmap(tex, 0);
    d3dDeviceContext->CopyResource(backBuffer, tex);
 
    tex->Release();
    backBuffer->Release();
}

т.к. будет большое проседание производительности уже при десятке повторений. В свою очередь на DirectX 9, было куда проще и производительнее:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
IDirect3DDevice9 *d3dDevice;
 
void Graphics::SetDot(int x, int y, int r, int g, int b)
{
    IDirect3DSurface9 *backBuffer = NULL;
    D3DLOCKED_RECT lockedRect;
 
    d3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
 
    backBuffer->LockRect(&lockedRect, NULL, NULL);
 
    ((D3DCOLOR*)lockedRect.pBits)[x + (lockedRect.Pitch >> 2) * y] = D3DCOLOR_XRGB(r, g, b);
 
    backBuffer->UnlockRect();
 
    backBuffer->Release();
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.06.2015, 16:20
Ответы с готовыми решениями:

Доступ к буферу по номеру
Всем привет! В шейдере есть два буфера: layout(binding = 1, std430) buffer firstBuf { ...

Доступ к видео буферу консольного приложения
Как считать из консольной программы её видео буфер (если в CRT буфера нет, то тогда напрямую из...

Доступ к буферу обмена ("выделенным блокам") в Office 2010
Поместил в буфер обмена несколько "выделенных блоков". Нужно достать не последний из блоков, а,...

Прерывание по заднему фронту
Всем привет,есть код который считывает данные с клавиатуры и выводит ее на динамический...

6
Эксперт С++
3574 / 2828 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 22
18.06.2015, 22:03 2
Цитата Сообщение от negest Посмотреть сообщение
Как организовать доступ к заднему буферу через указатель, более эффективно
сократить код вряд ли можно, пробуйте умные указатели
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <wrl\client.h>
 
using namespace Microsoft::WRL;
 
ComPtr<ID3D11Device> d3dDevice = nullptr;
ComPtr<ID3D11DeviceContext> d3dDeviceContext = nullptr;
ComPtr<ID3D11RenderTargetView> renderTargetView = nullptr;
ComPtr<IDXGISwapChain> dxgiSwapChain = nullptr;
ComPtr<IDXGIFactory> factory = nullptr;
 
void Graphics::SetDot(int x, int y, unsigned long color)
{
    DXGI_SWAP_CHAIN_DESC desc = { 0 };
 
    CreateDXGIFactory(IID_PPV_ARGS(&factory));
    factory->CreateSwapChain(d3dDevice.Get(), &desc, &dxgiSwapChain);
 
    ComPtr<ID3D11Texture2D> backBuffer = nullptr;
    dxgiSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer));
    d3dDevice->CreateRenderTargetView(backBuffer.Get(), nullptr, &renderTargetView);
    backBuffer.ReleaseAndGetAddressOf();
}
Цитата Сообщение от negest Посмотреть сообщение
В свою очередь на DirectX 9, было куда проще и производительнее
10 полностью переработанная и построенная с нуля версия API, которая является прородителем 11 (ну точнее 11 основана на 10.1, т.к. именно в ней появились аппаратные уровни в функции инициализации). Так что сравнивать что там было в 9 неуместно.
0
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
18.06.2015, 22:05 3
Задний буфер находится в видеоадаптере. Можно сделать только MAP

Смотря, что хотите делать с задним буфером. Может в шейдере можно сделать то что нужно вам ?
0
11 / 11 / 1
Регистрация: 31.03.2012
Сообщений: 29
19.06.2015, 01:06  [ТС] 4
Цитата Сообщение от _lunar_ Посмотреть сообщение
пробуйте умные указатели
Спасибо за предложение, но мне привычнее самому все контролировать.
Цитата Сообщение от _lunar_ Посмотреть сообщение
сравнивать что там было в 9 неуместно
Это не для сравнения, а опорная точка для реализации на 11-ом. Извиняюсь, если ввел в заблуждение.
Цитата Сообщение от Kabak Посмотреть сообщение
Может в шейдере можно сделать
Возможно, но меня интересовал именно данный случай, вывод цветной точки на экран.

Пришла мысль для увеличения производительность разделить мое "чудо" на три части:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
ID3D11Device        *d3dDevice;
ID3D11DeviceContext *d3dDeviceContext;
IDXGISwapChain      *dxgiSwapChain;
 
ID3D11Texture2D          *backBuffer;
ID3D11Texture2D          *tempBuffer;
D3D11_MAPPED_SUBRESOURCE  d3dMappedSubresource;
 
void GraphicsDevice::MapBegin()
{
    D3D11_TEXTURE2D_DESC texDesc;
    
    dxgiSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer);
    backBuffer->GetDesc(&texDesc);
 
    texDesc.BindFlags = 0;
    texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE;
    texDesc.Usage = D3D11_USAGE::D3D11_USAGE_STAGING;
 
    d3dDevice->CreateTexture2D(&texDesc, NULL, &tempBuffer);
 
    d3dDeviceContext->CopyResource(tempBuffer, backBuffer);
    HRESULT hr = d3dDeviceContext->Map(tempBuffer, 0, D3D11_MAP::D3D11_MAP_WRITE, 0, &d3dMappedSubresource);
}
 
void GraphicsDevice::MapEnd()
{
    d3dDeviceContext->Unmap(tempBuffer, 0);
    d3dDeviceContext->CopyResource(backBuffer, tempBuffer);
    
    tempBuffer->Release();
    backBuffer->Release();
}
 
void GraphicsDevice::SetDot(int x, int y, unsigned long color)
{
    ((unsigned long*)d3dMappedSubresource.pData)[x + (d3dMappedSubresource.RowPitch >> 2) * y] = color;
}

теперь, при вызове SetDot между парой MapBegin-MapEnd 100k раз, дает производительно больше чем у 9-го, при том же количестве вызовов.
1
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
19.06.2015, 10:52 5
А в чём принципиальная разница, и почему выросла производительность кода ?

Вам всё равно придётся вызывать все три функции чтобы обновлять задний буфер в реальном времени.

Или я чего-то не понимаю ?
0
11 / 11 / 1
Регистрация: 31.03.2012
Сообщений: 29
19.06.2015, 11:02  [ТС] 6
Разница в том, что при отображении 1000 точек, в первом коде Map-Unmap выполняется 1000 раз за кадр, т.е. при каждом вызове SetDot (отсюда и падение производительности), во втором SetDot вызывается 1000 раз за кадр между Map и Unmap, выполняемые 1 раз за кадр.
0
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
19.06.2015, 11:18 7
Я просто не подумал, что в предыдущем коде вы вызываете эту функцию многократно для множества точек.

Очевидное преимущество, но MAP медленнее шейдера в десятки/сотни раз.
0
19.06.2015, 11:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.06.2015, 11:18
Помогаю со студенческими работами здесь

Прямой доступ к памяти
Подскажите как сделать чтобы функция ChangeId меняла член структуры, я рассматриваю что после...

Прямой доступ к переменным
Доброго времени суток, форумчане. Сразу оговорю, что название темы может не совсем корректно...

Прямой доступ к видеопамяти
Требуется написать программу, которая будет напрямую обращаться в видеопамяти. Описание: ...

Прямой доступ к битмапу
К сожалению, в моей предыдущей теме какие-то конкретные советы по моей проблеме дать никто не смог,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru