Module: wine Branch: master Commit: b59d7220fe6fd04fd04f3e317e1fb11906588c38 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b59d7220fe6fd04fd04f3e317e...
Author: Józef Kucia jkucia@codeweavers.com Date: Wed Feb 15 14:27:38 2017 +0100
wined3d: Implement SM5 imm_atomic_* instructions.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wined3d/glsl_shader.c | 29 ++++++++++++++++++++++------- dlls/wined3d/shader.c | 7 ++++++- 2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 0d29b70..9900b08 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -4924,6 +4924,8 @@ static unsigned int shader_glsl_find_sampler(const struct wined3d_shader_sampler
static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins) { + const BOOL is_imm_instruction = WINED3DSIH_IMM_ATOMIC_AND <= ins->handler_idx + && ins->handler_idx <= WINED3DSIH_IMM_ATOMIC_XOR; const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; const struct wined3d_shader_version *version = ®_maps->shader_version; struct glsl_src_param coord_param, data_param, data_param2; @@ -4933,7 +4935,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins) DWORD coord_mask; const char *op;
- uav_idx = ins->dst[0].reg.idx[0].offset; + uav_idx = ins->dst[is_imm_instruction].reg.idx[0].offset; resource_type = reg_maps->uav_resource_info[uav_idx].type; if (resource_type >= ARRAY_SIZE(resource_type_info)) { @@ -4946,25 +4948,36 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins) switch (ins->handler_idx) { case WINED3DSIH_ATOMIC_AND: + case WINED3DSIH_IMM_ATOMIC_AND: op = "imageAtomicAnd"; break; case WINED3DSIH_ATOMIC_CMP_STORE: + case WINED3DSIH_IMM_ATOMIC_CMP_EXCH: op = "imageAtomicCompSwap"; break; case WINED3DSIH_ATOMIC_IADD: + case WINED3DSIH_IMM_ATOMIC_IADD: op = "imageAtomicAdd"; break; case WINED3DSIH_ATOMIC_OR: + case WINED3DSIH_IMM_ATOMIC_OR: op = "imageAtomicOr"; break; case WINED3DSIH_ATOMIC_XOR: + case WINED3DSIH_IMM_ATOMIC_XOR: op = "imageAtomicXor"; break; + case WINED3DSIH_IMM_ATOMIC_EXCH: + op = "imageAtomicExchange"; + break; default: ERR("Unhandled opcode %#x.\n", ins->handler_idx); return; }
+ if (is_imm_instruction) + shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], data_type); + shader_glsl_add_src_param(ins, &ins->src[0], coord_mask, &coord_param);
if (reg_maps->uav_resource_info[uav_idx].flags & WINED3D_VIEW_BUFFER_RAW) @@ -4982,6 +4995,8 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins) shader_addline(ins->ctx->buffer, ", %s", data_param2.param_str); }
+ if (is_imm_instruction) + shader_addline(ins->ctx->buffer, ")"); shader_addline(ins->ctx->buffer, ");\n"); }
@@ -9324,15 +9339,15 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_IMAX */ shader_glsl_map2gl, /* WINED3DSIH_IMIN */ shader_glsl_map2gl, /* WINED3DSIH_IMM_ATOMIC_ALLOC */ NULL, - /* WINED3DSIH_IMM_ATOMIC_AND */ NULL, - /* WINED3DSIH_IMM_ATOMIC_CMP_EXCH */ NULL, + /* WINED3DSIH_IMM_ATOMIC_AND */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_CMP_EXCH */ shader_glsl_atomic, /* WINED3DSIH_IMM_ATOMIC_CONSUME */ NULL, - /* WINED3DSIH_IMM_ATOMIC_EXCH */ NULL, - /* WINED3DSIH_IMM_ATOMIC_IADD */ NULL, - /* WINED3DSIH_IMM_ATOMIC_OR */ NULL, + /* WINED3DSIH_IMM_ATOMIC_EXCH */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_IADD */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_OR */ shader_glsl_atomic, /* WINED3DSIH_IMM_ATOMIC_UMAX */ NULL, /* WINED3DSIH_IMM_ATOMIC_UMIN */ NULL, - /* WINED3DSIH_IMM_ATOMIC_XOR */ NULL, + /* WINED3DSIH_IMM_ATOMIC_XOR */ shader_glsl_atomic, /* WINED3DSIH_IMUL */ shader_glsl_imul, /* WINED3DSIH_INE */ shader_glsl_relop, /* WINED3DSIH_INEG */ shader_glsl_unary_op, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index ee597f0..450e791 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1295,13 +1295,18 @@ 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) + || (WINED3DSIH_IMM_ATOMIC_AND <= ins.handler_idx + && ins.handler_idx <= WINED3DSIH_IMM_ATOMIC_XOR + && ins.handler_idx != WINED3DSIH_IMM_ATOMIC_CONSUME) || ins.handler_idx == WINED3DSIH_LD_UAV_TYPED) { unsigned int reg_idx; if (ins.handler_idx == WINED3DSIH_LD_UAV_TYPED) reg_idx = ins.src[1].reg.idx[0].offset; - else + else if (WINED3DSIH_ATOMIC_AND <= ins.handler_idx && ins.handler_idx <= WINED3DSIH_ATOMIC_XOR) reg_idx = ins.dst[0].reg.idx[0].offset; + else + reg_idx = ins.dst[1].reg.idx[0].offset; if (reg_idx >= MAX_UNORDERED_ACCESS_VIEWS) { ERR("Invalid UAV index %u.\n", reg_idx);