[virglrenderer-devel] [PATCH] vrend: enable sample shading

Dave Airlie airlied at gmail.com
Tue Feb 13 04:09:06 UTC 2018


From: Dave Airlie <airlied at redhat.com>

Another requirement for GL4.0 is support for ARB_sample_shading.

This enables it and turns on the cap when needed.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/include/pipe/p_state.h |  1 +
 src/virgl_protocol.h               |  1 +
 src/vrend_decode.c                 |  1 +
 src/vrend_renderer.c               | 13 ++++++++++
 src/vrend_shader.c                 | 51 +++++++++++++++++++++++++++++++++++---
 5 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index a99b386..2b4d9e4 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -102,6 +102,7 @@ struct pipe_rasterizer_state
    unsigned point_tri_clip:1; /** large points clipped as tris or points */
    unsigned point_size_per_vertex:1; /**< size computed in vertex shader */
    unsigned multisample:1;         /* XXX maybe more ms state in future */
+   unsigned force_persample_interp:1;
    unsigned line_smooth:1;
    unsigned line_stipple_enable:1;
    unsigned line_last_pixel:1;
diff --git a/src/virgl_protocol.h b/src/virgl_protocol.h
index 1430422..7688ac5 100644
--- a/src/virgl_protocol.h
+++ b/src/virgl_protocol.h
@@ -181,6 +181,7 @@ enum virgl_context_cmd {
 #define VIRGL_OBJ_RS_S0_LINE_LAST_PIXEL(x) (((x) & 0x1) << 28)
 #define VIRGL_OBJ_RS_S0_HALF_PIXEL_CENTER(x) (((x) & 0x1) << 29)
 #define VIRGL_OBJ_RS_S0_BOTTOM_EDGE_RULE(x) (((x) & 0x1) << 30)
+#define VIRGL_OBJ_RS_S0_FORCE_PERSAMPLE_INTERP(x) (((x) & 0x1) << 31)
 
 #define VIRGL_OBJ_RS_POINT_SIZE 3
 #define VIRGL_OBJ_RS_SPRITE_COORD_ENABLE 4
diff --git a/src/vrend_decode.c b/src/vrend_decode.c
index 3b18596..6112bd8 100644
--- a/src/vrend_decode.c
+++ b/src/vrend_decode.c
@@ -523,6 +523,7 @@ static int vrend_decode_create_rasterizer(struct vrend_decode_ctx *ctx, uint32_t
    ebit(line_last_pixel, 28);
    ebit(half_pixel_center, 29);
    ebit(bottom_edge_rule, 30);
+   ebit(force_persample_interp, 31);
    rs_state->point_size = uif(get_buf_entry(ctx, VIRGL_OBJ_RS_POINT_SIZE));
    rs_state->sprite_coord_enable = get_buf_entry(ctx, VIRGL_OBJ_RS_SPRITE_COORD_ENABLE);
    tmp = get_buf_entry(ctx, VIRGL_OBJ_RS_S3);
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 087139e..36ded80 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -115,6 +115,7 @@ struct global_renderer_state {
    bool have_vertex_attrib_binding;
    bool have_tf2;
    bool have_stencil_texturing;
+   bool have_sample_shading;
 
    /* these appeared broken on at least one driver */
    bool use_explicit_locations;
@@ -3646,6 +3647,12 @@ static void vrend_hw_emit_rs(struct vrend_context *ctx)
          glDisable(GL_MULTISAMPLE);
          glDisable(GL_SAMPLE_MASK);
       }
+      if (vrend_state.have_sample_shading) {
+         if (state->force_persample_interp)
+            glEnable(GL_SAMPLE_SHADING);
+         else
+            glDisable(GL_SAMPLE_SHADING);
+      }
    }
 }
 
@@ -4048,6 +4055,9 @@ int vrend_renderer_init(struct vrend_if_cbs *cbs, uint32_t flags)
          vrend_state.have_ms_scaled_blit = true;
    }
 
+   if (gl_ver >= 40 || epoxy_has_gl_extension("GL_ARB_sample_shading"))
+      vrend_state.have_sample_shading = true;
+
    /* callbacks for when we are cleaning up the object table */
    vrend_resource_set_destroy_callback(vrend_destroy_resource_object);
    vrend_object_set_destroy_callback(VIRGL_OBJECT_QUERY, vrend_destroy_query_object);
@@ -6337,6 +6347,7 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
       caps->v1.bset.cube_map_array = 1;
       caps->v1.bset.texture_query_lod = 1;
       caps->v1.bset.has_indirect_draw = 1;
+      caps->v1.bset.has_sample_shading = 1;
    } else {
       if (epoxy_has_gl_extension("GL_ARB_draw_buffers_blend"))
          caps->v1.bset.indep_blend_func = 1;
@@ -6346,6 +6357,8 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
          caps->v1.bset.texture_query_lod = 1;
       if (epoxy_has_gl_extension("GL_ARB_indirect_draw"))
          caps->v1.bset.has_indirect_draw = 1;
+      if (epoxy_has_gl_extension("GL_ARB_sample_shading"))
+         caps->v1.bset.has_sample_shading = 1;
    }
 
    if (gl_ver >= 42) {
diff --git a/src/vrend_shader.c b/src/vrend_shader.c
index 8e925d3..420bc83 100644
--- a/src/vrend_shader.c
+++ b/src/vrend_shader.c
@@ -141,6 +141,7 @@ struct dump_ctx {
    bool has_viewport_idx;
    bool has_frag_viewport_idx;
    bool vs_has_pervertex;
+   bool uses_sample_shading;
 };
 
 static inline const char *tgsi_proc_to_prefix(int shader_type)
@@ -506,7 +507,18 @@ iter_declaration(struct tgsi_iterate_context *iter,
          if (ctx->glsl_ver_required >= 140)
             ctx->has_clipvertex = true;
          break;
-
+      case TGSI_SEMANTIC_SAMPLEMASK:
+         if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
+            ctx->outputs[i].glsl_predefined_no_emit = true;
+            ctx->outputs[i].glsl_no_index = true;
+            ctx->outputs[i].override_no_wm = true;
+            ctx->outputs[i].is_int = true;
+            ctx->has_ints = true;
+            name_prefix = "gl_SampleMask";
+            ctx->uses_sample_shading = true;
+            break;
+         }
+         break;
       case TGSI_SEMANTIC_COLOR:
          if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
             if (ctx->glsl_ver_required < 140) {
@@ -660,6 +672,13 @@ iter_declaration(struct tgsi_iterate_context *iter,
       } else if (decl->Semantic.Name == TGSI_SEMANTIC_VERTEXID) {
          name_prefix = "gl_VertexID";
          ctx->has_ints = true;
+      } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEID) {
+         name_prefix = "gl_SampleID";
+         ctx->uses_sample_shading = true;
+         ctx->has_ints = true;
+      } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEPOS) {
+         name_prefix = "gl_SamplePosition";
+         ctx->uses_sample_shading = true;
       } else {
          fprintf(stderr, "unsupported system value %d\n", decl->Semantic.Name);
          name_prefix = "unknown";
@@ -1446,6 +1465,22 @@ iter_instruction(struct tgsi_iterate_context *iter,
                   snprintf(dsts[i], 255, "clipv_tmp");
                } else if (ctx->outputs[j].name == TGSI_SEMANTIC_CLIPDIST) {
                   snprintf(dsts[i], 255, "clip_dist_temp[%d]", ctx->outputs[j].sid);
+               } else if (ctx->outputs[j].name == TGSI_SEMANTIC_SAMPLEMASK) {
+                  int idx;
+                  switch (dst->Register.WriteMask) {
+                  case 0x1: idx = 0; break;
+                  case 0x2: idx = 1; break;
+                  case 0x4: idx = 2; break;
+                  case 0x8: idx = 3; break;
+                  default:
+                     idx = 0;
+                     break;
+                  }
+                  snprintf(dsts[i], 255, "%s[%d]", ctx->outputs[j].glsl_name, idx);
+                  if (ctx->outputs[j].is_int) {
+                        dtypeprefix = "floatBitsToInt";
+                        snprintf(dstconv, 6, "int");
+                  }
                } else {
                   snprintf(dsts[i], 255, "%s%s", ctx->outputs[j].glsl_name, ctx->outputs[j].override_no_wm ? "" : writemask);
                   dst_override_no_wm[i] = ctx->outputs[j].override_no_wm;
@@ -1646,9 +1681,17 @@ iter_instruction(struct tgsi_iterate_context *iter,
       } else if (src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
          for (j = 0; j < ctx->num_system_values; j++)
             if (ctx->system_values[j].first == src->Register.Index) {
-               if (ctx->system_values[j].name == TGSI_SEMANTIC_VERTEXID || ctx->system_values[j].name == TGSI_SEMANTIC_INSTANCEID)
+               if (ctx->system_values[j].name == TGSI_SEMANTIC_VERTEXID ||
+                   ctx->system_values[j].name == TGSI_SEMANTIC_INSTANCEID ||
+                   ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEID)
                   snprintf(srcs[i], 255, "%s(vec4(intBitsToFloat(%s)))", stypeprefix, ctx->system_values[j].glsl_name);
-               else
+               else if (ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEPOS) {
+                  snprintf(srcs[i], 255, "vec4(%s.%c, %s.%c, %s.%c, %s.%c)",
+                           ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleX),
+                           ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleY),
+                           ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleZ),
+                           ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleW));
+               } else
                   snprintf(srcs[i], 255, "%s%s", prefix, ctx->system_values[j].glsl_name);
                override_no_wm[i] = ctx->system_values[j].override_no_wm;
                break;
@@ -2128,6 +2171,8 @@ static char *emit_header(struct dump_ctx *ctx, char *glsl_hdr)
       STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_shader_stencil_export : require\n");
    if (ctx->uses_layer)
       STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_fragment_layer_viewport : require\n");
+   if (ctx->uses_sample_shading)
+      STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_sample_shading : require\n");
    return glsl_hdr;
 }
 
-- 
2.9.5



More information about the virglrenderer-devel mailing list