From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/cs.c | 13 ++++++------ dlls/wined3d/glsl_shader.c | 15 +++++--------- dlls/wined3d/stateblock.c | 36 +++++++++++++++++++++++++++++++--- dlls/wined3d/wined3d_private.h | 18 +++++++++++++++++ 4 files changed, 63 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 3cf0cb6c5b1..81a66ab3cf7 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2146,12 +2146,13 @@ static const struct push_constant_info } wined3d_cs_push_constant_info[] = { - [WINED3D_PUSH_CONSTANTS_VS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_VS_CONSTS_F, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_PS_CONSTS_F, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_VS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_VS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_VS_CONSTS_F, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_PS_CONSTS_F, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_FFP] = {1, sizeof(struct wined3d_ffp_ps_constants), WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, };
static bool prepare_push_constant_buffer(struct wined3d_device_context *context, enum wined3d_push_constants type) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index b45494b9f12..3f7199de87d 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1893,8 +1893,12 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv,
if (update_mask & WINED3D_SHADER_CONST_FFP_PS) { + const struct wined3d_ffp_ps_constants *constants; struct wined3d_color color;
+ constants = wined3d_buffer_load_sysmem( + context_gl->c.device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP], &context_gl->c); + if (prog->ps.tex_factor_location != -1) { wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); @@ -1911,8 +1915,7 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, if (prog->ps.tss_constant_location[i] == -1) continue;
- wined3d_color_from_d3dcolor(&color, state->texture_states[i][WINED3D_TSS_CONSTANT]); - GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, &color.r)); + GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, &constants->texture_constants[i].r)); }
checkGLcall("fixed function uniforms"); @@ -12453,14 +12456,6 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GLSL_130 }, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 9d597e293a3..267da31ff19 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -30,6 +30,8 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
struct wined3d_saved_states { + struct list changed_lights; + uint32_t vs_consts_f[WINED3D_BITMAP_SIZE(WINED3D_MAX_VS_CONSTS_F)]; uint16_t vertexShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */ uint16_t vertexShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */ @@ -55,9 +57,10 @@ struct wined3d_saved_states uint32_t alpha_to_coverage : 1; uint32_t lights : 1; uint32_t transforms : 1; - uint32_t padding : 1;
- struct list changed_lights; + /* Flags only consumed by wined3d_device_apply_stateblock(), concerned with + * translation from stateblock formats to wined3d_state formats. */ + uint32_t ffp_ps_constants : 1; };
struct stage_state @@ -1574,6 +1577,9 @@ void CDECL wined3d_stateblock_set_texture_stage_state(struct wined3d_stateblock
stateblock->stateblock_state.texture_states[stage][state] = value; stateblock->changed.textureState[stage] |= 1u << state; + + if (state == WINED3D_TSS_CONSTANT) + stateblock->changed.ffp_ps_constants = 1; }
void CDECL wined3d_stateblock_set_texture(struct wined3d_stateblock *stateblock, @@ -2190,6 +2196,10 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const stru stateblock->changed.store_stream_offset = 1; list_init(&stateblock->changed.changed_lights);
+ /* FFP push constant buffers need to be set if used; the backend does not + * have a default state for them. */ + stateblock->changed.ffp_ps_constants = 1; + if (type == WINED3D_SBT_RECORDED || type == WINED3D_SBT_PRIMARY) return WINED3D_OK;
@@ -2651,6 +2661,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_stateblock *stateblock) { bool set_blend_state = false, set_depth_stencil_state = false, set_rasterizer_state = false; + const struct wined3d_stateblock_state *state = &stateblock->stateblock_state; const struct wined3d_saved_states *changed = &stateblock->changed; const unsigned int word_bit_count = sizeof(DWORD) * CHAR_BIT; @@ -3193,7 +3204,15 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, while (map) { j = wined3d_bit_scan(&map); - wined3d_device_set_texture_stage_state(device, i, j, state->texture_states[i][j]); + + switch (j) + { + case WINED3D_TSS_CONSTANT: + break; + + default: + wined3d_device_set_texture_stage_state(device, i, j, state->texture_states[i][j]); + } } }
@@ -3286,6 +3305,17 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, wined3d_device_set_clip_plane(device, i, &state->clip_planes[i]); }
+ if (changed->ffp_ps_constants) + { + struct wined3d_ffp_ps_constants constants; + + for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) + wined3d_color_from_d3dcolor(&constants.texture_constants[i], state->texture_states[i][WINED3D_TSS_CONSTANT]); + + wined3d_device_context_push_constants(context, WINED3D_PUSH_CONSTANTS_PS_FFP, + WINED3D_SHADER_CONST_FFP_PS, 0, sizeof(constants), &constants); + } + assert(list_empty(&stateblock->changed.changed_lights)); memset(&stateblock->changed, 0, sizeof(stateblock->changed)); list_init(&stateblock->changed.changed_lights); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 178911dd08f..f0e1d3ed615 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2755,6 +2755,23 @@ void wined3d_unregister_window(HWND window);
BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size);
+/* Direct3D 1-9 shader constants are submitted by internally feeding them into + * wined3d_buffer objects, which are updated with + * wined3d_device_context_emit_update_sub_resource(). + * This allows Vulkan backend shaders to read from the buffers as they would + * any other uniform buffer, with no extra code needed to set up the descriptor + * set and bind buffers. Other renderers simply map the buffers as CPU buffers + * and read from them directly. + * + * The "FFP" buffer contains constants that are part of the D3D1-9 FFP pipe, + * i.e. only used when shaders are disabled. + */ + +struct wined3d_ffp_ps_constants +{ + struct wined3d_color texture_constants[WINED3D_MAX_FFP_TEXTURES]; +}; + enum wined3d_push_constants { WINED3D_PUSH_CONSTANTS_VS_F, @@ -2763,6 +2780,7 @@ enum wined3d_push_constants WINED3D_PUSH_CONSTANTS_PS_I, WINED3D_PUSH_CONSTANTS_VS_B, WINED3D_PUSH_CONSTANTS_PS_B, + WINED3D_PUSH_CONSTANTS_PS_FFP, WINED3D_PUSH_CONSTANTS_COUNT, };