Преглед на файлове

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.
jp9000 преди 8 години
родител
ревизия
ea6efc9514
променени са 3 файла, в които са добавени 29 реда и са изтрити 15 реда
  1. 2 0
      libobs-d3d11/d3d11-shader.cpp
  2. 22 15
      libobs-d3d11/d3d11-subsystem.cpp
  3. 5 0
      libobs-d3d11/d3d11-subsystem.hpp

+ 2 - 0
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;
 }
 

+ 22 - 15
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<ID3D11Buffer*> buffers;
 	vector<uint32_t> strides;
 	vector<uint32_t> 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;
 }
 

+ 5 - 0
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,