From: Marek Olšák Date: Mon, 12 Apr 2010 01:08:38 +0000 (+0200) Subject: r300g: atomize fragment shader X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=34092c55d63e24a4f326bd9bb90765ea4ec7e17e;p=mesa.git r300g: atomize fragment shader --- diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index f26330ef1da..322eaa83bd0 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -32,7 +32,7 @@ static void r300_blitter_save_states(struct r300_context* r300) util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state); util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref)); util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); - util_blitter_save_fragment_shader(r300->blitter, r300->fs); + util_blitter_save_fragment_shader(r300->blitter, r300->fs.state); util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state); util_blitter_save_viewport(r300->blitter, &r300->viewport); util_blitter_save_clip(r300->blitter, &r300->clip); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 38b8e35e5c5..8d8612ed6eb 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -115,6 +115,12 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(vs_state, 0); R300_INIT_ATOM(texture_cache_inval, 2); R300_INIT_ATOM(textures_state, 0); + R300_INIT_ATOM(fs, 0); + + /* Replace emission functions for r500. */ + if (r300->screen->caps.is_r500) { + r300->fs.emit = r500_emit_fs; + } /* Some non-CSO atoms need explicit space to store the state locally. */ r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index e3dd6de5c72..51beaa50f57 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -357,7 +357,7 @@ struct r300_context { /* Depth, stencil, and alpha state. */ struct r300_atom dsa_state; /* Fragment shader. */ - struct r300_fragment_shader* fs; + struct r300_atom fs; /* Framebuffer state. */ struct r300_atom fb_state; /* Rasterizer state. */ @@ -432,6 +432,10 @@ static INLINE struct r300_context* r300_context(struct pipe_context* context) return (struct r300_context*)context; } +static INLINE struct r300_fragment_shader *r300_fs(struct r300_context *r300) +{ + return (struct r300_fragment_shader*)r300->fs.state; +} struct pipe_context* r300_create_context(struct pipe_screen* screen, void *priv); diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h index 1cc8a8674fd..2bcf298c414 100644 --- a/src/gallium/drivers/r300/r300_defines.h +++ b/src/gallium/drivers/r300/r300_defines.h @@ -31,7 +31,6 @@ #define R300_RESOURCE_FLAG_TRANSFER PIPE_RESOURCE_FLAG_DRV_PRIV /* Non-atom dirty state flags. */ -#define R300_NEW_FRAGMENT_SHADER 0x00000020 #define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040 #define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000 #define R300_NEW_QUERY 0x40000000 diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 14faef24c5e..2fa3f6fe2ec 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -236,7 +236,7 @@ static uint32_t pack_float24(float f) static void r300_emit_fragment_depth_config(struct r300_context* r300) { CS_LOCALS(r300); - if (r300_fragment_shader_writes_depth(r300->fs)) { + if (r300_fragment_shader_writes_depth(r300_fs(r300))) { OUT_CS_REG(R300_FG_DEPTH_SRC, R300_FG_DEPTH_SRC_SHADER); OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W24 | R300_W_SRC_US); } else { @@ -245,22 +245,31 @@ static void r300_emit_fragment_depth_config(struct r300_context* r300) } } -void r300_emit_fragment_program_code(struct r300_context* r300, - struct rX00_fragment_program_code* generic_code) +unsigned r300_get_fs_atom_size(struct r300_context *r300) { + struct r300_fragment_shader *fs = r300_fs(r300); + unsigned imm_count = fs->shader->immediates_count; + struct r300_fragment_program_code *code = &fs->shader->code.code.r300; + + return 19 + + code->alu.length * 4 + + (code->tex.length ? (1 + code->tex.length) : 0) + + (imm_count ? imm_count * 5 : 0); +} + +void r300_emit_fs(struct r300_context* r300, unsigned size, void *state) +{ + struct r300_fragment_shader *fs = r300_fs(r300); + struct rX00_fragment_program_code* generic_code = &fs->shader->code; struct r300_fragment_program_code * code = &generic_code->code.r300; unsigned i; - unsigned imm_count = r300->fs->shader->immediates_count; - unsigned imm_first = r300->fs->shader->externals_count; + unsigned imm_count = fs->shader->immediates_count; + unsigned imm_first = fs->shader->externals_count; unsigned imm_end = generic_code->constants.Count; struct rc_constant *constants = generic_code->constants.Constants; CS_LOCALS(r300); - BEGIN_CS(19 + - code->alu.length * 4 + - (code->tex.length ? (1 + code->tex.length) : 0) + - (imm_count ? imm_count * 5 : 0)); - + BEGIN_CS(size); OUT_CS_REG(R300_US_CONFIG, code->config); OUT_CS_REG(R300_US_PIXSIZE, code->pixsize); OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset); @@ -314,7 +323,8 @@ void r300_emit_fragment_program_code(struct r300_context* r300, void r300_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants) { - unsigned i, count = r300->fs->shader->externals_count; + struct r300_fragment_shader *fs = r300_fs(r300); + unsigned i, count = fs->shader->externals_count; CS_LOCALS(r300); if (count == 0) @@ -337,9 +347,10 @@ void r300_emit_fs_constant_buffer(struct r300_context* r300, void r300_emit_fs_constant_rc_state(struct r300_context* r300, struct rc_constant_list* constants) { + struct r300_fragment_shader *fs = r300_fs(r300); unsigned i; - unsigned count = r300->fs->shader->rc_state_count; - unsigned first = r300->fs->shader->externals_count; + unsigned count = fs->shader->rc_state_count; + unsigned first = fs->shader->externals_count; unsigned end = constants->Count; CS_LOCALS(r300); @@ -362,20 +373,30 @@ void r300_emit_fs_constant_rc_state(struct r300_context* r300, END_CS; } -void r500_emit_fragment_program_code(struct r300_context* r300, - struct rX00_fragment_program_code* generic_code) +unsigned r500_get_fs_atom_size(struct r300_context *r300) { + struct r300_fragment_shader *fs = r300_fs(r300); + unsigned imm_count = fs->shader->immediates_count; + struct r500_fragment_program_code *code = &fs->shader->code.code.r500; + + return 17 + + ((code->inst_end + 1) * 6) + + (imm_count ? imm_count * 7 : 0); +} + +void r500_emit_fs(struct r300_context* r300, unsigned size, void *state) +{ + struct r300_fragment_shader *fs = r300_fs(r300); + struct rX00_fragment_program_code* generic_code = &fs->shader->code; struct r500_fragment_program_code * code = &generic_code->code.r500; unsigned i; - unsigned imm_count = r300->fs->shader->immediates_count; - unsigned imm_first = r300->fs->shader->externals_count; + unsigned imm_count = fs->shader->immediates_count; + unsigned imm_first = fs->shader->externals_count; unsigned imm_end = generic_code->constants.Count; struct rc_constant *constants = generic_code->constants.Constants; CS_LOCALS(r300); - BEGIN_CS(17 + - ((code->inst_end + 1) * 6) + - (imm_count ? imm_count * 7 : 0)); + BEGIN_CS(size); OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx); OUT_CS_REG(R500_US_CODE_RANGE, @@ -421,7 +442,8 @@ void r500_emit_fragment_program_code(struct r300_context* r300, void r500_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants) { - unsigned i, count = r300->fs->shader->externals_count; + struct r300_fragment_shader *fs = r300_fs(r300); + unsigned i, count = fs->shader->externals_count; CS_LOCALS(r300); if (count == 0) @@ -446,9 +468,10 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300, void r500_emit_fs_constant_rc_state(struct r300_context* r300, struct rc_constant_list* constants) { + struct r300_fragment_shader *fs = r300_fs(r300); unsigned i; - unsigned count = r300->fs->shader->rc_state_count; - unsigned first = r300->fs->shader->externals_count; + unsigned count = fs->shader->rc_state_count; + unsigned first = fs->shader->externals_count; unsigned end = constants->Count; CS_LOCALS(r300); @@ -1188,26 +1211,17 @@ void r300_emit_dirty_state(struct r300_context* r300) } } - if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) { - if (r300screen->caps.is_r500) { - r500_emit_fragment_program_code(r300, &r300->fs->shader->code); - } else { - r300_emit_fragment_program_code(r300, &r300->fs->shader->code); - } - r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER; - } - if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) { if (r300screen->caps.is_r500) { r500_emit_fs_constant_buffer(r300, - &r300->fs->shader->code.constants); + &r300_fs(r300)->shader->code.constants); r500_emit_fs_constant_rc_state(r300, - &r300->fs->shader->code.constants); + &r300_fs(r300)->shader->code.constants); } else { r300_emit_fs_constant_buffer(r300, - &r300->fs->shader->code.constants); + &r300_fs(r300)->shader->code.constants); r300_emit_fs_constant_rc_state(r300, - &r300->fs->shader->code.constants); + &r300_fs(r300)->shader->code.constants); } r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS; } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 19ab4308e68..266538d06f3 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -43,8 +43,9 @@ void r300_emit_clip_state(struct r300_context* r300, void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state); -void r300_emit_fragment_program_code(struct r300_context* r300, - struct rX00_fragment_program_code* generic_code); +unsigned r300_get_fs_atom_size(struct r300_context *r300); + +void r300_emit_fs(struct r300_context* r300, unsigned size, void *state); void r300_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); @@ -52,8 +53,9 @@ void r300_emit_fs_constant_buffer(struct r300_context* r300, void r300_emit_fs_constant_rc_state(struct r300_context* r300, struct rc_constant_list* constants); -void r500_emit_fragment_program_code(struct r300_context* r300, - struct rX00_fragment_program_code* generic_code); +unsigned r500_get_fs_atom_size(struct r300_context *r300); + +void r500_emit_fs(struct r300_context* r300, unsigned size, void *state); void r500_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 4969c1472b0..762cbf27e15 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -278,7 +278,7 @@ static void r300_translate_fragment_shader( boolean r300_pick_fragment_shader(struct r300_context* r300) { - struct r300_fragment_shader* fs = r300->fs; + struct r300_fragment_shader* fs = r300_fs(r300); struct r300_fragment_program_external_state state; struct r300_fragment_shader_code* ptr; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index f80935505b0..1a0087241d7 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -32,6 +32,7 @@ #include "pipe/p_config.h" #include "r300_context.h" +#include "r300_emit.h" #include "r300_reg.h" #include "r300_screen.h" #include "r300_screen_buffer.h" @@ -682,6 +683,21 @@ static void* r300_create_fs_state(struct pipe_context* pipe, return (void*)fs; } +static void r300_mark_fs_code_dirty(struct r300_context *r300) +{ + struct r300_fragment_shader* fs = r300_fs(r300); + + r300->fs.dirty = TRUE; + + if (r300->screen->caps.is_r500) { + r300->fs.size = r500_get_fs_atom_size(r300); + } else { + r300->fs.size = r300_get_fs_atom_size(r300); + } + + r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; +} + /* Bind fragment shader state. */ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) { @@ -689,20 +705,19 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; if (fs == NULL) { - r300->fs = NULL; + r300->fs.state = NULL; return; } - r300->fs = fs; + r300->fs.state = fs; r300_pick_fragment_shader(r300); + r300_mark_fs_code_dirty(r300); r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ if (r300->vs_state.state && r300_vertex_shader_setup_wpos(r300)) { r300->vap_output_state.dirty = TRUE; } - - r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; } /* Delete fragment shader state. */ @@ -933,10 +948,9 @@ static void r300_bind_sampler_states(struct pipe_context* pipe, r300->textures_state.dirty = TRUE; /* Pick a fragment shader based on the texture compare state. */ - if (r300->fs && count) { + if (r300->fs.state && count) { if (r300_pick_fragment_shader(r300)) { - r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | - R300_NEW_FRAGMENT_SHADER_CONSTANTS; + r300_mark_fs_code_dirty(r300); } } } @@ -1100,7 +1114,7 @@ static void r300_set_viewport_state(struct pipe_context* pipe, } r300->viewport_state.dirty = TRUE; - if (r300->fs && r300->fs->shader->inputs.wpos != ATTR_UNUSED) { + if (r300->fs.state && r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) { r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; } } @@ -1319,7 +1333,7 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->vs_state.state = vs; // VS output mapping for HWTCL or stream mapping for SWTCL to the RS block - if (r300->fs) { + if (r300->fs.state) { r300_vertex_shader_setup_wpos(r300); } memcpy(r300->vap_output_state.state, &vs->vap_out, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 1b4c2457d5f..86c5277263a 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -376,7 +376,7 @@ static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; - r300_update_rs_block(r300, &vs->outputs, &r300->fs->shader->inputs); + r300_update_rs_block(r300, &vs->outputs, &r300_fs(r300)->shader->inputs); } static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa) @@ -436,12 +436,12 @@ static void r300_update_ztop(struct r300_context* r300) /* ZS writes */ if (r300_dsa_writes_depth_stencil(r300->dsa_state.state) && - (r300_dsa_alpha_test_enabled(r300->dsa_state.state) ||/* (1) */ - r300->fs->shader->info.uses_kill)) { /* (2) */ + (r300_dsa_alpha_test_enabled(r300->dsa_state.state) || /* (1) */ + r300_fs(r300)->shader->info.uses_kill)) { /* (2) */ ztop_state->z_buffer_top = R300_ZTOP_DISABLE; - } else if (r300_fragment_shader_writes_depth(r300->fs)) { /* (5) */ + } else if (r300_fragment_shader_writes_depth(r300_fs(r300))) { /* (5) */ ztop_state->z_buffer_top = R300_ZTOP_DISABLE; - } else if (r300->query_current) { /* (6) */ + } else if (r300->query_current) { /* (6) */ ztop_state->z_buffer_top = R300_ZTOP_DISABLE; } else { ztop_state->z_buffer_top = R300_ZTOP_ENABLE; diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index a2619b38319..2f9ee76bd89 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -348,7 +348,7 @@ boolean r300_vertex_shader_setup_wpos(struct r300_context* r300) return FALSE; } - if (r300->fs->shader->inputs.wpos != ATTR_UNUSED) { + if (r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) { /* Enable WPOS in VAP. */ if (!(vap_out->vap_vsm_vtx_assm & tex_fmt)) { vap_out->vap_vsm_vtx_assm |= tex_fmt;