[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