st/nine: Reimplement nine_context_apply_stateblock
The new version uses nine_context functions instead of applying the changes directly to nine_context. This will enable it to work with CSMT. v2: Fix nine_context_light_enable_stateblock The memcpy arguments were wrong, and the state wasn't set dirty. Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
parent
8d967abb98
commit
97e4b65e7f
|
@ -1446,6 +1446,23 @@ nine_context_set_pixel_shader_constant_f(struct NineDevice9 *device,
|
|||
context->changed.group |= NINE_STATE_PS_CONST;
|
||||
}
|
||||
|
||||
/* For stateblocks */
|
||||
static void
|
||||
nine_context_set_pixel_shader_constant_i_transformed(struct NineDevice9 *device,
|
||||
UINT StartRegister,
|
||||
const int *pConstantData,
|
||||
UINT Vector4iCount)
|
||||
{
|
||||
struct nine_context *context = &device->context;
|
||||
|
||||
memcpy(&context->ps_const_i[StartRegister][0],
|
||||
pConstantData,
|
||||
Vector4iCount * sizeof(context->ps_const_i[0]));
|
||||
|
||||
context->changed.ps_const_i = TRUE;
|
||||
context->changed.group |= NINE_STATE_PS_CONST;
|
||||
}
|
||||
|
||||
void
|
||||
nine_context_set_pixel_shader_constant_i(struct NineDevice9 *device,
|
||||
UINT StartRegister,
|
||||
|
@ -1587,6 +1604,20 @@ nine_context_set_light(struct NineDevice9 *device,
|
|||
context->changed.group |= NINE_STATE_FF_LIGHTING;
|
||||
}
|
||||
|
||||
|
||||
/* For stateblocks */
|
||||
static void
|
||||
nine_context_light_enable_stateblock(struct NineDevice9 *device,
|
||||
const uint16_t active_light[NINE_MAX_LIGHTS_ACTIVE], /* TODO: use pointer that convey size for csmt */
|
||||
unsigned int num_lights_active)
|
||||
{
|
||||
struct nine_context *context = &device->context;
|
||||
|
||||
memcpy(context->ff.active_light, active_light, NINE_MAX_LIGHTS_ACTIVE * sizeof(context->ff.active_light[0]));
|
||||
context->ff.num_lights_active = num_lights_active;
|
||||
context->changed.group |= NINE_STATE_FF_LIGHTING;
|
||||
}
|
||||
|
||||
void
|
||||
nine_context_light_enable(struct NineDevice9 *device,
|
||||
DWORD Index,
|
||||
|
@ -1653,6 +1684,8 @@ nine_context_set_clip_plane(struct NineDevice9 *device,
|
|||
context->changed.ucp = TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void
|
||||
nine_context_apply_stateblock(struct NineDevice9 *device,
|
||||
const struct nine_state *src)
|
||||
|
@ -1878,6 +1911,179 @@ nine_context_apply_stateblock(struct NineDevice9 *device,
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Do not write to nine_context directly. Slower,
|
||||
* but works with csmt. TODO: write a special csmt version that
|
||||
* would record the list of commands as much as possible,
|
||||
* and use the version above else.
|
||||
*/
|
||||
void
|
||||
nine_context_apply_stateblock(struct NineDevice9 *device,
|
||||
const struct nine_state *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* No need to apply src->changed.group, since all calls do
|
||||
* set context->changed.group */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(src->changed.rs); ++i) {
|
||||
uint32_t m = src->changed.rs[i];
|
||||
while (m) {
|
||||
const int r = ffs(m) - 1;
|
||||
m &= ~(1 << r);
|
||||
nine_context_set_render_state(device, i * 32 + r, src->rs_advertised[i * 32 + r]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Textures */
|
||||
if (src->changed.texture) {
|
||||
uint32_t m = src->changed.texture;
|
||||
unsigned s;
|
||||
|
||||
for (s = 0; m; ++s, m >>= 1) {
|
||||
struct NineBaseTexture9 *tex = src->texture[s];
|
||||
if (!(m & 1))
|
||||
continue;
|
||||
nine_context_set_texture(device, s, tex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sampler state */
|
||||
if (src->changed.group & NINE_STATE_SAMPLER) {
|
||||
unsigned s;
|
||||
|
||||
for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
|
||||
uint32_t m = src->changed.sampler[s];
|
||||
while (m) {
|
||||
const int i = ffs(m) - 1;
|
||||
m &= ~(1 << i);
|
||||
nine_context_set_sampler_state(device, s, i, src->samp_advertised[s][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Vertex buffers */
|
||||
if (src->changed.vtxbuf | src->changed.stream_freq) {
|
||||
uint32_t m = src->changed.vtxbuf | src->changed.stream_freq;
|
||||
for (i = 0; m; ++i, m >>= 1) {
|
||||
if (src->changed.vtxbuf & (1 << i))
|
||||
nine_context_set_stream_source(device, i, src->stream[i], src->vtxbuf[i].buffer_offset, src->vtxbuf[i].stride);
|
||||
if (src->changed.stream_freq & (1 << i))
|
||||
nine_context_set_stream_source_freq(device, i, src->stream_freq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Index buffer */
|
||||
if (src->changed.group & NINE_STATE_IDXBUF)
|
||||
nine_context_set_indices(device, src->idxbuf);
|
||||
|
||||
/* Vertex declaration */
|
||||
if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
|
||||
nine_context_set_vertex_declaration(device, src->vdecl);
|
||||
|
||||
/* Vertex shader */
|
||||
if (src->changed.group & NINE_STATE_VS)
|
||||
nine_context_set_vertex_shader(device, src->vs);
|
||||
|
||||
/* Pixel shader */
|
||||
if (src->changed.group & NINE_STATE_PS)
|
||||
nine_context_set_pixel_shader(device, src->ps);
|
||||
|
||||
/* Vertex constants */
|
||||
if (src->changed.group & NINE_STATE_VS_CONST) {
|
||||
struct nine_range *r;
|
||||
for (r = src->changed.vs_const_f; r; r = r->next)
|
||||
nine_context_set_vertex_shader_constant_f(device, r->bgn,
|
||||
&src->vs_const_f[r->bgn * 4],
|
||||
r->end - r->bgn);
|
||||
for (r = src->changed.vs_const_i; r; r = r->next)
|
||||
nine_context_set_vertex_shader_constant_i(device, r->bgn,
|
||||
&src->vs_const_i[r->bgn * 4],
|
||||
r->end - r->bgn);
|
||||
for (r = src->changed.vs_const_b; r; r = r->next)
|
||||
nine_context_set_vertex_shader_constant_b(device, r->bgn,
|
||||
&src->vs_const_b[r->bgn * 4],
|
||||
r->end - r->bgn);
|
||||
}
|
||||
|
||||
/* Pixel constants */
|
||||
if (src->changed.group & NINE_STATE_PS_CONST) {
|
||||
struct nine_range *r;
|
||||
for (r = src->changed.ps_const_f; r; r = r->next)
|
||||
nine_context_set_pixel_shader_constant_f(device, r->bgn,
|
||||
&src->ps_const_f[r->bgn * 4],
|
||||
r->end - r->bgn);
|
||||
if (src->changed.ps_const_i) {
|
||||
uint16_t m = src->changed.ps_const_i;
|
||||
for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1)
|
||||
if (m & 1)
|
||||
nine_context_set_pixel_shader_constant_i_transformed(device, i,
|
||||
src->ps_const_i[i], 1);
|
||||
}
|
||||
if (src->changed.ps_const_b) {
|
||||
uint16_t m = src->changed.ps_const_b;
|
||||
for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1)
|
||||
if (m & 1)
|
||||
nine_context_set_pixel_shader_constant_b(device, i,
|
||||
&src->ps_const_b[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Viewport */
|
||||
if (src->changed.group & NINE_STATE_VIEWPORT)
|
||||
nine_context_set_viewport(device, &src->viewport);
|
||||
|
||||
/* Scissor */
|
||||
if (src->changed.group & NINE_STATE_SCISSOR)
|
||||
nine_context_set_scissor(device, &src->scissor);
|
||||
|
||||
/* User Clip Planes */
|
||||
if (src->changed.ucp)
|
||||
for (i = 0; i < PIPE_MAX_CLIP_PLANES; ++i)
|
||||
if (src->changed.ucp & (1 << i))
|
||||
nine_context_set_clip_plane(device, i, &src->clip.ucp[i][0]);
|
||||
|
||||
if (!(src->changed.group & NINE_STATE_FF))
|
||||
return;
|
||||
|
||||
/* Fixed function state. */
|
||||
|
||||
if (src->changed.group & NINE_STATE_FF_MATERIAL)
|
||||
nine_context_set_material(device, &src->ff.material);
|
||||
|
||||
if (src->changed.group & NINE_STATE_FF_PSSTAGES) {
|
||||
unsigned s;
|
||||
for (s = 0; s < NINE_MAX_TEXTURE_STAGES; ++s) {
|
||||
for (i = 0; i < NINED3DTSS_COUNT; ++i)
|
||||
if (src->ff.changed.tex_stage[s][i / 32] & (1 << (i % 32)))
|
||||
nine_context_set_texture_stage_state(device, s, i, src->ff.tex_stage[s][i]);
|
||||
}
|
||||
}
|
||||
if (src->changed.group & NINE_STATE_FF_LIGHTING) {
|
||||
for (i = 0; i < src->ff.num_lights; ++i)
|
||||
if (src->ff.light[i].Type != NINED3DLIGHT_INVALID)
|
||||
nine_context_set_light(device, i, &src->ff.light[i]);
|
||||
|
||||
nine_context_light_enable_stateblock(device, src->ff.active_light, src->ff.num_lights_active);
|
||||
}
|
||||
if (src->changed.group & NINE_STATE_FF_VSTRANSF) {
|
||||
for (i = 0; i < ARRAY_SIZE(src->ff.changed.transform); ++i) {
|
||||
unsigned s;
|
||||
if (!src->ff.changed.transform[i])
|
||||
continue;
|
||||
for (s = i * 32; s < (i * 32 + 32); ++s) {
|
||||
if (!(src->ff.changed.transform[i] & (1 << (s % 32))))
|
||||
continue;
|
||||
nine_context_set_transform(device, s,
|
||||
nine_state_access_transform(
|
||||
(struct nine_ff_state *)&src->ff,
|
||||
s, FALSE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nine_update_state_framebuffer_clear(struct NineDevice9 *device)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue