From b81481e31d7feebd4b8dbaf32cc2071b81cc92bf Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 26 Oct 2014 07:12:09 +0100 Subject: [PATCH] (360) HLSL - Allocate struct dynamically --- gfx/shader/shader_hlsl.c | 252 ++++++++++++++++++++++----------------- 1 file changed, 142 insertions(+), 110 deletions(-) diff --git a/gfx/shader/shader_hlsl.c b/gfx/shader/shader_hlsl.c index 297bfe0562..7d57ee16bf 100644 --- a/gfx/shader/shader_hlsl.c +++ b/gfx/shader/shader_hlsl.c @@ -80,16 +80,19 @@ struct hlsl_program XMMATRIX mvp_val; /* TODO: Move to D3DXMATRIX here */ }; -static struct hlsl_program prg[RARCH_HLSL_MAX_SHADERS] = {0}; -static bool hlsl_active = false; -static unsigned active_idx = 0; +typedef struct hlsl_shader_data +{ + struct hlsl_program prg[RARCH_HLSL_MAX_SHADERS]; + unsigned active_idx; + struct gfx_shader *cg_shader; +} hlsl_shader_data_t; -static struct gfx_shader *cg_shader; void hlsl_set_proj_matrix(XMMATRIX rotation_value) { - if (hlsl_active) - prg[active_idx].mvp_val = rotation_value; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)driver.video_shader_data; + if (hlsl) + hlsl->prg[hlsl->active_idx].mvp_val = rotation_value; } #define set_param_2f(param, xy, constanttable) \ @@ -110,8 +113,9 @@ static void hlsl_set_params(void *data, unsigned width, unsigned height, const struct gl_tex_info *info = (const struct gl_tex_info*)_info; const struct gl_tex_info *prev_info = (const struct gl_tex_info*)_prev_info; const struct gl_tex_info *fbo_info = (const struct gl_tex_info*)_fbo_info; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)driver.video_shader_data; - if (!hlsl_active) + if (!hlsl) return; const float ori_size[2] = { (float)width, (float)height }; @@ -119,26 +123,26 @@ static void hlsl_set_params(void *data, unsigned width, unsigned height, const float out_size[2] = { (float)out_width, (float)out_height }; float frame_cnt = frame_counter; - prg[active_idx].f_ctable->SetDefaults(d3d_device_ptr); - prg[active_idx].v_ctable->SetDefaults(d3d_device_ptr); + hlsl->prg[hlsl->active_idx].f_ctable->SetDefaults(d3d_device_ptr); + hlsl->prg[hlsl->active_idx].v_ctable->SetDefaults(d3d_device_ptr); - set_param_2f(prg[active_idx].vid_size_f, ori_size, prg[active_idx].f_ctable); - set_param_2f(prg[active_idx].tex_size_f, tex_size, prg[active_idx].f_ctable); - set_param_2f(prg[active_idx].out_size_f, out_size, prg[active_idx].f_ctable); - set_param_1f(prg[active_idx].frame_cnt_f, frame_cnt, prg[active_idx].f_ctable); - set_param_1f(prg[active_idx].frame_dir_f, g_extern.frame_is_reverse ? -1.0 : 1.0,prg[active_idx].f_ctable); - - set_param_2f(prg[active_idx].vid_size_v, ori_size, prg[active_idx].v_ctable); - set_param_2f(prg[active_idx].tex_size_v, tex_size, prg[active_idx].v_ctable); - set_param_2f(prg[active_idx].out_size_v, out_size, prg[active_idx].v_ctable); - set_param_1f(prg[active_idx].frame_cnt_v, frame_cnt, prg[active_idx].v_ctable); - set_param_1f(prg[active_idx].frame_dir_v, g_extern.frame_is_reverse ? -1.0 : 1.0,prg[active_idx].v_ctable); + set_param_2f(hlsl->prg[hlsl->active_idx].vid_size_f, ori_size, hlsl->prg[hlsl->active_idx].f_ctable); + set_param_2f(hlsl->prg[hlsl->active_idx].tex_size_f, tex_size, hlsl->prg[hlsl->active_idx].f_ctable); + set_param_2f(hlsl->prg[hlsl->active_idx].out_size_f, out_size, hlsl->prg[hlsl->active_idx].f_ctable); + set_param_1f(hlsl->prg[hlsl->active_idx].frame_cnt_f, frame_cnt, hlsl->prg[hlsl->active_idx].f_ctable); + set_param_1f(hlsl->prg[hlsl->active_idx].frame_dir_f, g_extern.frame_is_reverse ? -1.0 : 1.0, hlsl->prg[hlsl->active_idx].f_ctable); + set_param_2f(hlsl->prg[hlsl->active_idx].vid_size_v, ori_size, hlsl->prg[hlsl->active_idx].v_ctable); + set_param_2f(hlsl->prg[hlsl->active_idx].tex_size_v, tex_size, hlsl->prg[hlsl->active_idx].v_ctable); + set_param_2f(hlsl->prg[hlsl->active_idx].out_size_v, out_size, hlsl->prg[hlsl->active_idx].v_ctable); + set_param_1f(hlsl->prg[hlsl->active_idx].frame_cnt_v, frame_cnt, hlsl->prg[hlsl->active_idx].v_ctable); + set_param_1f(hlsl->prg[hlsl->active_idx].frame_dir_v, g_extern.frame_is_reverse ? -1.0 : 1.0, hlsl->prg[hlsl->active_idx].v_ctable); /* TODO - set lookup textures/FBO textures/state parameters/etc */ } -static bool load_program(void *data, unsigned idx, const char *prog, bool path_is_file) +static bool load_program(hlsl_shader_data_t *hlsl, + void *data, unsigned idx, const char *prog, bool path_is_file) { d3d_video_t *d3d = (d3d_video_t*)data; LPDIRECT3DDEVICE d3d_device_ptr = (LPDIRECT3DDEVICE)d3d->dev; @@ -151,17 +155,17 @@ static bool load_program(void *data, unsigned idx, const char *prog, bool path_i if (path_is_file) { ret_fp = D3DXCompileShaderFromFile(prog, NULL, NULL, - "main_fragment", "ps_3_0", 0, &code_f, &listing_f, &prg[idx].f_ctable); + "main_fragment", "ps_3_0", 0, &code_f, &listing_f, &hlsl->prg[idx].f_ctable); ret_vp = D3DXCompileShaderFromFile(prog, NULL, NULL, - "main_vertex", "vs_3_0", 0, &code_v, &listing_v, &prg[idx].v_ctable); + "main_vertex", "vs_3_0", 0, &code_v, &listing_v, &hlsl->prg[idx].v_ctable); } else { /* TODO - crashes currently - to do with 'end of line' of stock shader */ ret_fp = D3DXCompileShader(prog, strlen(prog), NULL, NULL, - "main_fragment", "ps_3_0", 0, &code_f, &listing_f, &prg[idx].f_ctable ); + "main_fragment", "ps_3_0", 0, &code_f, &listing_f, &hlsl->prg[idx].f_ctable ); ret_vp = D3DXCompileShader(prog, strlen(prog), NULL, NULL, - "main_vertex", "vs_3_0", 0, &code_v, &listing_v, &prg[idx].v_ctable ); + "main_vertex", "vs_3_0", 0, &code_v, &listing_v, &hlsl->prg[idx].v_ctable ); } if (ret_fp < 0 || ret_vp < 0 || listing_v || listing_f) @@ -176,8 +180,8 @@ static bool load_program(void *data, unsigned idx, const char *prog, bool path_i goto end; } - d3d_device_ptr->CreatePixelShader((const DWORD*)code_f->GetBufferPointer(), &prg[idx].fprg); - d3d_device_ptr->CreateVertexShader((const DWORD*)code_v->GetBufferPointer(), &prg[idx].vprg); + d3d_device_ptr->CreatePixelShader((const DWORD*)code_f->GetBufferPointer(), &hlsl->prg[idx].fprg); + d3d_device_ptr->CreateVertexShader((const DWORD*)code_v->GetBufferPointer(), &hlsl->prg[idx].vprg); code_f->Release(); code_v->Release(); @@ -189,9 +193,9 @@ end: return ret; } -static bool load_stock(void *data) +static bool load_stock(hlsl_shader_data_t *hlsl, void *data) { - if (!load_program(data, 0, stock_hlsl_program, false)) + if (!load_program(hlsl, data, 0, stock_hlsl_program, false)) { RARCH_ERR("Failed to compile passthrough shader, is something wrong with your environment?\n"); return false; @@ -200,98 +204,102 @@ static bool load_stock(void *data) return true; } -static void set_program_attributes(unsigned i) +static void set_program_attributes(hlsl_shader_data_t *hlsl, unsigned i) { - prg[i].vid_size_f = prg[i].f_ctable->GetConstantByName(NULL, "$IN.video_size"); - prg[i].tex_size_f = prg[i].f_ctable->GetConstantByName(NULL, "$IN.texture_size"); - prg[i].out_size_f = prg[i].f_ctable->GetConstantByName(NULL, "$IN.output_size"); - prg[i].frame_cnt_f = prg[i].f_ctable->GetConstantByName(NULL, "$IN.frame_count"); - prg[i].frame_dir_f = prg[i].f_ctable->GetConstantByName(NULL, "$IN.frame_direction"); - prg[i].vid_size_v = prg[i].v_ctable->GetConstantByName(NULL, "$IN.video_size"); - prg[i].tex_size_v = prg[i].v_ctable->GetConstantByName(NULL, "$IN.texture_size"); - prg[i].out_size_v = prg[i].v_ctable->GetConstantByName(NULL, "$IN.output_size"); - prg[i].frame_cnt_v = prg[i].v_ctable->GetConstantByName(NULL, "$IN.frame_count"); - prg[i].frame_dir_v = prg[i].v_ctable->GetConstantByName(NULL, "$IN.frame_direction"); - prg[i].mvp = prg[i].v_ctable->GetConstantByName(NULL, "$modelViewProj"); - prg[i].mvp_val = XMMatrixIdentity(); + if (!hlsl) + return; + + hlsl->prg[i].vid_size_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.video_size"); + hlsl->prg[i].tex_size_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.texture_size"); + hlsl->prg[i].out_size_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.output_size"); + hlsl->prg[i].frame_cnt_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.frame_count"); + hlsl->prg[i].frame_dir_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.frame_direction"); + hlsl->prg[i].vid_size_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.video_size"); + hlsl->prg[i].tex_size_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.texture_size"); + hlsl->prg[i].out_size_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.output_size"); + hlsl->prg[i].frame_cnt_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.frame_count"); + hlsl->prg[i].frame_dir_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.frame_direction"); + hlsl->prg[i].mvp = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$modelViewProj"); + hlsl->prg[i].mvp_val = XMMatrixIdentity(); } -static bool load_shader(void *data, const char *cgp_path, unsigned i) +static bool load_shader(hlsl_shader_data_t *hlsl, + void *data, const char *cgp_path, unsigned i) { char path_buf[PATH_MAX]; fill_pathname_resolve_relative(path_buf, cgp_path, - cg_shader->pass[i].source.path, sizeof(path_buf)); + hlsl->cg_shader->pass[i].source.path, sizeof(path_buf)); RARCH_LOG("Loading Cg/HLSL shader: \"%s\".\n", path_buf); - if (!load_program(data, i + 1, path_buf, true)) + if (!load_program(hlsl, data, i + 1, path_buf, true)) return false; return true; } -static bool load_plain(void *data, const char *path) +static bool load_plain(hlsl_shader_data_t *hlsl, void *data, const char *path) { - if (!load_stock(data)) + if (!load_stock(hlsl, data)) return false; - cg_shader = (struct gfx_shader*)calloc(1, sizeof(*cg_shader)); - if (!cg_shader) + hlsl->cg_shader = (struct gfx_shader*)calloc(1, sizeof(*hlsl->cg_shader)); + if (!hlsl->cg_shader) return false; - cg_shader->passes = 1; + hlsl->cg_shader->passes = 1; if (path && path[0] != '\0') { RARCH_LOG("Loading Cg/HLSL file: %s\n", path); - strlcpy(cg_shader->pass[0].source.path, path, sizeof(cg_shader->pass[0].source.path)); - if (!load_program(data, 1, path, true)) + strlcpy(hlsl->cg_shader->pass[0].source.path, + path, sizeof(hlsl->cg_shader->pass[0].source.path)); + if (!load_program(hlsl, data, 1, path, true)) return false; } else { RARCH_LOG("Loading stock Cg/HLSL file.\n"); - prg[1] = prg[0]; + hlsl->prg[1] = hlsl->prg[0]; } return true; } -static void hlsl_deinit_progs(void) +static void hlsl_deinit_progs(hlsl_shader_data_t *hlsl) { - for (unsigned i = 1; i < RARCH_HLSL_MAX_SHADERS; i++) + unsigned i; + for (i = 1; i < RARCH_HLSL_MAX_SHADERS; i++) { - if (prg[i].fprg && prg[i].fprg != prg[0].fprg) - prg[i].fprg->Release(); - if (prg[i].vprg && prg[i].vprg != prg[0].vprg) - prg[i].vprg->Release(); - - prg[i].fprg = NULL; - prg[i].vprg = NULL; + if (hlsl->prg[i].fprg && hlsl->prg[i].fprg != hlsl->prg[0].fprg) + hlsl->prg[i].fprg->Release(); + hlsl->prg[i].fprg = NULL; + if (hlsl->prg[i].vprg && hlsl->prg[i].vprg != hlsl->prg[0].vprg) + hlsl->prg[i].vprg->Release(); + hlsl->prg[i].vprg = NULL; } - if (prg[0].fprg) - prg[0].fprg->Release(); - if (prg[0].vprg) - prg[0].vprg->Release(); - - prg[0].fprg = NULL; - prg[0].vprg = NULL; + if (hlsl->prg[0].fprg) + hlsl->prg[0].fprg->Release(); + hlsl->prg[0].fprg = NULL; + if (hlsl->prg[0].vprg) + hlsl->prg[0].vprg->Release(); + hlsl->prg[0].vprg = NULL; } -static void hlsl_deinit_state(void) +static void hlsl_deinit_state(hlsl_shader_data_t *hlsl) { - hlsl_active = false; - hlsl_deinit_progs(); - memset(prg, 0, sizeof(prg)); + hlsl_deinit_progs(hlsl); + memset(hlsl->prg, 0, sizeof(hlsl->prg)); - free(cg_shader); - cg_shader = NULL; + if (hlsl->cg_shader) + free(hlsl->cg_shader); + hlsl->cg_shader = NULL; } -static bool load_preset(void *data, const char *path) +static bool load_preset(hlsl_shader_data_t *hlsl, void *data, const char *path) { - if (!load_stock(data)) + if (!load_stock(hlsl, data)) return false; RARCH_LOG("Loading Cg meta-shader: %s\n", path); @@ -303,12 +311,12 @@ static bool load_preset(void *data, const char *path) return false; } - if (!cg_shader) - cg_shader = (struct gfx_shader*)calloc(1, sizeof(*cg_shader)); - if (!cg_shader) + if (!hlsl->cg_shader) + hlsl->cg_shader = (struct gfx_shader*)calloc(1, sizeof(*hlsl->cg_shader)); + if (!hlsl->cg_shader) return false; - if (!gfx_shader_read_conf_cgp(conf, cg_shader)) + if (!gfx_shader_read_conf_cgp(conf, hlsl->cg_shader)) { RARCH_ERR("Failed to parse CGP file.\n"); config_file_free(conf); @@ -317,14 +325,14 @@ static bool load_preset(void *data, const char *path) config_file_free(conf); - if (cg_shader->passes > RARCH_HLSL_MAX_SHADERS - 3) + if (hlsl->cg_shader->passes > RARCH_HLSL_MAX_SHADERS - 3) { RARCH_WARN("Too many shaders ... Capping shader amount to %d.\n", RARCH_HLSL_MAX_SHADERS - 3); - cg_shader->passes = RARCH_HLSL_MAX_SHADERS - 3; + hlsl->cg_shader->passes = RARCH_HLSL_MAX_SHADERS - 3; } - for (unsigned i = 0; i < cg_shader->passes; i++) + for (unsigned i = 0; i < hlsl->cg_shader->passes; i++) { - if (!load_shader(data, path, i)) + if (!load_shader(hlsl, data, path, i)) { RARCH_ERR("Failed to load shaders ...\n"); return false; @@ -339,66 +347,86 @@ static bool load_preset(void *data, const char *path) static bool hlsl_init(void *data, const char *path) { d3d_video_t *d3d = (d3d_video_t*)data; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*) + calloc(1, sizeof(hlsl_shader_data_t)); + + if (!hlsl) + return false; if (path && strcmp(path_get_extension(path), ".cgp") == 0) { - if (!load_preset(d3d, path)) - return false; + if (!load_preset(hlsl, d3d, path)) + goto error; } else { - if (!load_plain(d3d, path)) - return false; + if (!load_plain(hlsl, d3d, path)) + goto error; } - for(unsigned i = 1; i <= cg_shader->passes; i++) - set_program_attributes(i); + for(unsigned i = 1; i <= hlsl->cg_shader->passes; i++) + set_program_attributes(hlsl, i); - d3d_set_vertex_shader(d3d->dev, 1, prg[1].vprg); - d3d->dev->SetPixelShader(prg[1].fprg); + d3d_set_vertex_shader(d3d->dev, 1, hlsl->prg[1].vprg); + d3d->dev->SetPixelShader(hlsl->prg[1].fprg); + + driver.video_shader_data = hlsl; - hlsl_active = true; return true; + +error: + if (hlsl) + free(hlsl); + return false; } // Full deinit. static void hlsl_deinit(void) { - if (!hlsl_active) + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)driver.video_shader_data; + if (!hlsl) return; - hlsl_deinit_state(); + hlsl_deinit_state(hlsl); + + if (driver.video_shader_data) + free(driver.video_shader_data); + driver.video_shader_data = NULL; } static void hlsl_use(void *data, unsigned idx) { d3d_video_t *d3d = (d3d_video_t*)data; LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev; - if (hlsl_active && prg[idx].vprg && prg[idx].fprg) + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)driver.video_shader_data; + + if (hlsl && hlsl->prg[idx].vprg && hlsl->prg[idx].fprg) { - active_idx = idx; - d3d_set_vertex_shader(d3dr, idx, prg[idx].vprg); + hlsl->active_idx = idx; + d3d_set_vertex_shader(d3dr, idx, hlsl->prg[idx].vprg); #ifdef _XBOX - D3DDevice_SetPixelShader(d3dr, prg[idx].fprg); + D3DDevice_SetPixelShader(d3dr, hlsl->prg[idx].fprg); #else - d3dr->SetPixelShader(prg[idx].fprg); + d3dr->SetPixelShader(hlsl->prg[idx].fprg); #endif } } static unsigned hlsl_num(void) { - if (hlsl_active) - return cg_shader->passes; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)driver.video_shader_data; + if (hlsl) + return hlsl->cg_shader->passes; return 0; } static bool hlsl_filter_type(unsigned idx, bool *smooth) { - if (hlsl_active && idx - && (cg_shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC)) + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)driver.video_shader_data; + if (hlsl && idx + && (hlsl->cg_shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC)) { - *smooth = cg_shader->pass[idx - 1].filter = RARCH_FILTER_LINEAR; + *smooth = hlsl->cg_shader->pass[idx - 1].filter = RARCH_FILTER_LINEAR; return true; } return false; @@ -406,8 +434,9 @@ static bool hlsl_filter_type(unsigned idx, bool *smooth) static void hlsl_shader_scale(unsigned idx, struct gfx_fbo_scale *scale) { - if (hlsl_active && idx) - *scale = cg_shader->pass[idx - 1].fbo; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)driver.video_shader_data; + if (hlsl && idx) + *scale = hlsl->cg_shader->pass[idx - 1].fbo; else scale->valid = false; } @@ -416,10 +445,13 @@ static bool hlsl_set_mvp(void *data, const math_matrix_4x4 *mat) { d3d_video_t *d3d = (d3d_video_t*)data; LPDIRECT3DDEVICE d3d_device_ptr = (LPDIRECT3DDEVICE)d3d->dev; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)driver.video_shader_data; - if(hlsl_active && prg[active_idx].mvp) + if(hlsl && hlsl->prg[hlsl->active_idx].mvp) { - prg[active_idx].v_ctable->SetMatrix(d3d_device_ptr, prg[active_idx].mvp, (D3DXMATRIX*)&prg[active_idx].mvp_val); + hlsl->prg[hlsl->active_idx].v_ctable->SetMatrix(d3d_device_ptr, + hlsl->prg[hlsl->active_idx].mvp, + (D3DXMATRIX*)&hlsl->prg[hlsl->active_idx].mvp_val); return true; } return false;