From 3942943819a87ad423df56e3138223fc37f5db21 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 16 Aug 2018 15:11:12 -0500 Subject: [PATCH] nir: Use a bitfield for image access qualifiers This commit expands the current memory access enum to contain the extra two bits provided for images. We choose to follow the SPIR-V convention of NonReadable and NonWriteable because readonly implies that you *can* read so readonly + writeonly doesn't make as much sense as NonReadable + NonWriteable. Reviewed-by: Kenneth Graunke --- src/amd/common/ac_nir_to_llvm.c | 4 ++-- src/compiler/glsl/gl_nir_link_uniforms.c | 12 +++++++----- src/compiler/glsl/glsl_to_nir.cpp | 19 ++++++++++++++----- src/compiler/nir/nir.h | 6 +----- src/compiler/nir/nir_print.c | 11 ++++++----- src/compiler/shader_enums.h | 10 ++++++---- src/compiler/spirv/vtn_variables.c | 10 +++++----- .../compiler/brw_nir_lower_image_load_store.c | 2 +- .../vulkan/anv_nir_apply_pipeline_layout.c | 3 ++- 9 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 3845a721a77..61e79ec9138 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -2342,7 +2342,7 @@ static LLVMValueRef visit_image_load(struct ac_nir_context *ctx, glsl_sampler_type_is_array(type)); args.dmask = 15; args.attributes = AC_FUNC_ATTR_READONLY; - if (var->data.image._volatile || var->data.image.coherent) + if (var->data.image.access & (ACCESS_VOLATILE | ACCESS_COHERENT)) args.cache_policy |= ac_glc; res = ac_build_image_opcode(&ctx->ac, &args); @@ -2383,7 +2383,7 @@ static void visit_image_store(struct ac_nir_context *ctx, args.dim = get_ac_image_dim(&ctx->ac, glsl_get_sampler_dim(type), glsl_sampler_type_is_array(type)); args.dmask = 15; - if (force_glc || var->data.image._volatile || var->data.image.coherent) + if (force_glc || (var->data.image.access & (ACCESS_VOLATILE | ACCESS_COHERENT))) args.cache_policy |= ac_glc; ac_build_image_opcode(&ctx->ac, &args); diff --git a/src/compiler/glsl/gl_nir_link_uniforms.c b/src/compiler/glsl/gl_nir_link_uniforms.c index 159dfeca59f..1a491dc2e5d 100644 --- a/src/compiler/glsl/gl_nir_link_uniforms.c +++ b/src/compiler/glsl/gl_nir_link_uniforms.c @@ -424,12 +424,14 @@ nir_link_uniform(struct gl_context *ctx, uniform->opaque[stage].index = image_index; /* Set image access qualifiers */ + enum gl_access_qualifier image_access = + state->current_var->data.image.access; const GLenum access = - state->current_var->data.image.read_only ? - (state->current_var->data.image.write_only ? GL_NONE : - GL_READ_ONLY) : - (state->current_var->data.image.write_only ? GL_WRITE_ONLY : - GL_READ_WRITE); + (image_access & ACCESS_NON_WRITEABLE) ? + ((image_access & ACCESS_NON_READABLE) ? GL_NONE : + GL_READ_ONLY) : + ((image_access & ACCESS_NON_READABLE) ? GL_WRITE_ONLY : + GL_READ_WRITE); for (unsigned i = image_index; i < MIN2(state->next_image_index, MAX_IMAGE_UNIFORMS); i++) { diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 22419abc571..f38d280d406 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -416,12 +416,21 @@ nir_visitor::visit(ir_variable *ir) var->data.explicit_binding = ir->data.explicit_binding; var->data.bindless = ir->data.bindless; var->data.offset = ir->data.offset; - var->data.image.read_only = ir->data.memory_read_only; - var->data.image.write_only = ir->data.memory_write_only; - var->data.image.coherent = ir->data.memory_coherent; - var->data.image._volatile = ir->data.memory_volatile; - var->data.image.restrict_flag = ir->data.memory_restrict; + + unsigned image_access = 0; + if (ir->data.memory_read_only) + image_access |= ACCESS_NON_WRITEABLE; + if (ir->data.memory_write_only) + image_access |= ACCESS_NON_READABLE; + if (ir->data.memory_coherent) + image_access |= ACCESS_COHERENT; + if (ir->data.memory_volatile) + image_access |= ACCESS_VOLATILE; + if (ir->data.memory_restrict) + image_access |= ACCESS_RESTRICT; + var->data.image.access = (gl_access_qualifier)image_access; var->data.image.format = ir->data.image_format; + var->data.fb_fetch_output = ir->data.fb_fetch_output; var->data.explicit_xfb_buffer = ir->data.explicit_xfb_buffer; var->data.explicit_xfb_stride = ir->data.explicit_xfb_stride; diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 12cad6029cd..264b67c8d79 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -377,11 +377,7 @@ typedef struct nir_variable { * ARB_shader_image_load_store qualifiers. */ struct { - bool read_only; /**< "readonly" qualifier. */ - bool write_only; /**< "writeonly" qualifier. */ - bool coherent; - bool _volatile; - bool restrict_flag; + enum gl_access_qualifier access; /** Image internal format if specified explicitly, otherwise GL_NONE. */ GLenum format; diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 7cb16abd146..9175560383f 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -433,11 +433,12 @@ print_var_decl(nir_variable *var, print_state *state) cent, samp, patch, inv, get_variable_mode_str(var->data.mode, false), glsl_interp_mode_name(var->data.interpolation)); - const char *const coher = (var->data.image.coherent) ? "coherent " : ""; - const char *const volat = (var->data.image._volatile) ? "volatile " : ""; - const char *const restr = (var->data.image.restrict_flag) ? "restrict " : ""; - const char *const ronly = (var->data.image.read_only) ? "readonly " : ""; - const char *const wonly = (var->data.image.write_only) ? "writeonly " : ""; + enum gl_access_qualifier access = var->data.image.access; + const char *const coher = (access & ACCESS_COHERENT) ? "coherent " : ""; + const char *const volat = (access & ACCESS_VOLATILE) ? "volatile " : ""; + const char *const restr = (access & ACCESS_RESTRICT) ? "restrict " : ""; + const char *const ronly = (access & ACCESS_NON_WRITEABLE) ? "readonly " : ""; + const char *const wonly = (access & ACCESS_NON_READABLE) ? "writeonly " : ""; fprintf(fp, "%s%s%s%s%s", coher, volat, restr, ronly, wonly); fprintf(fp, "%s %s", glsl_get_type_name(var->type), diff --git a/src/compiler/shader_enums.h b/src/compiler/shader_enums.h index 5c36f55283c..f023b48cbb3 100644 --- a/src/compiler/shader_enums.h +++ b/src/compiler/shader_enums.h @@ -690,11 +690,13 @@ enum gl_frag_depth_layout /** * \brief Buffer access qualifiers */ -enum gl_buffer_access_qualifier +enum gl_access_qualifier { - ACCESS_COHERENT = 1, - ACCESS_RESTRICT = 2, - ACCESS_VOLATILE = 4, + ACCESS_COHERENT = (1 << 0), + ACCESS_RESTRICT = (1 << 1), + ACCESS_VOLATILE = (1 << 2), + ACCESS_NON_READABLE = (1 << 3), + ACCESS_NON_WRITEABLE = (1 << 4), }; /** diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 571a14cf4cf..358ff4bef7a 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -1248,20 +1248,20 @@ apply_var_decoration(struct vtn_builder *b, var_data->read_only = true; break; case SpvDecorationNonReadable: - var_data->image.write_only = true; + var_data->image.access |= ACCESS_NON_READABLE; break; case SpvDecorationNonWritable: var_data->read_only = true; - var_data->image.read_only = true; + var_data->image.access |= ACCESS_NON_WRITEABLE; break; case SpvDecorationRestrict: - var_data->image.restrict_flag = true; + var_data->image.access |= ACCESS_RESTRICT; break; case SpvDecorationVolatile: - var_data->image._volatile = true; + var_data->image.access |= ACCESS_VOLATILE; break; case SpvDecorationCoherent: - var_data->image.coherent = true; + var_data->image.access |= ACCESS_COHERENT; break; case SpvDecorationComponent: var_data->location_frac = dec->literals[0]; diff --git a/src/intel/compiler/brw_nir_lower_image_load_store.c b/src/intel/compiler/brw_nir_lower_image_load_store.c index 4494dccccd2..819fb440f2c 100644 --- a/src/intel/compiler/brw_nir_lower_image_load_store.c +++ b/src/intel/compiler/brw_nir_lower_image_load_store.c @@ -617,7 +617,7 @@ lower_image_store_instr(nir_builder *b, /* For write-only surfaces, we trust that the hardware can just do the * conversion for us. */ - if (var->data.image.write_only) + if (var->data.image.access & ACCESS_NON_READABLE) return false; const enum isl_format image_fmt = diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c index 67ebaa6ce6c..84a664826e8 100644 --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c @@ -463,7 +463,8 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline *pipeline, dim == GLSL_SAMPLER_DIM_SUBPASS_MS) pipe_binding[i].input_attachment_index = var->data.index + i; - pipe_binding[i].write_only = var->data.image.write_only; + pipe_binding[i].write_only = + (var->data.image.access & ACCESS_NON_READABLE) != 0; } } -- 2.30.2