gs_texture_2d
2024-06-19
16
0
按照上节,gs_texture_2d有两种类型的纹理,分别为2D和2D-CUBE纹理类型。其从数据组织上来讲,一个是一拖一,一个是一拖6。
struct gs_texture_2d : gs_texture {
ComPtr<ID3D11Texture2D> texture; //纹理指针
ComPtr<ID3D11RenderTargetView> renderTarget[6]; //纹理需要一个纹理视图显示,CUBE得有6个
ComPtr<ID3D11RenderTargetView> renderTargetLinear[6];
ComPtr<IDXGISurface1> gdiSurface;
uint32_t width = 0, height = 0;
uint32_t flags = 0;
DXGI_FORMAT dxgiFormatResource = DXGI_FORMAT_UNKNOWN;
DXGI_FORMAT dxgiFormatView = DXGI_FORMAT_UNKNOWN;
DXGI_FORMAT dxgiFormatViewLinear = DXGI_FORMAT_UNKNOWN;
bool isRenderTarget = false;
bool isGDICompatible = false;
bool isDynamic = false;
bool isShared = false;
bool genMipmaps = false;
uint32_t sharedHandle = GS_INVALID_HANDLE;
gs_texture_2d *pairedTexture = nullptr;
bool twoPlane = false;
bool chroma = false;
bool acquired = false;
vector<vector<uint8_t>> data; //纹理数据
vector<D3D11_SUBRESOURCE_DATA> srd;//纹理数据描述符(创建纹理时用)
D3D11_TEXTURE2D_DESC td = {}; //纹理描述符(创建纹理时用)
void InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd);
void InitTexture(const uint8_t *const *data);
void InitResourceView();
void InitRenderTargets();
void BackupTexture(const uint8_t *const *data);
void GetSharedHandle(IDXGIResource *dxgi_res);
void RebuildSharedTextureFallback();
void Rebuild(ID3D11Device *dev);
void RebuildPaired_Y(ID3D11Device *dev);
void RebuildPaired_UV(ID3D11Device *dev);
inline void Release()
{
texture.Release();
for (ComPtr<ID3D11RenderTargetView> &rt : renderTarget)
rt.Release();
for (ComPtr<ID3D11RenderTargetView> &rt : renderTargetLinear)
rt.Release();
gdiSurface.Release();
shaderRes.Release();
shaderResLinear.Release();
}
inline gs_texture_2d() : gs_texture(GS_TEXTURE_2D, 0, GS_UNKNOWN) {}
gs_texture_2d(gs_device_t *device, uint32_t width, uint32_t height,
gs_color_format colorFormat, uint32_t levels,
const uint8_t *const *data, uint32_t flags,
gs_texture_type type, bool gdiCompatible,
bool twoPlane = false);
gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12,uint32_t flags);
gs_texture_2d(gs_device_t *device, uint32_t handle, bool ntHandle = false);
gs_texture_2d(gs_device_t *device, ID3D11Texture2D *obj);
};
提供了5个构造函数。第一个比较简单,其余4个才是实质。
#define SHARED_FLAGS (GS_SHARED_TEX | GS_SHARED_KM_TEX)
//例用原始数据构造
gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width,
uint32_t height, gs_color_format colorFormat,
uint32_t levels, const uint8_t *const *data,
uint32_t flags_, gs_texture_type type,
bool gdiCompatible, bool twoPlane_)
: gs_texture(device, gs_type::gs_texture_2d, type, levels, colorFormat),
width(width),
height(height),
flags(flags_),
dxgiFormatResource(ConvertGSTextureFormatResource(format)),
dxgiFormatView(ConvertGSTextureFormatView(format)),
dxgiFormatViewLinear(ConvertGSTextureFormatViewLinear(format)),
isRenderTarget((flags_ & GS_RENDER_TARGET) != 0),
isGDICompatible(gdiCompatible),
isDynamic((flags_ & GS_DYNAMIC) != 0),
isShared((flags_ & SHARED_FLAGS) != 0),
genMipmaps((flags_ & GS_BUILD_MIPMAPS) != 0),
sharedHandle(GS_INVALID_HANDLE),
twoPlane(twoPlane_)
{
InitTexture(data);
InitResourceView();
if (isRenderTarget)
InitRenderTargets();
}
//使用NV12纹理指针构造
gs_texture_2d::gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12tex,
uint32_t flags_)
: gs_texture(device, gs_type::gs_texture_2d, GS_TEXTURE_2D),
isRenderTarget((flags_ & GS_RENDER_TARGET) != 0),
isDynamic((flags_ & GS_DYNAMIC) != 0),
isShared((flags_ & SHARED_FLAGS) != 0),
genMipmaps((flags_ & GS_BUILD_MIPMAPS) != 0),
twoPlane(true),
texture(nv12tex)
{
texture->GetDesc(&td);
const bool p010 = td.Format == DXGI_FORMAT_P010;
const DXGI_FORMAT dxgi_format = p010 ? DXGI_FORMAT_R16G16_UNORM: DXGI_FORMAT_R8G8_UNORM;
this->type = GS_TEXTURE_2D;
this->format = p010 ? GS_RG16 : GS_R8G8;
this->flags = flags_;
this->levels = 1;
this->device = device;
this->chroma = true;
this->width = td.Width / 2;
this->height = td.Height / 2;
this->dxgiFormatResource = dxgi_format;
this->dxgiFormatView = dxgi_format;
this->dxgiFormatViewLinear = dxgi_format;
InitResourceView();
if (isRenderTarget)
InitRenderTargets();
}
//使用纹理指针构造
gs_texture_2d::gs_texture_2d(gs_device_t *device, ID3D11Texture2D *obj)
: gs_texture(device, gs_type::gs_texture_2d, GS_TEXTURE_2D)
{
texture = obj;
texture->GetDesc(&td);
const gs_color_format format = ConvertDXGITextureFormat(td.Format);
this->type = GS_TEXTURE_2D;
this->format = format;
this->levels = 1;
this->device = device;
this->width = td.Width;
this->height = td.Height;
this->dxgiFormatResource = ConvertGSTextureFormatResource(format);
this->dxgiFormatView = ConvertGSTextureFormatView(format);
this->dxgiFormatViewLinear = ConvertGSTextureFormatViewLinear(format);
InitResourceView();
}
//太高级了,不知道
gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle,
bool ntHandle)
: gs_texture(device, gs_type::gs_texture_2d, GS_TEXTURE_2D),
isShared(true),
sharedHandle(handle)
{
HRESULT hr;
if (ntHandle) {
ComQIPtr<ID3D11Device1> dev = device->device;
hr = dev->OpenSharedResource1((HANDLE)(uintptr_t)handle,
__uuidof(ID3D11Texture2D),
(void **)texture.Assign());
} else {
hr = device->device->OpenSharedResource(
(HANDLE)(uintptr_t)handle, __uuidof(ID3D11Texture2D),
(void **)texture.Assign());
}
if (FAILED(hr))
throw HRError("Failed to open shared 2D texture", hr);
texture->GetDesc(&td);
const gs_color_format format = ConvertDXGITextureFormat(td.Format);
this->type = GS_TEXTURE_2D;
this->format = format;
this->levels = 1;
this->device = device;
this->width = td.Width;
this->height = td.Height;
this->dxgiFormatResource = ConvertGSTextureFormatResource(format);
this->dxgiFormatView = ConvertGSTextureFormatView(format);
this->dxgiFormatViewLinear = ConvertGSTextureFormatViewLinear(format);
InitResourceView();
}
纵观这4个构造函数,除过最后一个不认识外。其余三分又分为两种。第一种是由原始数据构造纹理,然后再根据纹理构造渲染视图。第二种是由纹理构造,但又分为由NV12纹理构造和正常的纹理构造。