[virglrenderer-devel] [PATCH] Handling all exit points in vert and frag shaders

Robert Tarasov tutankhamen at chromium.org
Fri Feb 23 23:46:13 UTC 2018


Refactors vertex/fragment shader exit routine. Handles all end points properly.
Fixes dEQP-GLES2.functional.shaders.return.output_write_dynamic_vertex test.
---
 src/vrend_shader.c | 115 +++++++++++++++++++++++++++------------------
 1 file changed, 68 insertions(+), 47 deletions(-)

diff --git a/src/vrend_shader.c b/src/vrend_shader.c
index 8e925d3..e8ee8b9 100644
--- a/src/vrend_shader.c
+++ b/src/vrend_shader.c
@@ -997,6 +997,50 @@ static int emit_buf(struct dump_ctx *ctx, const char *buf)
       if (_ret) return FALSE;                        \
    } while(0)
 
+static int handle_vertex_proc_exit(struct dump_ctx *ctx)
+{
+    if (ctx->so && !ctx->key->gs_present) {
+       if (emit_so_movs(ctx))
+          return FALSE;
+    }
+
+    if (emit_clip_dist_movs(ctx))
+       return FALSE;
+
+    if (!ctx->key->gs_present) {
+       if (emit_prescale(ctx))
+          return FALSE;
+    }
+
+    return TRUE;
+}
+
+static int handle_fragment_proc_exit(struct dump_ctx *ctx)
+{
+    if (ctx->key->pstipple_tex) {
+       if (emit_pstipple_pass(ctx))
+          return FALSE;
+    }
+
+    if (ctx->key->cbufs_are_a8_bitmask) {
+       if (emit_a8_swizzle(ctx))
+          return FALSE;
+    }
+
+    if (ctx->key->add_alpha_test) {
+       if (emit_alpha_test(ctx))
+          return FALSE;
+    }
+
+    if (ctx->write_all_cbufs) {
+       if (emit_cbuf_writes(ctx))
+          return FALSE;
+    }
+
+    return TRUE;
+}
+
+
 static int translate_tex(struct dump_ctx *ctx,
                          struct tgsi_full_instruction *inst,
                          int sreg_index,
@@ -1967,53 +2011,30 @@ iter_instruction(struct tgsi_iterate_context *iter,
       snprintf(buf, 255, "%s = mix(%s, %s, notEqual(floatBitsToUint(%s), uvec4(0.0)))%s;\n", dsts[0], srcs[2], srcs[1], srcs[0], writemask);
       EMIT_BUF_WITH_RET(ctx, buf);
       break;
-   case TGSI_OPCODE_END:
-      if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
-         if (ctx->so && !ctx->key->gs_present) {
-            ret = emit_so_movs(ctx);
-            if (ret)
-               return FALSE;
-         }
-         ret = emit_clip_dist_movs(ctx);
-         if (ret)
-            return FALSE;
-         if (!ctx->key->gs_present) {
-            ret = emit_prescale(ctx);
-            if (ret)
-               return FALSE;
-         }
-
-      } else if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
-
-      } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
-         if (ctx->key->pstipple_tex) {
-            ret = emit_pstipple_pass(ctx);
-            if (ret)
-               return FALSE;
-         }
-         if (ctx->key->cbufs_are_a8_bitmask) {
-            ret = emit_a8_swizzle(ctx);
-            if (ret)
-               return FALSE;
-         }
-         if (ctx->key->add_alpha_test) {
-            ret = emit_alpha_test(ctx);
-            if (ret)
-               return FALSE;
-         }
-         if (ctx->write_all_cbufs) {
-            ret = emit_cbuf_writes(ctx);
-            if (ret)
-               return FALSE;
-         }
-      }
-      sret = add_str_to_glsl_main(ctx, "}\n");
-      if (!sret)
-         return FALSE;
-      break;
-   case TGSI_OPCODE_RET:
-      EMIT_BUF_WITH_RET(ctx, "return;\n");
-      break;
+    case TGSI_OPCODE_END:
+       if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
+          if (handle_vertex_proc_exit(ctx) == FALSE)
+             return FALSE;
+    } else if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
+    } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
+       if (handle_fragment_proc_exit(ctx) == FALSE)
+          return FALSE;
+       }
+       sret = add_str_to_glsl_main(ctx, "}\n");
+       if (!sret)
+          return FALSE;
+       break;
+    case TGSI_OPCODE_RET:
+       if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
+          if (handle_vertex_proc_exit(ctx) == FALSE)
+             return FALSE;
+       } else if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
+       } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
+          if (handle_fragment_proc_exit(ctx) == FALSE)
+             return FALSE;
+          }
+          EMIT_BUF_WITH_RET(ctx, "return;\n");
+          break;
    case TGSI_OPCODE_ARL:
       snprintf(buf, 255, "addr0 = int(floor(%s)%s);\n", srcs[0], writemask);
       EMIT_BUF_WITH_RET(ctx, buf);
-- 
2.16.1.291.g4437f3f132-goog



More information about the virglrenderer-devel mailing list