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.
11 #include "utils/MemUtils.h"
12 #include "utils/log.h"
16 std::unique_ptr
<CTexture
> CTexture::CreateTexture(unsigned int width
,
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
45 format
= DXGI_FORMAT_BC1_UNORM
; // D3DFMT_DXT1 -> DXGI_FORMAT_BC1_UNORM & DXGI_FORMAT_BC1_UNORM_SRGB
48 format
= DXGI_FORMAT_BC2_UNORM
; // D3DFMT_DXT3 -> DXGI_FORMAT_BC2_UNORM & DXGI_FORMAT_BC2_UNORM_SRGB
51 case XB_FMT_DXT5_YCoCg
:
52 format
= DXGI_FORMAT_BC3_UNORM
; // XB_FMT_DXT5 -> DXGI_FORMAT_BC3_UNORM & DXGI_FORMAT_BC3_UNORM_SRGB
56 format
= DXGI_FORMAT_B8G8R8A8_UNORM
; // D3DFMT_A8R8G8B8 -> DXGI_FORMAT_B8G8R8A8_UNORM | DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
59 format
= DXGI_FORMAT_R8_UNORM
; // XB_FMT_A8 -> DXGI_FORMAT_A8_UNORM
66 void CDXTexture::DestroyTextureObject()
71 void CDXTexture::LoadToGPU()
75 // nothing to load - probably same image (no change)
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)
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
);
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
)
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
);
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)
159 else if (srcPitch
== dstPitch
)
161 memcpy(dst
, src
, srcPitch
* rows
);
165 for (unsigned int y
= 0; y
< rows
; y
++)
167 memcpy(dst
, src
, minPitch
);
175 CLog::LogF(LOGERROR
, "failed to lock texture.");
177 m_texture
.UnlockRect(0);
178 if (usage
!= D3D11_USAGE_STAGING
&& IsMipmapped())
179 m_texture
.GenerateMipmaps();
184 KODI::MEMORY::AlignedFree(m_pixels
);
188 m_loadedToGPU
= true;
191 void CDXTexture::BindToUnit(unsigned int unit
)