st/nine: Finish Fog implementation
Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
@@ -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_ */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user