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.
This commit is contained in:
jpark37 2020-12-17 04:07:31 -08:00 committed by Jim
parent c72b5de23e
commit 535f6b0adc
9 changed files with 45 additions and 110 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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) \

View File

@ -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");

View File

@ -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");

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -13,6 +13,8 @@
#include <dxgi.h>
#include <d3d11.h>
#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);