Start work on effect files
Extends pipeline files
This commit is contained in:
		
							parent
							
								
									36e2314f35
								
							
						
					
					
						commit
						41fe5426b8
					
				@ -1,7 +1,9 @@
 | 
			
		||||
optimization speed;
 | 
			
		||||
 | 
			
		||||
vertex {
 | 
			
		||||
	vk BEGIN
 | 
			
		||||
passes {
 | 
			
		||||
    pass0 {
 | 
			
		||||
        vertex {
 | 
			
		||||
            vk BEGIN
 | 
			
		||||
#include "common.hlsl"
 | 
			
		||||
 | 
			
		||||
struct VSInput
 | 
			
		||||
@ -10,29 +12,31 @@ struct VSInput
 | 
			
		||||
 | 
			
		||||
struct VSOutput
 | 
			
		||||
{
 | 
			
		||||
	float4 Pos : SV_POSITION;
 | 
			
		||||
    float4 Pos : SV_POSITION;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
VSOutput VsMain(VSInput input, uint vertexIndex : SV_VertexID) {
 | 
			
		||||
	VSOutput output = (VSOutput)0;
 | 
			
		||||
	return output;
 | 
			
		||||
}
 | 
			
		||||
	END
 | 
			
		||||
    VSOutput output = (VSOutput)0;
 | 
			
		||||
    return output;
 | 
			
		||||
}
 | 
			
		||||
            END
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
fragment {
 | 
			
		||||
	vk BEGIN
 | 
			
		||||
        fragment {
 | 
			
		||||
            vk BEGIN
 | 
			
		||||
struct PSOutput {
 | 
			
		||||
	float4 Color : SV_TARGET0;
 | 
			
		||||
float4 Color : SV_TARGET0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PSOutput PsMain(void) {
 | 
			
		||||
	PSOutput output = (PSOutput)0;
 | 
			
		||||
	output.Color[0] = 0;
 | 
			
		||||
	output.Color[1] = 0;
 | 
			
		||||
	output.Color[2] = 0;
 | 
			
		||||
	output.Color[3] = 0;
 | 
			
		||||
	return output;
 | 
			
		||||
    PSOutput output = (PSOutput)0;
 | 
			
		||||
    output.Color[0] = 0;
 | 
			
		||||
    output.Color[1] = 0;
 | 
			
		||||
    output.Color[2] = 0;
 | 
			
		||||
    output.Color[3] = 0;
 | 
			
		||||
    return output;
 | 
			
		||||
}
 | 
			
		||||
	END
 | 
			
		||||
            END
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								assets/test.effect
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								assets/test.effect
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
passes {
 | 
			
		||||
    pass0 {
 | 
			
		||||
        pipeline test/shader/static_object.pipeline;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -15,10 +15,6 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    rt_attribute_binding *uniform_bindings;
 | 
			
		||||
    rt_attribute_binding *storage_bindings;
 | 
			
		||||
    rt_attribute_binding *texture_bindings;
 | 
			
		||||
 | 
			
		||||
    rt_resource shaders[3];
 | 
			
		||||
    char *shader_names[3];
 | 
			
		||||
    unsigned int shader_count;
 | 
			
		||||
@ -36,96 +32,17 @@ typedef struct {
 | 
			
		||||
    uint16_t texture_binding_count;
 | 
			
		||||
} rt_parsed_pipeline_data;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    unsigned int pass_count;
 | 
			
		||||
    rt_parsed_pipeline_data pipelines[RT_MAX_SUBRESOURCES];
 | 
			
		||||
} rt_parsed_effect_data;
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    RT_SHADER_NOT_PRESENT = RT_ASSET_PROCESSING_FAILED + 1
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern RT_DLLIMPORT rt_cvar rt_Renderer;
 | 
			
		||||
 | 
			
		||||
static bool ParseBindingIndex(rt_text_span span, unsigned int *index) {
 | 
			
		||||
    if (span.length == 0)
 | 
			
		||||
        return false;
 | 
			
		||||
    int at           = (int)span.length - 1;
 | 
			
		||||
    unsigned int exp = 1;
 | 
			
		||||
    unsigned int n   = 0;
 | 
			
		||||
    while (at >= 0) {
 | 
			
		||||
        if (span.start[at] >= '0' && span.start[at] <= '9') {
 | 
			
		||||
            unsigned int digit = (unsigned int)(span.start[at] - '0');
 | 
			
		||||
            n += digit * exp;
 | 
			
		||||
        } else {
 | 
			
		||||
            rtReportError("GFX", "Unexpected non-digit character in binding index");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        --at;
 | 
			
		||||
        exp *= 10;
 | 
			
		||||
    }
 | 
			
		||||
    *index = n;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rt_attribute_value ParseBindingValue(rt_text_span span) {
 | 
			
		||||
    if (rtCompareSpanToString(span, "MATERIAL_ALBEDO") == 0) {
 | 
			
		||||
        return RT_ATTRIBUTE_VALUE_MATERIAL_ALBEDO;
 | 
			
		||||
    } else if (rtCompareSpanToString(span, "MATERIAL_NORMAL") == 0) {
 | 
			
		||||
        return RT_ATTRIBUTE_VALUE_MATERIAL_NORMAL;
 | 
			
		||||
    }
 | 
			
		||||
    rtReportError("GFX", "Unsupported binding value %*.s", span.length, span.start);
 | 
			
		||||
    return RT_ATTRIBUTE_VALUE_UNDEFINED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool ParseBindings(rt_parse_state *state,
 | 
			
		||||
                          unsigned int root_list,
 | 
			
		||||
                          const char *name,
 | 
			
		||||
                          const char *file_path,
 | 
			
		||||
                          rt_attribute_binding **p_bindings,
 | 
			
		||||
                          uint16_t *p_binding_count) {
 | 
			
		||||
    const rt_parsed_stmt *bindings = rtFindStatement(state, root_list, name);
 | 
			
		||||
    if (bindings) {
 | 
			
		||||
        if (bindings->form != RT_STMT_FORM_LIST) {
 | 
			
		||||
            rtReportError("GFX",
 | 
			
		||||
                          "Expected list of bindings as the value of "
 | 
			
		||||
                          "\"%s\" in %s",
 | 
			
		||||
                          name,
 | 
			
		||||
                          file_path);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        const rt_parsed_stmt_list *binding_list = &state->statement_lists[bindings->list_index];
 | 
			
		||||
        rt_attribute_binding *shader_bindings =
 | 
			
		||||
            rtAllocBuffer(sizeof(rt_attribute_binding) * binding_list->count);
 | 
			
		||||
        if (!bindings) {
 | 
			
		||||
            rtReportError("GFX", "Out of memory");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        unsigned int binding_count = binding_list->count;
 | 
			
		||||
 | 
			
		||||
        unsigned int stmt_index = binding_list->first;
 | 
			
		||||
        for (unsigned int i = 0; i < binding_list->count; ++i) {
 | 
			
		||||
            const rt_parsed_stmt *stmt = &state->statements[stmt_index];
 | 
			
		||||
            if (!ParseBindingIndex(stmt->attribute, &shader_bindings[i].index)) {
 | 
			
		||||
                rtReleaseBuffer(shader_bindings,
 | 
			
		||||
                                sizeof(rt_attribute_binding) * binding_list->count);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            shader_bindings[i].value = ParseBindingValue(stmt->value);
 | 
			
		||||
            if (shader_bindings[i].value == RT_ATTRIBUTE_VALUE_UNDEFINED) {
 | 
			
		||||
                rtReleaseBuffer(shader_bindings,
 | 
			
		||||
                                sizeof(rt_attribute_binding) * binding_list->count);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            stmt_index = stmt->next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        *p_bindings      = shader_bindings;
 | 
			
		||||
        *p_binding_count = (uint16_t)binding_count;
 | 
			
		||||
        return true;
 | 
			
		||||
    } else {
 | 
			
		||||
        *p_bindings      = NULL;
 | 
			
		||||
        *p_binding_count = 0;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *GenerateShaderName(rt_shader_type type,
 | 
			
		||||
                                rt_shader_stage stage,
 | 
			
		||||
                                rt_shader_optimization_level optimization,
 | 
			
		||||
@ -300,27 +217,13 @@ ParseOptimizationLevel(rt_parse_state *state, unsigned int root_list, const char
 | 
			
		||||
    return optimization_level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rt_result ParsePipelineFile(rt_file_id fid,
 | 
			
		||||
                                   const char *text,
 | 
			
		||||
                                   size_t length,
 | 
			
		||||
                                   rt_parsed_pipeline_data *pipeline,
 | 
			
		||||
                                   rt_arena *arena) {
 | 
			
		||||
    /* This is the grammar for pipeline files:
 | 
			
		||||
     * <stmt-list> ::= <stmt>*
 | 
			
		||||
     * <stmt> ::= <attribute> ( ( <value> ';' ) | ( '{' <stmt-list> '}' ) )
 | 
			
		||||
     * <attribute> ::= [:alnum:]*
 | 
			
		||||
     * <value>:: = [:alnum:]* */
 | 
			
		||||
    const char *file_path = rtGetFilePath(fid);
 | 
			
		||||
    rt_parse_state state;
 | 
			
		||||
    unsigned int root_list;
 | 
			
		||||
    rt_result result = rtParseDescription(text, length, file_path, &root_list, &state, arena);
 | 
			
		||||
    if (result != RT_SUCCESS) {
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* We allow the pipeline file to overwrite the optimization level */
 | 
			
		||||
    rt_shader_optimization_level optimization =
 | 
			
		||||
        ParseOptimizationLevel(&state, root_list, file_path);
 | 
			
		||||
static rt_result ParsePipeline(rt_parse_state *state,
 | 
			
		||||
                               unsigned int root_list,
 | 
			
		||||
                               const char *file_path,
 | 
			
		||||
                               rt_shader_optimization_level optimization,
 | 
			
		||||
                               rt_parsed_pipeline_data *pipeline,
 | 
			
		||||
                               rt_arena *arena) {
 | 
			
		||||
    rt_result result = RT_SUCCESS;
 | 
			
		||||
 | 
			
		||||
    rt_shader_type type = RT_SHADER_TYPE_INVALID;
 | 
			
		||||
    if (strcmp(rt_Renderer.s, "vk") == 0)
 | 
			
		||||
@ -333,7 +236,7 @@ static rt_result ParsePipelineFile(rt_file_id fid,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Process shader stages */
 | 
			
		||||
    result = ParseShader(&state,
 | 
			
		||||
    result = ParseShader(state,
 | 
			
		||||
                         root_list,
 | 
			
		||||
                         "vertex",
 | 
			
		||||
                         file_path,
 | 
			
		||||
@ -353,7 +256,7 @@ static rt_result ParsePipelineFile(rt_file_id fid,
 | 
			
		||||
    }
 | 
			
		||||
    result = RT_SUCCESS;
 | 
			
		||||
 | 
			
		||||
    result = ParseShader(&state,
 | 
			
		||||
    result = ParseShader(state,
 | 
			
		||||
                         root_list,
 | 
			
		||||
                         "fragment",
 | 
			
		||||
                         file_path,
 | 
			
		||||
@ -373,7 +276,7 @@ static rt_result ParsePipelineFile(rt_file_id fid,
 | 
			
		||||
    }
 | 
			
		||||
    result = RT_SUCCESS;
 | 
			
		||||
 | 
			
		||||
    result = ParseShader(&state,
 | 
			
		||||
    result = ParseShader(state,
 | 
			
		||||
                         root_list,
 | 
			
		||||
                         "compute",
 | 
			
		||||
                         file_path,
 | 
			
		||||
@ -393,115 +296,123 @@ static rt_result ParsePipelineFile(rt_file_id fid,
 | 
			
		||||
    }
 | 
			
		||||
    result = RT_SUCCESS;
 | 
			
		||||
 | 
			
		||||
    /* Process bindings */
 | 
			
		||||
    pipeline->texture_bindings      = NULL;
 | 
			
		||||
    pipeline->texture_binding_count = 0;
 | 
			
		||||
    pipeline->uniform_bindings      = NULL;
 | 
			
		||||
    pipeline->uniform_binding_count = 0;
 | 
			
		||||
    pipeline->storage_bindings      = NULL;
 | 
			
		||||
    pipeline->storage_binding_count = 0;
 | 
			
		||||
 | 
			
		||||
    if (!ParseBindings(&state,
 | 
			
		||||
                       root_list,
 | 
			
		||||
                       "texture_bindings",
 | 
			
		||||
                       file_path,
 | 
			
		||||
                       &pipeline->texture_bindings,
 | 
			
		||||
                       &pipeline->texture_binding_count)) {
 | 
			
		||||
        result = RT_ASSET_PROCESSING_FAILED;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!ParseBindings(&state,
 | 
			
		||||
                       root_list,
 | 
			
		||||
                       "uniform_bindings",
 | 
			
		||||
                       file_path,
 | 
			
		||||
                       &pipeline->uniform_bindings,
 | 
			
		||||
                       &pipeline->uniform_binding_count)) {
 | 
			
		||||
        result = RT_ASSET_PROCESSING_FAILED;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!ParseBindings(&state,
 | 
			
		||||
                       root_list,
 | 
			
		||||
                       "storage_bindings",
 | 
			
		||||
                       file_path,
 | 
			
		||||
                       &pipeline->storage_bindings,
 | 
			
		||||
                       &pipeline->storage_binding_count)) {
 | 
			
		||||
        result = RT_ASSET_PROCESSING_FAILED;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rt_result ParseEffect(rt_file_id fid,
 | 
			
		||||
                             const char *text,
 | 
			
		||||
                             size_t length,
 | 
			
		||||
                             rt_parsed_effect_data *effect,
 | 
			
		||||
                             rt_arena *arena) {
 | 
			
		||||
    /* This is the grammar for pipeline files:
 | 
			
		||||
     * <stmt-list> ::= <stmt>*
 | 
			
		||||
     * <stmt> ::= <attribute> ( ( <value> ';' ) | ( '{' <stmt-list> '}' ) )
 | 
			
		||||
     * <attribute> ::= [:alnum:]*
 | 
			
		||||
     * <value>:: = [:alnum:]* */
 | 
			
		||||
    const char *file_path = rtGetFilePath(fid);
 | 
			
		||||
    rt_parse_state state;
 | 
			
		||||
    unsigned int root_list;
 | 
			
		||||
    rt_result result = rtParseDescription(text, length, file_path, &root_list, &state, arena);
 | 
			
		||||
    if (result != RT_SUCCESS) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset(effect, 0, sizeof(*effect));
 | 
			
		||||
 | 
			
		||||
    rt_shader_optimization_level optimization =
 | 
			
		||||
        ParseOptimizationLevel(&state, root_list, file_path);
 | 
			
		||||
 | 
			
		||||
    const rt_parsed_stmt *passes_stmt = rtFindStatement(&state, root_list, "passes");
 | 
			
		||||
    if (!passes_stmt) {
 | 
			
		||||
        rtLog("AC", "Did not find passes list in %s.", file_path);
 | 
			
		||||
        return RT_INVALID_VALUE;
 | 
			
		||||
    }
 | 
			
		||||
    const rt_parsed_stmt_list *passes_list = &state.statement_lists[passes_stmt->list_index];
 | 
			
		||||
    if (passes_list->count > RT_MAX_SUBRESOURCES) {
 | 
			
		||||
        rtLog("AC",
 | 
			
		||||
              "Too many passes in 'passes'. Maximum supported number is %u. In %s.",
 | 
			
		||||
              RT_MAX_SUBRESOURCES,
 | 
			
		||||
              file_path);
 | 
			
		||||
        return RT_INVALID_VALUE;
 | 
			
		||||
    }
 | 
			
		||||
    const rt_parsed_stmt *pass_stmt = &state.statements[passes_list->first];
 | 
			
		||||
    for (unsigned int i = 0; i < passes_list->count;
 | 
			
		||||
         ++i, pass_stmt = &state.statements[pass_stmt->next]) {
 | 
			
		||||
        if (pass_stmt->form != RT_STMT_FORM_LIST) {
 | 
			
		||||
            rtLog("AC",
 | 
			
		||||
                  "Expected a list as the value of passes.%*s in %s",
 | 
			
		||||
                  pass_stmt->attribute.length,
 | 
			
		||||
                  pass_stmt->attribute.start,
 | 
			
		||||
                  file_path);
 | 
			
		||||
            return RT_INVALID_VALUE;
 | 
			
		||||
        }
 | 
			
		||||
        result = ParsePipeline(&state,
 | 
			
		||||
                               pass_stmt->list_index,
 | 
			
		||||
                               file_path,
 | 
			
		||||
                               optimization,
 | 
			
		||||
                               &effect->pipelines[i],
 | 
			
		||||
                               arena);
 | 
			
		||||
        if (result != RT_SUCCESS)
 | 
			
		||||
            return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RT_ASSET_PROCESSOR_FN(PipelineProcessor) {
 | 
			
		||||
    rt_loaded_asset asset = LoadAsset(file);
 | 
			
		||||
    if (!asset.buffer)
 | 
			
		||||
        return RT_UNKNOWN_ERROR;
 | 
			
		||||
 | 
			
		||||
    rt_parsed_pipeline_data pipeline;
 | 
			
		||||
    memset(&pipeline, 0, sizeof(pipeline));
 | 
			
		||||
    rt_result result = ParsePipelineFile(file, asset.buffer, asset.size, &pipeline, arena);
 | 
			
		||||
    rt_parsed_effect_data effect;
 | 
			
		||||
    memset(&effect, 0, sizeof(effect));
 | 
			
		||||
    rt_result result = ParseEffect(file, asset.buffer, asset.size, &effect, arena);
 | 
			
		||||
    if (result != RT_SUCCESS)
 | 
			
		||||
        goto out;
 | 
			
		||||
 | 
			
		||||
    rt_resource_id shader_resources[3] = {0};
 | 
			
		||||
    result                             = rtCreateResources(pipeline.shader_count,
 | 
			
		||||
                               pipeline.shader_names,
 | 
			
		||||
                               pipeline.shaders,
 | 
			
		||||
                               shader_resources);
 | 
			
		||||
    if (result != RT_SUCCESS)
 | 
			
		||||
        goto out;
 | 
			
		||||
    for (unsigned int i = 0; i < effect.pass_count; ++i) {
 | 
			
		||||
        rt_parsed_pipeline_data pipeline;
 | 
			
		||||
        memcpy(&pipeline, &effect.pipelines[i], sizeof(pipeline));
 | 
			
		||||
        rt_resource_id shader_resources[3] = {0};
 | 
			
		||||
        result                             = rtCreateResources(pipeline.shader_count,
 | 
			
		||||
                                   pipeline.shader_names,
 | 
			
		||||
                                   pipeline.shaders,
 | 
			
		||||
                                   shader_resources);
 | 
			
		||||
        if (result != RT_SUCCESS)
 | 
			
		||||
            goto out;
 | 
			
		||||
 | 
			
		||||
    rt_resource pipeline_resource      = {0};
 | 
			
		||||
    pipeline_resource.type             = RT_RESOURCE_PIPELINE;
 | 
			
		||||
    pipeline_resource.dependency_count = pipeline.shader_count;
 | 
			
		||||
    memcpy(pipeline_resource.dependencies, shader_resources, sizeof(shader_resources));
 | 
			
		||||
    pipeline_resource.subresource_count = 0;
 | 
			
		||||
        rt_resource pipeline_resource      = {0};
 | 
			
		||||
        pipeline_resource.type             = RT_RESOURCE_PIPELINE;
 | 
			
		||||
        pipeline_resource.dependency_count = pipeline.shader_count;
 | 
			
		||||
        memcpy(pipeline_resource.dependencies, shader_resources, sizeof(shader_resources));
 | 
			
		||||
        pipeline_resource.subresource_count = 0;
 | 
			
		||||
 | 
			
		||||
    size_t data_size =
 | 
			
		||||
        sizeof(rt_pipeline_info) + sizeof(rt_attribute_binding) * (pipeline.texture_binding_count +
 | 
			
		||||
                                                                   pipeline.uniform_binding_count +
 | 
			
		||||
                                                                   pipeline.storage_binding_count);
 | 
			
		||||
    pipeline_resource.data = rtArenaPush(arena, data_size);
 | 
			
		||||
    if (!pipeline_resource.data) {
 | 
			
		||||
        result = RT_OUT_OF_MEMORY;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    rt_pipeline_info *info = pipeline_resource.data;
 | 
			
		||||
    memset(info, 0, sizeof(*info));
 | 
			
		||||
    info->vertex_shader                    = (pipeline.vertex_shader != UINT_MAX)
 | 
			
		||||
                                                 ? shader_resources[pipeline.vertex_shader]
 | 
			
		||||
                                                 : RT_INVALID_RESOURCE_ID;
 | 
			
		||||
    info->fragment_shader                  = (pipeline.fragment_shader != UINT_MAX)
 | 
			
		||||
                                                 ? shader_resources[pipeline.fragment_shader]
 | 
			
		||||
                                                 : RT_INVALID_RESOURCE_ID;
 | 
			
		||||
    info->compute_shader                   = (pipeline.compute_shader != UINT_MAX)
 | 
			
		||||
                                                 ? shader_resources[pipeline.compute_shader]
 | 
			
		||||
                                                 : RT_INVALID_RESOURCE_ID;
 | 
			
		||||
    rt_attribute_binding *uniform_bindings = (rt_attribute_binding *)(info + 1);
 | 
			
		||||
    if (pipeline.uniform_binding_count > 0) {
 | 
			
		||||
        memcpy(uniform_bindings, pipeline.uniform_bindings, pipeline.uniform_binding_count);
 | 
			
		||||
        rtSetRelptr(&info->uniform_bindings, uniform_bindings);
 | 
			
		||||
    }
 | 
			
		||||
    rt_attribute_binding *texture_bindings = (uniform_bindings + pipeline.uniform_binding_count);
 | 
			
		||||
    if (pipeline.texture_binding_count > 0) {
 | 
			
		||||
        memcpy(texture_bindings, pipeline.texture_bindings, pipeline.texture_binding_count);
 | 
			
		||||
        rtSetRelptr(&info->texture_bindings, texture_bindings);
 | 
			
		||||
    }
 | 
			
		||||
    rt_attribute_binding *storage_bindings = (texture_bindings + pipeline.texture_binding_count);
 | 
			
		||||
    if (pipeline.texture_binding_count > 0) {
 | 
			
		||||
        memcpy(storage_bindings, pipeline.storage_bindings, pipeline.storage_binding_count);
 | 
			
		||||
        rtSetRelptr(&info->storage_bindings, storage_bindings);
 | 
			
		||||
    }
 | 
			
		||||
    rt_resource_id pipeline_id;
 | 
			
		||||
    const char *name = rtGetFilePath(file);
 | 
			
		||||
    result           = rtCreateResources(1, &name, &pipeline_resource, &pipeline_id);
 | 
			
		||||
    if (result == RT_SUCCESS) {
 | 
			
		||||
        new_resources[0] = pipeline_id;
 | 
			
		||||
        memcpy(&new_resources[1], shader_resources, sizeof(shader_resources));
 | 
			
		||||
        *new_resource_count = 1 + pipeline.shader_count;
 | 
			
		||||
        size_t data_size       = sizeof(rt_pipeline_info);
 | 
			
		||||
        pipeline_resource.data = rtArenaPush(arena, data_size);
 | 
			
		||||
        if (!pipeline_resource.data) {
 | 
			
		||||
            result = RT_OUT_OF_MEMORY;
 | 
			
		||||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
        rt_pipeline_info *info = pipeline_resource.data;
 | 
			
		||||
        memset(info, 0, sizeof(*info));
 | 
			
		||||
        info->vertex_shader   = (pipeline.vertex_shader != UINT_MAX)
 | 
			
		||||
                                    ? shader_resources[pipeline.vertex_shader]
 | 
			
		||||
                                    : RT_INVALID_RESOURCE_ID;
 | 
			
		||||
        info->fragment_shader = (pipeline.fragment_shader != UINT_MAX)
 | 
			
		||||
                                    ? shader_resources[pipeline.fragment_shader]
 | 
			
		||||
                                    : RT_INVALID_RESOURCE_ID;
 | 
			
		||||
        info->compute_shader  = (pipeline.compute_shader != UINT_MAX)
 | 
			
		||||
                                    ? shader_resources[pipeline.compute_shader]
 | 
			
		||||
                                    : RT_INVALID_RESOURCE_ID;
 | 
			
		||||
        rt_resource_id pipeline_id;
 | 
			
		||||
        const char *name = rtGetFilePath(file);
 | 
			
		||||
        result           = rtCreateResources(1, &name, &pipeline_resource, &pipeline_id);
 | 
			
		||||
        if (result == RT_SUCCESS) {
 | 
			
		||||
            new_resources[0] = pipeline_id;
 | 
			
		||||
            memcpy(&new_resources[1], shader_resources, sizeof(shader_resources));
 | 
			
		||||
            *new_resource_count = 1 + pipeline.shader_count;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
out:
 | 
			
		||||
    rtLog("AC", "Released %p", asset.buffer);
 | 
			
		||||
@ -33,8 +33,8 @@ asset_compiler = static_library('asset_compiler',
 | 
			
		||||
 | 
			
		||||
  'asset_compiler.c',
 | 
			
		||||
  'description_parser.c',
 | 
			
		||||
  'effect_processor.c',
 | 
			
		||||
  'framegraph_processor.c',
 | 
			
		||||
  'pipeline_processor.c',
 | 
			
		||||
  'shader_compiler.c',
 | 
			
		||||
  sources : ac_sources,
 | 
			
		||||
  include_directories : engine_incdir,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										25
									
								
								src/gfx/effect.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/gfx/effect.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
#ifndef RT_GFX_EFFECT_H
 | 
			
		||||
#define RT_GFX_EFFECT_H
 | 
			
		||||
 | 
			
		||||
/* A effect lists the passes during which an object needs to be rendered
 | 
			
		||||
 * and a pipeline for each pass.
 | 
			
		||||
 * The effect also defines the required vertex layout per pass.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "gfx.h"
 | 
			
		||||
#include "runtime/resources.h"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    /* Id of the render pass during which this effect pass is run. */
 | 
			
		||||
    rt_render_pass_id pass_id;
 | 
			
		||||
 | 
			
		||||
    rt_resource_id vertex_shader;
 | 
			
		||||
    rt_resource_id fragment_shader;
 | 
			
		||||
    rt_resource_id compute_shader;
 | 
			
		||||
} rt_effect_pass_info;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    
 | 
			
		||||
} rt_effect_info;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
gfx_deps = [thread_dep, m_dep]
 | 
			
		||||
gfx_lib = library('rtgfx',
 | 
			
		||||
  # Project Sources
 | 
			
		||||
  'effect.h',
 | 
			
		||||
  'gfx.h',
 | 
			
		||||
  'renderer_api.h',
 | 
			
		||||
  'render_list.h',
 | 
			
		||||
 | 
			
		||||
@ -59,20 +59,14 @@ typedef enum {
 | 
			
		||||
    RT_TRANSFER_QUEUE,
 | 
			
		||||
} rt_gpu_queue;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    rt_resource_id vertex_shader;
 | 
			
		||||
    rt_resource_id fragment_shader;
 | 
			
		||||
    rt_resource_id compute_shader;
 | 
			
		||||
 | 
			
		||||
    rt_relptr texture_bindings;
 | 
			
		||||
    rt_relptr uniform_bindings;
 | 
			
		||||
    rt_relptr storage_bindings;
 | 
			
		||||
 | 
			
		||||
    uint16_t texture_binding_count;
 | 
			
		||||
    uint16_t uniform_binding_count;
 | 
			
		||||
    uint16_t storage_binding_count;
 | 
			
		||||
} rt_pipeline_info;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
/* Attributes are used to bind buffers (or textures) to symbolic values.
 | 
			
		||||
 * For example, an attribute might be bound to "CELL_GRID", which would be
 | 
			
		||||
 * replaced with the (at the time of the invoke) grid buffer of the current
 | 
			
		||||
@ -93,6 +87,8 @@ typedef struct {
 | 
			
		||||
    rt_attribute_value value;
 | 
			
		||||
} rt_attribute_binding;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    RT_SHADER_TYPE_INVALID,
 | 
			
		||||
    RT_SHADER_TYPE_VULKAN,
 | 
			
		||||
 | 
			
		||||
@ -957,47 +957,11 @@ RT_DLLEXPORT void rDebugLogResource(rt_resource_id id, const rt_resource *resour
 | 
			
		||||
    }
 | 
			
		||||
    switch (resource->type) {
 | 
			
		||||
    case RT_RESOURCE_PIPELINE: {
 | 
			
		||||
        static const char *binding_str[RT_ATTRIBUTE_VALUE_count] = {"<UNDEFINED>",
 | 
			
		||||
                                                                    "MaterialAlbedo",
 | 
			
		||||
                                                                    "MaterialNormal"};
 | 
			
		||||
        const rt_pipeline_info *pipeline                         = resource->data;
 | 
			
		||||
        rtLog("RESMGR", "  pipeline data:");
 | 
			
		||||
        rtLog("RESMGR", "    vertex shader:   %llx", pipeline->vertex_shader);
 | 
			
		||||
        rtLog("RESMGR", "    fragment shader: %llx", pipeline->fragment_shader);
 | 
			
		||||
        rtLog("RESMGR", "    compute shader:  %llx", pipeline->compute_shader);
 | 
			
		||||
        rtLog("RESMGR", "    uniform bindings:");
 | 
			
		||||
        const rt_attribute_binding *uniform_bindings =
 | 
			
		||||
            rtResolveConstRelptr(&pipeline->uniform_bindings);
 | 
			
		||||
        for (uint32_t i = 0; i < pipeline->uniform_binding_count; ++i) {
 | 
			
		||||
            rtLog("RESMGR",
 | 
			
		||||
                  "      - %u : %s",
 | 
			
		||||
                  uniform_bindings[i].index,
 | 
			
		||||
                  (uniform_bindings[i].value < RT_ATTRIBUTE_VALUE_count)
 | 
			
		||||
                      ? binding_str[uniform_bindings[i].value]
 | 
			
		||||
                      : "<INVALID>");
 | 
			
		||||
        }
 | 
			
		||||
        rtLog("RESMGR", "    texture bindings:");
 | 
			
		||||
        const rt_attribute_binding *texture_bindings =
 | 
			
		||||
            rtResolveConstRelptr(&pipeline->texture_bindings);
 | 
			
		||||
        for (uint32_t i = 0; i < pipeline->texture_binding_count; ++i) {
 | 
			
		||||
            rtLog("RESMGR",
 | 
			
		||||
                  "      - %u : %s",
 | 
			
		||||
                  texture_bindings[i].index,
 | 
			
		||||
                  (texture_bindings[i].value < RT_ATTRIBUTE_VALUE_count)
 | 
			
		||||
                      ? binding_str[texture_bindings[i].value]
 | 
			
		||||
                      : "<INVALID>");
 | 
			
		||||
        }
 | 
			
		||||
        rtLog("RESMGR", "    storage bindings:");
 | 
			
		||||
        const rt_attribute_binding *storage_bindings =
 | 
			
		||||
            rtResolveConstRelptr(&pipeline->storage_bindings);
 | 
			
		||||
        for (uint32_t i = 0; i < pipeline->storage_binding_count; ++i) {
 | 
			
		||||
            rtLog("RESMGR",
 | 
			
		||||
                  "      - %u : %s",
 | 
			
		||||
                  storage_bindings[i].index,
 | 
			
		||||
                  (storage_bindings[i].value < RT_ATTRIBUTE_VALUE_count)
 | 
			
		||||
                      ? binding_str[storage_bindings[i].value]
 | 
			
		||||
                      : "<INVALID>");
 | 
			
		||||
        }
 | 
			
		||||
    } break;
 | 
			
		||||
    case RT_RESOURCE_SHADER: {
 | 
			
		||||
        static const char *stype_str[RT_SHADER_TYPE_count]  = {"<INVALID>", "Vulkan"};
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,8 @@ typedef enum {
 | 
			
		||||
 | 
			
		||||
    RT_RESOURCE_FRAMEGRAPH,
 | 
			
		||||
 | 
			
		||||
    RT_RESOURCE_EFFECT,
 | 
			
		||||
 | 
			
		||||
    RT_RESOURCE_TYPE_count,
 | 
			
		||||
} rt_resource_type;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user