gs_texture_2d
			 2024-06-19
			  40
			 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纹理构造和正常的纹理构造。
 OBS-Direct11数据结构
			OBS-Direct11数据结构
			




