IDirect3DPixelShader9 *pShader )
{
struct nine_state *state = This->update;
- struct nine_context *context = &This->context;
- unsigned old_mask = state->ps ? state->ps->rt_mask : 1;
- unsigned mask;
+ struct NinePixelShader9 *ps = (struct NinePixelShader9*)pShader;
DBG("This=%p pShader=%p\n", This, pShader);
- if (!This->is_recording && state->ps == (struct NinePixelShader9*)pShader)
- return D3D_OK;
-
- /* ff -> non-ff: commit back non-ff constants */
- if (!state->ps && pShader)
- context->commit |= NINE_STATE_COMMIT_CONST_PS;
+ if (unlikely(This->is_recording)) {
+ /* Technically we need NINE_STATE_FB only
+ * if the ps mask changes, but put it always
+ * to be safe */
+ nine_bind(&state->ps, pShader);
+ state->changed.group |= NINE_STATE_PS | NINE_STATE_FB;
+ return D3D_OK;
+ }
- nine_bind(&state->ps, pShader);
+ if (state->ps == ps)
+ return D3D_OK;
- state->changed.group |= NINE_STATE_PS;
+ nine_bind(&state->ps, ps);
- mask = state->ps ? state->ps->rt_mask : 1;
- /* We need to update cbufs if the pixel shader would
- * write to different render targets */
- if (mask != old_mask)
- state->changed.group |= NINE_STATE_FB;
+ nine_context_set_pixel_shader(This, ps);
return D3D_OK;
}
struct pipe_constant_buffer cb;
cb.buffer = NULL;
cb.buffer_offset = 0;
- cb.buffer_size = device->state.ps->const_used_size;
+ cb.buffer_size = context->ps->const_used_size;
cb.user_buffer = context->ps_const_f;
if (context->changed.ps_const_i) {
}
/* Upload special constants needed to implement PS1.x instructions like TEXBEM,TEXBEML and BEM */
- if (device->state.ps->bumpenvmat_needed) {
+ if (context->ps->bumpenvmat_needed) {
memcpy(context->ps_lconstf_temp, cb.user_buffer, cb.buffer_size);
memcpy(&context->ps_lconstf_temp[4 * 8], &device->context.bumpmap_vars, sizeof(device->context.bumpmap_vars));
cb.user_buffer = context->ps_lconstf_temp;
}
- if (state->ps->byte_code.version < 0x30 &&
+ if (context->ps->byte_code.version < 0x30 &&
context->rs[D3DRS_FOGENABLE]) {
float *dst = &context->ps_lconstf_temp[4 * 32];
if (cb.user_buffer != context->ps_lconstf_temp) {
static inline uint32_t
prepare_ps(struct NineDevice9 *device, uint8_t shader_changed)
{
- struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
- struct NinePixelShader9 *ps = state->ps;
+ struct NinePixelShader9 *ps = context->ps;
uint32_t changed_group = 0;
int has_key_changed = 0;
unsigned w = rt0->desc.Width;
unsigned h = rt0->desc.Height;
unsigned nr_samples = rt0->base.info.nr_samples;
- unsigned ps_mask = state->ps ? state->ps->rt_mask : 1;
+ unsigned ps_mask = context->ps ? context->ps->rt_mask : 1;
unsigned mask = is_clear ? 0xf : ps_mask;
const int sRGB = context->rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
static void
update_textures_and_samplers(struct NineDevice9 *device)
{
- struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
struct pipe_sampler_view *view[NINE_MAX_SAMPLERS];
unsigned num_textures;
unsigned i;
boolean commit_samplers;
- uint16_t sampler_mask = state->ps ? state->ps->sampler_mask :
+ uint16_t sampler_mask = context->ps ? context->ps->sampler_mask :
device->ff.ps->sampler_mask;
/* TODO: Can we reduce iterations here ? */
{
struct pipe_context *pipe = device->pipe;
- if (unlikely(!device->state.ps))
+ if (unlikely(!device->context.ps))
pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &device->context.pipe.cb_ps_ff);
else
pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &device->context.pipe.cb_ps);
update_managed_buffers(device);
/* ff_update may change VS/PS dirty bits */
- if (unlikely(!context->programmable_vs || !state->ps))
+ if (unlikely(!context->programmable_vs || !context->ps))
nine_ff_update(device);
group = state->changed.group;
update_textures_and_samplers(device);
if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS | NINE_STATE_SWVP)) && context->programmable_vs)
prepare_vs_constants_userbuf(device);
- if ((group & (NINE_STATE_PS_CONST | NINE_STATE_PS)) && state->ps)
+ if ((group & (NINE_STATE_PS_CONST | NINE_STATE_PS)) && context->ps)
prepare_ps_constants_userbuf(device);
}
state->changed.group |= NINE_STATE_VS_CONST;
}
+void
+nine_context_set_pixel_shader(struct NineDevice9 *device,
+ struct NinePixelShader9* ps)
+{
+ struct nine_state *state = &device->state;
+ struct nine_context *context = &device->context;
+ unsigned old_mask = context->ps ? context->ps->rt_mask : 1;
+ unsigned mask;
+
+ /* ff -> non-ff: commit back non-ff constants */
+ if (!context->ps && ps)
+ context->commit |= NINE_STATE_COMMIT_CONST_PS;
+
+ nine_bind(&context->ps, ps);
+
+ state->changed.group |= NINE_STATE_PS;
+
+ mask = context->ps ? context->ps->rt_mask : 1;
+ /* We need to update cbufs if the pixel shader would
+ * write to different render targets */
+ if (mask != old_mask)
+ state->changed.group |= NINE_STATE_FB;
+}
+
void
nine_context_set_pixel_shader_constant_f(struct NineDevice9 *device,
UINT StartRegister,
context->programmable_vs = context->vs && !(context->vdecl && context->vdecl->position_t);
+ /* Pixel shader */
+ if (src->changed.group & NINE_STATE_PS)
+ nine_bind(&context->ps, src->ps);
+
/* Vertex constants */
if (src->changed.group & NINE_STATE_VS_CONST) {
struct nine_range *r;
nine_bind(&context->rt[i], NULL);
nine_bind(&context->ds, NULL);
nine_bind(&context->vs, NULL);
+ nine_bind(&context->ps, NULL);
nine_bind(&context->vdecl, NULL);
for (i = 0; i < PIPE_MAX_ATTRIBS; ++i)
pipe_resource_reference(&context->vtxbuf[i].buffer, NULL);