[Mesa-dev] [PATCH 19/22] nir: Use a bitfield for image access qualifiers
Jason Ekstrand
jason at jlekstrand.net
Fri Aug 17 20:06:25 UTC 2018
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.
---
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 | 4 ++--
.../vulkan/anv_nir_apply_pipeline_layout.c | 3 ++-
9 files changed, 45 insertions(+), 34 deletions(-)
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index cffc980e51f..ac66cbcb39c 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -2348,7 +2348,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);
@@ -2389,7 +2389,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 fbe25dcc5a4..2535beef8dc 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 d0fa693884b..55e48bbb693 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 99206d81ee0..dfad39c898d 100644
--- a/src/intel/compiler/brw_nir_lower_image_load_store.c
+++ b/src/intel/compiler/brw_nir_lower_image_load_store.c
@@ -618,7 +618,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 =
@@ -732,7 +732,7 @@ lower_image_size_instr(nir_builder *b,
/* For write-only images, we have an actual image surface so we fall back
* and let the back-end emit a TXQ for this.
*/
- if (var->data.image.write_only)
+ if (var->data.image.access & ACCESS_NON_READABLE)
return false;
/* If we have a matching typed format, then we have an actual image surface
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.17.1
More information about the mesa-dev
mailing list