[PATCH 10/12] wined3d: Implement SM5 bufinfo instruction.

Józef Kucia jkucia at codeweavers.com
Thu Mar 2 18:30:36 CST 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/d3d11/tests/d3d11.c   |  2 +-
 dlls/wined3d/glsl_shader.c | 66 +++++++++++++++++++++++++++++++++++++++++++++-
 dlls/wined3d/shader.c      |  8 ++++++
 3 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 9f317de..2d9d07a 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -14079,7 +14079,7 @@ static void test_sm5_bufinfo_instruction(void)
         }
 
         draw_quad(&test_context);
-        todo_wine check_texture_uvec4(texture, &test->expected_result);
+        check_texture_uvec4(texture, &test->expected_result);
 
         if (srv)
             ID3D11ShaderResourceView_Release(srv);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 13f1edd..b13bb84 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -5389,6 +5389,70 @@ static void shader_glsl_sync(const struct wined3d_shader_instruction *ins)
         FIXME("Unhandled sync flags %#x.\n", sync_flags);
 }
 
+static const struct wined3d_shader_resource_info *shader_glsl_get_resource_info(
+        const struct wined3d_shader_instruction *ins, const struct wined3d_shader_register *reg)
+{
+    const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
+    unsigned int idx = reg->idx[0].offset;
+
+    if (reg->type == WINED3DSPR_RESOURCE)
+    {
+        if (idx >= ARRAY_SIZE(reg_maps->resource_info))
+        {
+            ERR("Invalid resource index %u.\n", idx);
+            return NULL;
+        }
+        return &reg_maps->resource_info[idx];
+    }
+
+    if (reg->type == WINED3DSPR_UAV)
+    {
+        if (idx >= ARRAY_SIZE(reg_maps->uav_resource_info))
+        {
+            ERR("Invalid UAV index %u.\n", idx);
+            return NULL;
+        }
+        return &reg_maps->uav_resource_info[idx];
+    }
+
+    FIXME("Unhandled register type %#x.\n", reg->type);
+    return NULL;
+}
+
+static void shader_glsl_bufinfo(const struct wined3d_shader_instruction *ins)
+{
+    const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type);
+    const struct wined3d_shader_resource_info *resource_info;
+    struct wined3d_string_buffer *buffer = ins->ctx->buffer;
+    unsigned int resource_idx;
+    char dst_swizzle[6];
+    DWORD write_mask;
+
+    write_mask = shader_glsl_append_dst(buffer, ins);
+    shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle);
+
+    if (!(resource_info = shader_glsl_get_resource_info(ins, &ins->src[0].reg)))
+        return;
+    resource_idx = ins->src[0].reg.idx[0].offset;
+
+    shader_addline(buffer, "ivec2(");
+    if (ins->src[0].reg.type == WINED3DSPR_RESOURCE)
+    {
+        unsigned int bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map,
+                resource_idx, WINED3D_SAMPLER_DEFAULT);
+        shader_addline(buffer, "textureSize(%s_sampler%u)", prefix, bind_idx);
+    }
+    else
+    {
+        shader_addline(buffer, "imageSize(%s_image%u)", prefix, resource_idx);
+    }
+    if (resource_info->stride)
+        shader_addline(buffer, " / %u", resource_info->stride);
+    else if (resource_info->flags & WINED3D_VIEW_BUFFER_RAW)
+        shader_addline(buffer, " * 4");
+    shader_addline(buffer, ", %u)%s);\n", resource_info->stride, dst_swizzle);
+}
+
 static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
@@ -9555,7 +9619,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_BREAK                            */ shader_glsl_break,
     /* WINED3DSIH_BREAKC                           */ shader_glsl_breakc,
     /* WINED3DSIH_BREAKP                           */ shader_glsl_breakp,
-    /* WINED3DSIH_BUFINFO                          */ NULL,
+    /* WINED3DSIH_BUFINFO                          */ shader_glsl_bufinfo,
     /* WINED3DSIH_CALL                             */ shader_glsl_call,
     /* WINED3DSIH_CALLNZ                           */ shader_glsl_callnz,
     /* WINED3DSIH_CASE                             */ shader_glsl_case,
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 76c9762..222f1be 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1381,6 +1381,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             }
             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_BUFINFO && ins.src[0].reg.type == WINED3DSPR_UAV)
                     || ins.handler_idx == WINED3DSIH_LD_UAV_TYPED
                     || (ins.handler_idx == WINED3DSIH_LD_RAW && ins.src[1].reg.type == WINED3DSPR_UAV)
                     || (ins.handler_idx == WINED3DSIH_LD_STRUCTURED && ins.src[2].reg.type == WINED3DSPR_UAV))
@@ -1392,6 +1393,8 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                     reg_idx = ins.src[2].reg.idx[0].offset;
                 else if (WINED3DSIH_ATOMIC_AND <= ins.handler_idx && ins.handler_idx <= WINED3DSIH_ATOMIC_XOR)
                     reg_idx = ins.dst[0].reg.idx[0].offset;
+                else if (ins.handler_idx == WINED3DSIH_BUFINFO)
+                    reg_idx = ins.src[0].reg.idx[0].offset;
                 else
                     reg_idx = ins.dst[1].reg.idx[0].offset;
                 if (reg_idx >= MAX_UNORDERED_ACCESS_VIEWS)
@@ -1445,6 +1448,11 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                 shader_record_sample(reg_maps, ins.src[1].reg.idx[0].offset,
                         ins.src[2].reg.idx[0].offset, reg_maps->sampler_map.count);
             }
+            else if (ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE)
+            {
+                shader_record_sample(reg_maps, ins.src[0].reg.idx[0].offset,
+                        WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count);
+            }
             else if (ins.handler_idx == WINED3DSIH_LD
                     || (ins.handler_idx == WINED3DSIH_LD_RAW && ins.src[1].reg.type == WINED3DSPR_RESOURCE)
                     || (ins.handler_idx == WINED3DSIH_RESINFO && ins.src[1].reg.type == WINED3DSPR_RESOURCE))
-- 
2.10.2




More information about the wine-patches mailing list