From 63933997586bf88c862159bf5cb20be56b713283 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Mon, 22 Jun 2020 15:07:07 -0700 Subject: [PATCH] win-capture: Remove game capture scaling The performance save is not worth accidental usage support. Also remove unnecessary copies from the shmem paths. --- plugins/win-capture/cursor-capture.c | 3 +- plugins/win-capture/cursor-capture.h | 2 +- .../win-capture/duplicator-monitor-capture.c | 2 +- plugins/win-capture/game-capture.c | 96 +--- plugins/win-capture/graphics-hook-info.h | 6 +- .../graphics-hook/d3d10-capture.cpp | 462 +--------------- .../graphics-hook/d3d11-capture.cpp | 498 ++---------------- .../graphics-hook/d3d12-capture.cpp | 36 +- .../graphics-hook/d3d1x_shaders.hpp | 31 -- .../graphics-hook/d3d8-capture.cpp | 39 +- .../graphics-hook/d3d9-capture.cpp | 135 ++--- .../graphics-hook/dxgi-capture.cpp | 81 --- .../win-capture/graphics-hook/gl-capture.c | 97 ++-- .../win-capture/graphics-hook/graphics-hook.c | 19 +- .../win-capture/graphics-hook/graphics-hook.h | 13 +- .../graphics-hook/vulkan-capture.c | 10 +- 16 files changed, 201 insertions(+), 1329 deletions(-) delete mode 100644 plugins/win-capture/graphics-hook/d3d1x_shaders.hpp diff --git a/plugins/win-capture/cursor-capture.c b/plugins/win-capture/cursor-capture.c index c0dcef287..2cac62807 100644 --- a/plugins/win-capture/cursor-capture.c +++ b/plugins/win-capture/cursor-capture.c @@ -210,7 +210,7 @@ void cursor_capture(struct cursor_data *data) } void cursor_draw(struct cursor_data *data, long x_offset, long y_offset, - float x_scale, float y_scale, long width, long height) + long width, long height) { long x = data->cursor_pos.x + x_offset; long y = data->cursor_pos.y + y_offset; @@ -226,7 +226,6 @@ void cursor_draw(struct cursor_data *data, long x_offset, long y_offset, gs_enable_color(true, true, true, false); gs_matrix_push(); - gs_matrix_scale3f(x_scale, y_scale, 1.0f); obs_source_draw(data->texture, x_draw, y_draw, 0, 0, false); gs_matrix_pop(); diff --git a/plugins/win-capture/cursor-capture.h b/plugins/win-capture/cursor-capture.h index e5e72fd18..81de59b68 100644 --- a/plugins/win-capture/cursor-capture.h +++ b/plugins/win-capture/cursor-capture.h @@ -24,5 +24,5 @@ struct cursor_data { extern void cursor_capture(struct cursor_data *data); extern void cursor_draw(struct cursor_data *data, long x_offset, long y_offset, - float x_scale, float y_scale, long width, long height); + long width, long height); extern void cursor_data_free(struct cursor_data *data); diff --git a/plugins/win-capture/duplicator-monitor-capture.c b/plugins/win-capture/duplicator-monitor-capture.c index 91a12bb3e..c26a98805 100644 --- a/plugins/win-capture/duplicator-monitor-capture.c +++ b/plugins/win-capture/duplicator-monitor-capture.c @@ -205,7 +205,7 @@ static uint32_t duplicator_capture_height(void *data) static void draw_cursor(struct duplicator_capture *capture) { - cursor_draw(&capture->cursor_data, -capture->x, -capture->y, 1.0f, 1.0f, + cursor_draw(&capture->cursor_data, -capture->x, -capture->y, capture->rot % 180 == 0 ? capture->width : capture->height, capture->rot % 180 == 0 ? capture->height : capture->width); } diff --git a/plugins/win-capture/game-capture.c b/plugins/win-capture/game-capture.c index fce3ce607..55adeb4be 100644 --- a/plugins/win-capture/game-capture.c +++ b/plugins/win-capture/game-capture.c @@ -32,8 +32,6 @@ #define SETTING_ACTIVE_WINDOW "active_window" #define SETTING_WINDOW_PRIORITY "priority" #define SETTING_COMPATIBILITY "sli_compatibility" -#define SETTING_FORCE_SCALING "force_scaling" -#define SETTING_SCALE_RES "scale_res" #define SETTING_CURSOR "capture_cursor" #define SETTING_TRANSPARENCY "allow_transparency" #define SETTING_LIMIT_FRAMERATE "limit_framerate" @@ -56,8 +54,6 @@ #define TEXT_ANY_FULLSCREEN obs_module_text("GameCapture.AnyFullscreen") #define TEXT_SLI_COMPATIBILITY obs_module_text("SLIFix") #define TEXT_ALLOW_TRANSPARENCY obs_module_text("AllowTransparency") -#define TEXT_FORCE_SCALING obs_module_text("GameCapture.ForceScaling") -#define TEXT_SCALE_RES obs_module_text("GameCapture.ScaleRes") #define TEXT_WINDOW obs_module_text("WindowCapture.Window") #define TEXT_MATCH_PRIORITY obs_module_text("WindowCapture.Priority") #define TEXT_MATCH_TITLE obs_module_text("WindowCapture.Priority.Title") @@ -104,11 +100,8 @@ struct game_capture_config { char *executable; enum window_priority priority; enum capture_mode mode; - uint32_t scale_cx; - uint32_t scale_cy; bool cursor; bool force_shmem; - bool force_scaling; bool allow_transparency; bool limit_framerate; bool capture_overlays; @@ -392,8 +385,6 @@ static inline bool using_older_non_mode_format(obs_data_t *settings) static inline void get_config(struct game_capture_config *cfg, obs_data_t *settings, const char *window) { - int ret; - const char *scale_str; const char *mode_str = NULL; build_window_strings(window, &cfg->class, &cfg->title, @@ -419,7 +410,6 @@ static inline void get_config(struct game_capture_config *cfg, cfg->cursor = obs_data_get_bool(settings, SETTING_CURSOR); cfg->allow_transparency = obs_data_get_bool(settings, SETTING_TRANSPARENCY); - cfg->force_scaling = obs_data_get_bool(settings, SETTING_FORCE_SCALING); cfg->limit_framerate = obs_data_get_bool(settings, SETTING_LIMIT_FRAMERATE); cfg->capture_overlays = @@ -428,20 +418,6 @@ static inline void get_config(struct game_capture_config *cfg, obs_data_get_bool(settings, SETTING_ANTI_CHEAT_HOOK); cfg->hook_rate = (enum hook_rate)obs_data_get_int(settings, SETTING_HOOK_RATE); - - scale_str = obs_data_get_string(settings, SETTING_SCALE_RES); - ret = sscanf(scale_str, "%" PRIu32 "x%" PRIu32, &cfg->scale_cx, - &cfg->scale_cy); - - cfg->scale_cx &= ~2; - cfg->scale_cy &= ~2; - - if (cfg->force_scaling) { - if (ret != 2 || cfg->scale_cx == 0 || cfg->scale_cy == 0) { - cfg->scale_cx = 0; - cfg->scale_cy = 0; - } - } } static inline int s_cmp(const char *str1, const char *str2) @@ -465,13 +441,6 @@ static inline bool capture_needs_reset(struct game_capture_config *cfg1, cfg1->priority != cfg2->priority)) { return true; - } else if (cfg1->force_scaling != cfg2->force_scaling) { - return true; - - } else if (cfg1->force_scaling && (cfg1->scale_cx != cfg2->scale_cx || - cfg1->scale_cy != cfg2->scale_cy)) { - return true; - } else if (cfg1->force_shmem != cfg2->force_shmem) { return true; @@ -525,12 +494,7 @@ static void game_capture_update(void *data, obs_data_t *settings) get_config(&cfg, settings, window); reset_capture = capture_needs_reset(&cfg, &gc->config); - if (cfg.force_scaling && (cfg.scale_cx == 0 || cfg.scale_cy == 0)) { - gc->error_acquiring = true; - warn("error acquiring, scale is bad"); - } else { - gc->error_acquiring = false; - } + gc->error_acquiring = false; if (cfg.mode == CAPTURE_MODE_HOTKEY && gc->config.mode != CAPTURE_MODE_HOTKEY) { @@ -771,11 +735,7 @@ static inline bool init_hook_info(struct game_capture *gc) : offsets32; gc->global_hook_info->capture_overlay = gc->config.capture_overlays; gc->global_hook_info->force_shmem = gc->config.force_shmem; - gc->global_hook_info->use_scale = gc->config.force_scaling; - if (gc->config.scale_cx) - gc->global_hook_info->cx = gc->config.scale_cx; - if (gc->config.scale_cy) - gc->global_hook_info->cy = gc->config.scale_cy; + gc->global_hook_info->UNUSED_use_scale = false; reset_frame_interval(gc); obs_enter_graphics(); @@ -1817,7 +1777,7 @@ static inline void game_capture_render_cursor(struct game_capture *gc) POINT p = {0}; HWND window; - if (!gc->global_hook_info->base_cx || !gc->global_hook_info->base_cy) + if (!gc->global_hook_info->cx || !gc->global_hook_info->cy) return; window = !!gc->global_hook_info->window @@ -1826,14 +1786,8 @@ static inline void game_capture_render_cursor(struct game_capture *gc) ClientToScreen(window, &p); - float x_scale = (float)gc->global_hook_info->cx / - (float)gc->global_hook_info->base_cx; - float y_scale = (float)gc->global_hook_info->cy / - (float)gc->global_hook_info->base_cy; - - cursor_draw(&gc->cursor_data, -p.x, -p.y, x_scale, y_scale, - gc->global_hook_info->base_cx, - gc->global_hook_info->base_cy); + cursor_draw(&gc->cursor_data, -p.x, -p.y, gc->global_hook_info->cx, + gc->global_hook_info->cy); } static void game_capture_render(void *data, gs_effect_t *effect) @@ -1890,10 +1844,8 @@ static void game_capture_defaults(obs_data_t *settings) obs_data_set_default_int(settings, SETTING_WINDOW_PRIORITY, (int)WINDOW_PRIORITY_EXE); obs_data_set_default_bool(settings, SETTING_COMPATIBILITY, false); - obs_data_set_default_bool(settings, SETTING_FORCE_SCALING, false); obs_data_set_default_bool(settings, SETTING_CURSOR, true); obs_data_set_default_bool(settings, SETTING_TRANSPARENCY, false); - obs_data_set_default_string(settings, SETTING_SCALE_RES, "0x0"); obs_data_set_default_bool(settings, SETTING_LIMIT_FRAMERATE, false); obs_data_set_default_bool(settings, SETTING_CAPTURE_OVERLAYS, false); obs_data_set_default_bool(settings, SETTING_ANTI_CHEAT_HOOK, true); @@ -1923,16 +1875,6 @@ static bool mode_callback(obs_properties_t *ppts, obs_property_t *p, return true; } -static bool use_scaling_callback(obs_properties_t *ppts, obs_property_t *p, - obs_data_t *settings) -{ - bool use_scale = obs_data_get_bool(settings, SETTING_FORCE_SCALING); - - p = obs_properties_get(ppts, SETTING_SCALE_RES); - obs_property_set_enabled(p, use_scale); - return true; -} - static void insert_preserved_val(obs_property_t *p, const char *val, size_t idx) { char *class = NULL; @@ -1992,11 +1934,6 @@ static bool window_changed_callback(obs_properties_t *ppts, obs_property_t *p, SETTING_CAPTURE_WINDOW, 1); } -static const double default_scale_vals[] = {1.25, 1.5, 2.0, 2.5, 3.0}; - -#define NUM_DEFAULT_SCALE_VALS \ - (sizeof(default_scale_vals) / sizeof(default_scale_vals[0])) - static BOOL CALLBACK EnumFirstMonitor(HMONITOR monitor, HDC hdc, LPRECT rc, LPARAM data) { @@ -2082,29 +2019,6 @@ static obs_properties_t *game_capture_properties(void *data) obs_properties_add_bool(ppts, SETTING_COMPATIBILITY, TEXT_SLI_COMPATIBILITY); - p = obs_properties_add_bool(ppts, SETTING_FORCE_SCALING, - TEXT_FORCE_SCALING); - - obs_property_set_modified_callback(p, use_scaling_callback); - - p = obs_properties_add_list(ppts, SETTING_SCALE_RES, TEXT_SCALE_RES, - OBS_COMBO_TYPE_EDITABLE, - OBS_COMBO_FORMAT_STRING); - - for (size_t i = 0; i < NUM_DEFAULT_SCALE_VALS; i++) { - char scale_str[64]; - uint32_t new_cx = - (uint32_t)((double)cx / default_scale_vals[i]) & ~2; - uint32_t new_cy = - (uint32_t)((double)cy / default_scale_vals[i]) & ~2; - - sprintf(scale_str, "%" PRIu32 "x%" PRIu32, new_cx, new_cy); - - obs_property_list_add_string(p, scale_str, scale_str); - } - - obs_property_set_enabled(p, false); - obs_properties_add_bool(ppts, SETTING_TRANSPARENCY, TEXT_ALLOW_TRANSPARENCY); diff --git a/plugins/win-capture/graphics-hook-info.h b/plugins/win-capture/graphics-hook-info.h index 17f93574b..9e741105b 100644 --- a/plugins/win-capture/graphics-hook-info.h +++ b/plugins/win-capture/graphics-hook-info.h @@ -90,8 +90,8 @@ struct hook_info { uint32_t format; uint32_t cx; uint32_t cy; - uint32_t base_cx; - uint32_t base_cy; + uint32_t UNUSED_base_cx; + uint32_t UNUSED_base_cy; uint32_t pitch; uint32_t map_id; uint32_t map_size; @@ -99,7 +99,7 @@ struct hook_info { /* additional options */ uint64_t frame_interval; - bool use_scale; + bool UNUSED_use_scale; bool force_shmem; bool capture_overlay; diff --git a/plugins/win-capture/graphics-hook/d3d10-capture.cpp b/plugins/win-capture/graphics-hook/d3d10-capture.cpp index e1c625d7b..a96183e9e 100644 --- a/plugins/win-capture/graphics-hook/d3d10-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d10-capture.cpp @@ -7,13 +7,10 @@ struct d3d10_data { ID3D10Device *device; /* do not release */ - uint32_t base_cx; - uint32_t base_cy; uint32_t cx; uint32_t cy; DXGI_FORMAT format; bool using_shtex; - bool using_scale; bool multisampled; ID3D10Texture2D *scale_tex; @@ -42,8 +39,6 @@ struct d3d10_data { struct { struct shmem_data *shmem_info; ID3D10Texture2D *copy_surfaces[NUM_BUFFERS]; - ID3D10Texture2D *textures[NUM_BUFFERS]; - ID3D10RenderTargetView *render_targets[NUM_BUFFERS]; bool texture_ready[NUM_BUFFERS]; bool texture_mapped[NUM_BUFFERS]; uint32_t pitch; @@ -92,10 +87,6 @@ void d3d10_free(void) data.copy_surfaces[i]->Unmap(0); data.copy_surfaces[i]->Release(); } - if (data.textures[i]) - data.textures[i]->Release(); - if (data.render_targets[i]) - data.render_targets[i]->Release(); } } @@ -225,218 +216,8 @@ static inline bool d3d10_init_format(IDXGISwapChain *swap, HWND &window) data.format = fix_dxgi_format(desc.BufferDesc.Format); data.multisampled = desc.SampleDesc.Count > 1; window = desc.OutputWindow; - data.base_cx = desc.BufferDesc.Width; - data.base_cy = desc.BufferDesc.Height; - - if (data.using_scale) { - data.cx = global_hook_info->cx; - data.cy = global_hook_info->cy; - } else { - data.cx = desc.BufferDesc.Width; - data.cy = desc.BufferDesc.Height; - } - return true; -} - -static inline bool d3d10_init_vertex_shader(void) -{ - D3D10_INPUT_ELEMENT_DESC desc[2]; - uint8_t *vs_data; - size_t size; - HRESULT hr; - - vs_data = get_d3d1x_vertex_shader(&size); - - hr = data.device->CreateVertexShader(vs_data, size, - &data.vertex_shader); - if (FAILED(hr)) { - hlog_hr("d3d10_init_vertex_shader: failed to create shader", - hr); - return false; - } - - desc[0].SemanticName = "SV_Position"; - desc[0].SemanticIndex = 0; - desc[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - desc[0].InputSlot = 0; - desc[0].AlignedByteOffset = 0; - desc[0].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA; - desc[0].InstanceDataStepRate = 0; - - desc[1].SemanticName = "TEXCOORD"; - desc[1].SemanticIndex = 0; - desc[1].Format = DXGI_FORMAT_R32G32_FLOAT; - desc[1].InputSlot = 0; - desc[1].AlignedByteOffset = D3D10_APPEND_ALIGNED_ELEMENT; - desc[1].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA; - desc[1].InstanceDataStepRate = 0; - - hr = data.device->CreateInputLayout(desc, 2, vs_data, size, - &data.vertex_layout); - if (FAILED(hr)) { - hlog_hr("d3d10_init_vertex_shader: failed to create layout", - hr); - return false; - } - - return true; -} - -static inline bool d3d10_init_pixel_shader(void) -{ - uint8_t *ps_data; - size_t size; - HRESULT hr; - - ps_data = get_d3d1x_pixel_shader(&size); - - hr = data.device->CreatePixelShader(ps_data, size, &data.pixel_shader); - if (FAILED(hr)) { - hlog_hr("d3d10_init_pixel_shader: failed to create shader", hr); - return false; - } - - return true; -} - -static inline bool d3d10_init_sampler_state(void) -{ - HRESULT hr; - - D3D10_SAMPLER_DESC desc = {}; - desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; - desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP; - desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP; - desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP; - - hr = data.device->CreateSamplerState(&desc, &data.sampler_state); - if (FAILED(hr)) { - hlog_hr("d3d10_init_sampler_state: failed to create sampler " - "state", - hr); - return false; - } - - return true; -} - -static inline bool d3d10_init_blend_state(void) -{ - D3D10_BLEND_DESC desc = {}; - HRESULT hr; - - for (size_t i = 0; i < 8; i++) - desc.RenderTargetWriteMask[i] = D3D10_COLOR_WRITE_ENABLE_ALL; - - hr = data.device->CreateBlendState(&desc, &data.blend_state); - if (FAILED(hr)) { - hlog_hr("d3d10_init_blend_state: failed to create blend state", - hr); - return false; - } - - return true; -} - -static inline bool d3d10_init_zstencil_state(void) -{ - D3D10_DEPTH_STENCIL_DESC desc = {}; /* defaults all to off */ - HRESULT hr; - - hr = data.device->CreateDepthStencilState(&desc, &data.zstencil_state); - if (FAILED(hr)) { - hlog_hr("d3d10_init_zstencil_state: failed to create " - "zstencil state", - hr); - return false; - } - - return true; -} - -static inline bool d3d10_init_raster_state(void) -{ - D3D10_RASTERIZER_DESC desc = {}; - HRESULT hr; - - desc.FillMode = D3D10_FILL_SOLID; - desc.CullMode = D3D10_CULL_NONE; - - hr = data.device->CreateRasterizerState(&desc, &data.raster_state); - if (FAILED(hr)) { - hlog_hr("d3d10_init_raster_state: failed to create raster " - "state", - hr); - return false; - } - - return true; -} - -#define NUM_VERTS 4 - -static inline bool d3d10_init_vertex_buffer(void) -{ - HRESULT hr; - const vertex verts[NUM_VERTS] = { - {{-1.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}, - {{-1.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 1.0f}}, - {{1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.0f}}, - {{1.0f, -1.0f, 0.0f, 1.0f}, {1.0f, 1.0f}}}; - - D3D10_BUFFER_DESC desc; - desc.ByteWidth = sizeof(vertex) * NUM_VERTS; - desc.Usage = D3D10_USAGE_DEFAULT; - desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - D3D10_SUBRESOURCE_DATA srd = {}; - srd.pSysMem = (const void *)verts; - - hr = data.device->CreateBuffer(&desc, &srd, &data.vertex_buffer); - if (FAILED(hr)) { - hlog_hr("d3d10_init_vertex_buffer: failed to create vertex " - "buffer", - hr); - return false; - } - - return true; -} - -static bool d3d10_init_scaling(void) -{ - bool success; - - success = create_d3d10_tex(data.base_cx, data.base_cy, &data.scale_tex, - &data.scale_resource, nullptr, nullptr); - if (!success) { - hlog("d3d10_init_scaling: failed to create scale texture"); - return false; - } - - if (!d3d10_init_vertex_shader()) { - return false; - } - if (!d3d10_init_pixel_shader()) { - return false; - } - if (!d3d10_init_sampler_state()) { - return false; - } - if (!d3d10_init_blend_state()) { - return false; - } - if (!d3d10_init_zstencil_state()) { - return false; - } - if (!d3d10_init_raster_state()) { - return false; - } - if (!d3d10_init_vertex_buffer()) { - return false; - } + data.cx = desc.BufferDesc.Width; + data.cy = desc.BufferDesc.Height; return true; } @@ -467,13 +248,6 @@ static bool d3d10_shmem_init_buffers(size_t idx) data.copy_surfaces[idx]->Unmap(0); } - success = create_d3d10_tex(data.cx, data.cy, &data.textures[idx], - nullptr, &data.render_targets[idx], nullptr); - if (!success) { - hlog("d3d10_shmem_init_buffers: failed to create texture"); - return false; - } - return true; } @@ -486,9 +260,8 @@ static bool d3d10_shmem_init(HWND window) return false; } } - if (!capture_init_shmem(&data.shmem_info, window, data.base_cx, - data.base_cy, data.cx, data.cy, data.pitch, - data.format, false)) { + if (!capture_init_shmem(&data.shmem_info, window, data.cx, data.cy, + data.pitch, data.format, false)) { return false; } @@ -512,9 +285,8 @@ static bool d3d10_shtex_init(HWND window) hlog("d3d10_shtex_init: failed to create texture"); return false; } - if (!capture_init_shtex(&data.shtex_info, window, data.base_cx, - data.base_cy, data.cx, data.cy, data.format, - false, (uintptr_t)data.handle)) { + if (!capture_init_shtex(&data.shtex_info, window, data.cx, data.cy, + data.format, false, (uintptr_t)data.handle)) { return false; } @@ -524,12 +296,9 @@ static bool d3d10_shtex_init(HWND window) static void d3d10_init(IDXGISwapChain *swap) { - bool success = true; HWND window; HRESULT hr; - data.using_scale = global_hook_info->use_scale; - hr = swap->GetDevice(__uuidof(ID3D10Device), (void **)&data.device); if (FAILED(hr)) { hlog_hr("d3d10_init: failed to get device from swap", hr); @@ -542,169 +311,14 @@ static void d3d10_init(IDXGISwapChain *swap) if (!d3d10_init_format(swap, window)) { return; } - if (data.using_scale && !d3d10_init_scaling()) { - hlog("d3d10_init: failed to initialize scaling"); - success = false; - } - if (success) { - if (global_hook_info->force_shmem) { - success = d3d10_shmem_init(window); - } else { - success = d3d10_shtex_init(window); - } - } + const bool success = global_hook_info->force_shmem + ? d3d10_shmem_init(window) + : d3d10_shtex_init(window); if (!success) d3d10_free(); } -#define MAX_RENDER_TARGETS D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT -#define MAX_SO_TARGETS 4 - -struct d3d10_state { - ID3D10GeometryShader *geom_shader; - ID3D10InputLayout *vertex_layout; - D3D10_PRIMITIVE_TOPOLOGY topology; - ID3D10Buffer *vertex_buffer; - UINT vb_stride; - UINT vb_offset; - ID3D10BlendState *blend_state; - float blend_factor[4]; - UINT sample_mask; - ID3D10DepthStencilState *zstencil_state; - UINT zstencil_ref; - ID3D10RenderTargetView *render_targets[MAX_RENDER_TARGETS]; - ID3D10DepthStencilView *zstencil_view; - ID3D10SamplerState *sampler_state; - ID3D10PixelShader *pixel_shader; - ID3D10ShaderResourceView *resource; - ID3D10RasterizerState *raster_state; - UINT num_viewports; - D3D10_VIEWPORT *viewports; - ID3D10Buffer *stream_output_targets[MAX_SO_TARGETS]; - UINT so_offsets[MAX_SO_TARGETS]; - ID3D10VertexShader *vertex_shader; -}; - -static inline void d3d10_save_state(struct d3d10_state *state) -{ - data.device->GSGetShader(&state->geom_shader); - data.device->IAGetInputLayout(&state->vertex_layout); - data.device->IAGetPrimitiveTopology(&state->topology); - data.device->IAGetVertexBuffers(0, 1, &state->vertex_buffer, - &state->vb_stride, &state->vb_offset); - data.device->OMGetBlendState(&state->blend_state, state->blend_factor, - &state->sample_mask); - data.device->OMGetDepthStencilState(&state->zstencil_state, - &state->zstencil_ref); - data.device->OMGetRenderTargets(MAX_RENDER_TARGETS, - state->render_targets, - &state->zstencil_view); - data.device->PSGetSamplers(0, 1, &state->sampler_state); - data.device->PSGetShader(&state->pixel_shader); - data.device->PSGetShaderResources(0, 1, &state->resource); - data.device->RSGetState(&state->raster_state); - data.device->RSGetViewports(&state->num_viewports, nullptr); - if (state->num_viewports) { - state->viewports = (D3D10_VIEWPORT *)malloc( - sizeof(D3D10_VIEWPORT) * state->num_viewports); - data.device->RSGetViewports(&state->num_viewports, - state->viewports); - } - data.device->SOGetTargets(MAX_SO_TARGETS, state->stream_output_targets, - state->so_offsets); - data.device->VSGetShader(&state->vertex_shader); -} - -static inline void safe_release(IUnknown *p) -{ - if (p) - p->Release(); -} - -static inline void d3d10_restore_state(struct d3d10_state *state) -{ - data.device->GSSetShader(state->geom_shader); - data.device->IASetInputLayout(state->vertex_layout); - data.device->IASetPrimitiveTopology(state->topology); - data.device->IASetVertexBuffers(0, 1, &state->vertex_buffer, - &state->vb_stride, &state->vb_offset); - data.device->OMSetBlendState(state->blend_state, state->blend_factor, - state->sample_mask); - data.device->OMSetDepthStencilState(state->zstencil_state, - state->zstencil_ref); - data.device->OMSetRenderTargets(MAX_RENDER_TARGETS, - state->render_targets, - state->zstencil_view); - data.device->PSSetSamplers(0, 1, &state->sampler_state); - data.device->PSSetShader(state->pixel_shader); - data.device->PSSetShaderResources(0, 1, &state->resource); - data.device->RSSetState(state->raster_state); - data.device->RSSetViewports(state->num_viewports, state->viewports); - data.device->SOSetTargets(MAX_SO_TARGETS, state->stream_output_targets, - state->so_offsets); - data.device->VSSetShader(state->vertex_shader); - safe_release(state->geom_shader); - safe_release(state->vertex_layout); - safe_release(state->vertex_buffer); - safe_release(state->blend_state); - safe_release(state->zstencil_state); - for (size_t i = 0; i < MAX_RENDER_TARGETS; i++) - safe_release(state->render_targets[i]); - safe_release(state->zstencil_view); - safe_release(state->sampler_state); - safe_release(state->pixel_shader); - safe_release(state->resource); - safe_release(state->raster_state); - for (size_t i = 0; i < MAX_SO_TARGETS; i++) - safe_release(state->stream_output_targets[i]); - safe_release(state->vertex_shader); - free(state->viewports); - memset(state, 0, sizeof(*state)); -} - -static inline void d3d10_setup_pipeline(ID3D10RenderTargetView *target, - ID3D10ShaderResourceView *resource) -{ - D3D10_VIEWPORT viewport = {0}; - const float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - void *emptyptr = nullptr; - UINT stride = sizeof(vertex); - UINT zero = 0; - - viewport.Width = data.cx; - viewport.Height = data.cy; - viewport.MaxDepth = 1.0f; - - data.device->GSSetShader(nullptr); - data.device->IASetInputLayout(data.vertex_layout); - data.device->IASetPrimitiveTopology( - D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - data.device->IASetVertexBuffers(0, 1, &data.vertex_buffer, &stride, - &zero); - data.device->OMSetBlendState(data.blend_state, factor, 0xFFFFFFFF); - data.device->OMSetDepthStencilState(data.zstencil_state, 0); - data.device->OMSetRenderTargets(1, &target, nullptr); - data.device->PSSetSamplers(0, 1, &data.sampler_state); - data.device->PSSetShader(data.pixel_shader); - data.device->PSSetShaderResources(0, 1, &resource); - data.device->RSSetState(data.raster_state); - data.device->RSSetViewports(1, &viewport); - data.device->SOSetTargets(1, (ID3D10Buffer **)&emptyptr, &zero); - data.device->VSSetShader(data.vertex_shader); -} - -static inline void d3d10_scale_texture(ID3D10RenderTargetView *target, - ID3D10ShaderResourceView *resource) -{ - struct d3d10_state old_state = {}; - - d3d10_save_state(&old_state); - d3d10_setup_pipeline(target, resource); - data.device->Draw(4, 0); - d3d10_restore_state(&old_state); -} - static inline void d3d10_copy_texture(ID3D10Resource *dst, ID3D10Resource *src) { if (data.multisampled) { @@ -716,30 +330,21 @@ static inline void d3d10_copy_texture(ID3D10Resource *dst, ID3D10Resource *src) static inline void d3d10_shtex_capture(ID3D10Resource *backbuffer) { - if (data.using_scale) { - d3d10_copy_texture(data.scale_tex, backbuffer); - d3d10_scale_texture(data.render_target, data.scale_resource); - } else { - d3d10_copy_texture(data.texture, backbuffer); - } + d3d10_copy_texture(data.texture, backbuffer); } -static inline void d3d10_shmem_queue_copy() +static void d3d10_shmem_capture_copy(int i) { - for (size_t i = 0; i < NUM_BUFFERS; i++) { - D3D10_MAPPED_TEXTURE2D map; - HRESULT hr; + D3D10_MAPPED_TEXTURE2D map; + HRESULT hr; - if (data.texture_ready[i]) { - data.texture_ready[i] = false; + if (data.texture_ready[i]) { + data.texture_ready[i] = false; - hr = data.copy_surfaces[i]->Map(0, D3D10_MAP_READ, 0, - &map); - if (SUCCEEDED(hr)) { - data.texture_mapped[i] = true; - shmem_copy_data(i, map.pData); - } - break; + hr = data.copy_surfaces[i]->Map(0, D3D10_MAP_READ, 0, &map); + if (SUCCEEDED(hr)) { + data.texture_mapped[i] = true; + shmem_copy_data(i, map.pData); } } } @@ -748,32 +353,21 @@ static inline void d3d10_shmem_capture(ID3D10Resource *backbuffer) { int next_tex; - d3d10_shmem_queue_copy(); - - next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1; - - if (data.using_scale) { - d3d10_copy_texture(data.scale_tex, backbuffer); - d3d10_scale_texture(data.render_targets[data.cur_tex], - data.scale_resource); - } else { - d3d10_copy_texture(data.textures[data.cur_tex], backbuffer); - } + next_tex = (data.cur_tex + 1) % NUM_BUFFERS; + d3d10_shmem_capture_copy(next_tex); if (data.copy_wait < NUM_BUFFERS - 1) { data.copy_wait++; } else { - ID3D10Texture2D *src = data.textures[next_tex]; - ID3D10Texture2D *dst = data.copy_surfaces[next_tex]; - - if (shmem_texture_data_lock(next_tex)) { - dst->Unmap(0); - data.texture_mapped[next_tex] = false; - shmem_texture_data_unlock(next_tex); + if (shmem_texture_data_lock(data.cur_tex)) { + data.copy_surfaces[data.cur_tex]->Unmap(0); + data.texture_mapped[data.cur_tex] = false; + shmem_texture_data_unlock(data.cur_tex); } - d3d10_copy_texture(dst, src); - data.texture_ready[next_tex] = true; + d3d10_copy_texture(data.copy_surfaces[data.cur_tex], + backbuffer); + data.texture_ready[data.cur_tex] = true; } data.cur_tex = next_tex; diff --git a/plugins/win-capture/graphics-hook/d3d11-capture.cpp b/plugins/win-capture/graphics-hook/d3d11-capture.cpp index c56e47b4c..ae2afe58e 100644 --- a/plugins/win-capture/graphics-hook/d3d11-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d11-capture.cpp @@ -8,13 +8,10 @@ struct d3d11_data { ID3D11Device *device; /* do not release */ ID3D11DeviceContext *context; /* do not release */ - uint32_t base_cx; - uint32_t base_cy; uint32_t cx; uint32_t cy; DXGI_FORMAT format; bool using_shtex; - bool using_scale; bool multisampled; ID3D11Texture2D *scale_tex; @@ -42,8 +39,6 @@ struct d3d11_data { /* shared memory */ struct { ID3D11Texture2D *copy_surfaces[NUM_BUFFERS]; - ID3D11Texture2D *textures[NUM_BUFFERS]; - ID3D11RenderTargetView *render_targets[NUM_BUFFERS]; bool texture_ready[NUM_BUFFERS]; bool texture_mapped[NUM_BUFFERS]; uint32_t pitch; @@ -94,10 +89,6 @@ void d3d11_free(void) data.copy_surfaces[i], 0); data.copy_surfaces[i]->Release(); } - if (data.textures[i]) - data.textures[i]->Release(); - if (data.render_targets[i]) - data.render_targets[i]->Release(); } } @@ -227,220 +218,8 @@ static inline bool d3d11_init_format(IDXGISwapChain *swap, HWND &window) data.format = fix_dxgi_format(desc.BufferDesc.Format); data.multisampled = desc.SampleDesc.Count > 1; window = desc.OutputWindow; - data.base_cx = desc.BufferDesc.Width; - data.base_cy = desc.BufferDesc.Height; - - if (data.using_scale) { - data.cx = global_hook_info->cx; - data.cy = global_hook_info->cy; - } else { - data.cx = desc.BufferDesc.Width; - data.cy = desc.BufferDesc.Height; - } - return true; -} - -static inline bool d3d11_init_vertex_shader(void) -{ - D3D11_INPUT_ELEMENT_DESC desc[2]; - uint8_t *vs_data; - size_t size; - HRESULT hr; - - vs_data = get_d3d1x_vertex_shader(&size); - - hr = data.device->CreateVertexShader(vs_data, size, nullptr, - &data.vertex_shader); - if (FAILED(hr)) { - hlog_hr("d3d11_init_vertex_shader: failed to create shader", - hr); - return false; - } - - desc[0].SemanticName = "SV_Position"; - desc[0].SemanticIndex = 0; - desc[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - desc[0].InputSlot = 0; - desc[0].AlignedByteOffset = 0; - desc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - desc[0].InstanceDataStepRate = 0; - - desc[1].SemanticName = "TEXCOORD"; - desc[1].SemanticIndex = 0; - desc[1].Format = DXGI_FORMAT_R32G32_FLOAT; - desc[1].InputSlot = 0; - desc[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; - desc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - desc[1].InstanceDataStepRate = 0; - - hr = data.device->CreateInputLayout(desc, 2, vs_data, size, - &data.vertex_layout); - if (FAILED(hr)) { - hlog_hr("d3d11_init_vertex_shader: failed to create layout", - hr); - return false; - } - - return true; -} - -static inline bool d3d11_init_pixel_shader(void) -{ - uint8_t *ps_data; - size_t size; - HRESULT hr; - - ps_data = get_d3d1x_pixel_shader(&size); - - hr = data.device->CreatePixelShader(ps_data, size, nullptr, - &data.pixel_shader); - if (FAILED(hr)) { - hlog_hr("d3d11_init_pixel_shader: failed to create shader", hr); - return false; - } - - return true; -} - -static inline bool d3d11_init_sampler_state(void) -{ - HRESULT hr; - - D3D11_SAMPLER_DESC desc = {}; - desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - - hr = data.device->CreateSamplerState(&desc, &data.sampler_state); - if (FAILED(hr)) { - hlog_hr("d3d11_init_sampler_state: failed to create sampler " - "state", - hr); - return false; - } - - return true; -} - -static inline bool d3d11_init_blend_state(void) -{ - D3D11_BLEND_DESC desc = {}; - HRESULT hr; - - for (size_t i = 0; i < 8; i++) - desc.RenderTarget[i].RenderTargetWriteMask = - D3D11_COLOR_WRITE_ENABLE_ALL; - - hr = data.device->CreateBlendState(&desc, &data.blend_state); - if (FAILED(hr)) { - hlog_hr("d3d11_init_blend_state: failed to create blend state", - hr); - return false; - } - - return true; -} - -static inline bool d3d11_init_zstencil_state(void) -{ - D3D11_DEPTH_STENCIL_DESC desc = {}; /* defaults all to off */ - HRESULT hr; - - hr = data.device->CreateDepthStencilState(&desc, &data.zstencil_state); - if (FAILED(hr)) { - hlog_hr("d3d11_init_zstencil_state: failed to create " - "zstencil state", - hr); - return false; - } - - return true; -} - -static inline bool d3d11_init_raster_state(void) -{ - D3D11_RASTERIZER_DESC desc = {}; - HRESULT hr; - - desc.FillMode = D3D11_FILL_SOLID; - desc.CullMode = D3D11_CULL_NONE; - - hr = data.device->CreateRasterizerState(&desc, &data.raster_state); - if (FAILED(hr)) { - hlog_hr("d3d11_init_raster_state: failed to create raster " - "state", - hr); - return false; - } - - return true; -} - -#define NUM_VERTS 4 - -static inline bool d3d11_init_vertex_buffer(void) -{ - HRESULT hr; - const vertex verts[NUM_VERTS] = { - {{-1.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}, - {{-1.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 1.0f}}, - {{1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.0f}}, - {{1.0f, -1.0f, 0.0f, 1.0f}, {1.0f, 1.0f}}}; - - D3D11_BUFFER_DESC desc; - desc.ByteWidth = sizeof(vertex) * NUM_VERTS; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - D3D11_SUBRESOURCE_DATA srd = {}; - srd.pSysMem = (const void *)verts; - - hr = data.device->CreateBuffer(&desc, &srd, &data.vertex_buffer); - if (FAILED(hr)) { - hlog_hr("d3d11_init_vertex_buffer: failed to create vertex " - "buffer", - hr); - return false; - } - - return true; -} - -static bool d3d11_init_scaling(void) -{ - bool success; - - success = create_d3d11_tex(data.base_cx, data.base_cy, &data.scale_tex, - &data.scale_resource, nullptr, nullptr); - if (!success) { - hlog("d3d11_init_scaling: failed to create scale texture"); - return false; - } - - if (!d3d11_init_vertex_shader()) { - return false; - } - if (!d3d11_init_pixel_shader()) { - return false; - } - if (!d3d11_init_sampler_state()) { - return false; - } - if (!d3d11_init_blend_state()) { - return false; - } - if (!d3d11_init_zstencil_state()) { - return false; - } - if (!d3d11_init_raster_state()) { - return false; - } - if (!d3d11_init_vertex_buffer()) { - return false; - } + data.cx = desc.BufferDesc.Width; + data.cy = desc.BufferDesc.Height; return true; } @@ -472,13 +251,6 @@ static bool d3d11_shmem_init_buffers(size_t idx) data.context->Unmap(data.copy_surfaces[idx], 0); } - success = create_d3d11_tex(data.cx, data.cy, &data.textures[idx], - nullptr, &data.render_targets[idx], nullptr); - if (!success) { - hlog("d3d11_shmem_init_buffers: failed to create texture"); - return false; - } - return true; } @@ -491,9 +263,8 @@ static bool d3d11_shmem_init(HWND window) return false; } } - if (!capture_init_shmem(&data.shmem_info, window, data.base_cx, - data.base_cy, data.cx, data.cy, data.pitch, - data.format, false)) { + if (!capture_init_shmem(&data.shmem_info, window, data.cx, data.cy, + data.pitch, data.format, false)) { return false; } @@ -517,9 +288,8 @@ static bool d3d11_shtex_init(HWND window) hlog("d3d11_shtex_init: failed to create texture"); return false; } - if (!capture_init_shtex(&data.shtex_info, window, data.base_cx, - data.base_cy, data.cx, data.cy, data.format, - false, (uintptr_t)data.handle)) { + if (!capture_init_shtex(&data.shtex_info, window, data.cx, data.cy, + data.format, false, (uintptr_t)data.handle)) { return false; } @@ -529,12 +299,9 @@ static bool d3d11_shtex_init(HWND window) static void d3d11_init(IDXGISwapChain *swap) { - bool success = true; HWND window; HRESULT hr; - data.using_scale = global_hook_info->use_scale; - hr = swap->GetDevice(__uuidof(ID3D11Device), (void **)&data.device); if (FAILED(hr)) { hlog_hr("d3d11_init: failed to get device from swap", hr); @@ -549,201 +316,14 @@ static void d3d11_init(IDXGISwapChain *swap) if (!d3d11_init_format(swap, window)) { return; } - if (data.using_scale && !d3d11_init_scaling()) { - hlog("d3d11_init: failed to initialize scaling"); - success = false; - } - if (success) { - if (global_hook_info->force_shmem) { - success = d3d11_shmem_init(window); - } else { - success = d3d11_shtex_init(window); - } - } + const bool success = global_hook_info->force_shmem + ? d3d11_shmem_init(window) + : d3d11_shtex_init(window); if (!success) d3d11_free(); } -#define MAX_RENDER_TARGETS D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT -#define MAX_SO_TARGETS 4 -#define MAX_CLASS_INSTS 256 - -struct d3d11_state { - ID3D11GeometryShader *geom_shader; - ID3D11InputLayout *vertex_layout; - D3D11_PRIMITIVE_TOPOLOGY topology; - ID3D11Buffer *vertex_buffer; - UINT vb_stride; - UINT vb_offset; - ID3D11BlendState *blend_state; - float blend_factor[4]; - UINT sample_mask; - ID3D11DepthStencilState *zstencil_state; - UINT zstencil_ref; - ID3D11RenderTargetView *render_targets[MAX_RENDER_TARGETS]; - ID3D11DepthStencilView *zstencil_view; - ID3D11SamplerState *sampler_state; - ID3D11PixelShader *pixel_shader; - ID3D11ShaderResourceView *resource; - ID3D11RasterizerState *raster_state; - UINT num_viewports; - D3D11_VIEWPORT *viewports; - ID3D11Buffer *stream_output_targets[MAX_SO_TARGETS]; - ID3D11VertexShader *vertex_shader; - ID3D11ClassInstance *gs_class_instances[MAX_CLASS_INSTS]; - ID3D11ClassInstance *ps_class_instances[MAX_CLASS_INSTS]; - ID3D11ClassInstance *vs_class_instances[MAX_CLASS_INSTS]; - UINT gs_class_inst_count; - UINT ps_class_inst_count; - UINT vs_class_inst_count; -}; - -static inline void d3d11_save_state(struct d3d11_state *state) -{ - state->gs_class_inst_count = MAX_CLASS_INSTS; - state->ps_class_inst_count = MAX_CLASS_INSTS; - state->vs_class_inst_count = MAX_CLASS_INSTS; - - data.context->GSGetShader(&state->geom_shader, - state->gs_class_instances, - &state->gs_class_inst_count); - data.context->IAGetInputLayout(&state->vertex_layout); - data.context->IAGetPrimitiveTopology(&state->topology); - data.context->IAGetVertexBuffers(0, 1, &state->vertex_buffer, - &state->vb_stride, &state->vb_offset); - data.context->OMGetBlendState(&state->blend_state, state->blend_factor, - &state->sample_mask); - data.context->OMGetDepthStencilState(&state->zstencil_state, - &state->zstencil_ref); - data.context->OMGetRenderTargets(MAX_RENDER_TARGETS, - state->render_targets, - &state->zstencil_view); - data.context->PSGetSamplers(0, 1, &state->sampler_state); - data.context->PSGetShader(&state->pixel_shader, - state->ps_class_instances, - &state->ps_class_inst_count); - data.context->PSGetShaderResources(0, 1, &state->resource); - data.context->RSGetState(&state->raster_state); - data.context->RSGetViewports(&state->num_viewports, nullptr); - if (state->num_viewports) { - state->viewports = (D3D11_VIEWPORT *)malloc( - sizeof(D3D11_VIEWPORT) * state->num_viewports); - data.context->RSGetViewports(&state->num_viewports, - state->viewports); - } - data.context->SOGetTargets(MAX_SO_TARGETS, - state->stream_output_targets); - data.context->VSGetShader(&state->vertex_shader, - state->vs_class_instances, - &state->vs_class_inst_count); -} - -static inline void safe_release(IUnknown *p) -{ - if (p) - p->Release(); -} - -#define SO_APPEND ((UINT)-1) - -static inline void d3d11_restore_state(struct d3d11_state *state) -{ - UINT so_offsets[MAX_SO_TARGETS] = {SO_APPEND, SO_APPEND, SO_APPEND, - SO_APPEND}; - - data.context->GSSetShader(state->geom_shader, state->gs_class_instances, - state->gs_class_inst_count); - data.context->IASetInputLayout(state->vertex_layout); - data.context->IASetPrimitiveTopology(state->topology); - data.context->IASetVertexBuffers(0, 1, &state->vertex_buffer, - &state->vb_stride, &state->vb_offset); - data.context->OMSetBlendState(state->blend_state, state->blend_factor, - state->sample_mask); - data.context->OMSetDepthStencilState(state->zstencil_state, - state->zstencil_ref); - data.context->OMSetRenderTargets(MAX_RENDER_TARGETS, - state->render_targets, - state->zstencil_view); - data.context->PSSetSamplers(0, 1, &state->sampler_state); - data.context->PSSetShader(state->pixel_shader, - state->ps_class_instances, - state->ps_class_inst_count); - data.context->PSSetShaderResources(0, 1, &state->resource); - data.context->RSSetState(state->raster_state); - data.context->RSSetViewports(state->num_viewports, state->viewports); - data.context->SOSetTargets(MAX_SO_TARGETS, state->stream_output_targets, - so_offsets); - data.context->VSSetShader(state->vertex_shader, - state->vs_class_instances, - state->vs_class_inst_count); - safe_release(state->geom_shader); - safe_release(state->vertex_layout); - safe_release(state->vertex_buffer); - safe_release(state->blend_state); - safe_release(state->zstencil_state); - for (size_t i = 0; i < MAX_RENDER_TARGETS; i++) - safe_release(state->render_targets[i]); - safe_release(state->zstencil_view); - safe_release(state->sampler_state); - safe_release(state->pixel_shader); - safe_release(state->resource); - safe_release(state->raster_state); - for (size_t i = 0; i < MAX_SO_TARGETS; i++) - safe_release(state->stream_output_targets[i]); - safe_release(state->vertex_shader); - for (size_t i = 0; i < state->gs_class_inst_count; i++) - state->gs_class_instances[i]->Release(); - for (size_t i = 0; i < state->ps_class_inst_count; i++) - state->ps_class_instances[i]->Release(); - for (size_t i = 0; i < state->vs_class_inst_count; i++) - state->vs_class_instances[i]->Release(); - free(state->viewports); - memset(state, 0, sizeof(*state)); -} - -static inline void d3d11_setup_pipeline(ID3D11RenderTargetView *target, - ID3D11ShaderResourceView *resource) -{ - const float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - D3D11_VIEWPORT viewport = {0}; - UINT stride = sizeof(vertex); - void *emptyptr = nullptr; - UINT zero = 0; - - viewport.Width = (float)data.cx; - viewport.Height = (float)data.cy; - viewport.MaxDepth = 1.0f; - - data.context->GSSetShader(nullptr, nullptr, 0); - data.context->IASetInputLayout(data.vertex_layout); - data.context->IASetPrimitiveTopology( - D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - data.context->IASetVertexBuffers(0, 1, &data.vertex_buffer, &stride, - &zero); - data.context->OMSetBlendState(data.blend_state, factor, 0xFFFFFFFF); - data.context->OMSetDepthStencilState(data.zstencil_state, 0); - data.context->OMSetRenderTargets(1, &target, nullptr); - data.context->PSSetSamplers(0, 1, &data.sampler_state); - data.context->PSSetShader(data.pixel_shader, nullptr, 0); - data.context->PSSetShaderResources(0, 1, &resource); - data.context->RSSetState(data.raster_state); - data.context->RSSetViewports(1, &viewport); - data.context->SOSetTargets(1, (ID3D11Buffer **)&emptyptr, &zero); - data.context->VSSetShader(data.vertex_shader, nullptr, 0); -} - -static inline void d3d11_scale_texture(ID3D11RenderTargetView *target, - ID3D11ShaderResourceView *resource) -{ - static struct d3d11_state old_state = {0}; - - d3d11_save_state(&old_state); - d3d11_setup_pipeline(target, resource); - data.context->Draw(4, 0); - d3d11_restore_state(&old_state); -} - static inline void d3d11_copy_texture(ID3D11Resource *dst, ID3D11Resource *src) { if (data.multisampled) { @@ -755,30 +335,22 @@ static inline void d3d11_copy_texture(ID3D11Resource *dst, ID3D11Resource *src) static inline void d3d11_shtex_capture(ID3D11Resource *backbuffer) { - if (data.using_scale) { - d3d11_copy_texture(data.scale_tex, backbuffer); - d3d11_scale_texture(data.render_target, data.scale_resource); - } else { - d3d11_copy_texture(data.texture, backbuffer); - } + d3d11_copy_texture(data.texture, backbuffer); } -static inline void d3d11_shmem_queue_copy() +static void d3d11_shmem_capture_copy(int i) { - for (size_t i = 0; i < NUM_BUFFERS; i++) { - D3D11_MAPPED_SUBRESOURCE map; - HRESULT hr; + D3D11_MAPPED_SUBRESOURCE map; + HRESULT hr; - if (data.texture_ready[i]) { - data.texture_ready[i] = false; + if (data.texture_ready[i]) { + data.texture_ready[i] = false; - hr = data.context->Map(data.copy_surfaces[i], 0, - D3D11_MAP_READ, 0, &map); - if (SUCCEEDED(hr)) { - data.texture_mapped[i] = true; - shmem_copy_data(i, map.pData); - } - break; + hr = data.context->Map(data.copy_surfaces[i], 0, D3D11_MAP_READ, + 0, &map); + if (SUCCEEDED(hr)) { + data.texture_mapped[i] = true; + shmem_copy_data(i, map.pData); } } } @@ -787,32 +359,22 @@ static inline void d3d11_shmem_capture(ID3D11Resource *backbuffer) { int next_tex; - d3d11_shmem_queue_copy(); - - next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1; - - if (data.using_scale) { - d3d11_copy_texture(data.scale_tex, backbuffer); - d3d11_scale_texture(data.render_targets[data.cur_tex], - data.scale_resource); - } else { - d3d11_copy_texture(data.textures[data.cur_tex], backbuffer); - } + next_tex = (data.cur_tex + 1) % NUM_BUFFERS; + d3d11_shmem_capture_copy(next_tex); if (data.copy_wait < NUM_BUFFERS - 1) { data.copy_wait++; } else { - ID3D11Texture2D *src = data.textures[next_tex]; - ID3D11Texture2D *dst = data.copy_surfaces[next_tex]; - - if (shmem_texture_data_lock(next_tex)) { - data.context->Unmap(dst, 0); - data.texture_mapped[next_tex] = false; - shmem_texture_data_unlock(next_tex); + if (shmem_texture_data_lock(data.cur_tex)) { + data.context->Unmap(data.copy_surfaces[data.cur_tex], + 0); + data.texture_mapped[data.cur_tex] = false; + shmem_texture_data_unlock(data.cur_tex); } - d3d11_copy_texture(dst, src); - data.texture_ready[next_tex] = true; + d3d11_copy_texture(data.copy_surfaces[data.cur_tex], + backbuffer); + data.texture_ready[data.cur_tex] = true; } data.cur_tex = next_tex; diff --git a/plugins/win-capture/graphics-hook/d3d12-capture.cpp b/plugins/win-capture/graphics-hook/d3d12-capture.cpp index 00fbf6e26..eac437377 100644 --- a/plugins/win-capture/graphics-hook/d3d12-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d12-capture.cpp @@ -14,13 +14,10 @@ struct d3d12_data { ID3D12Device *device; /* do not release */ - uint32_t base_cx; - uint32_t base_cy; uint32_t cx; uint32_t cy; DXGI_FORMAT format; bool using_shtex; - bool using_scale; bool multisampled; bool dxgi_1_4; @@ -197,9 +194,8 @@ static bool d3d12_shtex_init(HWND window, bb_info &bb) if (!create_d3d12_tex(bb)) { return false; } - if (!capture_init_shtex(&data.shtex_info, window, data.base_cx, - data.base_cy, data.cx, data.cy, data.format, - false, (uintptr_t)data.handle)) { + if (!capture_init_shtex(&data.shtex_info, window, data.cx, data.cy, + data.format, false, (uintptr_t)data.handle)) { return false; } @@ -223,8 +219,8 @@ static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window, data.format = fix_dxgi_format(desc.BufferDesc.Format); data.multisampled = desc.SampleDesc.Count > 1; window = desc.OutputWindow; - data.base_cx = desc.BufferDesc.Width; - data.base_cy = desc.BufferDesc.Height; + data.cx = desc.BufferDesc.Width; + data.cy = desc.BufferDesc.Height; hr = swap->QueryInterface(__uuidof(IDXGISwapChain3), (void **)&swap3); if (SUCCEEDED(hr)) { @@ -260,25 +256,15 @@ static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window, } } - if (data.using_scale) { - data.cx = global_hook_info->cx; - data.cy = global_hook_info->cy; - } else { - data.cx = desc.BufferDesc.Width; - data.cy = desc.BufferDesc.Height; - } return true; } static void d3d12_init(IDXGISwapChain *swap) { - bool success = true; bb_info bb = {}; HWND window; HRESULT hr; - data.using_scale = global_hook_info->use_scale; - hr = swap->GetDevice(__uuidof(ID3D12Device), (void **)&data.device); if (FAILED(hr)) { hlog_hr("d3d12_init: failed to get device from swap", hr); @@ -290,19 +276,13 @@ static void d3d12_init(IDXGISwapChain *swap) if (!d3d12_init_format(swap, window, bb)) { return; } - if (data.using_scale) { - hlog("d3d12_init: scaling currently unsupported; ignoring"); - } - if (success) { - if (global_hook_info->force_shmem) { - hlog("d3d12_init: shared memory capture currently " - "unsupported; ignoring"); - } - success = d3d12_shtex_init(window, bb); + if (global_hook_info->force_shmem) { + hlog("d3d12_init: shared memory capture currently " + "unsupported; ignoring"); } - if (!success) + if (!d3d12_shtex_init(window, bb)) d3d12_free(); } diff --git a/plugins/win-capture/graphics-hook/d3d1x_shaders.hpp b/plugins/win-capture/graphics-hook/d3d1x_shaders.hpp deleted file mode 100644 index a12b35118..000000000 --- a/plugins/win-capture/graphics-hook/d3d1x_shaders.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -static const char vertex_shader_string[] = "struct VertData \ -{ \ - float4 pos : SV_Position; \ - float2 texCoord : TexCoord0; \ -}; \ -VertData main(VertData input) \ -{ \ - VertData output; \ - output.pos = input.pos; \ - output.texCoord = input.texCoord; \ - return output; \ -}"; - -static const char pixel_shader_string[] = "uniform Texture2D diffuseTexture; \ -SamplerState textureSampler \ -{ \ - AddressU = Clamp; \ - AddressV = Clamp; \ - Filter = Linear; \ -}; \ -struct VertData \ -{ \ - float4 pos : SV_Position; \ - float2 texCoord : TexCoord0; \ -}; \ -float4 main(VertData input) : SV_Target \ -{ \ - return diffuseTexture.Sample(textureSampler, input.texCoord); \ -}"; diff --git a/plugins/win-capture/graphics-hook/d3d8-capture.cpp b/plugins/win-capture/graphics-hook/d3d8-capture.cpp index 592417585..2f46d0c4c 100644 --- a/plugins/win-capture/graphics-hook/d3d8-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d8-capture.cpp @@ -24,6 +24,7 @@ struct d3d8_data { HWND window; uint32_t pitch; IDirect3DSurface8 *copy_surfaces[NUM_BUFFERS]; + bool texture_ready[NUM_BUFFERS]; bool surface_locked[NUM_BUFFERS]; int cur_surface; int copy_wait; @@ -145,8 +146,7 @@ static bool d3d8_shmem_init(IDirect3DDevice8 *device) } } if (!capture_init_shmem(&data.shmem_info, data.window, data.cx, data.cy, - data.cx, data.cy, data.pitch, data.dxgi_format, - false)) { + data.pitch, data.dxgi_format, false)) { return false; } @@ -184,45 +184,50 @@ static void d3d8_init(IDirect3DDevice8 *device) static void d3d8_shmem_capture_copy(int idx) { - IDirect3DSurface8 *target = data.copy_surfaces[idx]; D3DLOCKED_RECT rect; HRESULT hr; - if (data.surface_locked[idx]) - return; + if (data.texture_ready[idx]) { + data.texture_ready[idx] = false; - hr = target->LockRect(&rect, nullptr, D3DLOCK_READONLY); - if (SUCCEEDED(hr)) { - shmem_copy_data(idx, rect.pBits); + IDirect3DSurface8 *target = data.copy_surfaces[idx]; + hr = target->LockRect(&rect, nullptr, D3DLOCK_READONLY); + if (SUCCEEDED(hr)) { + data.surface_locked[idx] = true; + shmem_copy_data(idx, rect.pBits); + } } } static void d3d8_shmem_capture(IDirect3DDevice8 *device, IDirect3DSurface8 *backbuffer) { - int cur_surface; int next_surface; HRESULT hr; - cur_surface = data.cur_surface; - next_surface = (cur_surface == NUM_BUFFERS - 1) ? 0 : cur_surface + 1; + next_surface = (data.cur_surface + 1) % NUM_BUFFERS; + d3d8_shmem_capture_copy(next_surface); if (data.copy_wait < NUM_BUFFERS - 1) { data.copy_wait++; } else { IDirect3DSurface8 *src = backbuffer; - IDirect3DSurface8 *dst = data.copy_surfaces[cur_surface]; + IDirect3DSurface8 *dst = data.copy_surfaces[data.cur_surface]; - if (shmem_texture_data_lock(next_surface)) { + if (shmem_texture_data_lock(data.cur_surface)) { dst->UnlockRect(); - data.surface_locked[next_surface] = false; - shmem_texture_data_unlock(next_surface); + data.surface_locked[data.cur_surface] = false; + shmem_texture_data_unlock(data.cur_surface); } hr = device->CopyRects(src, nullptr, 0, dst, nullptr); - if (SUCCEEDED(hr)) { - d3d8_shmem_capture_copy(cur_surface); + if (FAILED(hr)) { + hlog_hr("d3d8_shmem_capture: CopyRects " + "failed", + hr); } + + data.texture_ready[data.cur_surface] = true; } data.cur_surface = next_surface; diff --git a/plugins/win-capture/graphics-hook/d3d9-capture.cpp b/plugins/win-capture/graphics-hook/d3d9-capture.cpp index 12ac6ba50..92b5eacc7 100644 --- a/plugins/win-capture/graphics-hook/d3d9-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d9-capture.cpp @@ -38,7 +38,6 @@ struct d3d9_data { D3DFORMAT d3d9_format; DXGI_FORMAT dxgi_format; bool using_shtex; - bool using_scale; /* shared texture */ IDirect3DSurface9 *d3d9_copytex; @@ -51,7 +50,6 @@ struct d3d9_data { /* shared memory */ IDirect3DSurface9 *copy_surfaces[NUM_BUFFERS]; - IDirect3DSurface9 *render_targets[NUM_BUFFERS]; IDirect3DQuery9 *queries[NUM_BUFFERS]; struct shmem_data *shmem_info; bool texture_mapped[NUM_BUFFERS]; @@ -83,8 +81,6 @@ static void d3d9_free() data.copy_surfaces[i]->UnlockRect(); data.copy_surfaces[i]->Release(); } - if (data.render_targets[i]) - data.render_targets[i]->Release(); if (data.queries[i]) data.queries[i]->Release(); } @@ -289,7 +285,7 @@ static inline bool d3d9_shtex_init_copytex() return true; } -static bool d3d9_shtex_init(uint32_t cx, uint32_t cy, HWND window) +static bool d3d9_shtex_init(HWND window) { data.using_shtex = true; @@ -302,8 +298,8 @@ static bool d3d9_shtex_init(uint32_t cx, uint32_t cy, HWND window) if (!d3d9_shtex_init_copytex()) { return false; } - if (!capture_init_shtex(&data.shtex_info, window, cx, cy, data.cx, - data.cy, data.dxgi_format, false, + if (!capture_init_shtex(&data.shtex_info, window, data.cx, data.cy, + data.dxgi_format, false, (uintptr_t)data.handle)) { return false; } @@ -340,17 +336,6 @@ static bool d3d9_shmem_init_buffers(size_t buffer) data.copy_surfaces[buffer]->UnlockRect(); } - hr = data.device->CreateRenderTarget(data.cx, data.cy, data.d3d9_format, - D3DMULTISAMPLE_NONE, 0, false, - &data.render_targets[buffer], - nullptr); - if (FAILED(hr)) { - hlog_hr("d3d9_shmem_init_buffers: Failed to create render " - "target", - hr); - return false; - } - hr = data.device->CreateQuery(D3DQUERYTYPE_EVENT, &data.queries[buffer]); if (FAILED(hr)) { @@ -361,7 +346,7 @@ static bool d3d9_shmem_init_buffers(size_t buffer) return true; } -static bool d3d9_shmem_init(uint32_t cx, uint32_t cy, HWND window) +static bool d3d9_shmem_init(HWND window) { data.using_shtex = false; @@ -370,8 +355,8 @@ static bool d3d9_shmem_init(uint32_t cx, uint32_t cy, HWND window) return false; } } - if (!capture_init_shmem(&data.shmem_info, window, cx, cy, data.cx, - data.cy, data.pitch, data.dxgi_format, false)) { + if (!capture_init_shmem(&data.shmem_info, window, data.cx, data.cy, + data.pitch, data.dxgi_format, false)) { return false; } @@ -403,8 +388,7 @@ static bool d3d9_get_swap_desc(D3DPRESENT_PARAMETERS &pp) return true; } -static bool d3d9_init_format_backbuffer(uint32_t &cx, uint32_t &cy, - HWND &window) +static bool d3d9_init_format_backbuffer(HWND &window) { IDirect3DSurface9 *back_buffer = nullptr; D3DPRESENT_PARAMETERS pp; @@ -432,23 +416,15 @@ static bool d3d9_init_format_backbuffer(uint32_t &cx, uint32_t &cy, data.d3d9_format = desc.Format; data.dxgi_format = d3d9_to_dxgi_format(desc.Format); - data.using_scale = global_hook_info->use_scale; window = pp.hDeviceWindow; - cx = desc.Width; - cy = desc.Height; - if (data.using_scale) { - data.cx = global_hook_info->cx; - data.cy = global_hook_info->cy; - } else { - data.cx = desc.Width; - data.cy = desc.Height; - } + data.cx = desc.Width; + data.cy = desc.Height; return true; } -static bool d3d9_init_format_swapchain(uint32_t &cx, uint32_t &cy, HWND &window) +static bool d3d9_init_format_swapchain(HWND &window) { D3DPRESENT_PARAMETERS pp; @@ -458,18 +434,10 @@ static bool d3d9_init_format_swapchain(uint32_t &cx, uint32_t &cy, HWND &window) data.dxgi_format = d3d9_to_dxgi_format(pp.BackBufferFormat); data.d3d9_format = pp.BackBufferFormat; - data.using_scale = global_hook_info->use_scale; window = pp.hDeviceWindow; - cx = pp.BackBufferWidth; - cy = pp.BackBufferHeight; - if (data.using_scale) { - data.cx = global_hook_info->cx; - data.cy = global_hook_info->cy; - } else { - data.cx = pp.BackBufferWidth; - data.cy = pp.BackBufferHeight; - } + data.cx = pp.BackBufferWidth; + data.cy = pp.BackBufferHeight; return true; } @@ -481,8 +449,6 @@ static void d3d9_init(IDirect3DDevice9 *device) global_hook_info->offsets.d3d9.d3d9_clsoff && global_hook_info->offsets.d3d9.is_d3d9ex_clsoff; bool success; - uint32_t cx = 0; - uint32_t cy = 0; HWND window = nullptr; HRESULT hr; @@ -500,17 +466,17 @@ static void d3d9_init(IDirect3DDevice9 *device) data.patch = -1; } - if (!d3d9_init_format_backbuffer(cx, cy, window)) { - if (!d3d9_init_format_swapchain(cx, cy, window)) { + if (!d3d9_init_format_backbuffer(window)) { + if (!d3d9_init_format_swapchain(window)) { return; } } if (global_hook_info->force_shmem || (!d3d9ex && data.patch == -1 && !has_d3d9ex_bool_offset)) { - success = d3d9_shmem_init(cx, cy, window); + success = d3d9_shmem_init(window); } else { - success = d3d9_shtex_init(cx, cy, window); + success = d3d9_shtex_init(window); } if (!success) @@ -539,73 +505,54 @@ static inline HRESULT get_backbuffer(IDirect3DDevice9 *device, static inline void d3d9_shtex_capture(IDirect3DSurface9 *backbuffer) { - D3DTEXTUREFILTERTYPE filter; HRESULT hr; - filter = data.using_scale ? D3DTEXF_LINEAR : D3DTEXF_NONE; - hr = data.device->StretchRect(backbuffer, nullptr, data.d3d9_copytex, - nullptr, filter); + nullptr, D3DTEXF_NONE); if (FAILED(hr)) hlog_hr("d3d9_shtex_capture: StretchRect failed", hr); } -static inline void d3d9_shmem_capture_queue_copy() +static void d3d9_shmem_capture_copy(int i) { - for (int i = 0; i < NUM_BUFFERS; i++) { - IDirect3DSurface9 *target = data.copy_surfaces[i]; - D3DLOCKED_RECT rect; - HRESULT hr; + IDirect3DSurface9 *target = data.copy_surfaces[i]; + D3DLOCKED_RECT rect; + HRESULT hr; - if (!data.issued_queries[i]) { - continue; - } - if (data.queries[i]->GetData(0, 0, 0) != S_OK) { - continue; - } + if (!data.issued_queries[i]) { + return; + } + if (data.queries[i]->GetData(0, 0, 0) != S_OK) { + return; + } - data.issued_queries[i] = false; + data.issued_queries[i] = false; - hr = target->LockRect(&rect, nullptr, D3DLOCK_READONLY); - if (SUCCEEDED(hr)) { - data.texture_mapped[i] = true; - shmem_copy_data(i, rect.pBits); - } - break; + hr = target->LockRect(&rect, nullptr, D3DLOCK_READONLY); + if (SUCCEEDED(hr)) { + data.texture_mapped[i] = true; + shmem_copy_data(i, rect.pBits); } } static inline void d3d9_shmem_capture(IDirect3DSurface9 *backbuffer) { - D3DTEXTUREFILTERTYPE filter; - IDirect3DSurface9 *copy; int next_tex; HRESULT hr; - d3d9_shmem_capture_queue_copy(); - - next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1; - filter = data.using_scale ? D3DTEXF_LINEAR : D3DTEXF_NONE; - copy = data.render_targets[data.cur_tex]; - - hr = data.device->StretchRect(backbuffer, nullptr, copy, nullptr, - filter); - - if (FAILED(hr)) { - hlog_hr("d3d9_shmem_capture: StretchRect failed", hr); - return; - } + next_tex = (data.cur_tex + 1) % NUM_BUFFERS; + d3d9_shmem_capture_copy(next_tex); if (data.copy_wait < NUM_BUFFERS - 1) { data.copy_wait++; } else { - IDirect3DSurface9 *src = data.render_targets[next_tex]; - IDirect3DSurface9 *dst = data.copy_surfaces[next_tex]; + IDirect3DSurface9 *src = backbuffer; + IDirect3DSurface9 *dst = data.copy_surfaces[data.cur_tex]; - if (shmem_texture_data_lock(next_tex)) { + if (shmem_texture_data_lock(data.cur_tex)) { dst->UnlockRect(); - data.texture_mapped[next_tex] = false; - shmem_texture_data_unlock(next_tex); + data.texture_mapped[data.cur_tex] = false; + shmem_texture_data_unlock(data.cur_tex); } hr = data.device->GetRenderTargetData(src, dst); @@ -615,8 +562,8 @@ static inline void d3d9_shmem_capture(IDirect3DSurface9 *backbuffer) hr); } - data.queries[next_tex]->Issue(D3DISSUE_END); - data.issued_queries[next_tex] = true; + data.queries[data.cur_tex]->Issue(D3DISSUE_END); + data.issued_queries[data.cur_tex] = true; } data.cur_tex = next_tex; diff --git a/plugins/win-capture/graphics-hook/dxgi-capture.cpp b/plugins/win-capture/graphics-hook/dxgi-capture.cpp index 4bcbd3658..b5c82f6c4 100644 --- a/plugins/win-capture/graphics-hook/dxgi-capture.cpp +++ b/plugins/win-capture/graphics-hook/dxgi-capture.cpp @@ -3,7 +3,6 @@ #include #include -#include "d3d1x_shaders.hpp" #include "graphics-hook.h" #include "../funchook.h" @@ -218,41 +217,9 @@ hook_present1(IDXGISwapChain1 *swap, UINT sync_interval, UINT flags, return hr; } -static pD3DCompile get_compiler(void) -{ - pD3DCompile compile = nullptr; - char d3dcompiler[40] = {}; - int ver = 49; - - while (ver > 30) { - sprintf_s(d3dcompiler, 40, "D3DCompiler_%02d.dll", ver); - - HMODULE module = LoadLibraryA(d3dcompiler); - if (module) { - compile = (pD3DCompile)GetProcAddress(module, - "D3DCompile"); - if (compile) { - break; - } - } - - ver--; - } - - return compile; -} - -static uint8_t vertex_shader_data[1024]; -static uint8_t pixel_shader_data[1024]; -static size_t vertex_shader_size = 0; -static size_t pixel_shader_size = 0; - bool hook_dxgi(void) { - pD3DCompile compile; - ID3D10Blob *blob; HMODULE dxgi_module = get_system_module("dxgi.dll"); - HRESULT hr; void *present_addr; void *resize_addr; void *present1_addr = nullptr; @@ -261,42 +228,6 @@ bool hook_dxgi(void) return false; } - compile = get_compiler(); - if (!compile) { - hlog("hook_dxgi: failed to find d3d compiler library"); - return true; - } - - /* ---------------------- */ - - hr = compile(vertex_shader_string, sizeof(vertex_shader_string), - "vertex_shader_string", nullptr, nullptr, "main", "vs_4_0", - D3D10_SHADER_OPTIMIZATION_LEVEL1, 0, &blob, nullptr); - if (FAILED(hr)) { - hlog_hr("hook_dxgi: failed to compile vertex shader", hr); - return true; - } - - vertex_shader_size = (size_t)blob->GetBufferSize(); - memcpy(vertex_shader_data, blob->GetBufferPointer(), - blob->GetBufferSize()); - blob->Release(); - - /* ---------------------- */ - - hr = compile(pixel_shader_string, sizeof(pixel_shader_string), - "pixel_shader_string", nullptr, nullptr, "main", "ps_4_0", - D3D10_SHADER_OPTIMIZATION_LEVEL1, 0, &blob, nullptr); - if (FAILED(hr)) { - hlog_hr("hook_dxgi: failed to compile pixel shader", hr); - return true; - } - - pixel_shader_size = (size_t)blob->GetBufferSize(); - memcpy(pixel_shader_data, blob->GetBufferPointer(), - blob->GetBufferSize()); - blob->Release(); - /* ---------------------- */ present_addr = get_offset_addr(dxgi_module, @@ -323,15 +254,3 @@ bool hook_dxgi(void) hlog("Hooked DXGI"); return true; } - -uint8_t *get_d3d1x_vertex_shader(size_t *size) -{ - *size = vertex_shader_size; - return vertex_shader_data; -} - -uint8_t *get_d3d1x_pixel_shader(size_t *size) -{ - *size = pixel_shader_size; - return pixel_shader_data; -} diff --git a/plugins/win-capture/graphics-hook/gl-capture.c b/plugins/win-capture/graphics-hook/gl-capture.c index 5d6db11a9..91f068e5c 100644 --- a/plugins/win-capture/graphics-hook/gl-capture.c +++ b/plugins/win-capture/graphics-hook/gl-capture.c @@ -34,14 +34,11 @@ static bool functions_initialized = false; struct gl_data { HDC hdc; - uint32_t base_cx; - uint32_t base_cy; uint32_t cx; uint32_t cy; DXGI_FORMAT format; GLuint fbo; bool using_shtex; - bool using_scale; bool shmem_fallback; union { @@ -434,9 +431,8 @@ static bool gl_shtex_init(HWND window) if (!gl_init_fbo()) { return false; } - if (!capture_init_shtex(&data.shtex_info, window, data.base_cx, - data.base_cy, data.cx, data.cy, data.format, - true, (uintptr_t)data.handle)) { + if (!capture_init_shtex(&data.shtex_info, window, data.cx, data.cy, + data.format, true, (uintptr_t)data.handle)) { return false; } @@ -516,9 +512,8 @@ static bool gl_shmem_init(HWND window) if (!gl_init_fbo()) { return false; } - if (!capture_init_shmem(&data.shmem_info, window, data.base_cx, - data.base_cy, data.cx, data.cy, data.cx * 4, - data.format, true)) { + if (!capture_init_shmem(&data.shmem_info, window, data.cx, data.cy, + data.cx * 4, data.format, true)) { return false; } @@ -538,29 +533,20 @@ static int gl_init(HDC hdc) RECT rc = {0}; if (darkest_dungeon_fix) { - data.base_cx = 1920; - data.base_cy = 1080; + data.cx = 1920; + data.cy = 1080; } else { GetClientRect(window, &rc); - data.base_cx = rc.right; - data.base_cy = rc.bottom; + data.cx = rc.right; + data.cy = rc.bottom; } data.hdc = hdc; data.format = DXGI_FORMAT_B8G8R8A8_UNORM; - data.using_scale = global_hook_info->use_scale; data.using_shtex = nv_capture_available && !global_hook_info->force_shmem && !data.shmem_fallback; - if (data.using_scale) { - data.cx = global_hook_info->cx; - data.cy = global_hook_info->cy; - } else { - data.cx = data.base_cx; - data.cy = data.base_cy; - } - if (data.using_shtex) { success = gl_shtex_init(window); if (!success) @@ -606,8 +592,8 @@ static void gl_copy_backbuffer(GLuint dst) return; } - glBlitFramebuffer(0, 0, data.base_cx, data.base_cy, 0, 0, data.cx, - data.cy, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBlitFramebuffer(0, 0, data.cx, data.cy, 0, 0, data.cx, data.cy, + GL_COLOR_BUFFER_BIT, GL_LINEAR); gl_error("gl_copy_backbuffer", "failed to blit"); } @@ -638,27 +624,23 @@ static void gl_shtex_capture(void) IDXGISwapChain_Present(data.dxgi_swap, 0, 0); } -static inline void gl_shmem_capture_queue_copy(void) +static void gl_shmem_capture_copy(int i) { - for (int i = 0; i < NUM_BUFFERS; i++) { - if (data.texture_ready[i]) { - GLvoid *buffer; + if (data.texture_ready[i]) { + GLvoid *buffer; - data.texture_ready[i] = false; + data.texture_ready[i] = false; - glBindBuffer(GL_PIXEL_PACK_BUFFER, data.pbos[i]); - if (gl_error("gl_shmem_capture_queue_copy", - "failed to bind pbo")) { - return; - } + glBindBuffer(GL_PIXEL_PACK_BUFFER, data.pbos[i]); + if (gl_error("gl_shmem_capture_queue_copy", + "failed to bind pbo")) { + return; + } - buffer = - glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (buffer) { - data.texture_mapped[i] = true; - shmem_copy_data(i, buffer); - } - break; + buffer = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (buffer) { + data.texture_mapped[i] = true; + shmem_copy_data(i, buffer); } } } @@ -686,6 +668,7 @@ static void gl_shmem_capture(void) int next_tex; GLint last_fbo; GLint last_tex; + GLint last_pbo; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fbo); if (gl_error("gl_shmem_capture", "failed to get last fbo")) { @@ -697,30 +680,36 @@ static void gl_shmem_capture(void) return; } - gl_shmem_capture_queue_copy(); + glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &last_pbo); + if (gl_error("gl_shmem_capture", "failed to get last pbo")) { + return; + } - next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1; - - gl_copy_backbuffer(data.textures[next_tex]); + next_tex = (data.cur_tex + 1) % NUM_BUFFERS; + gl_shmem_capture_copy(next_tex); if (data.copy_wait < NUM_BUFFERS - 1) { data.copy_wait++; } else { - GLuint src = data.textures[next_tex]; - GLuint dst = data.pbos[next_tex]; - - if (shmem_texture_data_lock(next_tex)) { + if (shmem_texture_data_lock(data.cur_tex)) { + glBindBuffer(GL_PIXEL_PACK_BUFFER, + data.pbos[data.cur_tex]); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - data.texture_mapped[next_tex] = false; - shmem_texture_data_unlock(next_tex); + data.texture_mapped[data.cur_tex] = false; + shmem_texture_data_unlock(data.cur_tex); } - gl_shmem_capture_stage(dst, src); - data.texture_ready[next_tex] = true; + gl_copy_backbuffer(data.textures[data.cur_tex]); + gl_shmem_capture_stage(data.pbos[data.cur_tex], + data.textures[data.cur_tex]); + data.texture_ready[data.cur_tex] = true; } glBindTexture(GL_TEXTURE_2D, last_tex); + glBindBuffer(GL_PIXEL_PACK_BUFFER, last_pbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, last_fbo); + + data.cur_tex = next_tex; } static void gl_capture(HDC hdc) @@ -757,7 +746,7 @@ static void gl_capture(HDC hdc) /* reset capture if resized */ get_window_size(hdc, &new_cx, &new_cy); - if (new_cx != data.base_cx || new_cy != data.base_cy) { + if (new_cx != data.cx || new_cy != data.cy) { if (new_cx != 0 && new_cy != 0) gl_free(); return; diff --git a/plugins/win-capture/graphics-hook/graphics-hook.c b/plugins/win-capture/graphics-hook/graphics-hook.c index e6171b15b..d95b723eb 100644 --- a/plugins/win-capture/graphics-hook/graphics-hook.c +++ b/plugins/win-capture/graphics-hook/graphics-hook.c @@ -531,9 +531,9 @@ static inline bool init_shared_info(size_t size, HWND window) return true; } -bool capture_init_shtex(struct shtex_data **data, HWND window, uint32_t base_cx, - uint32_t base_cy, uint32_t cx, uint32_t cy, - uint32_t format, bool flip, uintptr_t handle) +bool capture_init_shtex(struct shtex_data **data, HWND window, uint32_t cx, + uint32_t cy, uint32_t format, bool flip, + uintptr_t handle) { if (!init_shared_info(sizeof(struct shtex_data), window)) { hlog("capture_init_shtex: Failed to initialize memory"); @@ -553,8 +553,8 @@ bool capture_init_shtex(struct shtex_data **data, HWND window, uint32_t base_cx, global_hook_info->map_size = sizeof(struct shtex_data); global_hook_info->cx = cx; global_hook_info->cy = cy; - global_hook_info->base_cx = base_cx; - global_hook_info->base_cy = base_cy; + global_hook_info->UNUSED_base_cx = cx; + global_hook_info->UNUSED_base_cy = cy; if (!SetEvent(signal_ready)) { hlog("capture_init_shtex: Failed to signal ready: %d", @@ -708,9 +708,8 @@ static inline bool init_shmem_thread(uint32_t pitch, uint32_t cy) #define ALIGN(bytes, align) (((bytes) + ((align)-1)) & ~((align)-1)) #endif -bool capture_init_shmem(struct shmem_data **data, HWND window, uint32_t base_cx, - uint32_t base_cy, uint32_t cx, uint32_t cy, - uint32_t pitch, uint32_t format, bool flip) +bool capture_init_shmem(struct shmem_data **data, HWND window, uint32_t cx, + uint32_t cy, uint32_t pitch, uint32_t format, bool flip) { uint32_t tex_size = cy * pitch; uint32_t aligned_header = ALIGN(sizeof(struct shmem_data), 32); @@ -749,8 +748,8 @@ bool capture_init_shmem(struct shmem_data **data, HWND window, uint32_t base_cx, global_hook_info->pitch = pitch; global_hook_info->cx = cx; global_hook_info->cy = cy; - global_hook_info->base_cx = base_cx; - global_hook_info->base_cy = base_cy; + global_hook_info->UNUSED_base_cx = cx; + global_hook_info->UNUSED_base_cy = cy; if (!init_shmem_thread(pitch, cy)) { return false; diff --git a/plugins/win-capture/graphics-hook/graphics-hook.h b/plugins/win-capture/graphics-hook/graphics-hook.h index e4e649d88..54bbcf1c6 100644 --- a/plugins/win-capture/graphics-hook/graphics-hook.h +++ b/plugins/win-capture/graphics-hook/graphics-hook.h @@ -59,19 +59,14 @@ extern void d3d12_capture(void *swap, void *backbuffer, bool capture_overlay); extern void d3d12_free(void); #endif -extern uint8_t *get_d3d1x_vertex_shader(size_t *size); -extern uint8_t *get_d3d1x_pixel_shader(size_t *size); - extern bool rehook_gl(void); extern bool capture_init_shtex(struct shtex_data **data, HWND window, - uint32_t base_cx, uint32_t base_cy, uint32_t cx, - uint32_t cy, uint32_t format, bool flip, - uintptr_t handle); + uint32_t cx, uint32_t cy, uint32_t format, + bool flip, uintptr_t handle); extern bool capture_init_shmem(struct shmem_data **data, HWND window, - uint32_t base_cx, uint32_t base_cy, uint32_t cx, - uint32_t cy, uint32_t pitch, uint32_t format, - bool flip); + uint32_t cx, uint32_t cy, uint32_t pitch, + uint32_t format, bool flip); extern void capture_free(void); extern struct hook_info *global_hook_info; diff --git a/plugins/win-capture/graphics-hook/vulkan-capture.c b/plugins/win-capture/graphics-hook/vulkan-capture.c index 2f0c3c70c..c03310717 100644 --- a/plugins/win-capture/graphics-hook/vulkan-capture.c +++ b/plugins/win-capture/graphics-hook/vulkan-capture.c @@ -705,11 +705,11 @@ static bool vk_shtex_init(struct vk_data *data, HWND window, data->cur_swap = swap; - swap->captured = capture_init_shtex( - &swap->shtex_info, window, swap->image_extent.width, - swap->image_extent.height, swap->image_extent.width, - swap->image_extent.height, (uint32_t)swap->format, false, - (uintptr_t)swap->handle); + swap->captured = capture_init_shtex(&swap->shtex_info, window, + swap->image_extent.width, + swap->image_extent.height, + (uint32_t)swap->format, false, + (uintptr_t)swap->handle); if (swap->captured) { if (global_hook_info->force_shmem) {