[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / guilib / TextureDX.cpp
blob10ffcc65fc94167afafc4c2ed710bc79bdf7263f
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "TextureDX.h"
11 #include "utils/MemUtils.h"
12 #include "utils/log.h"
14 #include <memory>
16 std::unique_ptr<CTexture> CTexture::CreateTexture(unsigned int width,
17 unsigned int height,
18 XB_FMT format)
20 return std::make_unique<CDXTexture>(width, height, format);
23 CDXTexture::CDXTexture(unsigned int width, unsigned int height, XB_FMT format)
24 : CTexture(width, height, format)
28 CDXTexture::~CDXTexture()
30 DestroyTextureObject();
33 void CDXTexture::CreateTextureObject()
35 m_texture.Create(m_textureWidth, m_textureHeight, 1, D3D11_USAGE_DEFAULT, GetFormat());
38 DXGI_FORMAT CDXTexture::GetFormat()
40 DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; // DXGI_FORMAT_UNKNOWN
42 switch (m_format)
44 case XB_FMT_DXT1:
45 format = DXGI_FORMAT_BC1_UNORM; // D3DFMT_DXT1 -> DXGI_FORMAT_BC1_UNORM & DXGI_FORMAT_BC1_UNORM_SRGB
46 break;
47 case XB_FMT_DXT3:
48 format = DXGI_FORMAT_BC2_UNORM; // D3DFMT_DXT3 -> DXGI_FORMAT_BC2_UNORM & DXGI_FORMAT_BC2_UNORM_SRGB
49 break;
50 case XB_FMT_DXT5:
51 case XB_FMT_DXT5_YCoCg:
52 format = DXGI_FORMAT_BC3_UNORM; // XB_FMT_DXT5 -> DXGI_FORMAT_BC3_UNORM & DXGI_FORMAT_BC3_UNORM_SRGB
53 break;
54 case XB_FMT_RGB8:
55 case XB_FMT_A8R8G8B8:
56 format = DXGI_FORMAT_B8G8R8A8_UNORM; // D3DFMT_A8R8G8B8 -> DXGI_FORMAT_B8G8R8A8_UNORM | DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
57 break;
58 case XB_FMT_A8:
59 format = DXGI_FORMAT_R8_UNORM; // XB_FMT_A8 -> DXGI_FORMAT_A8_UNORM
60 break;
63 return format;
66 void CDXTexture::DestroyTextureObject()
68 m_texture.Release();
71 void CDXTexture::LoadToGPU()
73 if (!m_pixels)
75 // nothing to load - probably same image (no change)
76 return;
79 bool needUpdate = true;
80 D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
81 if (m_format == XB_FMT_RGB8)
82 usage = D3D11_USAGE_DYNAMIC; // fallback to dynamic to allow CPU write to texture
84 if (m_texture.Get() == nullptr)
86 // creates texture with initial data
87 if (m_format != XB_FMT_RGB8)
89 // this is faster way to create texture with initial data instead of create empty and then copy to it
90 m_texture.Create(m_textureWidth, m_textureHeight, IsMipmapped() ? 0 : 1, usage, GetFormat(), m_pixels, GetPitch());
91 if (m_texture.Get() != nullptr)
92 needUpdate = false;
94 else
95 m_texture.Create(m_textureWidth, m_textureHeight, IsMipmapped() ? 0 : 1, usage, GetFormat());
97 if (m_texture.Get() == nullptr)
99 CLog::Log(LOGDEBUG, "CDXTexture::CDXTexture: Error creating new texture for size {} x {}.",
100 m_textureWidth, m_textureHeight);
101 return;
104 else
106 // need to update texture, check usage first
107 D3D11_TEXTURE2D_DESC texDesc;
108 m_texture.GetDesc(&texDesc);
109 usage = texDesc.Usage;
111 // if usage is not dynamic re-create texture with dynamic usage for future updates
112 if (usage != D3D11_USAGE_DYNAMIC && usage != D3D11_USAGE_STAGING)
114 m_texture.Release();
115 usage = D3D11_USAGE_DYNAMIC;
117 m_texture.Create(m_textureWidth, m_textureHeight, IsMipmapped() ? 0 : 1, usage, GetFormat(), m_pixels, GetPitch());
118 if (m_texture.Get() == nullptr)
120 CLog::Log(LOGDEBUG, "CDXTexture::CDXTexture: Error creating new texture for size {} x {}.",
121 m_textureWidth, m_textureHeight);
122 return;
125 needUpdate = false;
129 if (needUpdate)
131 D3D11_MAP mapType = (usage == D3D11_USAGE_STAGING) ? D3D11_MAP_WRITE : D3D11_MAP_WRITE_DISCARD;
132 D3D11_MAPPED_SUBRESOURCE lr;
133 if (m_texture.LockRect(0, &lr, mapType))
135 unsigned char *dst = (unsigned char *)lr.pData;
136 unsigned char *src = m_pixels;
137 unsigned int dstPitch = lr.RowPitch;
138 unsigned int srcPitch = GetPitch();
139 unsigned int minPitch = std::min(srcPitch, dstPitch);
141 unsigned int rows = GetRows();
142 if (m_format == XB_FMT_RGB8)
144 for (unsigned int y = 0; y < rows; y++)
146 unsigned char *dst2 = dst;
147 unsigned char *src2 = src;
148 for (unsigned int x = 0; x < srcPitch / 3; x++, dst2 += 4, src2 += 3)
150 dst2[0] = src2[2];
151 dst2[1] = src2[1];
152 dst2[2] = src2[0];
153 dst2[3] = 0xff;
155 src += srcPitch;
156 dst += dstPitch;
159 else if (srcPitch == dstPitch)
161 memcpy(dst, src, srcPitch * rows);
163 else
165 for (unsigned int y = 0; y < rows; y++)
167 memcpy(dst, src, minPitch);
168 src += srcPitch;
169 dst += dstPitch;
173 else
175 CLog::LogF(LOGERROR, "failed to lock texture.");
177 m_texture.UnlockRect(0);
178 if (usage != D3D11_USAGE_STAGING && IsMipmapped())
179 m_texture.GenerateMipmaps();
182 if (!m_bCacheMemory)
184 KODI::MEMORY::AlignedFree(m_pixels);
185 m_pixels = nullptr;
188 m_loadedToGPU = true;
191 void CDXTexture::BindToUnit(unsigned int unit)