summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/common/drirc2
-rw-r--r--src/mesa/drivers/dri/common/utils.c2
-rw-r--r--src/mesa/drivers/dri/i915/intel_pixel_read.c2
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex_image.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_conditional_render.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c41
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp58
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h10
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_nir.cpp87
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp12
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_nir.c23
-rw-r--r--src/mesa/drivers/dri/i965/brw_primitive_restart.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_queryobj.c19
-rw-r--r--src/mesa/drivers/dri/i965/brw_shader.cpp20
-rw-r--r--src/mesa/drivers/dri/i965/brw_shader.h11
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h7
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp4
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_nir.cpp51
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp7
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp48
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_surface_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c8
-rw-r--r--src/mesa/drivers/dri/i965/gen6_vs_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen7_sol_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen8_draw_upload.c73
-rw-r--r--src/mesa/drivers/dri/i965/intel_extensions.c1
-rw-r--r--src/mesa/drivers/dri/i965/intel_fbo.c4
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.c8
-rw-r--r--src/mesa/main/bufferobj.c4
-rw-r--r--src/mesa/main/context.c4
-rw-r--r--src/mesa/main/extensions.c8
-rw-r--r--src/mesa/main/fbobject.c10
-rw-r--r--src/mesa/main/format_info.py12
-rw-r--r--src/mesa/main/format_utils.c2
-rw-r--r--src/mesa/main/formats.c258
-rw-r--r--src/mesa/main/formats.h10
-rw-r--r--src/mesa/main/get_hash_params.py2
-rw-r--r--src/mesa/main/mipmap.c2
-rw-r--r--src/mesa/main/mtypes.h17
-rw-r--r--src/mesa/main/multisample.c9
-rw-r--r--src/mesa/main/readpix.c2
-rw-r--r--src/mesa/main/shaderapi.c100
-rw-r--r--src/mesa/main/shaderimage.c150
-rw-r--r--src/mesa/main/shaderimage.h9
-rw-r--r--src/mesa/main/tests/Makefile.am1
-rw-r--r--src/mesa/main/tests/dispatch_sanity.cpp9
-rw-r--r--src/mesa/main/tests/mesa_formats.cpp139
-rw-r--r--src/mesa/main/texcompress.c30
-rw-r--r--src/mesa/main/texgetimage.c2
-rw-r--r--src/mesa/main/teximage.c190
-rw-r--r--src/mesa/main/teximage.h2
-rw-r--r--src/mesa/main/texobj.c15
-rw-r--r--src/mesa/main/texobj.h4
-rw-r--r--src/mesa/main/texparam.c38
-rw-r--r--src/mesa/main/texstorage.c37
-rw-r--r--src/mesa/main/texstorage.h21
-rw-r--r--src/mesa/main/texstore.c2
-rw-r--r--src/mesa/main/uniform_query.cpp25
-rw-r--r--src/mesa/main/uniforms.c9
-rw-r--r--src/mesa/program/prog_to_nir.c44
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c1
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c2
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c35
-rw-r--r--src/mesa/state_tracker/st_format.c2
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp14
-rw-r--r--src/mesa/swrast/s_drawpix.c2
72 files changed, 1023 insertions, 729 deletions
diff --git a/src/mesa/drivers/dri/common/drirc b/src/mesa/drivers/dri/common/drirc
index 97d961b..bb840ea 100644
--- a/src/mesa/drivers/dri/common/drirc
+++ b/src/mesa/drivers/dri/common/drirc
@@ -53,10 +53,12 @@ TODO: document the other workarounds.
<application name="Unigine OilRush (32-bit)" executable="OilRush_x86">
<option name="disable_blend_func_extended" value="true" />
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
</application>
<application name="Unigine OilRush (64-bit)" executable="OilRush_x64">
<option name="disable_blend_func_extended" value="true" />
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
</application>
<application name="Savage 2" executable="savage2.bin">
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index b51b263..43d90d9 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -452,7 +452,7 @@ int
driGetConfigAttrib(const __DRIconfig *config,
unsigned int attrib, unsigned int *value)
{
- int i;
+ unsigned i;
for (i = 0; i < ARRAY_SIZE(attribMap); i++)
if (attribMap[i].attrib == attrib)
diff --git a/src/mesa/drivers/dri/i915/intel_pixel_read.c b/src/mesa/drivers/dri/i915/intel_pixel_read.c
index 149e921..e6fa8f2 100644
--- a/src/mesa/drivers/dri/i915/intel_pixel_read.c
+++ b/src/mesa/drivers/dri/i915/intel_pixel_read.c
@@ -91,7 +91,7 @@ do_blit_readpixels(struct gl_context * ctx,
if (ctx->_ImageTransferState ||
!_mesa_format_matches_format_and_type(irb->mt->format, format, type,
- false)) {
+ false, NULL)) {
DBG("%s - bad format for blit\n", __func__);
return false;
}
diff --git a/src/mesa/drivers/dri/i915/intel_tex_image.c b/src/mesa/drivers/dri/i915/intel_tex_image.c
index 0a213e9..5ab60d1 100644
--- a/src/mesa/drivers/dri/i915/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i915/intel_tex_image.c
@@ -134,7 +134,7 @@ try_pbo_upload(struct gl_context *ctx,
}
if (!_mesa_format_matches_format_and_type(intelImage->mt->format,
- format, type, false)) {
+ format, type, false, NULL)) {
DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n",
__func__, _mesa_get_format_name(intelImage->mt->format),
format, type);
diff --git a/src/mesa/drivers/dri/i965/brw_conditional_render.c b/src/mesa/drivers/dri/i965/brw_conditional_render.c
index 6d37c3b..122a4ec 100644
--- a/src/mesa/drivers/dri/i965/brw_conditional_render.c
+++ b/src/mesa/drivers/dri/i965/brw_conditional_render.c
@@ -56,6 +56,12 @@ set_predicate_for_result(struct brw_context *brw,
assert(query->bo != NULL);
+ /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM
+ * command when loading the values into the predicate source registers for
+ * conditional rendering.
+ */
+ brw_emit_pipe_control_flush(brw, PIPE_CONTROL_FLUSH_ENABLE);
+
brw_load_register_mem64(brw,
MI_PREDICATE_SRC0,
query->bo,
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 328662d..0ee5ab2 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -514,7 +514,7 @@ brw_initialize_context_constants(struct brw_context *brw)
ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms =
BRW_MAX_IMAGES;
ctx->Const.MaxImageUnits = MAX_IMAGE_UNITS;
- ctx->Const.MaxCombinedImageUnitsAndFragmentOutputs =
+ ctx->Const.MaxCombinedShaderOutputResources =
MAX_IMAGE_UNITS + BRW_MAX_DRAW_BUFFERS;
ctx->Const.MaxImageSamples = 0;
ctx->Const.MaxCombinedImageUniforms = 3 * BRW_MAX_IMAGES;
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index e092ef4..e5de420 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -383,7 +383,7 @@ brw_postdraw_set_buffers_need_resolve(struct brw_context *brw)
brw_render_cache_set_add_bo(brw, stencil_irb->mt->bo);
}
- for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
+ for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) {
struct intel_renderbuffer *irb =
intel_renderbuffer(fb->_ColorDrawBuffers[i]);
@@ -626,7 +626,7 @@ brw_draw_init(struct brw_context *brw)
void
brw_draw_destroy(struct brw_context *brw)
{
- int i;
+ unsigned i;
for (i = 0; i < brw->vb.nr_buffers; i++) {
drm_intel_bo_unreference(brw->vb.buffers[i].bo);
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index cbfd585..21d8f1e 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -395,7 +395,8 @@ brw_prepare_vertices(struct brw_context *brw)
GLuint interleaved = 0;
unsigned int min_index = brw->vb.min_index + brw->basevertex;
unsigned int max_index = brw->vb.max_index + brw->basevertex;
- int delta, i, j;
+ unsigned i;
+ int delta, j;
struct brw_vertex_element *upload[VERT_ATTRIB_MAX];
GLuint nr_uploads = 0;
@@ -418,10 +419,10 @@ brw_prepare_vertices(struct brw_context *brw)
/* Accumulate the list of enabled arrays. */
brw->vb.nr_enabled = 0;
while (vs_inputs) {
- GLuint i = ffsll(vs_inputs) - 1;
- struct brw_vertex_element *input = &brw->vb.inputs[i];
+ GLuint index = ffsll(vs_inputs) - 1;
+ struct brw_vertex_element *input = &brw->vb.inputs[index];
- vs_inputs &= ~BITFIELD64_BIT(i);
+ vs_inputs &= ~BITFIELD64_BIT(index);
brw->vb.enabled[brw->vb.nr_enabled++] = input;
}
@@ -438,7 +439,7 @@ brw_prepare_vertices(struct brw_context *brw)
if (_mesa_is_bufferobj(glarray->BufferObj)) {
struct intel_buffer_object *intel_buffer =
intel_buffer_object(glarray->BufferObj);
- int k;
+ unsigned k;
/* If we have a VB set to be uploaded for this buffer object
* already, reuse that VB state so that we emit fewer
@@ -792,21 +793,6 @@ brw_emit_vertices(struct brw_context *brw)
((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
}
- if (brw->gen >= 6 && gen6_edgeflag_input) {
- uint32_t format =
- brw_get_vertex_surface_type(brw, gen6_edgeflag_input->glarray);
-
- OUT_BATCH((gen6_edgeflag_input->buffer << GEN6_VE0_INDEX_SHIFT) |
- GEN6_VE0_VALID |
- GEN6_VE0_EDGE_FLAG_ENABLE |
- (format << BRW_VE0_FORMAT_SHIFT) |
- (gen6_edgeflag_input->offset << BRW_VE0_SRC_OFFSET_SHIFT));
- OUT_BATCH((BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT));
- }
-
if (brw->vs.prog_data->uses_vertexid || brw->vs.prog_data->uses_instanceid) {
uint32_t dw0 = 0, dw1 = 0;
uint32_t comp0 = BRW_VE1_COMPONENT_STORE_0;
@@ -847,6 +833,21 @@ brw_emit_vertices(struct brw_context *brw)
OUT_BATCH(dw1);
}
+ if (brw->gen >= 6 && gen6_edgeflag_input) {
+ uint32_t format =
+ brw_get_vertex_surface_type(brw, gen6_edgeflag_input->glarray);
+
+ OUT_BATCH((gen6_edgeflag_input->buffer << GEN6_VE0_INDEX_SHIFT) |
+ GEN6_VE0_VALID |
+ GEN6_VE0_EDGE_FLAG_ENABLE |
+ (format << BRW_VE0_FORMAT_SHIFT) |
+ (gen6_edgeflag_input->offset << BRW_VE0_SRC_OFFSET_SHIFT));
+ OUT_BATCH((BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT));
+ }
+
ADVANCE_BATCH();
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 0e091dd..159f716 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -455,8 +455,8 @@ fs_reg::component_size(unsigned width) const
return MAX2(width * stride, 1) * type_sz(type);
}
-int
-fs_visitor::type_size(const struct glsl_type *type)
+extern "C" int
+type_size_scalar(const struct glsl_type *type)
{
unsigned int size, i;
@@ -467,11 +467,11 @@ fs_visitor::type_size(const struct glsl_type *type)
case GLSL_TYPE_BOOL:
return type->components();
case GLSL_TYPE_ARRAY:
- return type_size(type->fields.array) * type->length;
+ return type_size_scalar(type->fields.array) * type->length;
case GLSL_TYPE_STRUCT:
size = 0;
for (i = 0; i < type->length; i++) {
- size += type_size(type->fields.structure[i].type);
+ size += type_size_scalar(type->fields.structure[i].type);
}
return size;
case GLSL_TYPE_SAMPLER:
@@ -907,7 +907,7 @@ fs_reg
fs_visitor::vgrf(const glsl_type *const type)
{
int reg_width = dispatch_width / 8;
- return fs_reg(GRF, alloc.allocate(type_size(type) * reg_width),
+ return fs_reg(GRF, alloc.allocate(type_size_scalar(type) * reg_width),
brw_type_for_base_type(type));
}
@@ -944,15 +944,17 @@ fs_visitor::import_uniforms(fs_visitor *v)
}
void
-fs_visitor::setup_vector_uniform_values(const gl_constant_value *values, unsigned n)
+fs_visitor::setup_vec4_uniform_value(unsigned param_offset,
+ const gl_constant_value *values,
+ unsigned n)
{
static const gl_constant_value zero = { 0 };
for (unsigned i = 0; i < n; ++i)
- stage_prog_data->param[uniforms++] = &values[i];
+ stage_prog_data->param[param_offset + i] = &values[i];
for (unsigned i = n; i < 4; ++i)
- stage_prog_data->param[uniforms++] = &zero;
+ stage_prog_data->param[param_offset + i] = &zero;
}
fs_reg *
@@ -1769,21 +1771,21 @@ fs_visitor::compact_virtual_grfs()
return progress;
}
-/*
- * Implements array access of uniforms by inserting a
- * PULL_CONSTANT_LOAD instruction.
+/**
+ * Assign UNIFORM file registers to either push constants or pull constants.
*
- * Unlike temporary GRF array access (where we don't support it due to
- * the difficulty of doing relative addressing on instruction
- * destinations), we could potentially do array access of uniforms
- * that were loaded in GRF space as push constants. In real-world
- * usage we've seen, though, the arrays being used are always larger
- * than we could load as push constants, so just always move all
- * uniform array access out to a pull constant buffer.
+ * We allow a fragment shader to have more than the specified minimum
+ * maximum number of fragment shader uniform components (64). If
+ * there are too many of these, they'd fill up all of register space.
+ * So, this will push some of them out to the pull constant buffer and
+ * update the program to load them. We also use pull constants for all
+ * indirect constant loads because we don't support indirect accesses in
+ * registers yet.
*/
void
-fs_visitor::move_uniform_array_access_to_pull_constants()
+fs_visitor::assign_constant_locations()
{
+ /* Only the first compile (SIMD8 mode) gets to decide on locations. */
if (dispatch_width != 8)
return;
@@ -1820,23 +1822,6 @@ fs_visitor::move_uniform_array_access_to_pull_constants()
}
}
}
-}
-
-/**
- * Assign UNIFORM file registers to either push constants or pull constants.
- *
- * We allow a fragment shader to have more than the specified minimum
- * maximum number of fragment shader uniform components (64). If
- * there are too many of these, they'd fill up all of register space.
- * So, this will push some of them out to the pull constant buffer and
- * update the program to load them.
- */
-void
-fs_visitor::assign_constant_locations()
-{
- /* Only the first compile (SIMD8 mode) gets to decide on locations. */
- if (dispatch_width != 8)
- return;
/* Find which UNIFORM registers are still in use. */
bool is_live[uniforms];
@@ -4823,7 +4808,6 @@ fs_visitor::optimize()
split_virtual_grfs();
- move_uniform_array_access_to_pull_constants();
assign_constant_locations();
demote_pull_constants();
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 975183e..31f39fe 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -112,7 +112,6 @@ public:
void swizzle_result(ir_texture_opcode op, int dest_components,
fs_reg orig_val, uint32_t sampler);
- int type_size(const struct glsl_type *type);
fs_inst *get_instruction_generating_reg(fs_inst *start,
fs_inst *end,
const fs_reg &reg);
@@ -147,7 +146,6 @@ public:
void spill_reg(int spill_reg);
void split_virtual_grfs();
bool compact_virtual_grfs();
- void move_uniform_array_access_to_pull_constants();
void assign_constant_locations();
void demote_pull_constants();
void invalidate_live_intervals();
@@ -291,8 +289,9 @@ public:
struct brw_reg interp_reg(int location, int channel);
- virtual void setup_vector_uniform_values(const gl_constant_value *values,
- unsigned n);
+ virtual void setup_vec4_uniform_value(unsigned param_offset,
+ const gl_constant_value *values,
+ unsigned n);
int implied_mrf_writes(fs_inst *inst);
@@ -318,9 +317,6 @@ public:
/** Number of uniform variable components visited. */
unsigned uniforms;
- /** Total number of direct uniforms we can get from NIR */
- unsigned num_direct_uniforms;
-
/** Byte-offset for the next available spot in the scratch space buffer. */
unsigned last_scratch;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 93a36cc..6272b61 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -131,7 +131,7 @@ fs_visitor::nir_setup_outputs(nir_shader *shader)
switch (stage) {
case MESA_SHADER_VERTEX:
- for (int i = 0; i < ALIGN(type_size(var->type), 4) / 4; i++) {
+ for (int i = 0; i < ALIGN(type_size_scalar(var->type), 4) / 4; i++) {
int output = var->data.location + i;
this->outputs[output] = offset(reg, bld, 4 * i);
this->output_components[output] = vector_elements;
@@ -175,19 +175,9 @@ fs_visitor::nir_setup_outputs(nir_shader *shader)
void
fs_visitor::nir_setup_uniforms(nir_shader *shader)
{
- num_direct_uniforms = shader->num_direct_uniforms;
-
if (dispatch_width != 8)
return;
- /* We split the uniform register file in half. The first half is
- * entirely direct uniforms. The second half is indirect.
- */
- if (num_direct_uniforms > 0)
- param_size[0] = num_direct_uniforms;
- if (shader->num_uniforms > num_direct_uniforms)
- param_size[num_direct_uniforms] = shader->num_uniforms - num_direct_uniforms;
-
uniforms = shader->num_uniforms;
if (shader_prog) {
@@ -200,15 +190,19 @@ fs_visitor::nir_setup_uniforms(nir_shader *shader)
nir_setup_builtin_uniform(var);
else
nir_setup_uniform(var);
+
+ param_size[var->data.driver_location] = type_size_scalar(var->type);
}
} else {
- /* prog_to_nir doesn't create uniform variables; set param up directly. */
+ /* prog_to_nir only creates a single giant uniform variable so we can
+ * just set param up directly. */
for (unsigned p = 0; p < prog->Parameters->NumParameters; p++) {
for (unsigned int i = 0; i < 4; i++) {
stage_prog_data->param[4 * p + i] =
&prog->Parameters->ParameterValues[p][i];
}
}
+ param_size[0] = prog->Parameters->NumParameters * 4;
}
}
@@ -239,15 +233,7 @@ fs_visitor::nir_setup_uniform(nir_variable *var)
}
if (storage->type->is_image()) {
- /* Images don't get a valid location assigned by nir_lower_io()
- * because their size is driver-specific, so we need to allocate
- * space for them here at the end of the parameter array.
- */
- var->data.driver_location = uniforms;
- param_size[uniforms] =
- BRW_IMAGE_PARAM_SIZE * MAX2(storage->array_elements, 1);
-
- setup_image_uniform_values(storage);
+ setup_image_uniform_values(index, storage);
} else {
unsigned slots = storage->type->component_slots();
if (storage->array_elements)
@@ -1406,6 +1392,51 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
break;
}
+ case nir_intrinsic_image_size: {
+ /* Get the referenced image variable and type. */
+ const nir_variable *var = instr->variables[0]->var;
+ const glsl_type *type = var->type->without_array();
+
+ /* Get the size of the image. */
+ const fs_reg image = get_nir_image_deref(instr->variables[0]);
+ const fs_reg size = offset(image, bld, BRW_IMAGE_PARAM_SIZE_OFFSET);
+
+ /* For 1DArray image types, the array index is stored in the Z component.
+ * Fix this by swizzling the Z component to the Y component.
+ */
+ const bool is_1d_array_image =
+ type->sampler_dimensionality == GLSL_SAMPLER_DIM_1D &&
+ type->sampler_array;
+
+ /* For CubeArray images, we should count the number of cubes instead
+ * of the number of faces. Fix it by dividing the (Z component) by 6.
+ */
+ const bool is_cube_array_image =
+ type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE &&
+ type->sampler_array;
+
+ /* Copy all the components. */
+ const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
+ for (unsigned c = 0; c < info->dest_components; ++c) {
+ if ((int)c >= type->coordinate_components()) {
+ bld.MOV(offset(retype(dest, BRW_REGISTER_TYPE_D), bld, c),
+ fs_reg(1));
+ } else if (c == 1 && is_1d_array_image) {
+ bld.MOV(offset(retype(dest, BRW_REGISTER_TYPE_D), bld, c),
+ offset(size, bld, 2));
+ } else if (c == 2 && is_cube_array_image) {
+ bld.emit(SHADER_OPCODE_INT_QUOTIENT,
+ offset(retype(dest, BRW_REGISTER_TYPE_D), bld, c),
+ offset(size, bld, c), fs_reg(6));
+ } else {
+ bld.MOV(offset(retype(dest, BRW_REGISTER_TYPE_D), bld, c),
+ offset(size, bld, c));
+ }
+ }
+
+ break;
+ }
+
case nir_intrinsic_load_front_face:
bld.MOV(retype(dest, BRW_REGISTER_TYPE_D),
*emit_frontfacing_interpolation());
@@ -1467,21 +1498,13 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
has_indirect = true;
/* fallthrough */
case nir_intrinsic_load_uniform: {
- unsigned index = instr->const_index[0];
-
- fs_reg uniform_reg;
- if (index < num_direct_uniforms) {
- uniform_reg = fs_reg(UNIFORM, 0);
- } else {
- uniform_reg = fs_reg(UNIFORM, num_direct_uniforms);
- index -= num_direct_uniforms;
- }
+ fs_reg uniform_reg(UNIFORM, instr->const_index[0]);
+ uniform_reg.reg_offset = instr->const_index[1];
for (unsigned j = 0; j < instr->num_components; j++) {
- fs_reg src = offset(retype(uniform_reg, dest.type), bld, index);
+ fs_reg src = offset(retype(uniform_reg, dest.type), bld, j);
if (has_indirect)
src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));
- index++;
bld.MOV(dest, src);
dest = offset(dest, bld, 1);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
index b70895e..6eb9889 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -156,7 +156,7 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
}
uint8_t *ra_reg_to_grf = ralloc_array(compiler, uint8_t, ra_reg_count);
- struct ra_regs *regs = ra_alloc_reg_set(compiler, ra_reg_count);
+ struct ra_regs *regs = ra_alloc_reg_set(compiler, ra_reg_count, false);
if (devinfo->gen >= 6)
ra_set_allocate_round_robin(regs);
int *classes = ralloc_array(compiler, int, class_count);
@@ -232,7 +232,7 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
for (int base_reg = j;
base_reg < j + (class_sizes[i] + 1) / 2;
base_reg++) {
- ra_add_transitive_reg_conflict(regs, base_reg, reg);
+ ra_add_reg_conflict(regs, base_reg, reg);
}
reg++;
@@ -246,7 +246,7 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
for (int base_reg = j;
base_reg < j + class_sizes[i];
base_reg++) {
- ra_add_transitive_reg_conflict(regs, base_reg, reg);
+ ra_add_reg_conflict(regs, base_reg, reg);
}
reg++;
@@ -255,6 +255,12 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
}
assert(reg == ra_reg_count);
+ /* Applying transitivity to all of the base registers gives us the
+ * appropreate register conflict relationships everywhere.
+ */
+ for (int reg = 0; reg < base_reg_count; reg++)
+ ra_make_reg_conflicts_transitive(regs, reg);
+
/* Add a special class for aligned pairs, which we'll put delta_xy
* in on Gen <= 6 so that we can do PLN.
*/
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index e9d9467..2751152 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -878,7 +878,8 @@ brw_upload_invariant_state(struct brw_context *brw)
{
const bool is_965 = brw->gen == 4 && !brw->is_g4x;
- brw_select_pipeline(brw, BRW_RENDER_PIPELINE);
+ brw_emit_select_pipeline(brw, BRW_RENDER_PIPELINE);
+ brw->last_pipeline = BRW_RENDER_PIPELINE;
if (brw->gen < 6) {
/* Disable depth offset clamping. */
diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c
index 79e31d8..0276d47 100644
--- a/src/mesa/drivers/dri/i965/brw_nir.c
+++ b/src/mesa/drivers/dri/i965/brw_nir.c
@@ -22,6 +22,7 @@
*/
#include "brw_nir.h"
+#include "brw_shader.h"
#include "glsl/glsl_parser_extras.h"
#include "glsl/nir/glsl_to_nir.h"
#include "program/prog_to_nir.h"
@@ -130,22 +131,24 @@ brw_process_nir(nir_shader *nir,
nir_optimize(nir, is_scalar);
if (is_scalar) {
- nir_assign_var_locations_direct_first(nir, &nir->uniforms,
- &nir->num_direct_uniforms,
- &nir->num_uniforms,
- is_scalar);
- nir_assign_var_locations(&nir->outputs, &nir->num_outputs, is_scalar);
+ nir_assign_var_locations(&nir->uniforms,
+ &nir->num_uniforms,
+ type_size_scalar);
+ nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_scalar);
+ nir_assign_var_locations(&nir->outputs, &nir->num_outputs, type_size_scalar);
+ nir_lower_io(nir, type_size_scalar);
} else {
nir_assign_var_locations(&nir->uniforms,
&nir->num_uniforms,
- is_scalar);
+ type_size_vec4);
+
+ nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_vec4);
foreach_list_typed(nir_variable, var, node, &nir->outputs)
var->data.driver_location = var->data.location;
- }
- nir_assign_var_locations(&nir->inputs, &nir->num_inputs, is_scalar);
- nir_lower_io(nir, is_scalar);
+ nir_lower_io(nir, type_size_vec4);
+ }
nir_validate_shader(nir);
@@ -153,7 +156,7 @@ brw_process_nir(nir_shader *nir,
nir_validate_shader(nir);
if (shader_prog) {
- nir_lower_samplers(nir, shader_prog, stage);
+ nir_lower_samplers(nir, shader_prog);
} else {
nir_lower_samplers_for_vk(nir);
}
diff --git a/src/mesa/drivers/dri/i965/brw_primitive_restart.c b/src/mesa/drivers/dri/i965/brw_primitive_restart.c
index 6ed79d7..c8d9002 100644
--- a/src/mesa/drivers/dri/i965/brw_primitive_restart.c
+++ b/src/mesa/drivers/dri/i965/brw_primitive_restart.c
@@ -91,7 +91,7 @@ can_cut_index_handle_prims(struct gl_context *ctx,
return false;
}
- for (int i = 0; i < nr_prims; i++) {
+ for (unsigned i = 0; i < nr_prims; i++) {
switch (prim[i].mode) {
case GL_POINTS:
case GL_LINES:
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index d6b012c..a8e5aba 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -66,20 +66,11 @@ brw_write_timestamp(struct brw_context *brw, drm_intel_bo *query_bo, int idx)
void
brw_write_depth_count(struct brw_context *brw, drm_intel_bo *query_bo, int idx)
{
- uint32_t flags;
-
- flags = (PIPE_CONTROL_WRITE_DEPTH_COUNT |
- PIPE_CONTROL_DEPTH_STALL);
-
- /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM
- * command when loading the values into the predicate source registers for
- * conditional rendering.
- */
- if (brw->predicate.supported)
- flags |= PIPE_CONTROL_FLUSH_ENABLE;
-
- brw_emit_pipe_control_write(brw, flags, query_bo,
- idx * sizeof(uint64_t), 0, 0);
+ brw_emit_pipe_control_write(brw,
+ PIPE_CONTROL_WRITE_DEPTH_COUNT |
+ PIPE_CONTROL_DEPTH_STALL,
+ query_bo, idx * sizeof(uint64_t),
+ 0, 0);
}
/**
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 67b8dde..0007e5c 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -122,7 +122,7 @@ brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo)
compiler->glsl_compiler_options[MESA_SHADER_VERTEX].OptimizeForAOS = true;
compiler->glsl_compiler_options[MESA_SHADER_GEOMETRY].OptimizeForAOS = true;
- if (compiler->scalar_vs || brw_env_var_as_boolean("INTEL_USE_NIR", false)) {
+ if (compiler->scalar_vs || brw_env_var_as_boolean("INTEL_USE_NIR", true)) {
if (compiler->scalar_vs) {
/* If we're using the scalar backend for vertex shaders, we need to
* configure these accordingly.
@@ -135,7 +135,7 @@ brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo)
compiler->glsl_compiler_options[MESA_SHADER_VERTEX].NirOptions = nir_options;
}
- if (brw_env_var_as_boolean("INTEL_USE_NIR", false)) {
+ if (brw_env_var_as_boolean("INTEL_USE_NIR", true)) {
compiler->glsl_compiler_options[MESA_SHADER_GEOMETRY].NirOptions = nir_options;
}
@@ -1421,7 +1421,8 @@ backend_shader::assign_common_binding_table_offsets(uint32_t next_binding_table_
}
void
-backend_shader::setup_image_uniform_values(const gl_uniform_storage *storage)
+backend_shader::setup_image_uniform_values(unsigned param_offset,
+ const gl_uniform_storage *storage)
{
const unsigned stage = _mesa_program_enum_to_shader_stage(prog->Target);
@@ -1432,18 +1433,19 @@ backend_shader::setup_image_uniform_values(const gl_uniform_storage *storage)
/* Upload the brw_image_param structure. The order is expected to match
* the BRW_IMAGE_PARAM_*_OFFSET defines.
*/
- setup_vector_uniform_values(
+ setup_vec4_uniform_value(param_offset + BRW_IMAGE_PARAM_SURFACE_IDX_OFFSET,
(const gl_constant_value *)&param->surface_idx, 1);
- setup_vector_uniform_values(
+ setup_vec4_uniform_value(param_offset + BRW_IMAGE_PARAM_OFFSET_OFFSET,
(const gl_constant_value *)param->offset, 2);
- setup_vector_uniform_values(
+ setup_vec4_uniform_value(param_offset + BRW_IMAGE_PARAM_SIZE_OFFSET,
(const gl_constant_value *)param->size, 3);
- setup_vector_uniform_values(
+ setup_vec4_uniform_value(param_offset + BRW_IMAGE_PARAM_STRIDE_OFFSET,
(const gl_constant_value *)param->stride, 4);
- setup_vector_uniform_values(
+ setup_vec4_uniform_value(param_offset + BRW_IMAGE_PARAM_TILING_OFFSET,
(const gl_constant_value *)param->tiling, 3);
- setup_vector_uniform_values(
+ setup_vec4_uniform_value(param_offset + BRW_IMAGE_PARAM_SWIZZLING_OFFSET,
(const gl_constant_value *)param->swizzling, 2);
+ param_offset += BRW_IMAGE_PARAM_SIZE;
brw_mark_surface_used(
stage_prog_data,
diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h
index 2cc97f2..ccccf4d 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.h
+++ b/src/mesa/drivers/dri/i965/brw_shader.h
@@ -270,9 +270,11 @@ public:
virtual void invalidate_live_intervals() = 0;
- virtual void setup_vector_uniform_values(const gl_constant_value *values,
- unsigned n) = 0;
- void setup_image_uniform_values(const gl_uniform_storage *storage);
+ virtual void setup_vec4_uniform_value(unsigned param_offset,
+ const gl_constant_value *values,
+ unsigned n) = 0;
+ void setup_image_uniform_values(unsigned param_offset,
+ const gl_uniform_storage *storage);
};
uint32_t brw_texture_offset(int *offsets, unsigned num_components);
@@ -307,6 +309,9 @@ bool brw_cs_precompile(struct gl_context *ctx,
struct gl_shader_program *shader_prog,
struct gl_program *prog);
+int type_size_scalar(const struct glsl_type *type);
+int type_size_vec4(const struct glsl_type *type);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index 5effb4c..e817ecf 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -208,7 +208,7 @@ brw_lookup_prog(const struct brw_cache *cache,
const void *data, unsigned data_size)
{
const struct brw_context *brw = cache->brw;
- int i;
+ unsigned i;
const struct brw_cache_item *item;
for (i = 0; i < cache->size; i++) {
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index b8b0393..e96732a 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -555,7 +555,7 @@ brw_miptree_layout_texture_array(struct brw_context *brw,
if (mt->compressed)
img_height /= mt->align_h;
- for (int q = 0; q < mt->level[level].depth; q++) {
+ for (unsigned q = 0; q < mt->level[level].depth; q++) {
if (mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
intel_miptree_set_image_offset(mt, level, q, 0, q * img_height);
} else {
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 341c516..673a29e 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -177,8 +177,9 @@ public:
void fail(const char *msg, ...);
void setup_uniform_clipplane_values(gl_clip_plane *clip_planes);
- virtual void setup_vector_uniform_values(const gl_constant_value *values,
- unsigned n);
+ virtual void setup_vec4_uniform_value(unsigned param_offset,
+ const gl_constant_value *values,
+ unsigned n);
void setup_uniform_values(ir_variable *ir);
void setup_builtin_uniform_values(ir_variable *ir);
int setup_uniforms(int payload_reg);
@@ -409,7 +410,6 @@ public:
void visit_atomic_counter_intrinsic(ir_call *ir);
- int type_size(const struct glsl_type *type);
bool is_high_sampler(src_reg sampler);
virtual void emit_nir_code();
@@ -447,7 +447,6 @@ public:
dst_reg *nir_locals;
dst_reg *nir_ssa_values;
src_reg *nir_inputs;
- unsigned *nir_uniform_driver_location;
dst_reg *nir_system_values;
protected:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp
index d85fb6f..8a8dd57 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp
@@ -44,7 +44,7 @@ vec4_gs_visitor::nir_setup_inputs(nir_shader *shader)
*/
assert(var->type->length > 0);
int length = var->type->length;
- int size = type_size(var->type) / length;
+ int size = type_size_vec4(var->type) / length;
for (int i = 0; i < length; i++) {
int location = var->data.location + i * BRW_VARYING_SLOT_COUNT;
for (int j = 0; j < size; j++) {
@@ -55,7 +55,7 @@ vec4_gs_visitor::nir_setup_inputs(nir_shader *shader)
}
}
} else {
- int size = type_size(var->type);
+ int size = type_size_vec4(var->type);
for (int i = 0; i < size; i++) {
src_reg src = src_reg(ATTR, var->data.location + i, var->type);
src = retype(src, brw_type_for_base_type(var->type));
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
index fd3d556..d5a24d8 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
@@ -119,7 +119,7 @@ vec4_visitor::nir_setup_inputs(nir_shader *shader)
foreach_list_typed(nir_variable, var, node, &shader->inputs) {
int offset = var->data.driver_location;
- unsigned size = type_size(var->type);
+ unsigned size = type_size_vec4(var->type);
for (unsigned i = 0; i < size; i++) {
src_reg src = src_reg(ATTR, var->data.location + i, var->type);
nir_inputs[offset + i] = src;
@@ -132,20 +132,17 @@ vec4_visitor::nir_setup_uniforms(nir_shader *shader)
{
uniforms = 0;
- nir_uniform_driver_location =
- rzalloc_array(mem_ctx, unsigned, this->uniform_array_size);
-
if (shader_prog) {
foreach_list_typed(nir_variable, var, node, &shader->uniforms) {
/* UBO's, atomics and samplers don't take up space in the
uniform file */
if (var->interface_type != NULL || var->type->contains_atomic() ||
- type_size(var->type) == 0) {
+ type_size_vec4(var->type) == 0) {
continue;
}
assert(uniforms < uniform_array_size);
- this->uniform_size[uniforms] = type_size(var->type);
+ this->uniform_size[uniforms] = type_size_vec4(var->type);
if (strncmp(var->name, "gl_", 3) == 0)
nir_setup_builtin_uniform(var);
@@ -161,7 +158,7 @@ vec4_visitor::nir_setup_uniforms(nir_shader *shader)
strcmp(var->name, "parameters") == 0);
assert(uniforms < uniform_array_size);
- this->uniform_size[uniforms] = type_size(var->type);
+ this->uniform_size[uniforms] = type_size_vec4(var->type);
struct gl_program_parameter_list *plist = prog->Parameters;
for (unsigned p = 0; p < plist->NumParameters; p++) {
@@ -182,7 +179,6 @@ vec4_visitor::nir_setup_uniforms(nir_shader *shader)
stage_prog_data->param[uniforms * 4 + i] = &zero;
}
- nir_uniform_driver_location[uniforms] = var->data.driver_location;
uniforms++;
}
}
@@ -230,7 +226,6 @@ vec4_visitor::nir_setup_uniform(nir_variable *var)
stage_prog_data->param[uniforms * 4 + i] = &zero;
}
- nir_uniform_driver_location[uniforms] = var->data.driver_location;
uniforms++;
}
}
@@ -263,7 +258,6 @@ vec4_visitor::nir_setup_builtin_uniform(nir_variable *var)
(var->type->is_scalar() || var->type->is_vector() ||
var->type->is_matrix() ? var->type->vector_elements : 4);
- nir_uniform_driver_location[uniforms] = var->data.driver_location;
uniforms++;
}
}
@@ -458,13 +452,28 @@ vec4_visitor::nir_emit_load_const(nir_load_const_instr *instr)
dst_reg reg = dst_reg(GRF, alloc.allocate(1));
reg.type = BRW_REGISTER_TYPE_F;
+ unsigned remaining = brw_writemask_for_size(instr->def.num_components);
+
/* @FIXME: consider emitting vector operations to save some MOVs in
* cases where the components are representable in 8 bits.
- * By now, we emit a MOV for each component.
+ * For now, we emit a MOV for each distinct value.
*/
- for (unsigned i = 0; i < instr->def.num_components; ++i) {
- reg.writemask = 1 << i;
+ for (unsigned i = 0; i < instr->def.num_components; i++) {
+ unsigned writemask = 1 << i;
+
+ if ((remaining & writemask) == 0)
+ continue;
+
+ for (unsigned j = i; j < instr->def.num_components; j++) {
+ if (instr->value.u[i] == instr->value.u[j]) {
+ writemask |= 1 << j;
+ }
+ }
+
+ reg.writemask = writemask;
emit(MOV(reg, src_reg(instr->value.f[i])));
+
+ remaining &= ~writemask;
}
/* Set final writemask */
@@ -555,24 +564,14 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
has_indirect = true;
/* fallthrough */
case nir_intrinsic_load_uniform: {
- int uniform = instr->const_index[0];
-
dest = get_nir_dest(instr->dest);
- if (has_indirect) {
- /* Split addressing into uniform and offset */
- int offset = uniform - nir_uniform_driver_location[uniform];
- assert(offset >= 0);
+ src = src_reg(dst_reg(UNIFORM, instr->const_index[0]));
+ src.reg_offset = instr->const_index[1];
- uniform -= offset;
- assert(uniform >= 0);
-
- src = src_reg(dst_reg(UNIFORM, uniform));
- src.reg_offset = offset;
+ if (has_indirect) {
src_reg tmp = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_D, 1);
src.reladdr = new(mem_ctx) src_reg(tmp);
- } else {
- src = src_reg(dst_reg(UNIFORM, uniform));
}
emit(MOV(dest, src));
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
index 617c988..62ed708 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
@@ -115,7 +115,7 @@ brw_vec4_alloc_reg_set(struct brw_compiler *compiler)
ralloc_free(compiler->vec4_reg_set.ra_reg_to_grf);
compiler->vec4_reg_set.ra_reg_to_grf = ralloc_array(compiler, uint8_t, ra_reg_count);
ralloc_free(compiler->vec4_reg_set.regs);
- compiler->vec4_reg_set.regs = ra_alloc_reg_set(compiler, ra_reg_count);
+ compiler->vec4_reg_set.regs = ra_alloc_reg_set(compiler, ra_reg_count, false);
if (compiler->devinfo->gen >= 6)
ra_set_allocate_round_robin(compiler->vec4_reg_set.regs);
ralloc_free(compiler->vec4_reg_set.classes);
@@ -140,7 +140,7 @@ brw_vec4_alloc_reg_set(struct brw_compiler *compiler)
for (int base_reg = j;
base_reg < j + class_sizes[i];
base_reg++) {
- ra_add_transitive_reg_conflict(compiler->vec4_reg_set.regs, base_reg, reg);
+ ra_add_reg_conflict(compiler->vec4_reg_set.regs, base_reg, reg);
}
reg++;
@@ -158,6 +158,9 @@ brw_vec4_alloc_reg_set(struct brw_compiler *compiler)
}
assert(reg == ra_reg_count);
+ for (int reg = 0; reg < base_reg_count; reg++)
+ ra_make_reg_conflicts_transitive(compiler->vec4_reg_set.regs, reg);
+
ra_set_finalize(compiler->vec4_reg_set.regs, q_values);
for (int i = 0; i < MAX_VGRF_SIZE; i++)
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 20b628e..499f628 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -597,8 +597,8 @@ vec4_visitor::visit_instructions(const exec_list *list)
* This method is useful to calculate how much register space is needed to
* store a particular type.
*/
-int
-vec4_visitor::type_size(const struct glsl_type *type)
+extern "C" int
+type_size_vec4(const struct glsl_type *type)
{
unsigned int i;
int size;
@@ -620,11 +620,11 @@ vec4_visitor::type_size(const struct glsl_type *type)
}
case GLSL_TYPE_ARRAY:
assert(type->length > 0);
- return type_size(type->fields.array) * type->length;
+ return type_size_vec4(type->fields.array) * type->length;
case GLSL_TYPE_STRUCT:
size = 0;
for (i = 0; i < type->length; i++) {
- size += type_size(type->fields.structure[i].type);
+ size += type_size_vec4(type->fields.structure[i].type);
}
return size;
case GLSL_TYPE_SUBROUTINE:
@@ -655,7 +655,7 @@ src_reg::src_reg(class vec4_visitor *v, const struct glsl_type *type)
init();
this->file = GRF;
- this->reg = v->alloc.allocate(v->type_size(type));
+ this->reg = v->alloc.allocate(type_size_vec4(type));
if (type->is_array() || type->is_record()) {
this->swizzle = BRW_SWIZZLE_NOOP;
@@ -673,7 +673,7 @@ src_reg::src_reg(class vec4_visitor *v, const struct glsl_type *type, int size)
init();
this->file = GRF;
- this->reg = v->alloc.allocate(v->type_size(type) * size);
+ this->reg = v->alloc.allocate(type_size_vec4(type) * size);
this->swizzle = BRW_SWIZZLE_NOOP;
@@ -685,7 +685,7 @@ dst_reg::dst_reg(class vec4_visitor *v, const struct glsl_type *type)
init();
this->file = GRF;
- this->reg = v->alloc.allocate(v->type_size(type));
+ this->reg = v->alloc.allocate(type_size_vec4(type));
if (type->is_array() || type->is_record()) {
this->writemask = WRITEMASK_XYZW;
@@ -697,18 +697,21 @@ dst_reg::dst_reg(class vec4_visitor *v, const struct glsl_type *type)
}
void
-vec4_visitor::setup_vector_uniform_values(const gl_constant_value *values,
- unsigned n)
+vec4_visitor::setup_vec4_uniform_value(unsigned param_offset,
+ const gl_constant_value *values,
+ unsigned n)
{
static const gl_constant_value zero = { 0 };
+ assert(param_offset % 4 == 0);
+
for (unsigned i = 0; i < n; ++i)
- stage_prog_data->param[4 * uniforms + i] = &values[i];
+ stage_prog_data->param[param_offset + i] = &values[i];
for (unsigned i = n; i < 4; ++i)
- stage_prog_data->param[4 * uniforms + i] = &zero;
+ stage_prog_data->param[param_offset + i] = &zero;
- uniform_vector_size[uniforms++] = n;
+ uniform_vector_size[param_offset / 4] = n;
}
/* Our support for uniforms is piggy-backed on the struct
@@ -744,9 +747,12 @@ vec4_visitor::setup_uniform_values(ir_variable *ir)
storage->type->matrix_columns);
const unsigned vector_size = storage->type->vector_elements;
- for (unsigned s = 0; s < vector_count; s++)
- setup_vector_uniform_values(&storage->storage[s * vector_size],
- vector_size);
+ for (unsigned s = 0; s < vector_count; s++) {
+ setup_vec4_uniform_value(uniforms * 4,
+ &storage->storage[s * vector_size],
+ vector_size);
+ uniforms++;
+ }
}
}
@@ -1070,7 +1076,7 @@ vec4_visitor::visit(ir_variable *ir)
assert(ir->data.location != -1);
reg = new(mem_ctx) dst_reg(this, ir->type);
- for (int i = 0; i < type_size(ir->type); i++) {
+ for (int i = 0; i < type_size_vec4(ir->type); i++) {
output_reg[ir->data.location + i] = *reg;
output_reg[ir->data.location + i].reg_offset = i;
output_reg_annotation[ir->data.location + i] = ir->name;
@@ -1092,14 +1098,14 @@ vec4_visitor::visit(ir_variable *ir)
* Some uniforms, such as samplers and atomic counters, have no actual
* storage, so we should ignore them.
*/
- if (ir->is_in_buffer_block() || type_size(ir->type) == 0)
+ if (ir->is_in_buffer_block() || type_size_vec4(ir->type) == 0)
return;
/* Track how big the whole uniform variable is, in case we need to put a
* copy of its data into pull constants for array access.
*/
assert(this->uniforms < uniform_array_size);
- this->uniform_size[this->uniforms] = type_size(ir->type);
+ this->uniform_size[this->uniforms] = type_size_vec4(ir->type);
if (!strncmp(ir->name, "gl_", 3)) {
setup_builtin_uniform_values(ir);
@@ -2052,7 +2058,7 @@ vec4_visitor::compute_array_stride(ir_dereference_array *ir)
/* Under normal circumstances array elements are stored consecutively, so
* the stride is equal to the size of the array element.
*/
- return type_size(ir->type);
+ return type_size_vec4(ir->type);
}
@@ -2121,7 +2127,7 @@ vec4_visitor::visit(ir_dereference_record *ir)
for (i = 0; i < struct_type->length; i++) {
if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
break;
- offset += type_size(struct_type->fields.structure[i].type);
+ offset += type_size_vec4(struct_type->fields.structure[i].type);
}
/* If the type is smaller than a vec4, replicate the last channel out. */
@@ -2330,7 +2336,7 @@ vec4_visitor::visit(ir_assignment *ir)
emit_bool_to_cond_code(ir->condition, &predicate);
}
- for (i = 0; i < type_size(ir->lhs->type); i++) {
+ for (i = 0; i < type_size_vec4(ir->lhs->type); i++) {
vec4_instruction *inst = emit(MOV(dst, src));
inst->predicate = predicate;
diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
index 72e37d4..fd7e56e 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -56,7 +56,7 @@ brw_upload_pull_constants(struct brw_context *brw,
const struct brw_stage_prog_data *prog_data,
bool dword_pitch)
{
- int i;
+ unsigned i;
uint32_t surf_index = prog_data->binding_table.pull_constants_start;
if (!prog_data->nr_pull_params) {
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index 0cd4390..cd0b56b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -47,7 +47,7 @@ brw_color_buffer_write_enabled(struct brw_context *brw)
struct gl_context *ctx = &brw->ctx;
/* BRW_NEW_FRAGMENT_PROGRAM */
const struct gl_fragment_program *fp = brw->fragment_program;
- int i;
+ unsigned i;
/* _NEW_BUFFERS */
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index f13a97c..8213f4e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -898,7 +898,7 @@ brw_upload_ubo_surfaces(struct brw_context *brw,
uint32_t *surf_offsets =
&stage_state->surf_offset[prog_data->binding_table.ubo_start];
- for (int i = 0; i < shader->NumUniformBlocks; i++) {
+ for (unsigned i = 0; i < shader->NumUniformBlocks; i++) {
struct gl_uniform_buffer_binding *binding;
struct intel_buffer_object *intel_bo;
@@ -958,7 +958,7 @@ brw_upload_abo_surfaces(struct brw_context *brw,
uint32_t *surf_offsets =
&stage_state->surf_offset[prog_data->binding_table.abo_start];
- for (int i = 0; i < prog->NumAtomicBuffers; i++) {
+ for (unsigned i = 0; i < prog->NumAtomicBuffers; i++) {
struct gl_atomic_buffer_binding *binding =
&ctx->AtomicBufferBindings[prog->AtomicBuffers[i].Binding];
struct intel_buffer_object *intel_bo =
@@ -1117,7 +1117,7 @@ update_texture_image_param(struct brw_context *brw,
minify(mt->logical_depth0, u->Level) :
mt->logical_depth0);
- intel_miptree_get_image_offset(mt, u->Level, u->Layer,
+ intel_miptree_get_image_offset(mt, u->Level, u->_Layer,
&param->offset[0],
&param->offset[1]);
@@ -1202,7 +1202,7 @@ update_image_surface(struct brw_context *brw,
access != GL_READ_ONLY);
} else {
- const unsigned min_layer = obj->MinLayer + u->Layer;
+ const unsigned min_layer = obj->MinLayer + u->_Layer;
const unsigned min_level = obj->MinLevel + u->Level;
const unsigned num_layers = (!u->Layered ? 1 :
obj->Target == GL_TEXTURE_CUBE_MAP ? 6 :
diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c
index 35d10ef..6653a6d 100644
--- a/src/mesa/drivers/dri/i965/gen6_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c
@@ -68,7 +68,7 @@ gen6_upload_push_constants(struct brw_context *brw,
_mesa_load_state_parameters(ctx, prog->Parameters);
gl_constant_value *param;
- int i;
+ unsigned i;
param = brw_state_batch(brw, type,
prog_data->nr_params * sizeof(gl_constant_value),
diff --git a/src/mesa/drivers/dri/i965/gen7_sol_state.c b/src/mesa/drivers/dri/i965/gen7_sol_state.c
index 41573a8..8cd2fc4 100644
--- a/src/mesa/drivers/dri/i965/gen7_sol_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_sol_state.c
@@ -116,7 +116,7 @@ gen7_upload_3dstate_so_decl_list(struct brw_context *brw,
/* Construct the list of SO_DECLs to be emitted. The formatting of the
* command is feels strange -- each dword pair contains a SO_DECL per stream.
*/
- for (int i = 0; i < linked_xfb_info->NumOutputs; i++) {
+ for (unsigned i = 0; i < linked_xfb_info->NumOutputs; i++) {
int buffer = linked_xfb_info->Outputs[i].OutputBuffer;
uint16_t decl = 0;
int varying = linked_xfb_info->Outputs[i].OutputRegister;
diff --git a/src/mesa/drivers/dri/i965/gen8_draw_upload.c b/src/mesa/drivers/dri/i965/gen8_draw_upload.c
index 1af90ec..1b48643 100644
--- a/src/mesa/drivers/dri/i965/gen8_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/gen8_draw_upload.c
@@ -40,16 +40,25 @@ gen8_emit_vertices(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
uint32_t mocs_wb = brw->gen >= 9 ? SKL_MOCS_WB : BDW_MOCS_WB;
+ bool uses_edge_flag;
brw_prepare_vertices(brw);
brw_prepare_shader_draw_parameters(brw);
+ uses_edge_flag = (ctx->Polygon.FrontMode != GL_FILL ||
+ ctx->Polygon.BackMode != GL_FILL);
+
if (brw->vs.prog_data->uses_vertexid || brw->vs.prog_data->uses_instanceid) {
unsigned vue = brw->vb.nr_enabled;
- WARN_ONCE(brw->vs.prog_data->inputs_read & VERT_BIT_EDGEFLAG,
- "Using VID/IID with edgeflags, need to reorder the "
- "vertex attributes");
+ /* The element for the edge flags must always be last, so we have to
+ * insert the SGVS before it in that case.
+ */
+ if (uses_edge_flag) {
+ assert(vue > 0);
+ vue--;
+ }
+
WARN_ONCE(vue >= 33,
"Trying to insert VID/IID past 33rd vertex element, "
"need to reorder the vertex attrbutes.");
@@ -74,7 +83,7 @@ gen8_emit_vertices(struct brw_context *brw)
BEGIN_BATCH(3);
OUT_BATCH(_3DSTATE_VF_INSTANCING << 16 | (3 - 2));
- OUT_BATCH(brw->vb.nr_buffers | GEN8_VF_INSTANCING_ENABLE);
+ OUT_BATCH(vue | GEN8_VF_INSTANCING_ENABLE);
OUT_BATCH(0);
ADVANCE_BATCH();
} else {
@@ -138,7 +147,18 @@ gen8_emit_vertices(struct brw_context *brw)
ADVANCE_BATCH();
}
- unsigned nr_elements = brw->vb.nr_enabled + brw->vs.prog_data->uses_vertexid;
+ /* Normally we don't need an element for the SGVS attribute because the
+ * 3DSTATE_VF_SGVS instruction lets you store the generated attribute in an
+ * element that is past the list in 3DSTATE_VERTEX_ELEMENTS. However if the
+ * vertex ID is used then it needs an element for the base vertex buffer.
+ * Additionally if there is an edge flag element then the SGVS can't be
+ * inserted past that so we need a dummy element to ensure that the edge
+ * flag is the last one.
+ */
+ bool needs_sgvs_element = (brw->vs.prog_data->uses_vertexid ||
+ (brw->vs.prog_data->uses_instanceid &&
+ uses_edge_flag));
+ unsigned nr_elements = brw->vb.nr_enabled + needs_sgvs_element;
/* The hardware allows one more VERTEX_ELEMENTS than VERTEX_BUFFERS,
* presumably for VertexID/InstanceID.
@@ -192,6 +212,24 @@ gen8_emit_vertices(struct brw_context *brw)
(comp3 << BRW_VE1_COMPONENT_3_SHIFT));
}
+ if (needs_sgvs_element) {
+ if (brw->vs.prog_data->uses_vertexid) {
+ OUT_BATCH(GEN6_VE0_VALID |
+ brw->vb.nr_buffers << GEN6_VE0_INDEX_SHIFT |
+ BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT);
+ OUT_BATCH((BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT));
+ } else {
+ OUT_BATCH(GEN6_VE0_VALID);
+ OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT));
+ }
+ }
+
if (gen6_edgeflag_input) {
uint32_t format =
brw_get_vertex_surface_type(brw, gen6_edgeflag_input->glarray);
@@ -206,25 +244,26 @@ gen8_emit_vertices(struct brw_context *brw)
(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT));
}
-
- if (brw->vs.prog_data->uses_vertexid) {
- OUT_BATCH(GEN6_VE0_VALID |
- brw->vb.nr_buffers << GEN6_VE0_INDEX_SHIFT |
- BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT);
- OUT_BATCH((BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT));
- }
ADVANCE_BATCH();
- for (unsigned i = 0; i < brw->vb.nr_enabled; i++) {
+ for (unsigned i = 0, j = 0; i < brw->vb.nr_enabled; i++) {
const struct brw_vertex_element *input = brw->vb.enabled[i];
const struct brw_vertex_buffer *buffer = &brw->vb.buffers[input->buffer];
+ unsigned element_index;
+
+ /* The edge flag element is reordered to be the last one in the code
+ * above so we need to compensate for that in the element indices used
+ * below.
+ */
+ if (input == gen6_edgeflag_input)
+ element_index = nr_elements - 1;
+ else
+ element_index = j++;
BEGIN_BATCH(3);
OUT_BATCH(_3DSTATE_VF_INSTANCING << 16 | (3 - 2));
- OUT_BATCH(i | (buffer->step_rate ? GEN8_VF_INSTANCING_ENABLE : 0));
+ OUT_BATCH(element_index |
+ (buffer->step_rate ? GEN8_VF_INSTANCING_ENABLE : 0));
OUT_BATCH(buffer->step_rate);
ADVANCE_BATCH();
}
diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c
index 3bc28a1..1a246d3 100644
--- a/src/mesa/drivers/dri/i965/intel_extensions.c
+++ b/src/mesa/drivers/dri/i965/intel_extensions.c
@@ -331,6 +331,7 @@ intelInitExtensions(struct gl_context *ctx)
ctx->Extensions.ARB_gpu_shader5 = true;
ctx->Extensions.ARB_shader_atomic_counters = true;
ctx->Extensions.ARB_shader_image_load_store = true;
+ ctx->Extensions.ARB_shader_image_size = true;
ctx->Extensions.ARB_texture_compression_bptc = true;
ctx->Extensions.ARB_texture_view = true;
diff --git a/src/mesa/drivers/dri/i965/intel_fbo.c b/src/mesa/drivers/dri/i965/intel_fbo.c
index 72648b0..64d57e8 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.c
+++ b/src/mesa/drivers/dri/i965/intel_fbo.c
@@ -662,7 +662,7 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
struct intel_renderbuffer *stencilRb =
intel_get_renderbuffer(fb, BUFFER_STENCIL);
struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL;
- int i;
+ unsigned i;
DBG("%s() on fb %p (%s)\n", __func__,
fb, (fb == ctx->DrawBuffer ? "drawbuffer" :
@@ -797,7 +797,7 @@ intel_blit_framebuffer_with_blitter(struct gl_context *ctx,
intel_prepare_render(brw);
if (mask & GL_COLOR_BUFFER_BIT) {
- GLint i;
+ unsigned i;
struct gl_renderbuffer *src_rb = readFb->_ColorReadBuffer;
struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb);
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index a164c69..5911b44 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -122,7 +122,7 @@ aub_dump_bmp(struct gl_context *ctx)
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
- for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
+ for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) {
struct intel_renderbuffer *irb =
intel_renderbuffer(fb->_ColorDrawBuffers[i]);
@@ -1219,7 +1219,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
__DRIconfig **configs = NULL;
/* Generate singlesample configs without accumulation buffer. */
- for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+ for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
__DRIconfig **new_configs;
int num_depth_stencil_bits = 2;
@@ -1256,7 +1256,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
/* Generate the minimum possible set of configs that include an
* accumulation buffer.
*/
- for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+ for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
__DRIconfig **new_configs;
if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
@@ -1288,7 +1288,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
* supported. Singlebuffer configs are not supported because no one wants
* them.
*/
- for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+ for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
if (devinfo->gen < 6)
break;
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 1cdea93..e17b41c 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -866,8 +866,8 @@ _mesa_init_buffer_objects( struct gl_context *ctx )
_mesa_reference_buffer_object(ctx,
&ctx->AtomicBufferBindings[i].BufferObject,
ctx->Shared->NullBufferObj);
- ctx->AtomicBufferBindings[i].Offset = -1;
- ctx->AtomicBufferBindings[i].Size = -1;
+ ctx->AtomicBufferBindings[i].Offset = 0;
+ ctx->AtomicBufferBindings[i].Size = 0;
}
}
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 888c461..be542dd 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -402,10 +402,6 @@ one_time_init( struct gl_context *ctx )
PACKAGE_VERSION, __DATE__, __TIME__);
}
#endif
-
-#ifdef DEBUG
- _mesa_test_formats();
-#endif
}
/* per-API one-time init */
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index d934d19..4a3c231 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -50,6 +50,7 @@ enum {
ES1 = 1 << API_OPENGLES,
ES2 = 1 << API_OPENGLES2,
ES3 = 1 << (API_OPENGL_LAST + 1),
+ ES31 = 1 << (API_OPENGL_LAST + 2),
};
/**
@@ -152,6 +153,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_shader_atomic_counters", o(ARB_shader_atomic_counters), GL, 2011 },
{ "GL_ARB_shader_bit_encoding", o(ARB_shader_bit_encoding), GL, 2010 },
{ "GL_ARB_shader_image_load_store", o(ARB_shader_image_load_store), GL, 2011 },
+ { "GL_ARB_shader_image_size", o(ARB_shader_image_size), GL, 2012 },
{ "GL_ARB_shader_objects", o(dummy_true), GL, 2002 },
{ "GL_ARB_shader_precision", o(ARB_shader_precision), GL, 2010 },
{ "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 },
@@ -773,6 +775,8 @@ _mesa_make_extension_string(struct gl_context *ctx)
unsigned api_set = (1 << ctx->API);
if (_mesa_is_gles3(ctx))
api_set |= ES3;
+ if (_mesa_is_gles31(ctx))
+ api_set |= ES31;
/* Check if the MESA_EXTENSION_MAX_YEAR env var is set */
{
@@ -854,6 +858,8 @@ _mesa_get_extension_count(struct gl_context *ctx)
unsigned api_set = (1 << ctx->API);
if (_mesa_is_gles3(ctx))
api_set |= ES3;
+ if (_mesa_is_gles31(ctx))
+ api_set |= ES31;
/* only count once */
if (ctx->Extensions.Count != 0)
@@ -880,6 +886,8 @@ _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
unsigned api_set = (1 << ctx->API);
if (_mesa_is_gles3(ctx))
api_set |= ES3;
+ if (_mesa_is_gles31(ctx))
+ api_set |= ES31;
base = (GLboolean*) &ctx->Extensions;
n = 0;
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 8418340..07db195 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -2033,6 +2033,16 @@ renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
*/
sample_count_error = _mesa_check_sample_count(ctx, GL_RENDERBUFFER,
internalFormat, samples);
+
+ /* Section 2.5 (GL Errors) of OpenGL 3.0 specification, page 16:
+ *
+ * "If a negative number is provided where an argument of type sizei or
+ * sizeiptr is specified, the error INVALID VALUE is generated."
+ */
+ if (samples < 0) {
+ sample_count_error = GL_INVALID_VALUE;
+ }
+
if (sample_count_error != GL_NO_ERROR) {
_mesa_error(ctx, sample_count_error, "%s(samples)", func);
return;
diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py
index 3bae57e..839d407 100644
--- a/src/mesa/main/format_info.py
+++ b/src/mesa/main/format_info.py
@@ -98,14 +98,6 @@ def get_gl_data_type(fmat):
else:
assert False
-def get_mesa_layout(fmat):
- if fmat.layout == 'array':
- return 'MESA_FORMAT_LAYOUT_ARRAY'
- elif fmat.layout == 'packed':
- return 'MESA_FORMAT_LAYOUT_PACKED'
- else:
- return 'MESA_FORMAT_LAYOUT_OTHER'
-
def get_channel_bits(fmat, chan_name):
if fmat.is_compressed():
# These values are pretty-much bogus, but OpenGL requires that we
@@ -179,7 +171,7 @@ for fmat in formats:
print ' {'
print ' {0},'.format(fmat.name)
print ' "{0}",'.format(fmat.name)
- print ' {0},'.format(get_mesa_layout(fmat))
+ print ' {0},'.format('MESA_FORMAT_LAYOUT_' + fmat.layout.upper())
print ' {0},'.format(get_gl_base_format(fmat))
print ' {0},'.format(get_gl_data_type(fmat))
@@ -188,6 +180,8 @@ for fmat in formats:
bits = [ get_channel_bits(fmat, name) for name in ['l', 'i', 'z', 's']]
print ' {0},'.format(', '.join(map(str, bits)))
+ print ' {0:d},'.format(fmat.colorspace == 'srgb')
+
print ' {0}, {1}, {2},'.format(fmat.block_width, fmat.block_height,
int(fmat.block_size() / 8))
diff --git a/src/mesa/main/format_utils.c b/src/mesa/main/format_utils.c
index 810bb16..5fdabd5 100644
--- a/src/mesa/main/format_utils.c
+++ b/src/mesa/main/format_utils.c
@@ -602,7 +602,7 @@ _mesa_format_to_array(mesa_format format, GLenum *type, int *num_components,
*normalized = !_mesa_is_format_integer(format);
- _mesa_format_to_type_and_comps(format, type, &format_components);
+ _mesa_uncompressed_format_to_type_and_comps(format, type, &format_components);
switch (_mesa_get_format_layout(format)) {
case MESA_FORMAT_LAYOUT_ARRAY:
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index d7b2bae..8dd07d8 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -65,6 +65,8 @@ struct gl_format_info
GLubyte DepthBits;
GLubyte StencilBits;
+ bool IsSRGBFormat;
+
/**
* To describe compressed formats. If not compressed, Width=Height=1.
*/
@@ -81,6 +83,7 @@ static const struct gl_format_info *
_mesa_get_format_info(mesa_format format)
{
const struct gl_format_info *info = &format_info[format];
+ STATIC_ASSERT(ARRAY_SIZE(format_info) == MESA_FORMAT_COUNT);
assert(info->Name == format);
return info;
}
@@ -188,6 +191,12 @@ _mesa_get_format_max_bits(mesa_format format)
* The return value will be one of:
* MESA_FORMAT_LAYOUT_ARRAY
* MESA_FORMAT_LAYOUT_PACKED
+ * MESA_FORMAT_LAYOUT_S3TC
+ * MESA_FORMAT_LAYOUT_RGTC
+ * MESA_FORMAT_LAYOUT_FXT1
+ * MESA_FORMAT_LAYOUT_ETC1
+ * MESA_FORMAT_LAYOUT_ETC2
+ * MESA_FORMAT_LAYOUT_BPTC
* MESA_FORMAT_LAYOUT_OTHER
*/
extern enum mesa_format_layout
@@ -562,30 +571,8 @@ _mesa_is_format_color_format(mesa_format format)
GLenum
_mesa_get_format_color_encoding(mesa_format format)
{
- /* XXX this info should be encoded in gl_format_info */
- switch (format) {
- case MESA_FORMAT_BGR_SRGB8:
- case MESA_FORMAT_A8B8G8R8_SRGB:
- case MESA_FORMAT_B8G8R8A8_SRGB:
- case MESA_FORMAT_A8R8G8B8_SRGB:
- case MESA_FORMAT_R8G8B8A8_SRGB:
- case MESA_FORMAT_L_SRGB8:
- case MESA_FORMAT_L8A8_SRGB:
- case MESA_FORMAT_A8L8_SRGB:
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
- case MESA_FORMAT_R8G8B8X8_SRGB:
- case MESA_FORMAT_ETC2_SRGB8:
- case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
- case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
- case MESA_FORMAT_B8G8R8X8_SRGB:
- case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
- return GL_SRGB;
- default:
- return GL_LINEAR;
- }
+ const struct gl_format_info *info = _mesa_get_format_info(format);
+ return info->IsSRGBFormat ? GL_SRGB : GL_LINEAR;
}
@@ -878,124 +865,13 @@ _mesa_format_row_stride(mesa_format format, GLsizei width)
}
-/**
- * Debug/test: check that all formats are handled in the
- * _mesa_format_to_type_and_comps() function. When new pixel formats
- * are added to Mesa, that function needs to be updated.
- * This is a no-op after the first call.
- */
-static void
-check_format_to_type_and_comps(void)
-{
- mesa_format f;
-
- for (f = MESA_FORMAT_NONE + 1; f < MESA_FORMAT_COUNT; f++) {
- GLenum datatype = 0;
- GLuint comps = 0;
- /* This function will emit a problem/warning if the format is
- * not handled.
- */
- _mesa_format_to_type_and_comps(f, &datatype, &comps);
- }
-}
/**
- * Do sanity checking of the format info table.
+ * Return datatype and number of components per texel for the given
+ * uncompressed mesa_format. Only used for mipmap generation code.
*/
void
-_mesa_test_formats(void)
-{
- GLuint i;
-
- STATIC_ASSERT(ARRAY_SIZE(format_info) == MESA_FORMAT_COUNT);
-
- for (i = 0; i < MESA_FORMAT_COUNT; i++) {
- const struct gl_format_info *info = _mesa_get_format_info(i);
- assert(info);
-
- assert(info->Name == i);
-
- if (info->Name == MESA_FORMAT_NONE)
- continue;
-
- if (info->BlockWidth == 1 && info->BlockHeight == 1) {
- if (info->RedBits > 0) {
- GLuint t = info->RedBits + info->GreenBits
- + info->BlueBits + info->AlphaBits;
- assert(t / 8 <= info->BytesPerBlock);
- (void) t;
- }
- }
-
- assert(info->DataType == GL_UNSIGNED_NORMALIZED ||
- info->DataType == GL_SIGNED_NORMALIZED ||
- info->DataType == GL_UNSIGNED_INT ||
- info->DataType == GL_INT ||
- info->DataType == GL_FLOAT ||
- /* Z32_FLOAT_X24S8 has DataType of GL_NONE */
- info->DataType == GL_NONE);
-
- if (info->BaseFormat == GL_RGB) {
- assert(info->RedBits > 0);
- assert(info->GreenBits > 0);
- assert(info->BlueBits > 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_RGBA) {
- assert(info->RedBits > 0);
- assert(info->GreenBits > 0);
- assert(info->BlueBits > 0);
- assert(info->AlphaBits > 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_RG) {
- assert(info->RedBits > 0);
- assert(info->GreenBits > 0);
- assert(info->BlueBits == 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_RED) {
- assert(info->RedBits > 0);
- assert(info->GreenBits == 0);
- assert(info->BlueBits == 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_LUMINANCE) {
- assert(info->RedBits == 0);
- assert(info->GreenBits == 0);
- assert(info->BlueBits == 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits > 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_INTENSITY) {
- assert(info->RedBits == 0);
- assert(info->GreenBits == 0);
- assert(info->BlueBits == 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits > 0);
- }
- }
-
- check_format_to_type_and_comps();
-}
-
-
-
-/**
- * Return datatype and number of components per texel for the given mesa_format.
- * Only used for mipmap generation code.
- */
-void
-_mesa_format_to_type_and_comps(mesa_format format,
+_mesa_uncompressed_format_to_type_and_comps(mesa_format format,
GLenum *datatype, GLuint *comps)
{
switch (format) {
@@ -1229,44 +1105,6 @@ _mesa_format_to_type_and_comps(mesa_format format,
*comps = 2;
return;
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
- case MESA_FORMAT_R_RGTC1_UNORM:
- case MESA_FORMAT_R_RGTC1_SNORM:
- case MESA_FORMAT_RG_RGTC2_UNORM:
- case MESA_FORMAT_RG_RGTC2_SNORM:
- case MESA_FORMAT_L_LATC1_UNORM:
- case MESA_FORMAT_L_LATC1_SNORM:
- case MESA_FORMAT_LA_LATC2_UNORM:
- case MESA_FORMAT_LA_LATC2_SNORM:
- case MESA_FORMAT_ETC1_RGB8:
- case MESA_FORMAT_ETC2_RGB8:
- case MESA_FORMAT_ETC2_SRGB8:
- case MESA_FORMAT_ETC2_RGBA8_EAC:
- case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
- case MESA_FORMAT_ETC2_R11_EAC:
- case MESA_FORMAT_ETC2_RG11_EAC:
- case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
- case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
- case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
- case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
- case MESA_FORMAT_BPTC_RGBA_UNORM:
- case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
- case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT:
- case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT:
- /* XXX generate error instead? */
- *datatype = GL_UNSIGNED_BYTE;
- *comps = 0;
- return;
-
case MESA_FORMAT_RGBA_FLOAT32:
*datatype = GL_FLOAT;
*comps = 4;
@@ -1564,14 +1402,12 @@ _mesa_format_to_type_and_comps(mesa_format format,
case MESA_FORMAT_COUNT:
assert(0);
return;
-
- case MESA_FORMAT_NONE:
- /* For debug builds, warn if any formats are not handled */
-#ifdef DEBUG
default:
-#endif
- _mesa_problem(NULL, "bad format %s in _mesa_format_to_type_and_comps",
+ /* Warn if any formats are not handled */
+ _mesa_problem(NULL, "bad format %s in _mesa_uncompressed_format_to_type_and_comps",
_mesa_get_format_name(format));
+ assert(format == MESA_FORMAT_NONE ||
+ _mesa_is_format_compressed(format));
*datatype = 0;
*comps = 1;
}
@@ -1584,20 +1420,26 @@ _mesa_format_to_type_and_comps(mesa_format format,
* \param format the user-specified image format
* \param type the user-specified image datatype
* \param swapBytes typically the current pixel pack/unpack byteswap state
+ * \param[out] error GL_NO_ERROR if format is an expected input.
+ * GL_INVALID_ENUM if format is an unexpected input.
* \return GL_TRUE if the formats match, GL_FALSE otherwise.
*/
GLboolean
_mesa_format_matches_format_and_type(mesa_format mesa_format,
GLenum format, GLenum type,
- GLboolean swapBytes)
+ GLboolean swapBytes, GLenum *error)
{
const GLboolean littleEndian = _mesa_little_endian();
+ if (error)
+ *error = GL_NO_ERROR;
/* Note: When reading a GL format/type combination, the format lists channel
* assignments from most significant channel in the type to least
* significant. A type with _REV indicates that the assignments are
* swapped, so they are listed from least significant to most significant.
*
+ * Compressed formats will fall through and return GL_FALSE.
+ *
* For sanity, please keep this switch statement ordered the same as the
* enums in formats.h.
*/
@@ -1858,26 +1700,6 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format,
case MESA_FORMAT_S_UINT8:
return format == GL_STENCIL_INDEX && type == GL_UNSIGNED_BYTE;
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
- return GL_FALSE;
-
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- return GL_FALSE;
-
- case MESA_FORMAT_BPTC_RGBA_UNORM:
- case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
- case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT:
- case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT:
- return GL_FALSE;
-
case MESA_FORMAT_RGBA_FLOAT32:
return format == GL_RGBA && type == GL_FLOAT && !swapBytes;
case MESA_FORMAT_RGBA_FLOAT16:
@@ -2074,31 +1896,6 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format,
return format == GL_RGBA && type == GL_UNSIGNED_SHORT &&
!swapBytes;
- case MESA_FORMAT_R_RGTC1_UNORM:
- case MESA_FORMAT_R_RGTC1_SNORM:
- case MESA_FORMAT_RG_RGTC2_UNORM:
- case MESA_FORMAT_RG_RGTC2_SNORM:
- return GL_FALSE;
-
- case MESA_FORMAT_L_LATC1_UNORM:
- case MESA_FORMAT_L_LATC1_SNORM:
- case MESA_FORMAT_LA_LATC2_UNORM:
- case MESA_FORMAT_LA_LATC2_SNORM:
- return GL_FALSE;
-
- case MESA_FORMAT_ETC1_RGB8:
- case MESA_FORMAT_ETC2_RGB8:
- case MESA_FORMAT_ETC2_SRGB8:
- case MESA_FORMAT_ETC2_RGBA8_EAC:
- case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
- case MESA_FORMAT_ETC2_R11_EAC:
- case MESA_FORMAT_ETC2_RG11_EAC:
- case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
- case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
- case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
- case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
- return GL_FALSE;
-
case MESA_FORMAT_A_SNORM8:
return format == GL_ALPHA && type == GL_BYTE;
case MESA_FORMAT_L_SNORM8:
@@ -2181,8 +1978,11 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format,
case MESA_FORMAT_B8G8R8X8_SRGB:
case MESA_FORMAT_X8R8G8B8_SRGB:
return GL_FALSE;
+ default:
+ assert(_mesa_is_format_compressed(format));
+ if (error)
+ *error = GL_INVALID_ENUM;
}
-
return GL_FALSE;
}
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index d938e6a..4936fa0 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -64,6 +64,12 @@ extern "C" {
enum mesa_format_layout {
MESA_FORMAT_LAYOUT_ARRAY,
MESA_FORMAT_LAYOUT_PACKED,
+ MESA_FORMAT_LAYOUT_S3TC,
+ MESA_FORMAT_LAYOUT_RGTC,
+ MESA_FORMAT_LAYOUT_FXT1,
+ MESA_FORMAT_LAYOUT_ETC1,
+ MESA_FORMAT_LAYOUT_ETC2,
+ MESA_FORMAT_LAYOUT_BPTC,
MESA_FORMAT_LAYOUT_OTHER,
};
@@ -659,7 +665,7 @@ extern GLint
_mesa_format_row_stride(mesa_format format, GLsizei width);
extern void
-_mesa_format_to_type_and_comps(mesa_format format,
+_mesa_uncompressed_format_to_type_and_comps(mesa_format format,
GLenum *datatype, GLuint *comps);
extern void
@@ -680,7 +686,7 @@ _mesa_format_has_color_component(mesa_format format, int component);
GLboolean
_mesa_format_matches_format_and_type(mesa_format mesa_format,
GLenum format, GLenum type,
- GLboolean swapBytes);
+ GLboolean swapBytes, GLenum *error);
#ifdef __cplusplus
}
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 7dc92f1..517c391 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -806,7 +806,7 @@ descriptor=[
[ "MAX_VERTEX_ATTRIB_BINDINGS", "CONTEXT_ENUM(Const.MaxVertexAttribBindings), NO_EXTRA" ],
# GL_ARB_shader_image_load_store
- [ "MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS", "CONTEXT_INT(Const.MaxCombinedImageUnitsAndFragmentOutputs), extra_ARB_shader_image_load_store" ],
+ [ "MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS", "CONTEXT_INT(Const.MaxCombinedShaderOutputResources), extra_ARB_shader_image_load_store" ],
[ "MAX_IMAGE_SAMPLES", "CONTEXT_INT(Const.MaxImageSamples), extra_ARB_shader_image_load_store" ],
[ "MAX_GEOMETRY_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxImageUniforms), extra_ARB_shader_image_load_store_and_geometry_shader"],
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 1e22f93..2bf5902 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -1886,7 +1886,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
GLenum datatype;
GLuint comps;
- _mesa_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps);
+ _mesa_uncompressed_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps);
for (level = texObj->BaseLevel; level < maxLevel; level++) {
/* generate image[level+1] from image[level] */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 83f3717..4883cbc 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -94,7 +94,10 @@ struct vbo_context;
#define PRIM_OUTSIDE_BEGIN_END (PRIM_MAX + 1)
#define PRIM_UNKNOWN (PRIM_MAX + 2)
-
+#define VARYING_SLOT_MAX (VARYING_SLOT_VAR0 + MAX_VARYING)
+#define VARYING_SLOT_PATCH0 (VARYING_SLOT_MAX)
+#define VARYING_SLOT_TESS_MAX (VARYING_SLOT_PATCH0 + MAX_VARYING)
+#define FRAG_RESULT_MAX (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
/**
* Determine if the given gl_varying_slot appears in the fragment shader.
@@ -117,7 +120,6 @@ _mesa_varying_slot_in_fs(gl_varying_slot slot)
}
}
-
/**
* Indexes for all renderbuffers
*/
@@ -3571,7 +3573,7 @@ struct gl_constants
/* GL_ARB_shader_image_load_store */
GLuint MaxImageUnits;
- GLuint MaxCombinedImageUnitsAndFragmentOutputs;
+ GLuint MaxCombinedShaderOutputResources;
GLuint MaxImageSamples;
GLuint MaxCombinedImageUniforms;
@@ -3656,6 +3658,7 @@ struct gl_extensions
GLboolean ARB_shader_atomic_counters;
GLboolean ARB_shader_bit_encoding;
GLboolean ARB_shader_image_load_store;
+ GLboolean ARB_shader_image_size;
GLboolean ARB_shader_precision;
GLboolean ARB_shader_stencil_export;
GLboolean ARB_shader_storage_buffer_object;
@@ -4073,10 +4076,16 @@ struct gl_image_unit
GLboolean _Valid;
/**
+ * Layer of the texture object bound to this unit as specified by the
+ * application.
+ */
+ GLuint Layer;
+
+ /**
* Layer of the texture object bound to this unit, or zero if the
* whole level is bound.
*/
- GLuint Layer;
+ GLuint _Layer;
/**
* Access allowed to this texture image. Either \c GL_READ_ONLY,
diff --git a/src/mesa/main/multisample.c b/src/mesa/main/multisample.c
index 09e6154..e7783ea 100644
--- a/src/mesa/main/multisample.c
+++ b/src/mesa/main/multisample.c
@@ -150,15 +150,6 @@ GLenum
_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
GLenum internalFormat, GLsizei samples)
{
- /* Section 2.5 (GL Errors) of OpenGL 3.0 specification, page 16:
- *
- * "If a negative number is provided where an argument of type sizei or
- * sizeiptr is specified, the error INVALID VALUE is generated."
- */
- if (samples < 0) {
- return GL_INVALID_VALUE;
- }
-
/* Section 4.4 (Framebuffer objects), page 198 of the OpenGL ES 3.0.0
* specification says:
*
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index d826ecf..1277944 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -201,7 +201,7 @@ readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum ty
/* The Mesa format must match the input format and type. */
if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
- packing->SwapBytes)) {
+ packing->SwapBytes, NULL)) {
return GL_FALSE;
}
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index f9a7d13..b227c17 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1995,55 +1995,6 @@ _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
}
-static GLuint
-_mesa_create_shader_program(struct gl_context* ctx, GLboolean separate,
- GLenum type, GLsizei count,
- const GLchar* const *strings)
-{
- const GLuint shader = create_shader(ctx, type);
- GLuint program = 0;
-
- if (shader) {
- _mesa_ShaderSource(shader, count, strings, NULL);
-
- compile_shader(ctx, shader);
-
- program = create_shader_program(ctx);
- if (program) {
- struct gl_shader_program *shProg;
- struct gl_shader *sh;
- GLint compiled = GL_FALSE;
-
- shProg = _mesa_lookup_shader_program(ctx, program);
- sh = _mesa_lookup_shader(ctx, shader);
-
- shProg->SeparateShader = separate;
-
- get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
- if (compiled) {
- attach_shader(ctx, program, shader);
- link_program(ctx, program);
- detach_shader(ctx, program, shader);
-
-#if 0
- /* Possibly... */
- if (active-user-defined-varyings-in-linked-program) {
- append-error-to-info-log;
- shProg->LinkStatus = GL_FALSE;
- }
-#endif
- }
- if (sh->InfoLog)
- ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
- }
-
- delete_shader(ctx, shader);
- }
-
- return program;
-}
-
-
/**
* Copy program-specific data generated by linking from the gl_shader_program
* object to a specific gl_program object.
@@ -2111,7 +2062,56 @@ _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
{
GET_CURRENT_CONTEXT(ctx);
- return _mesa_create_shader_program(ctx, GL_TRUE, type, count, strings);
+ const GLuint shader = create_shader(ctx, type);
+ GLuint program = 0;
+
+ /*
+ * According to OpenGL 4.5 and OpenGL ES 3.1 standards, section 7.3:
+ * GL_INVALID_VALUE should be generated if count < 0
+ */
+ if (count < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCreateShaderProgram (count < 0)");
+ return program;
+ }
+
+ if (shader) {
+ _mesa_ShaderSource(shader, count, strings, NULL);
+
+ compile_shader(ctx, shader);
+
+ program = create_shader_program(ctx);
+ if (program) {
+ struct gl_shader_program *shProg;
+ struct gl_shader *sh;
+ GLint compiled = GL_FALSE;
+
+ shProg = _mesa_lookup_shader_program(ctx, program);
+ sh = _mesa_lookup_shader(ctx, shader);
+
+ shProg->SeparateShader = GL_TRUE;
+
+ get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
+ if (compiled) {
+ attach_shader(ctx, program, shader);
+ link_program(ctx, program);
+ detach_shader(ctx, program, shader);
+
+#if 0
+ /* Possibly... */
+ if (active-user-defined-varyings-in-linked-program) {
+ append-error-to-info-log;
+ shProg->LinkStatus = GL_FALSE;
+ }
+#endif
+ }
+ if (sh->InfoLog)
+ ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
+ }
+
+ delete_shader(ctx, shader);
+ }
+
+ return program;
}
diff --git a/src/mesa/main/shaderimage.c b/src/mesa/main/shaderimage.c
index a348cdb..c4bba84 100644
--- a/src/mesa/main/shaderimage.c
+++ b/src/mesa/main/shaderimage.c
@@ -331,17 +331,88 @@ get_image_format_class(mesa_format format)
}
}
+/**
+ * Return whether an image format should be supported based on the current API
+ * version of the context.
+ */
+static bool
+is_image_format_supported(const struct gl_context *ctx, GLenum format)
+{
+ switch (format) {
+ /* Formats supported on both desktop and ES GL, c.f. table 8.27 of the
+ * OpenGL ES 3.1 specification.
+ */
+ case GL_RGBA32F:
+ case GL_RGBA16F:
+ case GL_R32F:
+ case GL_RGBA32UI:
+ case GL_RGBA16UI:
+ case GL_RGBA8UI:
+ case GL_R32UI:
+ case GL_RGBA32I:
+ case GL_RGBA16I:
+ case GL_RGBA8I:
+ case GL_R32I:
+ case GL_RGBA8:
+ case GL_RGBA8_SNORM:
+ return true;
+
+ /* Formats supported on unextended desktop GL and the original
+ * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2
+ * specification.
+ */
+ case GL_RG32F:
+ case GL_RG16F:
+ case GL_R11F_G11F_B10F:
+ case GL_R16F:
+ case GL_RGB10_A2UI:
+ case GL_RG32UI:
+ case GL_RG16UI:
+ case GL_RG8UI:
+ case GL_R16UI:
+ case GL_R8UI:
+ case GL_RG32I:
+ case GL_RG16I:
+ case GL_RG8I:
+ case GL_R16I:
+ case GL_R8I:
+ case GL_RGBA16:
+ case GL_RGB10_A2:
+ case GL_RG16:
+ case GL_RG8:
+ case GL_R16:
+ case GL_R8:
+ case GL_RGBA16_SNORM:
+ case GL_RG16_SNORM:
+ case GL_RG8_SNORM:
+ case GL_R16_SNORM:
+ case GL_R8_SNORM:
+ return _mesa_is_desktop_gl(ctx);
+
+ default:
+ return false;
+ }
+}
+
+struct gl_image_unit
+_mesa_default_image_unit(struct gl_context *ctx)
+{
+ const GLenum format = _mesa_is_desktop_gl(ctx) ? GL_R8 : GL_R32UI;
+ const struct gl_image_unit u = {
+ .Access = GL_READ_ONLY,
+ .Format = format,
+ ._ActualFormat = _mesa_get_shader_image_format(format)
+ };
+ return u;
+}
+
void
_mesa_init_image_units(struct gl_context *ctx)
{
unsigned i;
- for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i) {
- struct gl_image_unit *u = &ctx->ImageUnits[i];
- u->Access = GL_READ_ONLY;
- u->Format = GL_R8;
- u->_ActualFormat = _mesa_get_shader_image_format(u->Format);
- }
+ for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i)
+ ctx->ImageUnits[i] = _mesa_default_image_unit(ctx);
}
static GLboolean
@@ -362,7 +433,7 @@ validate_image_unit(struct gl_context *ctx, struct gl_image_unit *u)
return GL_FALSE;
if (_mesa_tex_target_is_layered(t->Target) &&
- u->Layer >= _mesa_get_texture_layers(t, u->Level))
+ u->_Layer >= _mesa_get_texture_layers(t, u->Level))
return GL_FALSE;
if (t->Target == GL_TEXTURE_BUFFER) {
@@ -370,7 +441,7 @@ validate_image_unit(struct gl_context *ctx, struct gl_image_unit *u)
} else {
struct gl_texture_image *img = (t->Target == GL_TEXTURE_CUBE_MAP ?
- t->Image[u->Layer][u->Level] :
+ t->Image[u->_Layer][u->Level] :
t->Image[0][u->Level]);
if (!img || img->Border || img->NumSamples > ctx->Const.MaxImageSamples)
@@ -442,7 +513,7 @@ validate_bind_image_texture(struct gl_context *ctx, GLuint unit,
return GL_FALSE;
}
- if (!_mesa_get_shader_image_format(format)) {
+ if (!is_image_format_supported(ctx, format)) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)");
return GL_FALSE;
}
@@ -475,6 +546,18 @@ _mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
return;
}
+ /* From section 8.22 "Texture Image Loads and Stores" of the OpenGL ES
+ * 3.1 spec:
+ *
+ * "An INVALID_OPERATION error is generated if texture is not the name
+ * of an immutable texture object."
+ */
+ if (_mesa_is_gles(ctx) && !t->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindImageTexture(!immutable)");
+ return;
+ }
+
_mesa_reference_texobj(&u->TexObj, t);
} else {
_mesa_reference_texobj(&u->TexObj, NULL);
@@ -488,7 +571,8 @@ _mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
if (u->TexObj && _mesa_tex_target_is_layered(u->TexObj->Target)) {
u->Layered = layered;
- u->Layer = (layered ? 0 : layer);
+ u->Layer = layer;
+ u->_Layer = (u->Layered ? 0 : u->Layer);
} else {
u->Layered = GL_FALSE;
u->Layer = 0;
@@ -599,7 +683,7 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
tex_format = image->InternalFormat;
}
- if (_mesa_get_shader_image_format(tex_format) == MESA_FORMAT_NONE) {
+ if (!is_image_format_supported(ctx, tex_format)) {
/* The ARB_multi_bind spec says:
*
* "An INVALID_OPERATION error is generated if the internal
@@ -619,7 +703,7 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
_mesa_reference_texobj(&u->TexObj, texObj);
u->Level = 0;
u->Layered = _mesa_tex_target_is_layered(texObj->Target);
- u->Layer = 0;
+ u->_Layer = u->Layer = 0;
u->Access = GL_READ_WRITE;
u->Format = tex_format;
u->_ActualFormat = _mesa_get_shader_image_format(tex_format);
@@ -629,7 +713,7 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
_mesa_reference_texobj(&u->TexObj, NULL);
u->Level = 0;
u->Layered = GL_FALSE;
- u->Layer = 0;
+ u->_Layer = u->Layer = 0;
u->Access = GL_READ_ONLY;
u->Format = GL_R8;
u->_ActualFormat = MESA_FORMAT_R_UNORM8;
@@ -653,3 +737,43 @@ _mesa_MemoryBarrier(GLbitfield barriers)
if (ctx->Driver.MemoryBarrier)
ctx->Driver.MemoryBarrier(ctx, barriers);
}
+
+void GLAPIENTRY
+_mesa_MemoryBarrierByRegion(GLbitfield barriers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ GLbitfield all_allowed_bits = GL_ATOMIC_COUNTER_BARRIER_BIT |
+ GL_FRAMEBUFFER_BARRIER_BIT |
+ GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
+ GL_SHADER_STORAGE_BARRIER_BIT |
+ GL_TEXTURE_FETCH_BARRIER_BIT |
+ GL_UNIFORM_BARRIER_BIT;
+
+ if (ctx->Driver.MemoryBarrier) {
+ /* From section 7.11.2 of the OpenGL ES 3.1 specification:
+ *
+ * "When barriers is ALL_BARRIER_BITS, shader memory accesses will be
+ * synchronized relative to all these barrier bits, but not to other
+ * barrier bits specific to MemoryBarrier."
+ *
+ * That is, if barriers is the special value GL_ALL_BARRIER_BITS, then all
+ * barriers allowed by glMemoryBarrierByRegion should be activated."
+ */
+ if (barriers == GL_ALL_BARRIER_BITS)
+ return ctx->Driver.MemoryBarrier(ctx, all_allowed_bits);
+
+ /* From section 7.11.2 of the OpenGL ES 3.1 specification:
+ *
+ * "An INVALID_VALUE error is generated if barriers is not the special
+ * value ALL_BARRIER_BITS, and has any bits set other than those
+ * described above."
+ */
+ if ((barriers & ~all_allowed_bits) != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glMemoryBarrierByRegion(unsupported barrier bit");
+ }
+
+ ctx->Driver.MemoryBarrier(ctx, barriers);
+ }
+}
diff --git a/src/mesa/main/shaderimage.h b/src/mesa/main/shaderimage.h
index 33d8a1e..bbe088a 100644
--- a/src/mesa/main/shaderimage.h
+++ b/src/mesa/main/shaderimage.h
@@ -43,6 +43,12 @@ mesa_format
_mesa_get_shader_image_format(GLenum format);
/**
+ * Get a single image unit struct with the default state.
+ */
+struct gl_image_unit
+_mesa_default_image_unit(struct gl_context *ctx);
+
+/**
* Initialize a context's shader image units to the default state.
*/
void
@@ -68,6 +74,9 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures);
void GLAPIENTRY
_mesa_MemoryBarrier(GLbitfield barriers);
+void GLAPIENTRY
+_mesa_MemoryBarrierByRegion(GLbitfield barriers);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/mesa/main/tests/Makefile.am b/src/mesa/main/tests/Makefile.am
index 251474d..9467f3b 100644
--- a/src/mesa/main/tests/Makefile.am
+++ b/src/mesa/main/tests/Makefile.am
@@ -27,6 +27,7 @@ AM_CPPFLAGS += -DHAVE_SHARED_GLAPI
main_test_SOURCES += \
dispatch_sanity.cpp \
+ mesa_formats.cpp \
program_state_string.cpp
main_test_LDADD += \
diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp
index af89d2c..59107eb 100644
--- a/src/mesa/main/tests/dispatch_sanity.cpp
+++ b/src/mesa/main/tests/dispatch_sanity.cpp
@@ -851,6 +851,9 @@ const struct function common_desktop_functions_possible[] = {
// { "glTextureStorage2DMultisampleEXT", 43, -1 }, // XXX: Add to xml
// { "glTextureStorage3DMultisampleEXT", 43, -1 }, // XXX: Add to xml
+/* GL 4.5 */
+ { "glMemoryBarrierByRegion", 45, -1 },
+
/* GL_ARB_internalformat_query */
{ "glGetInternalformativ", 30, -1 },
@@ -1739,6 +1742,9 @@ const struct function gl_core_functions_possible[] = {
// { "glTextureStorage2DMultisampleEXT", 43, -1 }, // XXX: Add to xml
// { "glTextureStorage3DMultisampleEXT", 43, -1 }, // XXX: Add to xml
+/* GL 4.5 */
+ { "glMemoryBarrierByRegion", 45, -1 },
+
/* GL_ARB_direct_state_access */
{ "glCreateTransformFeedbacks", 45, -1 },
{ "glTransformFeedbackBufferBase", 45, -1 },
@@ -2461,8 +2467,7 @@ const struct function gles31_functions_possible[] = {
{ "glGetBooleani_v", 31, -1 },
{ "glMemoryBarrier", 31, -1 },
- // FINISHME: This function has not been implemented yet.
- // { "glMemoryBarrierByRegion", 31, -1 },
+ { "glMemoryBarrierByRegion", 31, -1 },
{ "glTexStorage2DMultisample", 31, -1 },
{ "glGetMultisamplefv", 31, -1 },
diff --git a/src/mesa/main/tests/mesa_formats.cpp b/src/mesa/main/tests/mesa_formats.cpp
new file mode 100644
index 0000000..5356cd9
--- /dev/null
+++ b/src/mesa/main/tests/mesa_formats.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \name mesa_formats.cpp
+ *
+ * Verify that all mesa formats are handled in certain functions and that
+ * the format info table is sane.
+ *
+ */
+
+#include <gtest/gtest.h>
+
+#include "main/formats.h"
+#include "main/glformats.h"
+
+/**
+ * Debug/test: check that all uncompressed formats are handled in the
+ * _mesa_uncompressed_format_to_type_and_comps() function. When new pixel
+ * formats are added to Mesa, that function needs to be updated.
+ */
+TEST(MesaFormatsTest, FormatTypeAndComps)
+{
+ for (int fi = MESA_FORMAT_NONE + 1; fi < MESA_FORMAT_COUNT; ++fi) {
+ mesa_format f = (mesa_format) fi;
+ SCOPED_TRACE(_mesa_get_format_name(f));
+
+ /* This function will emit a problem/warning if the format is
+ * not handled.
+ */
+ if (!_mesa_is_format_compressed(f)) {
+ GLenum datatype = 0;
+ GLenum error = 0;
+ GLuint comps = 0;
+
+ /* If the datatype is zero, the format was not handled */
+ _mesa_uncompressed_format_to_type_and_comps(f, &datatype, &comps);
+ EXPECT_NE(datatype, (GLenum)0);
+
+ /* If the error isn't NO_ERROR, the format was not handled.
+ * Use an arbitrary GLenum format. */
+ _mesa_format_matches_format_and_type(f, GL_RG, datatype,
+ GL_FALSE, &error);
+ EXPECT_EQ((GLenum)GL_NO_ERROR, error);
+ }
+
+ }
+}
+
+/**
+ * Do sanity checking of the format info table.
+ */
+TEST(MesaFormatsTest, FormatSanity)
+{
+ for (int fi = 0; fi < MESA_FORMAT_COUNT; ++fi) {
+ mesa_format f = (mesa_format) fi;
+ SCOPED_TRACE(_mesa_get_format_name(f));
+ GLenum datatype = _mesa_get_format_datatype(f);
+ GLint r = _mesa_get_format_bits(f, GL_RED_BITS);
+ GLint g = _mesa_get_format_bits(f, GL_GREEN_BITS);
+ GLint b = _mesa_get_format_bits(f, GL_BLUE_BITS);
+ GLint a = _mesa_get_format_bits(f, GL_ALPHA_BITS);
+ GLint l = _mesa_get_format_bits(f, GL_TEXTURE_LUMINANCE_SIZE);
+ GLint i = _mesa_get_format_bits(f, GL_TEXTURE_INTENSITY_SIZE);
+
+ /* Note: Z32_FLOAT_X24S8 has datatype of GL_NONE */
+ EXPECT_TRUE(datatype == GL_NONE ||
+ datatype == GL_UNSIGNED_NORMALIZED ||
+ datatype == GL_SIGNED_NORMALIZED ||
+ datatype == GL_UNSIGNED_INT ||
+ datatype == GL_INT ||
+ datatype == GL_FLOAT);
+
+ if (r > 0 && !_mesa_is_format_compressed(f)) {
+ GLint bytes = _mesa_get_format_bytes(f);
+ EXPECT_LE((r+g+b+a) / 8, bytes);
+ }
+
+ /* Determines if the base format has a channel [rgba] or property [li].
+ * > indicates existance
+ * == indicates non-existance
+ */
+ #define HAS_PROP(rop,gop,bop,aop,lop,iop) \
+ do { \
+ EXPECT_TRUE(r rop 0); \
+ EXPECT_TRUE(g gop 0); \
+ EXPECT_TRUE(b bop 0); \
+ EXPECT_TRUE(a aop 0); \
+ EXPECT_TRUE(l lop 0); \
+ EXPECT_TRUE(i iop 0); \
+ } while(0)
+
+ switch (_mesa_get_format_base_format(f)) {
+ case GL_RGBA:
+ HAS_PROP(>,>,>,>,==,==);
+ break;
+ case GL_RGB:
+ HAS_PROP(>,>,>,==,==,==);
+ break;
+ case GL_RG:
+ HAS_PROP(>,>,==,==,==,==);
+ break;
+ case GL_RED:
+ HAS_PROP(>,==,==,==,==,==);
+ break;
+ case GL_LUMINANCE:
+ HAS_PROP(==,==,==,==,>,==);
+ break;
+ case GL_INTENSITY:
+ HAS_PROP(==,==,==,==,==,>);
+ break;
+ default:
+ break;
+ }
+
+ #undef HAS_PROP
+
+ }
+}
diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c
index 0fd1a36..edfb036 100644
--- a/src/mesa/main/texcompress.c
+++ b/src/mesa/main/texcompress.c
@@ -586,34 +586,16 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img,
compressed_fetch_func
_mesa_get_compressed_fetch_func(mesa_format format)
{
- switch (format) {
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
+ switch (_mesa_get_format_layout(format)) {
+ case MESA_FORMAT_LAYOUT_S3TC:
return _mesa_get_dxt_fetch_func(format);
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
+ case MESA_FORMAT_LAYOUT_FXT1:
return _mesa_get_fxt_fetch_func(format);
- case MESA_FORMAT_R_RGTC1_UNORM:
- case MESA_FORMAT_L_LATC1_UNORM:
- case MESA_FORMAT_R_RGTC1_SNORM:
- case MESA_FORMAT_L_LATC1_SNORM:
- case MESA_FORMAT_RG_RGTC2_UNORM:
- case MESA_FORMAT_LA_LATC2_UNORM:
- case MESA_FORMAT_RG_RGTC2_SNORM:
- case MESA_FORMAT_LA_LATC2_SNORM:
+ case MESA_FORMAT_LAYOUT_RGTC:
return _mesa_get_compressed_rgtc_func(format);
- case MESA_FORMAT_ETC1_RGB8:
+ case MESA_FORMAT_LAYOUT_ETC1:
return _mesa_get_etc_fetch_func(format);
- case MESA_FORMAT_BPTC_RGBA_UNORM:
- case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
- case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT:
- case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT:
+ case MESA_FORMAT_LAYOUT_BPTC:
return _mesa_get_bptc_fetch_func(format);
default:
return NULL;
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index c0ccce3..3c1e166 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -651,7 +651,7 @@ get_tex_memcpy(struct gl_context *ctx,
texBaseFormat == texImage->_BaseFormat) {
memCopy = _mesa_format_matches_format_and_type(texImage->TexFormat,
format, type,
- ctx->Pack.SwapBytes);
+ ctx->Pack.SwapBytes, NULL);
}
if (depth > 1) {
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 3a556a6..274ecad 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1785,18 +1785,36 @@ compressedteximage_only_format(const struct gl_context *ctx, GLenum format)
}
+/* Writes to an GL error pointer if non-null and returns whether or not the
+ * error is GL_NO_ERROR */
+static bool
+write_error(GLenum *err_ptr, GLenum error)
+{
+ if (err_ptr)
+ *err_ptr = error;
+
+ return error == GL_NO_ERROR;
+}
+
/**
* Helper function to determine whether a target and specific compression
- * format are supported.
+ * format are supported. The error parameter returns GL_NO_ERROR if the
+ * target can be compressed. Otherwise it returns either GL_INVALID_OPERATION
+ * or GL_INVALID_ENUM, whichever is more appropriate.
*/
GLboolean
_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
- GLenum intFormat)
+ GLenum intFormat, GLenum *error)
{
+ GLboolean target_can_be_compresed = GL_FALSE;
+ mesa_format format = _mesa_glenum_to_compressed_format(intFormat);
+ enum mesa_format_layout layout = _mesa_get_format_layout(format);
+
switch (target) {
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
- return GL_TRUE; /* true for any compressed format so far */
+ target_can_be_compresed = GL_TRUE; /* true for any compressed format so far */
+ break;
case GL_PROXY_TEXTURE_CUBE_MAP:
case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
@@ -1805,26 +1823,46 @@ _mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- return ctx->Extensions.ARB_texture_cube_map;
+ target_can_be_compresed = ctx->Extensions.ARB_texture_cube_map;
+ break;
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
case GL_TEXTURE_2D_ARRAY_EXT:
- return ctx->Extensions.EXT_texture_array;
+ target_can_be_compresed = ctx->Extensions.EXT_texture_array;
+ break;
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
- return ctx->Extensions.ARB_texture_cube_map_array;
+ /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
+ *
+ * "The ETC2/EAC texture compression algorithm supports only
+ * two-dimensional images. If internalformat is an ETC2/EAC format,
+ * glCompressedTexImage3D will generate an INVALID_OPERATION error if
+ * target is not TEXTURE_2D_ARRAY."
+ *
+ * This should also be applicable for glTexStorage3D(). Other available
+ * targets for these functions are: TEXTURE_3D and TEXTURE_CUBE_MAP_ARRAY.
+ */
+ if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx))
+ return write_error(error, GL_INVALID_OPERATION);
+
+ target_can_be_compresed = ctx->Extensions.ARB_texture_cube_map_array;
+ break;
case GL_TEXTURE_3D:
- switch (intFormat) {
- case GL_COMPRESSED_RGBA_BPTC_UNORM:
- case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
- case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
- case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
- return ctx->Extensions.ARB_texture_compression_bptc;
- default:
- return GL_FALSE;
+
+ /* See ETC2/EAC comment in switch case GL_TEXTURE_CUBE_MAP_ARRAY. */
+ if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx))
+ return write_error(error, GL_INVALID_OPERATION);
+
+ if (layout == MESA_FORMAT_LAYOUT_BPTC) {
+ target_can_be_compresed = ctx->Extensions.ARB_texture_compression_bptc;
+ break;
}
+
+ break;
default:
- return GL_FALSE;
+ break;
}
+ return write_error(error,
+ target_can_be_compresed ? GL_NO_ERROR : GL_INVALID_ENUM);
}
@@ -2284,8 +2322,9 @@ texture_error_check( struct gl_context *ctx,
/* additional checks for compressed textures */
if (_mesa_is_compressed_format(ctx, internalFormat)) {
- if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
+ GLenum err;
+ if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) {
+ _mesa_error(ctx, err,
"glTexImage%dD(target can't be compressed)", dimensions);
return GL_TRUE;
}
@@ -2340,16 +2379,8 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
GLenum error = GL_NO_ERROR;
char *reason = ""; /* no error */
- if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) {
+ if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &error)) {
reason = "target";
- /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
- *
- * "The ETC2/EAC texture compression algorithm supports only
- * two-dimensional images. If internalformat is an ETC2/EAC format,
- * CompressedTexImage3D will generate an INVALID_OPERATION error if
- * target is not TEXTURE_2D_ARRAY."
- */
- error = _mesa_is_desktop_gl(ctx) ? GL_INVALID_ENUM : GL_INVALID_OPERATION;
goto error;
}
@@ -2813,9 +2844,10 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
}
if (_mesa_is_compressed_format(ctx, internalFormat)) {
- if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTexImage%dD(target)", dimensions);
+ GLenum err;
+ if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) {
+ _mesa_error(ctx, err,
+ "glCopyTexImage%dD(target can't be compressed)", dimensions);
return GL_TRUE;
}
if (compressedteximage_only_format(ctx, internalFormat)) {
@@ -5569,10 +5601,13 @@ static GLboolean
is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat)
{
/* Everything that is allowed for renderbuffers,
- * except for a base format of GL_STENCIL_INDEX.
+ * except for a base format of GL_STENCIL_INDEX, unless supported.
*/
GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat);
- return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX;
+ if (ctx->Extensions.ARB_texture_stencil8)
+ return baseFormat != 0;
+ else
+ return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX;
}
@@ -5596,13 +5631,13 @@ check_multisample_target(GLuint dims, GLenum target, bool dsa)
static void
-_mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
- struct gl_texture_object *texObj,
- GLenum target, GLsizei samples,
- GLint internalformat, GLsizei width,
- GLsizei height, GLsizei depth,
- GLboolean fixedsamplelocations,
- GLboolean immutable, const char *func)
+texture_image_multisample(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_object *texObj,
+ GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedsamplelocations,
+ GLboolean immutable, const char *func)
{
struct gl_texture_image *texImage;
GLboolean sizeOK, dimensionsOK, samplesOK;
@@ -5616,6 +5651,11 @@ _mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
return;
}
+ if (samples < 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples < 1)", func);
+ return;
+ }
+
if (!check_multisample_target(dims, target, dsa)) {
if (dsa) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", func);
@@ -5763,10 +5803,10 @@ _mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 2, texObj, target, samples,
- internalformat, width, height, 1,
- fixedsamplelocations, GL_FALSE,
- "glTexImage2DMultisample");
+ texture_image_multisample(ctx, 2, texObj, target, samples,
+ internalformat, width, height, 1,
+ fixedsamplelocations, GL_FALSE,
+ "glTexImage2DMultisample");
}
@@ -5783,12 +5823,26 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 3, texObj, target, samples,
- internalformat, width, height, depth,
- fixedsamplelocations, GL_FALSE,
- "glTexImage3DMultisample");
+ texture_image_multisample(ctx, 3, texObj, target, samples,
+ internalformat, width, height, depth,
+ fixedsamplelocations, GL_FALSE,
+ "glTexImage3DMultisample");
}
+static bool
+valid_texstorage_ms_parameters(GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei samples, unsigned dims)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexStorage%uDMultisample(width=%d,height=%d,depth=%d)",
+ dims, width, height, depth);
+ return false;
+ }
+ return true;
+}
void GLAPIENTRY
_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,
@@ -5802,10 +5856,13 @@ _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 2, texObj, target, samples,
- internalformat, width, height, 1,
- fixedsamplelocations, GL_TRUE,
- "glTexStorage2DMultisample");
+ if (!valid_texstorage_ms_parameters(width, height, 1, samples, 2))
+ return;
+
+ texture_image_multisample(ctx, 2, texObj, target, samples,
+ internalformat, width, height, 1,
+ fixedsamplelocations, GL_TRUE,
+ "glTexStorage2DMultisample");
}
void GLAPIENTRY
@@ -5821,10 +5878,13 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 3, texObj, target, samples,
- internalformat, width, height, depth,
- fixedsamplelocations, GL_TRUE,
- "glTexStorage3DMultisample");
+ if (!valid_texstorage_ms_parameters(width, height, depth, samples, 3))
+ return;
+
+ texture_image_multisample(ctx, 3, texObj, target, samples,
+ internalformat, width, height, depth,
+ fixedsamplelocations, GL_TRUE,
+ "glTexStorage3DMultisample");
}
void GLAPIENTRY
@@ -5841,10 +5901,13 @@ _mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 2, texObj, texObj->Target, samples,
- internalformat, width, height, 1,
- fixedsamplelocations, GL_TRUE,
- "glTextureStorage2DMultisample");
+ if (!valid_texstorage_ms_parameters(width, height, 1, samples, 2))
+ return;
+
+ texture_image_multisample(ctx, 2, texObj, texObj->Target, samples,
+ internalformat, width, height, 1,
+ fixedsamplelocations, GL_TRUE,
+ "glTextureStorage2DMultisample");
}
void GLAPIENTRY
@@ -5862,8 +5925,11 @@ _mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 3, texObj, texObj->Target, samples,
- internalformat, width, height, depth,
- fixedsamplelocations, GL_TRUE,
- "glTextureStorage3DMultisample");
+ if (!valid_texstorage_ms_parameters(width, height, depth, samples, 3))
+ return;
+
+ texture_image_multisample(ctx, 3, texObj, texObj->Target, samples,
+ internalformat, width, height, depth,
+ fixedsamplelocations, GL_TRUE,
+ "glTextureStorage3DMultisample");
}
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index bf729da..a4736b5 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -133,7 +133,7 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
extern GLboolean
_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
- GLenum intFormat);
+ GLenum intFormat, GLenum *error);
extern GLuint
_mesa_tex_target_to_face(GLenum target);
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index cd7cfd6..c5d83e1 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -37,6 +37,7 @@
#include "hash.h"
#include "imports.h"
#include "macros.h"
+#include "shaderimage.h"
#include "teximage.h"
#include "texobj.h"
#include "texstate.h"
@@ -1411,8 +1412,10 @@ unbind_texobj_from_image_units(struct gl_context *ctx,
for (i = 0; i < ctx->Const.MaxImageUnits; i++) {
struct gl_image_unit *unit = &ctx->ImageUnits[i];
- if (texObj == unit->TexObj)
+ if (texObj == unit->TexObj) {
_mesa_reference_texobj(&unit->TexObj, NULL);
+ *unit = _mesa_default_image_unit(ctx);
+ }
}
}
@@ -1742,10 +1745,10 @@ _mesa_BindTexture( GLenum target, GLuint texName )
* texture object will be decremented. It'll be deleted if the
* count hits zero.
*/
-void
-_mesa_bind_texture_unit(struct gl_context *ctx,
- GLuint unit,
- struct gl_texture_object *texObj)
+static void
+bind_texture_unit(struct gl_context *ctx,
+ GLuint unit,
+ struct gl_texture_object *texObj)
{
struct gl_texture_unit *texUnit;
@@ -1834,7 +1837,7 @@ _mesa_BindTextureUnit(GLuint unit, GLuint texture)
}
assert(valid_texture_object(texObj));
- _mesa_bind_texture_unit(ctx, unit, texObj);
+ bind_texture_unit(ctx, unit, texObj);
}
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index ec5ccb2..690878c 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -209,10 +209,6 @@ extern void
_mesa_delete_nameless_texture(struct gl_context *ctx,
struct gl_texture_object *texObj);
-extern void
-_mesa_bind_texture_unit(struct gl_context *ctx,
- GLuint unit,
- struct gl_texture_object *texObj);
/*@}*/
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index c0611c3..16739f1 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -1562,6 +1562,19 @@ invalid_pname:
_mesa_enum_to_string(pname));
}
+static bool
+valid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target,
+ bool dsa)
+{
+ const char *suffix = dsa ? "ture" : "";
+ if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTex%sLevelParameter[if]v(target=%s)", suffix,
+ _mesa_enum_to_string(target));
+ return false;
+ }
+ return true;
+}
/**
* This isn't exposed to the rest of the driver because it is a part of the
@@ -1585,13 +1598,6 @@ get_tex_level_parameteriv(struct gl_context *ctx,
return;
}
- if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTex%sLevelParameter[if]v(target=%s)", suffix,
- _mesa_enum_to_string(target));
- return;
- }
-
maxLevels = _mesa_max_texture_levels(ctx, target);
assert(maxLevels != 0);
@@ -1619,6 +1625,9 @@ _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
GLint iparam;
GET_CURRENT_CONTEXT(ctx);
+ if (!valid_tex_level_parameteriv_target(ctx, target, false))
+ return;
+
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
@@ -1636,6 +1645,9 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
+ if (!valid_tex_level_parameteriv_target(ctx, target, false))
+ return;
+
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
@@ -1657,6 +1669,9 @@ _mesa_GetTextureLevelParameterfv(GLuint texture, GLint level,
if (!texObj)
return;
+ if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
+ return;
+
get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
pname, &iparam, true);
@@ -1675,6 +1690,9 @@ _mesa_GetTextureLevelParameteriv(GLuint texture, GLint level,
if (!texObj)
return;
+ if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
+ return;
+
get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
pname, params, true);
}
@@ -1890,6 +1908,12 @@ get_tex_parameterfv(struct gl_context *ctx,
*params = (GLfloat) obj->Sampler.sRGBDecode;
break;
+ case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_pname;
+ *params = (GLfloat) obj->ImageFormatCompatibilityType;
+ break;
+
default:
goto invalid_pname;
}
diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c
index 4a2cc60..c53bb29 100644
--- a/src/mesa/main/texstorage.c
+++ b/src/mesa/main/texstorage.c
@@ -189,6 +189,20 @@ clear_texture_fields(struct gl_context *ctx,
}
+/**
+ * Update/re-validate framebuffer object.
+ */
+static void
+update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ const unsigned numFaces = _mesa_num_tex_faces(texObj->Target);
+ for (int level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) {
+ for (unsigned face = 0; face < numFaces; face++)
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
+ }
+}
+
+
GLboolean
_mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat)
{
@@ -287,29 +301,21 @@ tex_storage_error_check(struct gl_context *ctx,
* order to allow meta functions to use legacy formats. */
/* size check */
- if (width < 1 || height < 1 || depth < 1) {
+ if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTex%sStorage%uD(width, height or depth < 1)",
suffix, dims);
return GL_TRUE;
}
- /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
- *
- * "The ETC2/EAC texture compression algorithm supports only
- * two-dimensional images. If internalformat is an ETC2/EAC format,
- * CompressedTexImage3D will generate an INVALID_OPERATION error if
- * target is not TEXTURE_2D_ARRAY."
- *
- * This should also be applicable for glTexStorage3D().
- */
- if (_mesa_is_compressed_format(ctx, internalformat)
- && !_mesa_target_can_be_compressed(ctx, target, internalformat)) {
- _mesa_error(ctx, _mesa_is_desktop_gl(ctx)?
- GL_INVALID_ENUM : GL_INVALID_OPERATION,
+ if (_mesa_is_compressed_format(ctx, internalformat)) {
+ GLenum err;
+ if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) {
+ _mesa_error(ctx, err,
"glTex%sStorage%dD(internalformat = %s)", suffix, dims,
_mesa_enum_to_string(internalformat));
- return GL_TRUE;
+ return GL_TRUE;
+ }
}
/* levels check */
@@ -446,6 +452,7 @@ _mesa_texture_storage(struct gl_context *ctx, GLuint dims,
_mesa_set_texture_view_state(ctx, texObj, target, levels);
+ update_fbo_texture(ctx, texObj);
}
}
diff --git a/src/mesa/main/texstorage.h b/src/mesa/main/texstorage.h
index 6f5495f..033ecb7 100644
--- a/src/mesa/main/texstorage.h
+++ b/src/mesa/main/texstorage.h
@@ -38,6 +38,27 @@ _mesa_texture_storage(struct gl_context *ctx, GLuint dims,
GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, bool dsa);
+/**
+ * Texture width, height and depth check shared with the
+ * multisample variants of TexStorage functions.
+ *
+ * From OpenGL 4.5 Core spec, page 260 (section 8.19)
+ *
+ * "An INVALID_VALUE error is generated if width, height, depth
+ * or levels are less than 1, for commands with the corresponding
+ * parameters."
+ *
+ * (referring to TextureStorage* commands, these also match values
+ * specified for OpenGL ES 3.1.)
+ */
+static inline bool
+_mesa_valid_tex_storage_dim(GLsizei width, GLsizei height, GLsizei depth)
+{
+ if (width < 1 || height < 1 || depth < 1)
+ return false;
+ return true;
+}
+
/*@}*/
/**
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 37c0569..fc83310 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -863,7 +863,7 @@ _mesa_texstore_can_use_memcpy(struct gl_context *ctx,
/* The Mesa format must match the input format and type. */
if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
+ srcPacking->SwapBytes, NULL)) {
return GL_FALSE;
}
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 036530e..1026618 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -319,24 +319,31 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
return;
}
+ if ((uni->type->base_type == GLSL_TYPE_DOUBLE &&
+ returnType != GLSL_TYPE_DOUBLE) ||
+ (uni->type->base_type != GLSL_TYPE_DOUBLE &&
+ returnType == GLSL_TYPE_DOUBLE)) {
+ _mesa_error( ctx, GL_INVALID_OPERATION,
+ "glGetnUniform*vARB(incompatible uniform types)");
+ return;
+ }
{
unsigned elements = (uni->type->is_sampler())
? 1 : uni->type->components();
+ const int dmul = uni->type->base_type == GLSL_TYPE_DOUBLE ? 2 : 1;
/* Calculate the source base address *BEFORE* modifying elements to
* account for the size of the user's buffer.
*/
const union gl_constant_value *const src =
- &uni->storage[offset * elements];
+ &uni->storage[offset * elements * dmul];
assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
- returnType == GLSL_TYPE_UINT);
- /* The three (currently) supported types all have the same size,
- * which is of course the same as their union. That'll change
- * with glGetUniformdv()...
- */
- unsigned bytes = sizeof(src[0]) * elements;
+ returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE);
+
+ /* doubles have a different size than the other 3 types */
+ unsigned bytes = sizeof(src[0]) * elements * dmul;
if (bufSize < 0 || bytes > (unsigned) bufSize) {
_mesa_error( ctx, GL_INVALID_OPERATION,
"glGetnUniform*vARB(out of bounds: bufSize is %d,"
@@ -677,9 +684,11 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
match = (basicType != GLSL_TYPE_DOUBLE);
break;
case GLSL_TYPE_SAMPLER:
- case GLSL_TYPE_IMAGE:
match = (basicType == GLSL_TYPE_INT);
break;
+ case GLSL_TYPE_IMAGE:
+ match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
+ break;
default:
match = (basicType == uni->type->base_type);
break;
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index ff1df72..10819e2 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -888,16 +888,7 @@ _mesa_GetnUniformdvARB(GLuint program, GLint location,
{
GET_CURRENT_CONTEXT(ctx);
- (void) program;
- (void) location;
- (void) bufSize;
- (void) params;
-
- /*
_mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params);
- */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
- "(GL_ARB_gpu_shader_fp64 not implemented)");
}
void GLAPIENTRY
diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c
index d54f934..d96b7bc 100644
--- a/src/mesa/program/prog_to_nir.c
+++ b/src/mesa/program/prog_to_nir.c
@@ -33,6 +33,7 @@
#include "prog_instruction.h"
#include "prog_parameter.h"
#include "prog_print.h"
+#include "program.h"
/**
* \file prog_to_nir.c
@@ -142,7 +143,7 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
load->variables[0] = nir_deref_var_create(load, c->input_vars[prog_src->Index]);
nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
- nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
+ nir_builder_instr_insert(b, &load->instr);
src.src = nir_src_for_ssa(&load->dest.ssa);
break;
@@ -166,6 +167,8 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
}
/* FALLTHROUGH */
case PROGRAM_STATE_VAR: {
+ assert(c->parameters != NULL);
+
nir_intrinsic_instr *load =
nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
@@ -200,7 +203,7 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
deref_arr->base_offset = prog_src->Index;
}
- nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
+ nir_builder_instr_insert(b, &load->instr);
src.src = nir_src_for_ssa(&load->dest.ssa);
break;
@@ -250,7 +253,7 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
mov->dest.write_mask = 0x1;
mov->src[0] = src;
mov->src[0].swizzle[0] = swizzle;
- nir_instr_insert_after_cf_list(b->cf_node_list, &mov->instr);
+ nir_builder_instr_insert(b, &mov->instr);
chans[i] = &mov->dest.dest.ssa;
}
@@ -278,7 +281,7 @@ ptn_alu(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
instr->src[i].src = nir_src_for_ssa(src[i]);
instr->dest = dest;
- nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
+ nir_builder_instr_insert(b, &instr->instr);
}
static void
@@ -297,7 +300,7 @@ ptn_move_dest_masked(nir_builder *b, nir_alu_dest dest,
mov->src[0].src = nir_src_for_ssa(def);
for (unsigned i = def->num_components; i < 4; i++)
mov->src[0].swizzle[i] = def->num_components - 1;
- nir_instr_insert_after_cf_list(b->cf_node_list, &mov->instr);
+ nir_builder_instr_insert(b, &mov->instr);
}
static void
@@ -558,7 +561,7 @@ ptn_kil(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
nir_intrinsic_instr *discard =
nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
discard->src[0] = nir_src_for_ssa(cmp);
- nir_instr_insert_after_cf_list(b->cf_node_list, &discard->instr);
+ nir_builder_instr_insert(b, &discard->instr);
}
static void
@@ -685,7 +688,7 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
assert(src_number == num_srcs);
nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
- nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
+ nir_builder_instr_insert(b, &instr->instr);
/* Resolve the writemask on the texture op. */
ptn_move_dest(b, dest, &instr->dest.ssa);
@@ -941,7 +944,7 @@ ptn_add_output_stores(struct ptn_compile *c)
} else {
store->src[0].reg.reg = c->output_regs[var->data.location];
}
- nir_instr_insert_after_cf_list(c->build.cf_node_list, &store->instr);
+ nir_builder_instr_insert(b, &store->instr);
}
}
@@ -985,7 +988,7 @@ setup_registers_and_variables(struct ptn_compile *c)
load_x->num_components = 1;
load_x->variables[0] = nir_deref_var_create(load_x, var);
nir_ssa_dest_init(&load_x->instr, &load_x->dest, 1, NULL);
- nir_instr_insert_after_cf_list(b->cf_node_list, &load_x->instr);
+ nir_builder_instr_insert(b, &load_x->instr);
nir_ssa_def *f001 = nir_vec4(b, &load_x->dest.ssa, nir_imm_float(b, 0.0),
nir_imm_float(b, 0.0), nir_imm_float(b, 1.0));
@@ -1001,7 +1004,7 @@ setup_registers_and_variables(struct ptn_compile *c)
store->num_components = 4;
store->variables[0] = nir_deref_var_create(store, fullvar);
store->src[0] = nir_src_for_ssa(f001);
- nir_instr_insert_after_cf_list(b->cf_node_list, &store->instr);
+ nir_builder_instr_insert(b, &store->instr);
/* Insert the real input into the list so the driver has real
* inputs, but set c->input_vars[i] to the temporary so we use
@@ -1079,22 +1082,25 @@ prog_to_nir(const struct gl_program *prog,
{
struct ptn_compile *c;
struct nir_shader *s;
+ gl_shader_stage stage = _mesa_program_enum_to_shader_stage(prog->Target);
c = rzalloc(NULL, struct ptn_compile);
if (!c)
return NULL;
- s = nir_shader_create(NULL, options);
+ s = nir_shader_create(NULL, stage, options);
if (!s)
goto fail;
c->prog = prog;
- c->parameters = rzalloc(s, nir_variable);
- c->parameters->type = glsl_array_type(glsl_vec4_type(),
- prog->Parameters->NumParameters);
- c->parameters->name = "parameters";
- c->parameters->data.read_only = true;
- c->parameters->data.mode = nir_var_uniform;
- exec_list_push_tail(&s->uniforms, &c->parameters->node);
+ if (prog->Parameters->NumParameters > 0) {
+ c->parameters = rzalloc(s, nir_variable);
+ c->parameters->type =
+ glsl_array_type(glsl_vec4_type(), prog->Parameters->NumParameters);
+ c->parameters->name = "parameters";
+ c->parameters->data.read_only = true;
+ c->parameters->data.mode = nir_var_uniform;
+ exec_list_push_tail(&s->uniforms, &c->parameters->node);
+ }
nir_function *func = nir_function_create(s, "main");
nir_function_overload *overload = nir_function_overload_create(func);
@@ -1102,7 +1108,7 @@ prog_to_nir(const struct gl_program *prog,
c->build.shader = s;
c->build.impl = impl;
- c->build.cf_node_list = &impl->body;
+ nir_builder_insert_after_cf_list(&c->build, &impl->body);
setup_registers_and_variables(c);
if (unlikely(c->error))
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index 1396906..4fdef7f 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -192,6 +192,7 @@ st_BlitFramebuffer(struct gl_context *ctx,
blit.filter = pFilter;
blit.render_condition_enable = TRUE;
+ blit.alpha_blend = FALSE;
if (mask & GL_COLOR_BUFFER_BIT) {
struct gl_renderbuffer_attachment *srcAtt =
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 18ea43f..6ff6cf6 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -139,7 +139,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y,
* in which case the memcpy-based fast path will likely be used and
* we don't have to blit. */
if (_mesa_format_matches_format_and_type(rb->Format, format,
- type, pack->SwapBytes)) {
+ type, pack->SwapBytes, NULL)) {
goto fallback;
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 715d69c..93335ae 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -695,7 +695,7 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
* in which case the memcpy-based fast path will likely be used and
* we don't have to blit. */
if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
- type, unpack->SwapBytes)) {
+ type, unpack->SwapBytes, NULL)) {
goto fallback;
}
@@ -963,7 +963,7 @@ st_GetTexSubImage(struct gl_context * ctx,
/* See if the texture format already matches the format and type,
* in which case the memcpy-based fast path will be used. */
if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
- type, ctx->Pack.SwapBytes)) {
+ type, ctx->Pack.SwapBytes, NULL)) {
goto fallback;
}
@@ -1071,6 +1071,8 @@ st_GetTexSubImage(struct gl_context * ctx,
/* From now on, we need the gallium representation of dimensions. */
if (gl_target == GL_TEXTURE_1D_ARRAY) {
+ zoffset = yoffset;
+ yoffset = 0;
depth = height;
height = 1;
}
@@ -1114,7 +1116,7 @@ st_GetTexSubImage(struct gl_context * ctx,
/* copy/pack data into user buffer */
if (_mesa_format_matches_format_and_type(mesa_format, format, type,
- ctx->Pack.SwapBytes)) {
+ ctx->Pack.SwapBytes, NULL)) {
/* memcpy */
const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
GLuint row, slice;
@@ -1871,6 +1873,31 @@ st_TextureView(struct gl_context *ctx,
return GL_TRUE;
}
+/* HACK: this is only enough for the most basic uses of CopyImage. Must fix
+ * before actually exposing the extension.
+ */
+static void
+st_CopyImageSubData(struct gl_context *ctx,
+ struct gl_texture_image *src_image,
+ int src_x, int src_y, int src_z,
+ struct gl_texture_image *dst_image,
+ int dst_x, int dst_y, int dst_z,
+ int src_width, int src_height)
+{
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct st_texture_image *src = st_texture_image(src_image);
+ struct st_texture_image *dst = st_texture_image(dst_image);
+
+ struct pipe_box box;
+
+ u_box_2d_zslice(src_x, src_y, src_z, src_width, src_height, &box);
+ pipe->resource_copy_region(pipe, dst->pt, dst_image->Level,
+ dst_x, dst_y, dst_z,
+ src->pt, src_image->Level,
+ &box);
+}
+
void
st_init_texture_functions(struct dd_function_table *functions)
@@ -1903,4 +1930,6 @@ st_init_texture_functions(struct dd_function_table *functions)
functions->AllocTextureStorage = st_AllocTextureStorage;
functions->TextureView = st_TextureView;
+
+ functions->CopyImageSubData = st_CopyImageSubData;
}
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index db7b5b7..db74184 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1917,7 +1917,7 @@ st_choose_matching_format(struct st_context *st, unsigned bind,
}
if (_mesa_format_matches_format_and_type(mesa_format, format, type,
- swapBytes)) {
+ swapBytes, NULL)) {
enum pipe_format format =
st_mesa_format_to_pipe_format(st, mesa_format);
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 6f00727..cba9881 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2816,7 +2816,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
*/
glsl_to_tgsi_instruction *inst, *new_inst;
inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
- new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2]);
+ new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2], inst->src[3]);
new_inst->saturate = inst->saturate;
inst->dead_mask = inst->dst[0].writemask;
} else {
@@ -4402,12 +4402,12 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
* new visitor. */
foreach_in_list(glsl_to_tgsi_instruction, inst, &original->instructions) {
glsl_to_tgsi_instruction *newinst;
- st_src_reg src_regs[3];
+ st_src_reg src_regs[4];
if (inst->dst[0].file == PROGRAM_OUTPUT)
prog->OutputsWritten |= BITFIELD64_BIT(inst->dst[0].index);
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < 4; i++) {
src_regs[i] = inst->src[i];
if (src_regs[i].file == PROGRAM_INPUT &&
src_regs[i].index == VARYING_SLOT_COL0) {
@@ -4418,7 +4418,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index);
}
- newinst = v->emit_asm(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]);
+ newinst = v->emit_asm(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2], src_regs[3]);
newinst->tex_target = inst->tex_target;
newinst->sampler_array_size = inst->sampler_array_size;
}
@@ -4487,18 +4487,18 @@ get_bitmap_visitor(struct st_fragment_program *fp,
* new visitor. */
foreach_in_list(glsl_to_tgsi_instruction, inst, &original->instructions) {
glsl_to_tgsi_instruction *newinst;
- st_src_reg src_regs[3];
+ st_src_reg src_regs[4];
if (inst->dst[0].file == PROGRAM_OUTPUT)
prog->OutputsWritten |= BITFIELD64_BIT(inst->dst[0].index);
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < 4; i++) {
src_regs[i] = inst->src[i];
if (src_regs[i].file == PROGRAM_INPUT)
prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index);
}
- newinst = v->emit_asm(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]);
+ newinst = v->emit_asm(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2], src_regs[3]);
newinst->tex_target = inst->tex_target;
newinst->sampler_array_size = inst->sampler_array_size;
}
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index dc6827e..5393d50 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -242,7 +242,7 @@ fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y,
}
if (_mesa_format_matches_format_and_type(rb->Format, format, type,
- ctx->Unpack.SwapBytes)) {
+ ctx->Unpack.SwapBytes, NULL)) {
fast_draw_generic_pixels(ctx, rb, x, y, width, height,
format, type, &unpack, pixels);
return GL_TRUE;