Add support for shared textures to graphics API
parent
dc82e8d788
commit
caa32cb6d1
|
@ -1805,6 +1805,11 @@ extern "C" EXPORT bool device_gdi_texture_available(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
extern "C" EXPORT bool device_shared_texture_available(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device,
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
|
@ -1860,3 +1865,19 @@ extern "C" EXPORT void gs_texture_release_dc(gs_texture_t *tex)
|
|||
|
||||
tex2d->gdiSurface->ReleaseDC(nullptr);
|
||||
}
|
||||
|
||||
extern "C" EXPORT gs_texture_t *device_texture_open_shared(gs_device_t *device,
|
||||
uint32_t handle)
|
||||
{
|
||||
gs_texture *texture = nullptr;
|
||||
try {
|
||||
texture = new gs_texture_2d(device, handle);
|
||||
} catch (HRError error) {
|
||||
blog(LOG_ERROR, "gs_texture_open_shared (D3D11): %s (%08lX)",
|
||||
error.str, error.hr);
|
||||
} catch (const char *error) {
|
||||
blog(LOG_ERROR, "gs_texture_open_shared (D3D11): %s", error);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
|
|
@ -234,6 +234,8 @@ struct gs_texture {
|
|||
|
||||
ComPtr<ID3D11ShaderResourceView> shaderRes;
|
||||
|
||||
inline gs_texture() {}
|
||||
|
||||
inline gs_texture(gs_device *device, gs_texture_type type,
|
||||
uint32_t levels, gs_color_format format)
|
||||
: device (device),
|
||||
|
@ -258,7 +260,7 @@ struct gs_texture_2d : gs_texture {
|
|||
bool isDynamic;
|
||||
bool isShared;
|
||||
bool genMipmaps;
|
||||
HANDLE sharedHandle;
|
||||
uint32_t sharedHandle;
|
||||
|
||||
void InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd, const uint8_t **data);
|
||||
void InitTexture(const uint8_t **data);
|
||||
|
@ -283,6 +285,8 @@ struct gs_texture_2d : gs_texture {
|
|||
gs_color_format colorFormat, uint32_t levels,
|
||||
const uint8_t **data, uint32_t flags,
|
||||
gs_texture_type type, bool gdiCompatible, bool shared);
|
||||
|
||||
gs_texture_2d(gs_device_t *device, uint32_t handle);
|
||||
};
|
||||
|
||||
struct gs_zstencil_buffer {
|
||||
|
|
|
@ -25,7 +25,7 @@ void gs_texture_2d::InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd,
|
|||
uint32_t texSizeBytes = height * rowSizeBytes / 8;
|
||||
size_t textures = type == GS_TEXTURE_2D ? 1 : 6;
|
||||
uint32_t actual_levels = levels;
|
||||
|
||||
|
||||
if (!actual_levels)
|
||||
actual_levels = gs_get_total_levels(width, height);
|
||||
|
||||
|
@ -38,7 +38,7 @@ void gs_texture_2d::InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd,
|
|||
for (uint32_t j = 0; j < actual_levels; j++) {
|
||||
D3D11_SUBRESOURCE_DATA newSRD;
|
||||
newSRD.pSysMem = *data;
|
||||
newSRD.SysMemPitch = newRowSize;
|
||||
newSRD.SysMemPitch = newRowSize;
|
||||
newSRD.SysMemSlicePitch = newTexSize;
|
||||
srd.push_back(newSRD);
|
||||
|
||||
|
@ -161,3 +161,65 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width,
|
|||
if (isRenderTarget)
|
||||
InitRenderTargets();
|
||||
}
|
||||
|
||||
static inline gs_color_format ConvertDXGITextureFormat(DXGI_FORMAT format)
|
||||
{
|
||||
switch (format) {
|
||||
case DXGI_FORMAT_A8_UNORM: return GS_A8;
|
||||
case DXGI_FORMAT_R8_UNORM: return GS_R8;
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM: return GS_RGBA;
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM: return GS_BGRX;
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM: return GS_BGRA;
|
||||
case DXGI_FORMAT_R10G10B10A2_UNORM: return GS_R10G10B10A2;
|
||||
case DXGI_FORMAT_R16G16B16A16_UNORM: return GS_RGBA16;
|
||||
case DXGI_FORMAT_R16_UNORM: return GS_R16;
|
||||
case DXGI_FORMAT_R16G16B16A16_FLOAT: return GS_RGBA16F;
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT: return GS_RGBA32F;
|
||||
case DXGI_FORMAT_R16G16_FLOAT: return GS_RG16F;
|
||||
case DXGI_FORMAT_R32G32_FLOAT: return GS_RG32F;
|
||||
case DXGI_FORMAT_R16_FLOAT: return GS_R16F;
|
||||
case DXGI_FORMAT_R32_FLOAT: return GS_R32F;
|
||||
case DXGI_FORMAT_BC1_UNORM: return GS_DXT1;
|
||||
case DXGI_FORMAT_BC2_UNORM: return GS_DXT3;
|
||||
case DXGI_FORMAT_BC3_UNORM: return GS_DXT5;
|
||||
}
|
||||
|
||||
return GS_UNKNOWN;
|
||||
}
|
||||
|
||||
gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle)
|
||||
: isRenderTarget (false),
|
||||
isGDICompatible (false),
|
||||
isDynamic (false),
|
||||
isShared (true),
|
||||
genMipmaps (false),
|
||||
sharedHandle (handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = device->device->OpenSharedResource((HANDLE)handle,
|
||||
__uuidof(ID3D11Texture2D), (void**)texture.Assign());
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to open resource", hr);
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
texture->GetDesc(&desc);
|
||||
|
||||
this->type = GS_TEXTURE_2D;
|
||||
this->format = ConvertDXGITextureFormat(desc.Format);
|
||||
this->levels = 1;
|
||||
this->device = device;
|
||||
|
||||
this->width = desc.Width;
|
||||
this->height = desc.Height;
|
||||
this->dxgiFormat = desc.Format;
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesc = {};
|
||||
resourceDesc.Format = desc.Format;
|
||||
resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
resourceDesc.Texture2D.MipLevels = 1;
|
||||
|
||||
hr = device->device->CreateShaderResourceView(texture, &resourceDesc,
|
||||
shaderRes.Assign());
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create shader resource view", hr);
|
||||
}
|
||||
|
|
|
@ -532,3 +532,8 @@ EXPORT bool device_gdi_texture_available(void)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
EXPORT bool device_shared_texture_available(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -174,9 +174,11 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||
/* win32 specific functions */
|
||||
#elif _WIN32
|
||||
GRAPHICS_IMPORT(device_gdi_texture_available);
|
||||
GRAPHICS_IMPORT(device_shared_texture_available);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_gdi);
|
||||
GRAPHICS_IMPORT_OPTIONAL(gs_texture_get_dc);
|
||||
GRAPHICS_IMPORT_OPTIONAL(gs_texture_release_dc);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_open_shared);
|
||||
#endif
|
||||
|
||||
return success;
|
||||
|
|
|
@ -230,11 +230,16 @@ struct gs_exports {
|
|||
|
||||
#elif _WIN32
|
||||
bool (*device_gdi_texture_available)(void);
|
||||
bool (*device_shared_texture_available)(void);
|
||||
|
||||
gs_texture_t *(*device_texture_create_gdi)(gs_device_t *device,
|
||||
uint32_t width, uint32_t height);
|
||||
|
||||
void *(*gs_texture_get_dc)(gs_texture_t *gdi_tex);
|
||||
void (*gs_texture_release_dc)(gs_texture_t *gdi_tex);
|
||||
|
||||
gs_texture_t *(*device_texture_open_shared)(gs_device_t *device,
|
||||
uint32_t handle);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -1959,6 +1959,14 @@ bool gs_gdi_texture_available(void)
|
|||
return thread_graphics->exports.device_gdi_texture_available();
|
||||
}
|
||||
|
||||
bool gs_shared_texture_available(void)
|
||||
{
|
||||
if (!thread_graphics)
|
||||
return false;
|
||||
|
||||
return thread_graphics->exports.device_shared_texture_available();
|
||||
}
|
||||
|
||||
/** creates a windows GDI-lockable texture */
|
||||
gs_texture_t *gs_texture_create_gdi(uint32_t width, uint32_t height)
|
||||
{
|
||||
|
@ -1990,4 +1998,16 @@ void gs_texture_release_dc(gs_texture_t *gdi_tex)
|
|||
thread_graphics->exports.gs_texture_release_dc(gdi_tex);
|
||||
}
|
||||
|
||||
gs_texture_t *gs_texture_open_shared(uint32_t handle)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
if (!graphics)
|
||||
return NULL;
|
||||
|
||||
if (graphics->exports.device_texture_open_shared)
|
||||
return graphics->exports.device_texture_open_shared(
|
||||
graphics->device, handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -702,6 +702,7 @@ EXPORT bool gs_texture_rebind_iosurface(gs_texture_t *texture,
|
|||
#elif _WIN32
|
||||
|
||||
EXPORT bool gs_gdi_texture_available(void);
|
||||
EXPORT bool gs_shared_texture_available(void);
|
||||
|
||||
/** creates a windows GDI-lockable texture */
|
||||
EXPORT gs_texture_t *gs_texture_create_gdi(uint32_t width, uint32_t height);
|
||||
|
@ -709,6 +710,8 @@ EXPORT gs_texture_t *gs_texture_create_gdi(uint32_t width, uint32_t height);
|
|||
EXPORT void *gs_texture_get_dc(gs_texture_t *gdi_tex);
|
||||
EXPORT void gs_texture_release_dc(gs_texture_t *gdi_tex);
|
||||
|
||||
/** creates a windows shared texture from a texture handle */
|
||||
EXPORT gs_texture_t *gs_texture_open_shared(uint32_t handle);
|
||||
#endif
|
||||
|
||||
/* inline functions used by modules */
|
||||
|
|
Loading…
Reference in New Issue