123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- /******************************************************************************
- Copyright (C) 2013 by Hugh Bailey <[email protected]>
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- ******************************************************************************/
- #include "util/base.h"
- #include "GS_D3D11SubSystem.hpp"
- static inline bool IsPow2(uint32_t num)
- {
- return num >= 2 && (num & (num-1)) == 0;
- }
- void gs_texture_2d::InitSRD(D3D11_SUBRESOURCE_DATA *srd, void *data)
- {
- uint32_t rowSizeBytes = width * GetFormatBPP(format);
- uint32_t texSizeBytes = rowSizeBytes * height;
- if (type == GS_TEXTURE_2D) {
- srd->pSysMem = (uint8_t*)data;
- srd->SysMemPitch = rowSizeBytes;
- srd->SysMemSlicePitch = texSizeBytes;
- } else { /* GS_TEXTURE_CUBE */
- void **buffers = (void**)data;
- for (size_t i = 0; i < 6; i++) {
- srd[i].pSysMem = buffers[i];
- srd[i].SysMemPitch = rowSizeBytes;
- srd[i].SysMemSlicePitch = texSizeBytes;
- }
- }
- }
- void gs_texture_2d::InitTexture(void *data)
- {
- D3D11_TEXTURE2D_DESC td;
- D3D11_SUBRESOURCE_DATA srd[6];
- HRESULT hr;
- memset(&td, 0, sizeof(td));
- td.Width = width;
- td.Height = height;
- td.MipLevels = genMipmaps ? 0 : 1;
- td.ArraySize = type == GS_TEXTURE_CUBE ? 6 : 1;
- td.Format = dxgiFormat;
- td.BindFlags = D3D10_BIND_SHADER_RESOURCE;
- td.SampleDesc.Count = 1;
- td.CPUAccessFlags = isDynamic ? D3D11_CPU_ACCESS_WRITE : 0;
- td.Usage = isDynamic ? D3D11_USAGE_DYNAMIC :
- D3D11_USAGE_DEFAULT;
- if (type == GS_TEXTURE_CUBE)
- td.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
- if (isRenderTarget || isGDICompatible)
- td.BindFlags |= D3D10_BIND_RENDER_TARGET;
- if (data)
- InitSRD(srd, data);
- hr = device->device->CreateTexture2D(&td, data ? srd : NULL,
- texture.Assign());
- if (FAILED(hr))
- throw HRError("Failed to create 2D texture", hr);
- }
- void gs_texture_2d::InitResourceView()
- {
- D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesc;
- HRESULT hr;
- memset(&resourceDesc, 0, sizeof(resourceDesc));
- resourceDesc.Format = dxgiFormat;
- if (type == GS_TEXTURE_CUBE) {
- resourceDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURECUBE;
- resourceDesc.TextureCube.MipLevels = genMipmaps ? -1 : 1;
- } else {
- resourceDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
- resourceDesc.Texture2D.MipLevels = genMipmaps ? -1 : 1;
- }
- hr = device->device->CreateShaderResourceView(texture, &resourceDesc,
- shaderRes.Assign());
- if (FAILED(hr))
- throw HRError("Failed to create resource view", hr);
- }
- void gs_texture_2d::InitRenderTargets()
- {
- HRESULT hr;
- if (type == GS_TEXTURE_2D) {
- hr = device->device->CreateRenderTargetView(texture, NULL,
- renderTarget[0].Assign());
- if (FAILED(hr))
- throw HRError("Failed to create render target view",
- hr);
- } else {
- D3D11_RENDER_TARGET_VIEW_DESC rtv;
- rtv.Format = dxgiFormat;
- rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtv.Texture2DArray.MipSlice = 0;
- rtv.Texture2DArray.ArraySize = 1;
- for (UINT i = 0; i < 6; i++) {
- rtv.Texture2DArray.FirstArraySlice = i;
- hr = device->device->CreateRenderTargetView(texture,
- &rtv, renderTarget[i].Assign());
- if (FAILED(hr))
- throw HRError("Failed to create cube render "
- "target view", hr);
- }
- }
- }
- gs_texture_2d::gs_texture_2d(device_t device, uint32_t width, uint32_t height,
- gs_color_format colorFormat, void *data, uint32_t flags,
- bool isCubeMap, bool gdiCompatible, bool shared)
- : gs_texture (device, isCubeMap ? GS_TEXTURE_CUBE : GS_TEXTURE_2D),
- width (width),
- height (height),
- format (colorFormat),
- dxgiFormat (ConvertGSTextureFormat(format)),
- isGDICompatible (gdiCompatible),
- isShared (shared),
- isDynamic ((flags & GS_DYNAMIC) != 0),
- isRenderTarget ((flags & GS_RENDERTARGET) != 0),
- genMipmaps ((flags & GS_BUILDMIPMAPS) != 0)
- {
- if (genMipmaps && (!IsPow2(width) || !IsPow2(height))) {
- blog(LOG_WARNING, "Cannot generate mipmaps for a "
- "non-power-of-two texture. Disabling "
- "mipmaps for this texture.");
- genMipmaps = false;
- }
- InitTexture(data);
- InitResourceView();
- if (isRenderTarget)
- InitRenderTargets();
- }
|