st/nine: Finish Fog implementation

Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
Axel Davy
2015-05-12 21:56:04 +02:00
parent 69de5d626f
commit 8f39ffc11e
8 changed files with 147 additions and 26 deletions
+44 -3
View File
@@ -3199,9 +3199,50 @@ shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
{
struct ureg_program *ureg = tx->ureg;
struct ureg_dst oCol0 = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
struct ureg_src fog_end, fog_coeff, fog_density;
struct ureg_src fog_vs, depth, fog_color;
struct ureg_dst fog_factor;
/* TODO: fog computation */
ureg_MOV(ureg, oCol0, src_col);
if (!tx->info->fog_enable) {
ureg_MOV(ureg, oCol0, src_col);
return;
}
if (tx->info->fog_mode != D3DFOG_NONE)
depth = ureg_scalar(ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0,
TGSI_INTERPOLATE_LINEAR),
TGSI_SWIZZLE_Z);
nine_info_mark_const_f_used(tx->info, 33);
fog_color = NINE_CONSTANT_SRC(32);
fog_factor = tx_scratch_scalar(tx);
if (tx->info->fog_mode == D3DFOG_LINEAR) {
fog_end = NINE_CONSTANT_SRC_SWIZZLE(33, X);
fog_coeff = NINE_CONSTANT_SRC_SWIZZLE(33, Y);
ureg_SUB(ureg, fog_factor, fog_end, depth);
ureg_MUL(ureg, ureg_saturate(fog_factor), tx_src_scalar(fog_factor), fog_coeff);
} else if (tx->info->fog_mode == D3DFOG_EXP) {
fog_density = NINE_CONSTANT_SRC_SWIZZLE(33, X);
ureg_MUL(ureg, fog_factor, depth, fog_density);
ureg_MUL(ureg, fog_factor, tx_src_scalar(fog_factor), ureg_imm1f(ureg, -1.442695f));
ureg_EX2(ureg, fog_factor, tx_src_scalar(fog_factor));
} else if (tx->info->fog_mode == D3DFOG_EXP2) {
fog_density = NINE_CONSTANT_SRC_SWIZZLE(33, X);
ureg_MUL(ureg, fog_factor, depth, fog_density);
ureg_MUL(ureg, fog_factor, tx_src_scalar(fog_factor), tx_src_scalar(fog_factor));
ureg_MUL(ureg, fog_factor, tx_src_scalar(fog_factor), ureg_imm1f(ureg, -1.442695f));
ureg_EX2(ureg, fog_factor, tx_src_scalar(fog_factor));
} else {
fog_vs = ureg_scalar(ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_FOG, 0,
TGSI_INTERPOLATE_PERSPECTIVE),
TGSI_SWIZZLE_X);
ureg_MOV(ureg, fog_factor, fog_vs);
}
ureg_LRP(ureg, ureg_writemask(oCol0, TGSI_WRITEMASK_XYZ),
tx_src_scalar(fog_factor), src_col, fog_color);
ureg_MOV(ureg, ureg_writemask(oCol0, TGSI_WRITEMASK_W), src_col);
}
#define GET_CAP(n) device->screen->get_param( \
@@ -3285,7 +3326,7 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info)
}
}
if (IS_VS && tx->version.major < 3 && ureg_dst_is_undef(tx->regs.oFog)) {
if (IS_VS && tx->version.major < 3 && ureg_dst_is_undef(tx->regs.oFog) && info->fog_enable) {
tx->regs.oFog = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_FOG, 0);
ureg_MOV(tx->ureg, ureg_writemask(tx->regs.oFog, TGSI_WRITEMASK_X), ureg_imm1f(tx->ureg, 0.0f));
}
@@ -59,6 +59,9 @@ struct nine_shader_info
uint16_t sampler_mask_shadow; /* in, which samplers use depth compare */
uint8_t rt_mask; /* out, which render targets are being written */
uint8_t fog_enable;
uint8_t fog_mode;
unsigned const_i_base; /* in vec4 (16 byte) units */
unsigned const_b_base; /* in vec4 (16 byte) units */
unsigned const_used_size;
@@ -138,4 +141,48 @@ nine_shader_variants_free(struct nine_shader_variant *list)
}
}
struct nine_shader_variant64
{
struct nine_shader_variant64 *next;
void *cso;
uint64_t key;
};
static inline void *
nine_shader_variant_get64(struct nine_shader_variant64 *list, uint64_t key)
{
while (list->key != key && list->next)
list = list->next;
if (list->key == key)
return list->cso;
return NULL;
}
static inline boolean
nine_shader_variant_add64(struct nine_shader_variant64 *list,
uint64_t key, void *cso)
{
while (list->next) {
assert(list->key != key);
list = list->next;
}
list->next = MALLOC_STRUCT(nine_shader_variant64);
if (!list->next)
return FALSE;
list->next->next = NULL;
list->next->key = key;
list->next->cso = cso;
return TRUE;
}
static inline void
nine_shader_variants_free64(struct nine_shader_variant64 *list)
{
while (list->next) {
struct nine_shader_variant64 *ptr = list->next;
list->next = ptr->next;
FREE(ptr);
}
}
#endif /* _NINE_SHADER_H_ */
+31 -12
View File
@@ -280,9 +280,6 @@ prepare_ps_constants_userbuf(struct NineDevice9 *device)
cb.buffer_size = device->state.ps->const_used_size;
cb.user_buffer = device->state.ps_const_f;
if (!cb.buffer_size)
return;
if (state->changed.ps_const_i) {
int *idst = (int *)&state->ps_const_f[4 * device->max_ps_const_f];
memcpy(idst, state->ps_const_i, sizeof(state->ps_const_i));
@@ -303,6 +300,27 @@ prepare_ps_constants_userbuf(struct NineDevice9 *device)
cb.user_buffer = device->state.ps_lconstf_temp;
}
if (state->ps->byte_code.version < 0x30 &&
state->rs[D3DRS_FOGENABLE]) {
float *dst = &state->ps_lconstf_temp[4 * 32];
if (cb.user_buffer != state->ps_lconstf_temp) {
memcpy(state->ps_lconstf_temp, cb.user_buffer, cb.buffer_size);
cb.user_buffer = state->ps_lconstf_temp;
}
d3dcolor_to_rgba(dst, state->rs[D3DRS_FOGCOLOR]);
if (state->rs[D3DRS_FOGTABLEMODE] == D3DFOG_LINEAR) {
dst[4] = asfloat(state->rs[D3DRS_FOGEND]);
dst[5] = 1.0f / (asfloat(state->rs[D3DRS_FOGEND]) - asfloat(state->rs[D3DRS_FOGSTART]));
} else if (state->rs[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
dst[4] = asfloat(state->rs[D3DRS_FOGDENSITY]);
}
cb.buffer_size = 4 * 4 * 34;
}
if (!cb.buffer_size)
return;
if (!device->driver_caps.user_cbufs) {
u_upload_data(device->constbuf_uploader,
0,
@@ -931,7 +949,8 @@ commit_ps(struct NineDevice9 *device)
NINE_STATE_PS | \
NINE_STATE_BLEND_COLOR | \
NINE_STATE_STENCIL_REF | \
NINE_STATE_SAMPLE_MASK)
NINE_STATE_SAMPLE_MASK | \
NINE_STATE_FOG_SHADER)
#define NINE_STATE_FREQ_GROUP_1 ~NINE_STATE_FREQ_GROUP_0
@@ -996,13 +1015,13 @@ nine_update_state(struct NineDevice9 *device)
if (group & NINE_STATE_BLEND)
prepare_blend(device);
if (group & (NINE_STATE_VS | NINE_STATE_TEXTURE))
if (group & (NINE_STATE_VS | NINE_STATE_TEXTURE | NINE_STATE_FOG_SHADER))
group |= prepare_vs(device, (group & NINE_STATE_VS) != 0);
if (group & NINE_STATE_RASTERIZER)
prepare_rasterizer(device);
if (group & (NINE_STATE_PS | NINE_STATE_TEXTURE))
if (group & (NINE_STATE_PS | NINE_STATE_TEXTURE | NINE_STATE_FOG_SHADER))
group |= prepare_ps(device, (group & NINE_STATE_PS) != 0);
if (group & NINE_STATE_BLEND_COLOR) {
@@ -1486,13 +1505,13 @@ const uint32_t nine_render_state_group[NINED3DRS_LAST + 1] =
[D3DRS_ALPHAFUNC] = NINE_STATE_DSA,
[D3DRS_DITHERENABLE] = NINE_STATE_BLEND,
[D3DRS_ALPHABLENDENABLE] = NINE_STATE_BLEND,
[D3DRS_FOGENABLE] = NINE_STATE_FF_OTHER,
[D3DRS_FOGENABLE] = NINE_STATE_FF_OTHER | NINE_STATE_FOG_SHADER | NINE_STATE_PS_CONST,
[D3DRS_SPECULARENABLE] = NINE_STATE_FF_LIGHTING,
[D3DRS_FOGCOLOR] = NINE_STATE_FF_OTHER,
[D3DRS_FOGTABLEMODE] = NINE_STATE_FF_OTHER,
[D3DRS_FOGSTART] = NINE_STATE_FF_OTHER,
[D3DRS_FOGEND] = NINE_STATE_FF_OTHER,
[D3DRS_FOGDENSITY] = NINE_STATE_FF_OTHER,
[D3DRS_FOGCOLOR] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST,
[D3DRS_FOGTABLEMODE] = NINE_STATE_FF_OTHER | NINE_STATE_FOG_SHADER | NINE_STATE_PS_CONST,
[D3DRS_FOGSTART] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST,
[D3DRS_FOGEND] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST,
[D3DRS_FOGDENSITY] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST,
[D3DRS_RANGEFOGENABLE] = NINE_STATE_FF_OTHER,
[D3DRS_STENCILENABLE] = NINE_STATE_DSA,
[D3DRS_STENCILFAIL] = NINE_STATE_DSA,
+3 -2
View File
@@ -75,8 +75,9 @@
#define NINE_STATE_FF_VSTRANSF (1 << 21)
#define NINE_STATE_FF_PSSTAGES (1 << 22)
#define NINE_STATE_FF_OTHER (1 << 23)
#define NINE_STATE_ALL 0x0ffffff
#define NINE_STATE_UNHANDLED (1 << 24)
#define NINE_STATE_FOG_SHADER (1 << 24)
#define NINE_STATE_ALL 0x1ffffff
#define NINE_STATE_UNHANDLED (1 << 25)
#define NINE_STATE_COMMIT_DSA (1 << 0)
#define NINE_STATE_COMMIT_RASTERIZER (1 << 1)
@@ -57,6 +57,7 @@ NinePixelShader9_ctor( struct NinePixelShader9 *This,
info.const_b_base = NINE_CONST_B_BASE(device->max_ps_const_f) / 16;
info.sampler_mask_shadow = 0x0;
info.sampler_ps1xtypes = 0x0;
info.fog_enable = 0;
hr = nine_translate_shader(device, &info);
if (FAILED(hr))
@@ -90,7 +91,7 @@ NinePixelShader9_dtor( struct NinePixelShader9 *This )
if (This->base.device) {
struct pipe_context *pipe = This->base.device->pipe;
struct nine_shader_variant *var = &This->variant;
struct nine_shader_variant64 *var = &This->variant;
do {
if (var->cso) {
@@ -107,7 +108,7 @@ NinePixelShader9_dtor( struct NinePixelShader9 *This )
pipe->delete_fs_state(pipe, This->ff_cso);
}
}
nine_shader_variants_free(&This->variant);
nine_shader_variants_free64(&This->variant);
FREE((void *)This->byte_code.tokens); /* const_cast */
@@ -138,13 +139,13 @@ void *
NinePixelShader9_GetVariant( struct NinePixelShader9 *This )
{
void *cso;
uint32_t key;
uint64_t key;
key = This->next_key;
if (key == This->last_key)
return This->last_cso;
cso = nine_shader_variant_get(&This->variant, key);
cso = nine_shader_variant_get64(&This->variant, key);
if (!cso) {
struct NineDevice9 *device = This->base.device;
struct nine_shader_info info;
@@ -156,11 +157,13 @@ NinePixelShader9_GetVariant( struct NinePixelShader9 *This )
info.byte_code = This->byte_code.tokens;
info.sampler_mask_shadow = key & 0xffff;
info.sampler_ps1xtypes = key;
info.fog_enable = device->state.rs[D3DRS_FOGENABLE];
info.fog_mode = device->state.rs[D3DRS_FOGTABLEMODE];
hr = nine_translate_shader(This->base.device, &info);
if (FAILED(hr))
return NULL;
nine_shader_variant_add(&This->variant, key, info.cso);
nine_shader_variant_add64(&This->variant, key, info.cso);
cso = info.cso;
}
@@ -33,7 +33,7 @@ struct nine_lconstf;
struct NinePixelShader9
{
struct NineUnknown base;
struct nine_shader_variant variant;
struct nine_shader_variant64 variant;
struct {
const DWORD *tokens;
@@ -50,10 +50,10 @@ struct NinePixelShader9
uint64_t ff_key[6];
void *ff_cso;
uint32_t last_key;
uint64_t last_key;
void *last_cso;
uint32_t next_key;
uint64_t next_key;
};
static inline struct NinePixelShader9 *
NinePixelShader9( void *data )
@@ -67,7 +67,7 @@ NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
{
uint16_t samplers_shadow;
uint32_t samplers_ps1_types;
uint32_t key;
uint64_t key;
BOOL res;
if (unlikely(ps->byte_code.version < 0x20)) {
@@ -85,6 +85,11 @@ NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
key = samplers_shadow & ps->sampler_mask;
}
if (ps->byte_code.version < 0x30) {
key |= ((uint64_t)state->rs[D3DRS_FOGENABLE]) << 32;
key |= ((uint64_t)state->rs[D3DRS_FOGTABLEMODE]) << 33;
}
res = ps->last_key != key;
if (res)
ps->next_key = key;
@@ -60,6 +60,7 @@ NineVertexShader9_ctor( struct NineVertexShader9 *This,
info.const_b_base = NINE_CONST_B_BASE(device->max_vs_const_f) / 16;
info.sampler_mask_shadow = 0x0;
info.sampler_ps1xtypes = 0x0;
info.fog_enable = 0;
hr = nine_translate_shader(device, &info);
if (FAILED(hr))
@@ -161,6 +162,7 @@ NineVertexShader9_GetVariant( struct NineVertexShader9 *This )
info.const_b_base = NINE_CONST_B_BASE(device->max_vs_const_f) / 16;
info.byte_code = This->byte_code.tokens;
info.sampler_mask_shadow = key & 0xf;
info.fog_enable = device->state.rs[D3DRS_FOGENABLE];
hr = nine_translate_shader(This->base.device, &info);
if (FAILED(hr))
@@ -80,6 +80,9 @@ NineVertexShader9_UpdateKey( struct NineVertexShader9 *vs,
samplers_shadow &= vs->sampler_mask;
key = samplers_shadow;
if (vs->byte_code.version < 0x30)
key |= state->rs[D3DRS_FOGENABLE] << 8;
res = vs->last_key != key;
if (res)
vs->next_key = key;