From 535f6b0adc94f0469ea7673f6360ea269133d9bf Mon Sep 17 00:00:00 2001 From: jpark37 Date: Thu, 17 Dec 2020 04:07:31 -0800 Subject: [PATCH] win-capture: Typeless game capture textures Modify game capture shared textures to be typeless if they could potentially need SRGB and non-SRGB views in the future. These capture APIs have been updated: D3D 10/11/12, Vulkan. D3D8 capture does not use shared textures. D3D9 and GL interop do not support typeless textures. The new game capture DLL should be compatible with old versions of OBS. Also removed a lot of dead code around pointless SRV/RTV support. --- plugins/win-capture/game-capture.c | 1 + plugins/win-capture/graphics-hook-info.h | 1 + plugins/win-capture/graphics-hook-ver.h | 4 +- .../graphics-hook/d3d10-capture.cpp | 57 +++---------------- .../graphics-hook/d3d11-capture.cpp | 57 +++---------------- .../graphics-hook/d3d12-capture.cpp | 5 +- .../graphics-hook/dxgi-helpers.hpp | 17 +++++- .../win-capture/graphics-hook/gl-capture.c | 6 +- .../graphics-hook/vulkan-capture.c | 7 ++- 9 files changed, 45 insertions(+), 110 deletions(-) diff --git a/plugins/win-capture/game-capture.c b/plugins/win-capture/game-capture.c index 2d3229fae..27a49fece 100644 --- a/plugins/win-capture/game-capture.c +++ b/plugins/win-capture/game-capture.c @@ -743,6 +743,7 @@ static inline bool init_hook_info(struct game_capture *gc) gc->global_hook_info->capture_overlay = gc->config.capture_overlays; gc->global_hook_info->force_shmem = gc->config.force_shmem; gc->global_hook_info->UNUSED_use_scale = false; + gc->global_hook_info->allow_srgb_alias = true; reset_frame_interval(gc); obs_enter_graphics(); diff --git a/plugins/win-capture/graphics-hook-info.h b/plugins/win-capture/graphics-hook-info.h index af43cf4e6..09a206bf5 100644 --- a/plugins/win-capture/graphics-hook-info.h +++ b/plugins/win-capture/graphics-hook-info.h @@ -108,6 +108,7 @@ struct hook_info { bool UNUSED_use_scale; bool force_shmem; bool capture_overlay; + bool allow_srgb_alias; /* hook addresses */ struct graphics_offsets offsets; diff --git a/plugins/win-capture/graphics-hook-ver.h b/plugins/win-capture/graphics-hook-ver.h index 5b583aac0..63980ca17 100644 --- a/plugins/win-capture/graphics-hook-ver.h +++ b/plugins/win-capture/graphics-hook-ver.h @@ -12,8 +12,8 @@ * THIS IS YOUR ONLY WARNING. */ #define HOOK_VER_MAJOR 1 -#define HOOK_VER_MINOR 2 -#define HOOK_VER_PATCH 3 +#define HOOK_VER_MINOR 3 +#define HOOK_VER_PATCH 0 #define STRINGIFY(s) #s #define MAKE_VERSION_NAME(major, minor, patch) \ diff --git a/plugins/win-capture/graphics-hook/d3d10-capture.cpp b/plugins/win-capture/graphics-hook/d3d10-capture.cpp index a96183e9e..cec722cde 100644 --- a/plugins/win-capture/graphics-hook/d3d10-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d10-capture.cpp @@ -32,7 +32,6 @@ struct d3d10_data { struct { struct shtex_data *shtex_info; ID3D10Texture2D *texture; - ID3D10RenderTargetView *render_target; HANDLE handle; }; /* shared memory */ @@ -78,8 +77,6 @@ void d3d10_free(void) if (data.using_shtex) { if (data.texture) data.texture->Release(); - if (data.render_target) - data.render_target->Release(); } else { for (size_t i = 0; i < NUM_BUFFERS; i++) { if (data.copy_surfaces[i]) { @@ -120,31 +117,21 @@ static bool create_d3d10_stage_surface(ID3D10Texture2D **tex) } static bool create_d3d10_tex(uint32_t cx, uint32_t cy, ID3D10Texture2D **tex, - ID3D10ShaderResourceView **resource, - ID3D10RenderTargetView **render_target, HANDLE *handle) { - UINT flags = 0; - UINT misc_flags = 0; HRESULT hr; - if (!!resource) - flags |= D3D10_BIND_SHADER_RESOURCE; - if (!!render_target) - flags |= D3D10_BIND_RENDER_TARGET; - if (!!handle) - misc_flags |= D3D10_RESOURCE_MISC_SHARED; - D3D10_TEXTURE2D_DESC desc = {}; desc.Width = cx; desc.Height = cy; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = data.format; - desc.BindFlags = flags; + desc.Format = apply_dxgi_format_typeless( + data.format, global_hook_info->allow_srgb_alias); + desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; desc.SampleDesc.Count = 1; desc.Usage = D3D10_USAGE_DEFAULT; - desc.MiscFlags = misc_flags; + desc.MiscFlags = D3D10_RESOURCE_MISC_SHARED; hr = data.device->CreateTexture2D(&desc, nullptr, tex); if (FAILED(hr)) { @@ -152,33 +139,6 @@ static bool create_d3d10_tex(uint32_t cx, uint32_t cy, ID3D10Texture2D **tex, return false; } - if (!!resource) { - D3D10_SHADER_RESOURCE_VIEW_DESC res_desc = {}; - res_desc.Format = data.format; - res_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; - res_desc.Texture2D.MipLevels = 1; - - hr = data.device->CreateShaderResourceView(*tex, &res_desc, - resource); - if (FAILED(hr)) { - hlog_hr("create_d3d10_tex: failed to create resource " - "view", - hr); - return false; - } - } - - if (!!render_target) { - hr = data.device->CreateRenderTargetView(*tex, nullptr, - render_target); - if (FAILED(hr)) { - hlog_hr("create_d3d10_tex: failed to create render " - "target view", - hr); - return false; - } - } - if (!!handle) { IDXGIResource *dxgi_res; hr = (*tex)->QueryInterface(__uuidof(IDXGIResource), @@ -213,7 +173,7 @@ static inline bool d3d10_init_format(IDXGISwapChain *swap, HWND &window) return false; } - data.format = fix_dxgi_format(desc.BufferDesc.Format); + data.format = strip_dxgi_format_srgb(desc.BufferDesc.Format); data.multisampled = desc.SampleDesc.Count > 1; window = desc.OutputWindow; data.cx = desc.BufferDesc.Width; @@ -271,15 +231,12 @@ static bool d3d10_shmem_init(HWND window) static bool d3d10_shtex_init(HWND window) { - ID3D10ShaderResourceView *resource = nullptr; bool success; data.using_shtex = true; - success = create_d3d10_tex(data.cx, data.cy, &data.texture, &resource, - &data.render_target, &data.handle); - if (resource) - resource->Release(); + success = + create_d3d10_tex(data.cx, data.cy, &data.texture, &data.handle); if (!success) { hlog("d3d10_shtex_init: failed to create texture"); diff --git a/plugins/win-capture/graphics-hook/d3d11-capture.cpp b/plugins/win-capture/graphics-hook/d3d11-capture.cpp index ae2afe58e..168afed66 100644 --- a/plugins/win-capture/graphics-hook/d3d11-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d11-capture.cpp @@ -33,7 +33,6 @@ struct d3d11_data { struct { struct shtex_data *shtex_info; ID3D11Texture2D *texture; - ID3D11RenderTargetView *render_target; HANDLE handle; }; /* shared memory */ @@ -79,8 +78,6 @@ void d3d11_free(void) if (data.using_shtex) { if (data.texture) data.texture->Release(); - if (data.render_target) - data.render_target->Release(); } else { for (size_t i = 0; i < NUM_BUFFERS; i++) { if (data.copy_surfaces[i]) { @@ -122,31 +119,21 @@ static bool create_d3d11_stage_surface(ID3D11Texture2D **tex) } static bool create_d3d11_tex(uint32_t cx, uint32_t cy, ID3D11Texture2D **tex, - ID3D11ShaderResourceView **resource, - ID3D11RenderTargetView **render_target, HANDLE *handle) { - UINT flags = 0; - UINT misc_flags = 0; HRESULT hr; - if (!!resource) - flags |= D3D11_BIND_SHADER_RESOURCE; - if (!!render_target) - flags |= D3D11_BIND_RENDER_TARGET; - if (!!handle) - misc_flags |= D3D11_RESOURCE_MISC_SHARED; - D3D11_TEXTURE2D_DESC desc = {}; desc.Width = cx; desc.Height = cy; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = data.format; - desc.BindFlags = flags; + desc.Format = apply_dxgi_format_typeless( + data.format, global_hook_info->allow_srgb_alias); + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DEFAULT; - desc.MiscFlags = misc_flags; + desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; hr = data.device->CreateTexture2D(&desc, nullptr, tex); if (FAILED(hr)) { @@ -154,33 +141,6 @@ static bool create_d3d11_tex(uint32_t cx, uint32_t cy, ID3D11Texture2D **tex, return false; } - if (!!resource) { - D3D11_SHADER_RESOURCE_VIEW_DESC res_desc = {}; - res_desc.Format = data.format; - res_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - res_desc.Texture2D.MipLevels = 1; - - hr = data.device->CreateShaderResourceView(*tex, &res_desc, - resource); - if (FAILED(hr)) { - hlog_hr("create_d3d11_tex: failed to create resource " - "view", - hr); - return false; - } - } - - if (!!render_target) { - hr = data.device->CreateRenderTargetView(*tex, nullptr, - render_target); - if (FAILED(hr)) { - hlog_hr("create_d3d11_tex: failed to create render " - "target view", - hr); - return false; - } - } - if (!!handle) { IDXGIResource *dxgi_res; hr = (*tex)->QueryInterface(__uuidof(IDXGIResource), @@ -215,7 +175,7 @@ static inline bool d3d11_init_format(IDXGISwapChain *swap, HWND &window) return false; } - data.format = fix_dxgi_format(desc.BufferDesc.Format); + data.format = strip_dxgi_format_srgb(desc.BufferDesc.Format); data.multisampled = desc.SampleDesc.Count > 1; window = desc.OutputWindow; data.cx = desc.BufferDesc.Width; @@ -274,15 +234,12 @@ static bool d3d11_shmem_init(HWND window) static bool d3d11_shtex_init(HWND window) { - ID3D11ShaderResourceView *resource = nullptr; bool success; data.using_shtex = true; - success = create_d3d11_tex(data.cx, data.cy, &data.texture, &resource, - &data.render_target, &data.handle); - if (resource) - resource->Release(); + success = + create_d3d11_tex(data.cx, data.cy, &data.texture, &data.handle); if (!success) { hlog("d3d11_shtex_init: failed to create texture"); diff --git a/plugins/win-capture/graphics-hook/d3d12-capture.cpp b/plugins/win-capture/graphics-hook/d3d12-capture.cpp index eac437377..1318d2e9d 100644 --- a/plugins/win-capture/graphics-hook/d3d12-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d12-capture.cpp @@ -95,7 +95,8 @@ static bool create_d3d12_tex(bb_info &bb) desc11.Height = data.cy; desc11.MipLevels = 1; desc11.ArraySize = 1; - desc11.Format = data.format; + desc11.Format = apply_dxgi_format_typeless( + data.format, global_hook_info->allow_srgb_alias); desc11.SampleDesc.Count = 1; desc11.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc11.MiscFlags = D3D11_RESOURCE_MISC_SHARED; @@ -216,7 +217,7 @@ static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window, return false; } - data.format = fix_dxgi_format(desc.BufferDesc.Format); + data.format = strip_dxgi_format_srgb(desc.BufferDesc.Format); data.multisampled = desc.SampleDesc.Count > 1; window = desc.OutputWindow; data.cx = desc.BufferDesc.Width; diff --git a/plugins/win-capture/graphics-hook/dxgi-helpers.hpp b/plugins/win-capture/graphics-hook/dxgi-helpers.hpp index 72a68b6a1..353b4220b 100644 --- a/plugins/win-capture/graphics-hook/dxgi-helpers.hpp +++ b/plugins/win-capture/graphics-hook/dxgi-helpers.hpp @@ -1,6 +1,6 @@ #pragma once -static inline DXGI_FORMAT fix_dxgi_format(DXGI_FORMAT format) +static inline DXGI_FORMAT strip_dxgi_format_srgb(DXGI_FORMAT format) { switch ((unsigned long)format) { case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: @@ -11,3 +11,18 @@ static inline DXGI_FORMAT fix_dxgi_format(DXGI_FORMAT format) return format; } + +static inline DXGI_FORMAT apply_dxgi_format_typeless(DXGI_FORMAT format, + bool allow_srgb_alias) +{ + if (allow_srgb_alias) { + switch ((unsigned long)format) { + case DXGI_FORMAT_B8G8R8A8_UNORM: + return DXGI_FORMAT_B8G8R8A8_TYPELESS; + case DXGI_FORMAT_R8G8B8A8_UNORM: + return DXGI_FORMAT_R8G8B8A8_TYPELESS; + } + } + + return format; +} diff --git a/plugins/win-capture/graphics-hook/gl-capture.c b/plugins/win-capture/graphics-hook/gl-capture.c index 91f068e5c..854e85604 100644 --- a/plugins/win-capture/graphics-hook/gl-capture.c +++ b/plugins/win-capture/graphics-hook/gl-capture.c @@ -285,7 +285,7 @@ static inline bool gl_shtex_init_d3d11(void) DXGI_SWAP_CHAIN_DESC desc = {0}; desc.BufferCount = 2; - desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.BufferDesc.Format = data.format; desc.BufferDesc.Width = 2; desc.BufferDesc.Height = 2; desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; @@ -350,11 +350,11 @@ static inline bool gl_shtex_init_d3d11_tex(void) desc.Height = data.cy; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.Format = data.format; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DEFAULT; desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; - desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; hr = ID3D11Device_CreateTexture2D(data.d3d11_device, &desc, NULL, &data.d3d11_tex); diff --git a/plugins/win-capture/graphics-hook/vulkan-capture.c b/plugins/win-capture/graphics-hook/vulkan-capture.c index dd6626ec4..e72b2b20e 100644 --- a/plugins/win-capture/graphics-hook/vulkan-capture.c +++ b/plugins/win-capture/graphics-hook/vulkan-capture.c @@ -13,6 +13,8 @@ #include #include +#include "dxgi-helpers.hpp" + #include "vulkan-capture.h" /* ======================================================================== */ @@ -631,12 +633,13 @@ static inline bool vk_shtex_init_d3d11_tex(struct vk_data *data, desc.Height = height; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = format; + desc.Format = apply_dxgi_format_typeless( + format, global_hook_info->allow_srgb_alias); desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; - desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; hr = ID3D11Device_CreateTexture2D(data->d3d11_device, &desc, NULL, &swap->d3d11_tex);