diff options
Diffstat (limited to 'src/mesa')
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 ®); @@ -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 *)¶m->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, ¶m->offset[0], ¶m->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; |