From ea6efc95142ae8a3d9e56f377d3ffaa516f0cf6d Mon Sep 17 00:00:00 2001 From: jp9000 Date: Mon, 15 May 2017 23:35:50 -0700 Subject: [PATCH] libobs-d3d11: Only load vertex buffer before drawing Fixes a bug where loading vertex shaders could cause error messages about mismatching vertex buffer data to appear because the vertex shader would try to reload the previously used vertex buffer. --- libobs-d3d11/d3d11-shader.cpp | 2 ++ libobs-d3d11/d3d11-subsystem.cpp | 37 +++++++++++++++++++------------- libobs-d3d11/d3d11-subsystem.hpp | 5 +++++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/libobs-d3d11/d3d11-shader.cpp b/libobs-d3d11/d3d11-shader.cpp index fc3159f62..281d6ec69 100644 --- a/libobs-d3d11/d3d11-shader.cpp +++ b/libobs-d3d11/d3d11-shader.cpp @@ -287,6 +287,8 @@ void gs_shader::UploadParams() void gs_shader_destroy(gs_shader_t *shader) { + if (shader && shader->device->lastVertexShader == shader) + shader->device->lastVertexShader = nullptr; delete shader; } diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index 1cbaab8f1..8e72ddb14 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -929,33 +929,40 @@ enum gs_texture_type device_get_texture_type(const gs_texture_t *texture) return texture->type; } -void device_load_vertexbuffer(gs_device_t *device, gs_vertbuffer_t *vertbuffer) +void gs_device::LoadVertexBufferData() { - if (device->curVertexBuffer == vertbuffer) - return; - - device->curVertexBuffer = vertbuffer; - - if (!device->curVertexShader) + if (curVertexBuffer == lastVertexBuffer && + curVertexShader == lastVertexShader) return; vector buffers; vector strides; vector offsets; - if (vertbuffer) { - vertbuffer->MakeBufferList(device->curVertexShader, + if (curVertexBuffer && curVertexShader) { + curVertexBuffer->MakeBufferList(curVertexShader, buffers, strides); } else { - size_t buffersToClear = - device->curVertexShader->NumBuffersExpected(); + size_t buffersToClear = curVertexShader + ? curVertexShader->NumBuffersExpected() : 0; buffers.resize(buffersToClear); strides.resize(buffersToClear); } offsets.resize(buffers.size()); - device->context->IASetVertexBuffers(0, (UINT)buffers.size(), + context->IASetVertexBuffers(0, (UINT)buffers.size(), buffers.data(), strides.data(), offsets.data()); + + lastVertexBuffer = curVertexBuffer; + lastVertexShader = curVertexShader; +} + +void device_load_vertexbuffer(gs_device_t *device, gs_vertbuffer_t *vertbuffer) +{ + if (device->curVertexBuffer == vertbuffer) + return; + + device->curVertexBuffer = vertbuffer; } void device_load_indexbuffer(gs_device_t *device, gs_indexbuffer_t *indexbuffer) @@ -1044,9 +1051,6 @@ void device_load_vertexshader(gs_device_t *device, gs_shader_t *vertshader) device->context->VSSetShader(shader, NULL, 0); device->context->IASetInputLayout(layout); device->context->VSSetConstantBuffers(0, 1, &constants); - - if (vertshader && curVB) - device_load_vertexbuffer(device, curVB); } static inline void clear_textures(gs_device_t *device) @@ -1348,6 +1352,7 @@ void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode, if (effect) gs_effect_update_params(effect); + device->LoadVertexBufferData(); device->UpdateBlendState(); device->UpdateRasterState(); device->UpdateZStencilState(); @@ -1926,6 +1931,8 @@ void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate) void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer) { + if (vertbuffer && vertbuffer->device->lastVertexBuffer == vertbuffer) + vertbuffer->device->lastVertexBuffer = nullptr; delete vertbuffer; } diff --git a/libobs-d3d11/d3d11-subsystem.hpp b/libobs-d3d11/d3d11-subsystem.hpp index 1cec188cb..cf7ad6fab 100644 --- a/libobs-d3d11/d3d11-subsystem.hpp +++ b/libobs-d3d11/d3d11-subsystem.hpp @@ -789,6 +789,9 @@ struct gs_device { gs_pixel_shader *curPixelShader = nullptr; gs_swap_chain *curSwapChain = nullptr; + gs_vertex_buffer *lastVertexBuffer = nullptr; + gs_vertex_shader *lastVertexShader = nullptr; + bool zstencilStateChanged = true; bool rasterStateChanged = true; bool blendStateChanged = true; @@ -829,6 +832,8 @@ struct gs_device { void UpdateRasterState(); void UpdateBlendState(); + void LoadVertexBufferData(); + inline void CopyTex(ID3D11Texture2D *dst, uint32_t dst_x, uint32_t dst_y, gs_texture_t *src, uint32_t src_x, uint32_t src_y,