Przeglądaj źródła

Add initial sampler state support

Daniele Bartolini 8 lat temu
rodzic
commit
3e6c974e24

+ 12 - 0
samples/core/shaders/default.shader

@@ -101,6 +101,10 @@ bgfx_shaders = {
 	gui = {
 		includes = "common"
 
+		samplers = {
+			u_albedo = { sampler_state = "clamp_point" }
+		}
+
 		varying = """
 			vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
 			vec4 v_color0    : COLOR0 = vec4(0.0, 0.0, 0.0, 0.0);
@@ -149,6 +153,10 @@ bgfx_shaders = {
 	sprite = {
 		includes = "common"
 
+		samplers = {
+			u_albedo = { sampler_state = "clamp_point" }
+		}
+
 		varying = """
 			vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
 
@@ -191,6 +199,10 @@ bgfx_shaders = {
 	mesh = {
 		includes = "common"
 
+		samplers = {
+			u_albedo = { sampler_state = "clamp_anisotropic" }
+		}
+
 		varying = """
 			vec3 v_normal    : NORMAL    = vec3(0.0, 0.0, 0.0);
 			vec4 v_view      : TEXCOORD0 = vec4(0.0, 0.0, 0.0, 0.0);

+ 2 - 2
src/resource/material_resource.cpp

@@ -100,7 +100,7 @@ namespace material_resource_internal
 
 			TextureData td;
 			td.sampler_name_offset = sampler_name_offset;
-			td._pad0               = 0;
+			td.name                = StringId32(key.data(), key.length());
 			td.id                  = sjson::parse_resource_id(value);
 			td.data_offset         = reserve_dynamic_data(th, dynamic);
 			td._pad1               = 0;
@@ -217,7 +217,7 @@ namespace material_resource_internal
 		for (u32 i = 0; i < array::size(texdata); i++)
 		{
 			opts.write(texdata[i].sampler_name_offset);
-			opts.write(texdata[i]._pad0);
+			opts.write(texdata[i].name._id);
 			opts.write(texdata[i].id);
 			opts.write(texdata[i].data_offset);
 			opts.write(texdata[i]._pad1);

+ 1 - 1
src/resource/material_resource.h

@@ -29,7 +29,7 @@ struct MaterialResource
 struct TextureData
 {
 	u32 sampler_name_offset; // Sampler uniform name
-	u32 _pad0;
+	StringId32 name;         // Sampler name
 	StringId64 id;           // Resource name
 	u32 data_offset;         // Offset into dynamic blob
 	u32 _pad1;

+ 4 - 3
src/resource/shader_resource.cpp

@@ -1114,9 +1114,10 @@ namespace shader_resource_internal
 
 				const RenderState& rs = _render_states[render_state];
 
-				_opts.write(shader_name._id);  // Shader name
-				_opts.write(rs.encode());      // Render state
-				compile(bgfx_shader.c_str(), defines); // Shader code
+				_opts.write(shader_name._id);                // Shader name
+				_opts.write(rs.encode());                    // Render state
+				compile_sampler_states(bgfx_shader.c_str()); // Sampler states
+				compile(bgfx_shader.c_str(), defines);       // Shader code
 			}
 		}
 

+ 7 - 0
src/resource/shader_resource.h

@@ -23,10 +23,17 @@ struct ShaderResource
 	{
 	}
 
+	struct Sampler
+	{
+		u32 name;
+		u32 state;
+	};
+
 	struct Data
 	{
 		StringId32 name;
 		u64 state;
+		Sampler samplers[4];
 		const bgfx::Memory* vsmem;
 		const bgfx::Memory* fsmem;
 	};

+ 5 - 1
src/world/material.cpp

@@ -29,7 +29,11 @@ void Material::bind(ResourceManager& rm, ShaderManager& sm, u8 view, s32 depth)
 		sampler.idx = th->sampler_handle;
 		texture.idx = teximg->handle.idx;
 
-		bgfx::setTexture(i, sampler, texture);
+		bgfx::setTexture(i
+			, sampler
+			, texture
+			, sm.sampler_state(_resource->shader, td->name)
+			);
 	}
 
 	// Set uniforms

+ 37 - 2
src/world/shader_manager.cpp

@@ -39,6 +39,22 @@ void* ShaderManager::load(File& file, Allocator& a)
 		u64 render_state;
 		br.read(render_state);
 
+		u32 num_samplers;
+		br.read(num_samplers);
+		CE_ENSURE(num_samplers < countof(sr->_data[i].samplers));
+
+		for (u32 s = 0; s < num_samplers; ++s)
+		{
+			u32 sampler_name;
+			br.read(sampler_name);
+
+			u32 sampler_state;
+			br.read(sampler_state);
+
+			sr->_data[i].samplers[s].name = sampler_name;
+			sr->_data[i].samplers[s].state = sampler_state;
+		}
+
 		u32 vs_code_size;
 		br.read(vs_code_size);
 		const bgfx::Memory* vsmem = bgfx::alloc(vs_code_size);
@@ -73,7 +89,7 @@ void ShaderManager::online(StringId64 id, ResourceManager& rm)
 		bgfx::ProgramHandle program = bgfx::createProgram(vs, fs, true);
 		CE_ASSERT(bgfx::isValid(program), "Failed to create GPU program");
 
-		add_shader(data.name, data.state, program);
+		add_shader(data.name, data.state, data.samplers, program);
 	}
 }
 
@@ -101,14 +117,33 @@ void ShaderManager::unload(Allocator& a, void* res)
 	CE_DELETE(a, (ShaderResource*)res);
 }
 
-void ShaderManager::add_shader(StringId32 name, u64 state, bgfx::ProgramHandle program)
+void ShaderManager::add_shader(StringId32 name, u64 state, const ShaderResource::Sampler samplers[4], bgfx::ProgramHandle program)
 {
 	ShaderData sd;
 	sd.state = state;
+	memcpy(sd.samplers, samplers, sizeof(sd.samplers));
 	sd.program = program;
 	hash_map::set(_shader_map, name, sd);
 }
 
+u32 ShaderManager::sampler_state(StringId32 shader_id, StringId32 sampler_name)
+{
+	CE_ASSERT(hash_map::has(_shader_map, shader_id), "Shader not found");
+	ShaderData sd;
+	sd.state = BGFX_STATE_DEFAULT;
+	sd.program = BGFX_INVALID_HANDLE;
+	sd = hash_map::get(_shader_map, shader_id, sd);
+
+	for (u32 i = 0; i < countof(sd.samplers); ++i)
+	{
+		if (sd.samplers[i].name == sampler_name._id)
+			return sd.samplers[i].state;
+	}
+
+	CE_FATAL("Sampler not found");
+	return UINT32_MAX;
+}
+
 void ShaderManager::submit(StringId32 shader_id, u8 view_id, s32 depth, u64 state)
 {
 	CE_ASSERT(hash_map::has(_shader_map, shader_id), "Shader not found");

+ 8 - 2
src/world/shader_manager.h

@@ -9,6 +9,7 @@
 #include "core/filesystem/types.h"
 #include "core/memory/types.h"
 #include "core/strings/string_id.h"
+#include "resource/shader_resource.h"
 #include "resource/types.h"
 #include <bgfx/bgfx.h>
 
@@ -22,14 +23,13 @@ struct ShaderManager
 	struct ShaderData
 	{
 		u64 state;
+		ShaderResource::Sampler samplers[4];
 		bgfx::ProgramHandle program;
 	};
 
 	typedef HashMap<StringId32, ShaderData> ShaderMap;
 	ShaderMap _shader_map;
 
-	void add_shader(StringId32 name, u64 state, bgfx::ProgramHandle program);
-
 	///
 	ShaderManager(Allocator& a);
 
@@ -45,6 +45,12 @@ struct ShaderManager
 	///
 	void unload(Allocator& a, void* res);
 
+	///
+	void add_shader(StringId32 name, u64 state, const ShaderResource::Sampler samplers[4], bgfx::ProgramHandle program);
+
+	///
+	u32 sampler_state(StringId32 shader_id, StringId32 sampler_name);
+
 	///
 	void submit(StringId32 shader_id, u8 view_id, s32 depth = 0, u64 state = UINT64_MAX);
 };