mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-05 05:50:29 +01:00
r300g: atomize fragment shader
This commit is contained in:
parent
13b86fe207
commit
34092c55d6
10 changed files with 98 additions and 59 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue