diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 9b1d5ee5b09..8948e67ceee 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -2225,6 +2225,10 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont else shader_addline(buffer, "writeonly uniform %s%s %s_image%u;\n", image_type_prefix, image_type, prefix, i); + + if (reg_maps->uav_counter_mask & (1u << i)) + shader_addline(buffer, "layout(binding = %u) uniform atomic_uint %s_counter%u;\n", + i, prefix, i); } /* Declare uniforms for NP2 texcoord fixup: @@ -5145,6 +5149,15 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins) string_buffer_release(priv->string_buffers, address); } +static void shader_glsl_uav_counter(const struct wined3d_shader_instruction *ins) +{ + const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type); + + shader_glsl_append_dst(ins->ctx->buffer, ins); + shader_addline(ins->ctx->buffer, "atomicCounterIncrement(%s_counter%u));\n", + prefix, ins->src[0].reg.idx[0].offset); +} + static void shader_glsl_ld_uav(const struct wined3d_shader_instruction *ins) { const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; @@ -9637,7 +9650,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_IMAD */ shader_glsl_mad, /* WINED3DSIH_IMAX */ shader_glsl_map2gl, /* WINED3DSIH_IMIN */ shader_glsl_map2gl, - /* WINED3DSIH_IMM_ATOMIC_ALLOC */ NULL, + /* WINED3DSIH_IMM_ATOMIC_ALLOC */ shader_glsl_uav_counter, /* WINED3DSIH_IMM_ATOMIC_AND */ shader_glsl_atomic, /* WINED3DSIH_IMM_ATOMIC_CMP_EXCH */ shader_glsl_atomic, /* WINED3DSIH_IMM_ATOMIC_CONSUME */ NULL, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 0e884861c3a..10018edf58a 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1370,7 +1370,17 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st } } - if ((WINED3DSIH_ATOMIC_AND <= ins.handler_idx && ins.handler_idx <= WINED3DSIH_ATOMIC_XOR) + if (ins.handler_idx == WINED3DSIH_IMM_ATOMIC_ALLOC) + { + unsigned int reg_idx = ins.src[0].reg.idx[0].offset; + if (reg_idx >= MAX_UNORDERED_ACCESS_VIEWS) + { + ERR("Invalid UAV index %u.\n", reg_idx); + break; + } + reg_maps->uav_counter_mask |= (1u << reg_idx); + } + else if ((WINED3DSIH_ATOMIC_AND <= ins.handler_idx && ins.handler_idx <= WINED3DSIH_ATOMIC_XOR) || (WINED3DSIH_IMM_ATOMIC_AND <= ins.handler_idx && ins.handler_idx <= WINED3DSIH_IMM_ATOMIC_XOR && ins.handler_idx != WINED3DSIH_IMM_ATOMIC_CONSUME) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a6e6f3e2f58..101fe900f51 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -896,6 +896,7 @@ struct wined3d_shader_reg_maps BYTE luminanceparams; /* MAX_TEXTURES, 8 */ struct wined3d_shader_resource_info uav_resource_info[MAX_UNORDERED_ACCESS_VIEWS]; DWORD uav_read_mask; /* MAX_UNORDERED_ACCESS_VIEWS, 8 */ + DWORD uav_counter_mask; /* MAX_UNORDERED_ACCESS_VIEWS, 8 */ WORD usesnrm : 1; WORD vpos : 1;