浏览代码

libobs/graphics: Add ability to set shader texture sampler

(Note: This also modifies libobs-d3d11 and libobs-opengl)

Allows overriding the sampler for a specific shader parameter.
jp9000 9 年之前
父节点
当前提交
4dc0024198

+ 13 - 0
libobs-d3d11/d3d11-shader.cpp

@@ -222,10 +222,18 @@ inline void gs_shader::UpdateParam(vector<uint8_t> &constData,
 			upload = true;
 			upload = true;
 			param.changed = false;
 			param.changed = false;
 		}
 		}
+
 	} else if (param.curValue.size() == sizeof(gs_texture_t*)) {
 	} else if (param.curValue.size() == sizeof(gs_texture_t*)) {
 		gs_texture_t *tex;
 		gs_texture_t *tex;
 		memcpy(&tex, param.curValue.data(), sizeof(gs_texture_t*));
 		memcpy(&tex, param.curValue.data(), sizeof(gs_texture_t*));
 		device_load_texture(device, tex, param.textureID);
 		device_load_texture(device, tex, param.textureID);
+
+		if (param.nextSampler) {
+			ID3D11SamplerState *state = param.nextSampler->state;
+			device->context->PSSetSamplers(param.textureID, 1,
+					&state);
+			param.nextSampler = nullptr;
+		}
 	}
 	}
 }
 }
 
 
@@ -384,3 +392,8 @@ void gs_shader_set_default(gs_sparam_t *param)
 		shader_setval_inline(param, param->defaultValue.data(),
 		shader_setval_inline(param, param->defaultValue.data(),
 				param->defaultValue.size());
 				param->defaultValue.size());
 }
 }
+
+void gs_shader_set_next_sampler(gs_sparam_t *param, gs_samplerstate_t *sampler)
+{
+	param->nextSampler = sampler;
+}

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

@@ -356,6 +356,7 @@ struct gs_shader_param {
 	gs_shader_param_type           type;
 	gs_shader_param_type           type;
 
 
 	uint32_t                       textureID;
 	uint32_t                       textureID;
+	struct gs_sampler_state        *nextSampler = nullptr;
 
 
 	int                            arrayCount;
 	int                            arrayCount;
 
 

+ 11 - 0
libobs-opengl/gl-shader.c

@@ -487,6 +487,12 @@ static void program_set_param_data(struct gs_program *program,
 		}
 		}
 
 
 	} else if (pp->param->type == GS_SHADER_PARAM_TEXTURE) {
 	} else if (pp->param->type == GS_SHADER_PARAM_TEXTURE) {
+		if (pp->param->next_sampler) {
+			program->device->cur_samplers[pp->param->sampler_id] =
+				pp->param->next_sampler;
+			pp->param->next_sampler = NULL;
+		}
+
 		glUniform1i(pp->obj, pp->param->texture_id);
 		glUniform1i(pp->obj, pp->param->texture_id);
 		device_load_texture(program->device, pp->param->texture,
 		device_load_texture(program->device, pp->param->texture,
 				pp->param->texture_id);
 				pp->param->texture_id);
@@ -720,3 +726,8 @@ void gs_shader_set_default(gs_sparam_t *param)
 {
 {
 	gs_shader_set_val(param, param->def_value.array, param->def_value.num);
 	gs_shader_set_val(param, param->def_value.array, param->def_value.num);
 }
 }
+
+void gs_shader_set_next_sampler(gs_sparam_t *param, gs_samplerstate_t *sampler)
+{
+	param->next_sampler = sampler;
+}

+ 1 - 0
libobs-opengl/gl-subsystem.h

@@ -300,6 +300,7 @@ struct gs_shader_param {
 
 
 	char                 *name;
 	char                 *name;
 	gs_shader_t          *shader;
 	gs_shader_t          *shader;
+	gs_samplerstate_t    *next_sampler;
 	GLint                texture_id;
 	GLint                texture_id;
 	size_t               sampler_id;
 	size_t               sampler_id;
 	int                  array_count;
 	int                  array_count;

+ 16 - 0
libobs/graphics/effect.c

@@ -125,6 +125,8 @@ void gs_technique_end(gs_technique_t *tech)
 
 
 		da_free(param->cur_val);
 		da_free(param->cur_val);
 		param->changed = false;
 		param->changed = false;
+		if (param->next_sampler)
+			param->next_sampler = NULL;
 	}
 	}
 }
 }
 
 
@@ -147,6 +149,9 @@ static void upload_shader_params(struct darray *pass_params, bool changed_only)
 		struct gs_effect_param *eparam = param->eparam;
 		struct gs_effect_param *eparam = param->eparam;
 		gs_sparam_t *sparam = param->sparam;
 		gs_sparam_t *sparam = param->sparam;
 
 
+		if (eparam->next_sampler)
+			gs_shader_set_next_sampler(sparam, eparam->next_sampler);
+
 		if (changed_only && !eparam->changed)
 		if (changed_only && !eparam->changed)
 			continue;
 			continue;
 
 
@@ -378,3 +383,14 @@ void gs_effect_set_default(gs_eparam_t *param)
 	effect_setval_inline(param, param->default_val.array,
 	effect_setval_inline(param, param->default_val.array,
 			param->default_val.num);
 			param->default_val.num);
 }
 }
+
+void gs_effect_set_next_sampler(gs_eparam_t *param, gs_samplerstate_t *sampler)
+{
+	if (!param) {
+		blog(LOG_ERROR, "gs_effect_set_next_sampler: invalid param");
+		return;
+	}
+
+	if (param->type == GS_SHADER_PARAM_TEXTURE)
+		param->next_sampler = sampler;
+}

+ 1 - 0
libobs/graphics/effect.h

@@ -57,6 +57,7 @@ struct gs_effect_param {
 	DARRAY(uint8_t) default_val;
 	DARRAY(uint8_t) default_val;
 
 
 	gs_effect_t *effect;
 	gs_effect_t *effect;
+	gs_samplerstate_t *next_sampler;
 
 
 	/*char *full_name;
 	/*char *full_name;
 	float scroller_min, scroller_max, scroller_inc, scroller_mul;*/
 	float scroller_min, scroller_max, scroller_inc, scroller_mul;*/

+ 1 - 0
libobs/graphics/graphics-imports.c

@@ -167,6 +167,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
 	GRAPHICS_IMPORT(gs_shader_set_texture);
 	GRAPHICS_IMPORT(gs_shader_set_texture);
 	GRAPHICS_IMPORT(gs_shader_set_val);
 	GRAPHICS_IMPORT(gs_shader_set_val);
 	GRAPHICS_IMPORT(gs_shader_set_default);
 	GRAPHICS_IMPORT(gs_shader_set_default);
+	GRAPHICS_IMPORT(gs_shader_set_next_sampler);
 
 
 	/* OSX/Cocoa specific functions */
 	/* OSX/Cocoa specific functions */
 #ifdef __APPLE__
 #ifdef __APPLE__

+ 2 - 0
libobs/graphics/graphics-internal.h

@@ -225,6 +225,8 @@ struct gs_exports {
 	void (*gs_shader_set_val)(gs_sparam_t *param, const void *val,
 	void (*gs_shader_set_val)(gs_sparam_t *param, const void *val,
 			size_t size);
 			size_t size);
 	void (*gs_shader_set_default)(gs_sparam_t *param);
 	void (*gs_shader_set_default)(gs_sparam_t *param);
+	void (*gs_shader_set_next_sampler)(gs_sparam_t *param,
+			gs_samplerstate_t *sampler);
 
 
 #ifdef __APPLE__
 #ifdef __APPLE__
 	/* OSX/Cocoa specific functions */
 	/* OSX/Cocoa specific functions */

+ 10 - 0
libobs/graphics/graphics.c

@@ -2089,6 +2089,16 @@ void gs_shader_set_default(gs_sparam_t *param)
 	graphics->exports.gs_shader_set_default(param);
 	graphics->exports.gs_shader_set_default(param);
 }
 }
 
 
+void gs_shader_set_next_sampler(gs_sparam_t *param, gs_samplerstate_t *sampler)
+{
+	graphics_t *graphics = thread_graphics;
+
+	if (!gs_valid_p("gs_shader_set_next_sampler", param))
+		return;
+
+	graphics->exports.gs_shader_set_next_sampler(param, sampler);
+}
+
 void gs_texture_destroy(gs_texture_t *tex)
 void gs_texture_destroy(gs_texture_t *tex)
 {
 {
 	graphics_t *graphics = thread_graphics;
 	graphics_t *graphics = thread_graphics;

+ 4 - 0
libobs/graphics/graphics.h

@@ -325,6 +325,8 @@ EXPORT void gs_shader_set_vec4(gs_sparam_t *param, const struct vec4 *val);
 EXPORT void gs_shader_set_texture(gs_sparam_t *param, gs_texture_t *val);
 EXPORT void gs_shader_set_texture(gs_sparam_t *param, gs_texture_t *val);
 EXPORT void gs_shader_set_val(gs_sparam_t *param, const void *val, size_t size);
 EXPORT void gs_shader_set_val(gs_sparam_t *param, const void *val, size_t size);
 EXPORT void gs_shader_set_default(gs_sparam_t *param);
 EXPORT void gs_shader_set_default(gs_sparam_t *param);
+EXPORT void gs_shader_set_next_sampler(gs_sparam_t *param,
+		gs_samplerstate_t *sampler);
 
 
 /* ---------------------------------------------------
 /* ---------------------------------------------------
  * effect functions
  * effect functions
@@ -393,6 +395,8 @@ EXPORT void gs_effect_set_vec4(gs_eparam_t *param, const struct vec4 *val);
 EXPORT void gs_effect_set_texture(gs_eparam_t *param, gs_texture_t *val);
 EXPORT void gs_effect_set_texture(gs_eparam_t *param, gs_texture_t *val);
 EXPORT void gs_effect_set_val(gs_eparam_t *param, const void *val, size_t size);
 EXPORT void gs_effect_set_val(gs_eparam_t *param, const void *val, size_t size);
 EXPORT void gs_effect_set_default(gs_eparam_t *param);
 EXPORT void gs_effect_set_default(gs_eparam_t *param);
+EXPORT void gs_effect_set_next_sampler(gs_eparam_t *param,
+		gs_samplerstate_t *sampler);
 
 
 /* ---------------------------------------------------
 /* ---------------------------------------------------
  * texture render helper functions
  * texture render helper functions