| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- #include "DX11Texture.h"
- #include "Image.h"
- #ifdef WIN32
- # include <d3d11.h>
- #endif
- using namespace Framework;
- DX11Texture::DX11Texture(ID3D11Device* device,
- ID3D11DeviceContext* context,
- Critical& deviceLock,
- TextureDirection dir)
- : Texture(dir),
- txt(0),
- view(0),
- device(device),
- context(context),
- useMips(dir == RAM_TO_GPU),
- deviceLock(deviceLock),
- readAccessTexture(0)
- {}
- DX11Texture::~DX11Texture()
- {
- #ifdef WIN32
- if (txt) txt->Release();
- if (view) view->Release();
- if (readAccessTexture) readAccessTexture->Release();
- #endif
- }
- // Updates the texture. The pixels of the current image are copied into
- // the graphics memory
- bool DX11Texture::updateTextur()
- {
- if (!bild) return 0;
- #ifdef WIN32
- if (!txt || lastGr != bild->getSize())
- {
- if (txt) txt->Release();
- txt = 0;
- D3D11_TEXTURE2D_DESC bufferDesc;
- memset(&bufferDesc, 0, sizeof(D3D11_TEXTURE2D_DESC));
- bufferDesc.ArraySize = 1;
- bufferDesc.Width = bild->getWidth();
- bufferDesc.Height = bild->getHeight();
- bufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
- bufferDesc.BindFlags = (getDirection() == GPU_TO_RAM || useMips
- ? D3D11_BIND_RENDER_TARGET
- : 0)
- | D3D11_BIND_SHADER_RESOURCE;
- bufferDesc.CPUAccessFlags = getDirection() == GPU_TO_RAM || useMips
- ? 0
- : D3D11_CPU_ACCESS_WRITE;
- bufferDesc.SampleDesc.Count = 1;
- bufferDesc.MipLevels = useMips ? 0 : 1;
- bufferDesc.Usage = getDirection() == GPU_TO_RAM || useMips
- ? D3D11_USAGE_DEFAULT
- : D3D11_USAGE_DYNAMIC;
- bufferDesc.MiscFlags = useMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;
- deviceLock.lock();
- HRESULT r = device->CreateTexture2D(&bufferDesc, 0, &txt);
- deviceLock.unlock();
- if (r != S_OK) return 0;
- }
- if (getDirection() == RAM_TO_GPU && (bild->getNeedRender() || changed))
- {
- changed = 0;
- if (useMips)
- {
- deviceLock.lock();
- context->UpdateSubresource(txt,
- 0,
- 0,
- bild->getBuffer(),
- 4 * bild->getWidth(),
- 4 * bild->getWidth() * bild->getHeight());
- deviceLock.unlock();
- }
- else
- {
- D3D11_MAPPED_SUBRESOURCE buffer;
- deviceLock.lock();
- context->Map(
- txt, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &buffer);
- int* bgBuff = bild->getBuffer();
- int tmpBr = 4 * bild->getWidth();
- for (int y = 0, pitch = 0, bry = 0; y < bild->getHeight();
- ++y, pitch += buffer.RowPitch, bry += bild->getWidth())
- {
- memcpy(&((BYTE*)buffer.pData)[pitch],
- (void*)&(bgBuff[bry]),
- tmpBr);
- }
- context->Unmap(txt, 0);
- deviceLock.unlock();
- }
- }
- else if (getDirection() == GPU_TO_RAM)
- {
- if (!readAccessTexture || lastGr != bild->getSize())
- {
- if (readAccessTexture) readAccessTexture->Release();
- readAccessTexture = 0;
- D3D11_TEXTURE2D_DESC tempBufferDesc;
- memset(&tempBufferDesc, 0, sizeof(D3D11_TEXTURE2D_DESC));
- tempBufferDesc.ArraySize = 1;
- tempBufferDesc.Width = bild->getWidth();
- tempBufferDesc.Height = bild->getHeight();
- tempBufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
- tempBufferDesc.BindFlags = 0;
- tempBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- tempBufferDesc.SampleDesc.Count = 1;
- tempBufferDesc.MipLevels = 1;
- tempBufferDesc.Usage = D3D11_USAGE_STAGING;
- deviceLock.lock();
- HRESULT r = device->CreateTexture2D(
- &tempBufferDesc, 0, &readAccessTexture);
- deviceLock.unlock();
- if (r != S_OK) return 0;
- }
- else
- {
- deviceLock.lock();
- context->CopyResource(readAccessTexture, txt);
- deviceLock.unlock();
- D3D11_MAPPED_SUBRESOURCE buffer;
- deviceLock.lock();
- HRESULT r = context->Map(
- readAccessTexture, 0, D3D11_MAP::D3D11_MAP_READ, 0, &buffer);
- deviceLock.unlock();
- if (r != S_OK) return 0;
- int* bgBuff = bild->getBuffer();
- int tmpBr = 4 * bild->getWidth();
- for (int y = 0, pitch = 0, bry = 0; y < bild->getHeight();
- ++y, pitch += buffer.RowPitch, bry += bild->getWidth())
- {
- memcpy((void*)&(bgBuff[bry]),
- &((BYTE*)buffer.pData)[pitch],
- tmpBr);
- }
- for (int i = 0; i < bild->getWidth() * bild->getHeight(); i++)
- {
- if (bgBuff[i]) bgBuff[i] |= 0xFF000000;
- }
- deviceLock.lock();
- context->Unmap(readAccessTexture, 0);
- deviceLock.unlock();
- }
- }
- if (!view || lastGr != bild->getSize())
- {
- if (view) view->Release();
- view = 0;
- D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesk;
- memset(&resourceDesk, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
- resourceDesk.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
- resourceDesk.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
- resourceDesk.Texture2D.MipLevels = useMips ? -1 : 1;
- deviceLock.lock();
- HRESULT r = device->CreateShaderResourceView(txt, &resourceDesk, &view);
- deviceLock.unlock();
- if (r != S_OK) return 0;
- if (context && useMips)
- {
- deviceLock.lock();
- context->GenerateMips(view);
- deviceLock.unlock();
- }
- }
- lastGr = bild->getSize();
- #endif
- return 1;
- }
- // Returns true if updateTextur needs to be called
- bool DX11Texture::needsUpdate() const
- {
- return !view;
- }
- // Returns the used shader resource view
- DX11Texture::operator ID3D11ShaderResourceView*() const
- {
- return view;
- }
- //! Returns the used texture
- DX11Texture::operator ID3D11Texture2D*() const
- {
- return txt;
- }
- //! specifies if a mip map should be generated
- void DX11Texture::setUseMips(bool useMips)
- {
- this->useMips = useMips;
- }
|