Bläddra i källkod

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 år sedan
förälder
incheckning
ea6efc9514
3 ändrade filer med 29 tillägg och 15 borttagningar
  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)
 void gs_shader_destroy(gs_shader_t *shader)
 {
 {
+	if (shader && shader->device->lastVertexShader == shader)
+		shader->device->lastVertexShader = nullptr;
 	delete shader;
 	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;
 	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;
 		return;
 
 
 	vector<ID3D11Buffer*> buffers;
 	vector<ID3D11Buffer*> buffers;
 	vector<uint32_t> strides;
 	vector<uint32_t> strides;
 	vector<uint32_t> offsets;
 	vector<uint32_t> offsets;
 
 
-	if (vertbuffer) {
-		vertbuffer->MakeBufferList(device->curVertexShader,
+	if (curVertexBuffer && curVertexShader) {
+		curVertexBuffer->MakeBufferList(curVertexShader,
 				buffers, strides);
 				buffers, strides);
 	} else {
 	} else {
-		size_t buffersToClear =
-			device->curVertexShader->NumBuffersExpected();
+		size_t buffersToClear = curVertexShader
+			? curVertexShader->NumBuffersExpected() : 0;
 		buffers.resize(buffersToClear);
 		buffers.resize(buffersToClear);
 		strides.resize(buffersToClear);
 		strides.resize(buffersToClear);
 	}
 	}
 
 
 	offsets.resize(buffers.size());
 	offsets.resize(buffers.size());
-	device->context->IASetVertexBuffers(0, (UINT)buffers.size(),
+	context->IASetVertexBuffers(0, (UINT)buffers.size(),
 			buffers.data(), strides.data(), offsets.data());
 			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)
 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->VSSetShader(shader, NULL, 0);
 	device->context->IASetInputLayout(layout);
 	device->context->IASetInputLayout(layout);
 	device->context->VSSetConstantBuffers(0, 1, &constants);
 	device->context->VSSetConstantBuffers(0, 1, &constants);
-
-	if (vertshader && curVB)
-		device_load_vertexbuffer(device, curVB);
 }
 }
 
 
 static inline void clear_textures(gs_device_t *device)
 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)
 		if (effect)
 			gs_effect_update_params(effect);
 			gs_effect_update_params(effect);
 
 
+		device->LoadVertexBufferData();
 		device->UpdateBlendState();
 		device->UpdateBlendState();
 		device->UpdateRasterState();
 		device->UpdateRasterState();
 		device->UpdateZStencilState();
 		device->UpdateZStencilState();
@@ -1926,6 +1931,8 @@ void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate)
 
 
 void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer)
 void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer)
 {
 {
+	if (vertbuffer && vertbuffer->device->lastVertexBuffer == vertbuffer)
+		vertbuffer->device->lastVertexBuffer = nullptr;
 	delete vertbuffer;
 	delete vertbuffer;
 }
 }
 
 

+ 5 - 0
libobs-d3d11/d3d11-subsystem.hpp

@@ -789,6 +789,9 @@ struct gs_device {
 	gs_pixel_shader             *curPixelShader = nullptr;
 	gs_pixel_shader             *curPixelShader = nullptr;
 	gs_swap_chain               *curSwapChain = nullptr;
 	gs_swap_chain               *curSwapChain = nullptr;
 
 
+	gs_vertex_buffer            *lastVertexBuffer = nullptr;
+	gs_vertex_shader            *lastVertexShader = nullptr;
+
 	bool                        zstencilStateChanged = true;
 	bool                        zstencilStateChanged = true;
 	bool                        rasterStateChanged = true;
 	bool                        rasterStateChanged = true;
 	bool                        blendStateChanged = true;
 	bool                        blendStateChanged = true;
@@ -829,6 +832,8 @@ struct gs_device {
 	void UpdateRasterState();
 	void UpdateRasterState();
 	void UpdateBlendState();
 	void UpdateBlendState();
 
 
+	void LoadVertexBufferData();
+
 	inline void CopyTex(ID3D11Texture2D *dst,
 	inline void CopyTex(ID3D11Texture2D *dst,
 			uint32_t dst_x, uint32_t dst_y,
 			uint32_t dst_x, uint32_t dst_y,
 			gs_texture_t *src, uint32_t src_x, uint32_t src_y,
 			gs_texture_t *src, uint32_t src_x, uint32_t src_y,