=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Implement SM5 imm_atomic_* instructions.

Alexandre Julliard julliard at winehq.org
Wed Feb 15 16:06:24 CST 2017


Module: wine
Branch: master
Commit: b59d7220fe6fd04fd04f3e317e1fb11906588c38
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b59d7220fe6fd04fd04f3e317e1fb11906588c38

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Wed Feb 15 14:27:38 2017 +0100

wined3d: Implement SM5 imm_atomic_* instructions.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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 = &reg_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);




More information about the wine-cvs mailing list