diff --git a/docs/GL3.txt b/docs/GL3.txt index 58aace9a13c..f12e0ba8d29 100644 --- a/docs/GL3.txt +++ b/docs/GL3.txt @@ -112,7 +112,7 @@ GL 4.0, GLSL 4.00 --- all DONE: nvc0, r600, radeonsi GL_ARB_gpu_shader_fp64 DONE (llvmpipe, softpipe) GL_ARB_sample_shading DONE (i965, nv50) GL_ARB_shader_subroutine DONE (i965, nv50, llvmpipe, softpipe) - GL_ARB_tessellation_shader DONE (i965/gen8+) + GL_ARB_tessellation_shader DONE (i965) GL_ARB_texture_buffer_object_rgb32 DONE (i965, llvmpipe, softpipe) GL_ARB_texture_cube_map_array DONE (i965, nv50, llvmpipe, softpipe) GL_ARB_texture_gather DONE (i965, nv50, llvmpipe, softpipe) diff --git a/docs/relnotes/11.2.0.html b/docs/relnotes/11.2.0.html index 6f1752cec3f..23bb31c6235 100644 --- a/docs/relnotes/11.2.0.html +++ b/docs/relnotes/11.2.0.html @@ -47,7 +47,7 @@ Note: some of the new features are only available with certain drivers.
  • GL_ARB_base_instance on freedreno/a4xx
  • GL_ARB_compute_shader on i965
  • GL_ARB_copy_image on r600
  • -
  • GL_ARB_tessellation_shader on i965/gen8+ and r600 (evergreen/cayman only)
  • +
  • GL_ARB_tessellation_shader on i965 and r600 (evergreen/cayman only)
  • GL_ARB_texture_buffer_object_rgb32 on freedreno/a4xx
  • GL_ARB_texture_buffer_range on freedreno/a4xx
  • GL_ARB_texture_query_lod on freedreno/a4xx
  • diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c index 01426e86e61..94d992b0031 100644 --- a/src/gallium/auxiliary/nir/tgsi_to_nir.c +++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c @@ -1968,14 +1968,10 @@ tgsi_to_nir(const void *tgsi_tokens, tgsi_scan_shader(tgsi_tokens, &scan); c->scan = &scan; - s = nir_shader_create(NULL, tgsi_processor_to_shader_stage(scan.processor), - options); - - nir_function *func = nir_function_create(s, "main"); - nir_function_impl *impl = nir_function_impl_create(func); - - nir_builder_init(&c->build, impl); - c->build.cursor = nir_after_cf_list(&impl->body); + nir_builder_init_simple_shader(&c->build, NULL, + tgsi_processor_to_shader_stage(scan.processor), + options); + s = c->build.shader; s->num_inputs = scan.file_max[TGSI_FILE_INPUT] + 1; s->num_uniforms = scan.const_file_max[0] + 1; diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h index 5307072fa3a..34668f844e9 100644 --- a/src/gallium/auxiliary/util/u_debug.h +++ b/src/gallium/auxiliary/util/u_debug.h @@ -404,6 +404,19 @@ debug_get_flags_option(const char *name, const struct debug_named_value *flags, uint64_t dfault); +#define DEBUG_GET_ONCE_OPTION(suffix, name, dfault) \ +static const char * \ +debug_get_option_ ## suffix (void) \ +{ \ + static boolean first = TRUE; \ + static const char * value; \ + if (first) { \ + first = FALSE; \ + value = debug_get_option(name, dfault); \ + } \ + return value; \ +} + #define DEBUG_GET_ONCE_BOOL_OPTION(sufix, name, dfault) \ static boolean \ debug_get_option_ ## sufix (void) \ diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp index 022626ccb8f..c2842c2186f 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp @@ -1889,6 +1889,9 @@ AlgebraicOpt::handleCVT_EXTBF(Instruction *cvt) arg = shift->getSrc(0); offset = imm.reg.data.u32; } + // We just AND'd the high bits away, which means this is effectively an + // unsigned value. + cvt->sType = TYPE_U32; } else if (insn->op == OP_SHR && insn->sType == cvt->sType && insn->src(1).getImmediate(imm)) { diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 1443bc0c4af..1aee7dd2da8 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1956,7 +1956,7 @@ static void evergreen_emit_constant_buffers(struct r600_context *rctx, if (!gs_ring_buffer) { radeon_set_context_reg_flag(cs, reg_alu_constbuf_size + buffer_index * 4, - ALIGN_DIVUP(cb->buffer_size >> 4, 16), pkt_flags); + ALIGN_DIVUP(cb->buffer_size, 256), pkt_flags); radeon_set_context_reg_flag(cs, reg_alu_const_cache + buffer_index * 4, va >> 8, pkt_flags); } diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index e7ffe0dab1c..43b80742cb5 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -1768,7 +1768,7 @@ static void r600_emit_constant_buffers(struct r600_context *rctx, if (!gs_ring_buffer) { radeon_set_context_reg(cs, reg_alu_constbuf_size + buffer_index * 4, - ALIGN_DIVUP(cb->buffer_size >> 4, 16)); + ALIGN_DIVUP(cb->buffer_size, 256)); radeon_set_context_reg(cs, reg_alu_const_cache + buffer_index * 4, offset >> 8); } diff --git a/src/gallium/drivers/radeonsi/si_debug.c b/src/gallium/drivers/radeonsi/si_debug.c index c45f8c0ea50..a07b1c56579 100644 --- a/src/gallium/drivers/radeonsi/si_debug.c +++ b/src/gallium/drivers/radeonsi/si_debug.c @@ -28,8 +28,11 @@ #include "si_shader.h" #include "sid.h" #include "sid_tables.h" +#include "radeon/radeon_elf_util.h" #include "ddebug/dd_util.h" +#include "util/u_memory.h" +DEBUG_GET_ONCE_OPTION(replace_shaders, "RADEON_REPLACE_SHADERS", NULL) static void si_dump_shader(struct si_shader_ctx_state *state, const char *name, FILE *f) @@ -42,6 +45,98 @@ static void si_dump_shader(struct si_shader_ctx_state *state, const char *name, fprintf(f, "%s\n\n", state->current->binary.disasm_string); } +/** + * Shader compiles can be overridden with arbitrary ELF objects by setting + * the environment variable RADEON_REPLACE_SHADERS=num1:filename1[;num2:filename2] + */ +bool si_replace_shader(unsigned num, struct radeon_shader_binary *binary) +{ + const char *p = debug_get_option_replace_shaders(); + const char *semicolon; + char *copy = NULL; + FILE *f; + long filesize, nread; + char *buf = NULL; + bool replaced = false; + + if (!p) + return false; + + while (*p) { + unsigned long i; + char *endp; + i = strtoul(p, &endp, 0); + + p = endp; + if (*p != ':') { + fprintf(stderr, "RADEON_REPLACE_SHADERS formatted badly.\n"); + exit(1); + } + ++p; + + if (i == num) + break; + + p = strchr(p, ';'); + if (!p) + return false; + ++p; + } + if (!*p) + return false; + + semicolon = strchr(p, ';'); + if (semicolon) { + p = copy = strndup(p, semicolon - p); + if (!copy) { + fprintf(stderr, "out of memory\n"); + return false; + } + } + + fprintf(stderr, "radeonsi: replace shader %u by %s\n", num, p); + + f = fopen(p, "r"); + if (!f) { + perror("radeonsi: failed to open file"); + goto out_free; + } + + if (fseek(f, 0, SEEK_END) != 0) + goto file_error; + + filesize = ftell(f); + if (filesize < 0) + goto file_error; + + if (fseek(f, 0, SEEK_SET) != 0) + goto file_error; + + buf = MALLOC(filesize); + if (!buf) { + fprintf(stderr, "out of memory\n"); + goto out_close; + } + + nread = fread(buf, 1, filesize, f); + if (nread != filesize) + goto file_error; + + radeon_elf_read(buf, filesize, binary); + replaced = true; + +out_close: + fclose(f); +out_free: + FREE(buf); + free(copy); + return replaced; + +file_error: + perror("radeonsi: reading shader"); + goto out_close; +} + /* Parsed IBs are difficult to read without colors. Use "less -R file" to * read them, or use "aha -b -f file" to convert them to html. */ diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 65c7e198d1d..f83cb024f0e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -329,6 +329,7 @@ void si_init_cp_dma_functions(struct si_context *sctx); /* si_debug.c */ void si_init_debug_functions(struct si_context *sctx); void si_check_vm_faults(struct si_context *sctx); +bool si_replace_shader(unsigned num, struct radeon_shader_binary *binary); /* si_dma.c */ void si_dma_copy(struct pipe_context *ctx, diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 4a672766b0f..0e98784d51b 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -3884,11 +3884,17 @@ int si_compile_llvm(struct si_screen *sscreen, struct si_shader *shader, bool dump_asm = r600_can_dump_shader(&sscreen->b, shader->selector ? shader->selector->tokens : NULL); bool dump_ir = dump_asm && !(sscreen->b.debug_flags & DBG_NO_IR); + unsigned count = p_atomic_inc_return(&sscreen->b.num_compilations); - r = radeon_llvm_compile(mod, &shader->binary, - r600_get_llvm_processor_name(sscreen->b.family), dump_ir, dump_asm, tm); - if (r) - return r; + if (dump_ir || dump_asm) + fprintf(stderr, "radeonsi: Compiling shader %d\n", count); + + if (!si_replace_shader(count, &shader->binary)) { + r = radeon_llvm_compile(mod, &shader->binary, + r600_get_llvm_processor_name(sscreen->b.family), dump_ir, dump_asm, tm); + if (r) + return r; + } r = si_shader_binary_read(sscreen, shader); diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index f0147ce2bfc..8700590435f 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -634,7 +634,6 @@ static int si_shader_select(struct pipe_context *ctx, sel->last_variant = shader; } state->current = shader; - p_atomic_inc(&sctx->screen->b.num_compilations); pipe_mutex_unlock(sel->mutex); return 0; } diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp index e8eab808a19..e82c99ee3bb 100644 --- a/src/glsl/builtin_variables.cpp +++ b/src/glsl/builtin_variables.cpp @@ -951,6 +951,11 @@ builtin_variable_generator::generate_vs_special_vars() add_system_value(SYSTEM_VALUE_INSTANCE_ID, int_t, "gl_InstanceIDARB"); if (state->ARB_draw_instanced_enable || state->is_version(140, 300)) add_system_value(SYSTEM_VALUE_INSTANCE_ID, int_t, "gl_InstanceID"); + if (state->ARB_shader_draw_parameters_enable) { + add_system_value(SYSTEM_VALUE_BASE_VERTEX, int_t, "gl_BaseVertexARB"); + add_system_value(SYSTEM_VALUE_BASE_INSTANCE, int_t, "gl_BaseInstanceARB"); + add_system_value(SYSTEM_VALUE_DRAW_ID, int_t, "gl_DrawIDARB"); + } if (state->AMD_vertex_shader_layer_enable) { var = add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); var->data.interpolation = INTERP_QUALIFIER_FLAT; diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 3988376ea9d..fb53f6e2e2d 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -610,6 +610,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { EXT(ARB_shader_atomic_counters, true, false, ARB_shader_atomic_counters), EXT(ARB_shader_bit_encoding, true, false, ARB_shader_bit_encoding), EXT(ARB_shader_clock, true, false, ARB_shader_clock), + EXT(ARB_shader_draw_parameters, true, false, ARB_shader_draw_parameters), EXT(ARB_shader_image_load_store, true, false, ARB_shader_image_load_store), EXT(ARB_shader_image_size, true, false, ARB_shader_image_size), EXT(ARB_shader_precision, true, false, ARB_shader_precision), diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index a4bda772a0f..afb99afa5cd 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -536,6 +536,8 @@ struct _mesa_glsl_parse_state { bool ARB_shader_bit_encoding_warn; bool ARB_shader_clock_enable; bool ARB_shader_clock_warn; + bool ARB_shader_draw_parameters_enable; + bool ARB_shader_draw_parameters_warn; bool ARB_shader_image_load_store_enable; bool ARB_shader_image_load_store_warn; bool ARB_shader_image_size_enable; diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c index b78092b773e..273cac3e0ac 100644 --- a/src/glsl/nir/nir.c +++ b/src/glsl/nir/nir.c @@ -1655,6 +1655,10 @@ nir_intrinsic_from_system_value(gl_system_value val) return nir_intrinsic_load_vertex_id; case SYSTEM_VALUE_INSTANCE_ID: return nir_intrinsic_load_instance_id; + case SYSTEM_VALUE_DRAW_ID: + return nir_intrinsic_load_draw_id; + case SYSTEM_VALUE_BASE_INSTANCE: + return nir_intrinsic_load_base_instance; case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE: return nir_intrinsic_load_vertex_id_zero_base; case SYSTEM_VALUE_BASE_VERTEX: @@ -1700,6 +1704,10 @@ nir_system_value_from_intrinsic(nir_intrinsic_op intrin) return SYSTEM_VALUE_VERTEX_ID; case nir_intrinsic_load_instance_id: return SYSTEM_VALUE_INSTANCE_ID; + case nir_intrinsic_load_draw_id: + return SYSTEM_VALUE_DRAW_ID; + case nir_intrinsic_load_base_instance: + return SYSTEM_VALUE_BASE_INSTANCE; case nir_intrinsic_load_vertex_id_zero_base: return SYSTEM_VALUE_VERTEX_ID_ZERO_BASE; case nir_intrinsic_load_base_vertex: diff --git a/src/glsl/nir/nir_builder.h b/src/glsl/nir/nir_builder.h index d2a148e1c45..8ba48589aa6 100644 --- a/src/glsl/nir/nir_builder.h +++ b/src/glsl/nir/nir_builder.h @@ -43,6 +43,17 @@ nir_builder_init(nir_builder *build, nir_function_impl *impl) build->shader = impl->function->shader; } +static inline void +nir_builder_init_simple_shader(nir_builder *build, void *mem_ctx, + gl_shader_stage stage, + const nir_shader_compiler_options *options) +{ + build->shader = nir_shader_create(mem_ctx, stage, options); + nir_function *func = nir_function_create(build->shader, "main"); + build->impl = nir_function_impl_create(func); + build->cursor = nir_after_cf_list(&build->impl->body); +} + static inline void nir_builder_instr_insert(nir_builder *build, nir_instr *instr) { diff --git a/src/glsl/nir/nir_intrinsics.h b/src/glsl/nir/nir_intrinsics.h index e30750804dc..78c25707dc9 100644 --- a/src/glsl/nir/nir_intrinsics.h +++ b/src/glsl/nir/nir_intrinsics.h @@ -258,6 +258,8 @@ SYSTEM_VALUE(vertex_id, 1, 0) SYSTEM_VALUE(vertex_id_zero_base, 1, 0) SYSTEM_VALUE(base_vertex, 1, 0) SYSTEM_VALUE(instance_id, 1, 0) +SYSTEM_VALUE(base_instance, 1, 0) +SYSTEM_VALUE(draw_id, 1, 0) SYSTEM_VALUE(sample_id, 1, 0) SYSTEM_VALUE(sample_pos, 2, 0) SYSTEM_VALUE(sample_mask_in, 1, 0) diff --git a/src/glsl/nir/nir_opt_algebraic.py b/src/glsl/nir/nir_opt_algebraic.py index 3843f21c0ee..a5a4841f6b1 100644 --- a/src/glsl/nir/nir_opt_algebraic.py +++ b/src/glsl/nir/nir_opt_algebraic.py @@ -62,6 +62,10 @@ optimizations = [ (('iadd', ('imul', a, b), ('imul', a, c)), ('imul', a, ('iadd', b, c))), (('fadd', ('fneg', a), a), 0.0), (('iadd', ('ineg', a), a), 0), + (('iadd', ('ineg', a), ('iadd', a, b)), b), + (('iadd', a, ('iadd', ('ineg', a), b)), b), + (('fadd', ('fneg', a), ('fadd', a, b)), b), + (('fadd', a, ('fadd', ('fneg', a), b)), b), (('fmul', a, 0.0), 0.0), (('imul', a, 0), 0), (('umul_unorm_4x8', a, 0), 0), diff --git a/src/glsl/nir/shader_enums.h b/src/glsl/nir/shader_enums.h index 6f4a47dbd18..dfab0bb9952 100644 --- a/src/glsl/nir/shader_enums.h +++ b/src/glsl/nir/shader_enums.h @@ -379,6 +379,26 @@ typedef enum * \sa SYSTEM_VALUE_VERTEX_ID, SYSTEM_VALUE_VERTEX_ID_ZERO_BASE */ SYSTEM_VALUE_BASE_VERTEX, + + /** + * Value of \c baseinstance passed to instanced draw entry points + * + * \sa SYSTEM_VALUE_INSTANCE_ID + */ + SYSTEM_VALUE_BASE_INSTANCE, + + /** + * From _ARB_shader_draw_parameters: + * + * "Additionally, this extension adds a further built-in variable, + * gl_DrawID to the shading language. This variable contains the index + * of the draw currently being processed by a Multi* variant of a + * drawing command (such as MultiDrawElements or + * MultiDrawArraysIndirect)." + * + * If GL_ARB_multi_draw_indirect is not supported, this is always 0. + */ + SYSTEM_VALUE_DRAW_ID, /*@}*/ /** diff --git a/src/glsl/nir/tests/control_flow_tests.cpp b/src/glsl/nir/tests/control_flow_tests.cpp index b9f90e66d1d..b9379ef3b06 100644 --- a/src/glsl/nir/tests/control_flow_tests.cpp +++ b/src/glsl/nir/tests/control_flow_tests.cpp @@ -30,24 +30,17 @@ protected: ~nir_cf_test(); nir_builder b; - nir_shader *shader; - nir_function_impl *impl; }; nir_cf_test::nir_cf_test() { static const nir_shader_compiler_options options = { }; - shader = nir_shader_create(NULL, MESA_SHADER_VERTEX, &options); - nir_function *func = nir_function_create(shader, "main"); - nir_function_overload *overload = nir_function_overload_create(func); - impl = nir_function_impl_create(overload); - - nir_builder_init(&b, impl); + nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_VERTEX, &options); } nir_cf_test::~nir_cf_test() { - ralloc_free(shader); + ralloc_free(b.shader); } TEST_F(nir_cf_test, delete_break_in_loop) @@ -56,12 +49,12 @@ TEST_F(nir_cf_test, delete_break_in_loop) * * while (...) { break; } */ - nir_loop *loop = nir_loop_create(shader); - nir_cf_node_insert(nir_after_cf_list(&impl->body), &loop->cf_node); + nir_loop *loop = nir_loop_create(b.shader); + nir_cf_node_insert(nir_after_cf_list(&b.impl->body), &loop->cf_node); b.cursor = nir_after_cf_list(&loop->body); - nir_jump_instr *jump = nir_jump_instr_create(shader, nir_jump_break); + nir_jump_instr *jump = nir_jump_instr_create(b.shader, nir_jump_break); nir_builder_instr_insert(&b, &jump->instr); /* At this point, we should have: @@ -82,10 +75,10 @@ TEST_F(nir_cf_test, delete_break_in_loop) * block block_3: * } */ - nir_block *block_0 = nir_start_block(impl); + nir_block *block_0 = nir_start_block(b.impl); nir_block *block_1 = nir_cf_node_as_block(nir_loop_first_cf_node(loop)); nir_block *block_2 = nir_cf_node_as_block(nir_cf_node_next(&loop->cf_node)); - nir_block *block_3 = impl->end_block; + nir_block *block_3 = b.impl->end_block; ASSERT_EQ(nir_cf_node_block, block_0->cf_node.type); ASSERT_EQ(nir_cf_node_block, block_1->cf_node.type); ASSERT_EQ(nir_cf_node_block, block_2->cf_node.type); @@ -108,12 +101,12 @@ TEST_F(nir_cf_test, delete_break_in_loop) EXPECT_TRUE(_mesa_set_search(block_2->predecessors, block_1)); EXPECT_TRUE(_mesa_set_search(block_3->predecessors, block_2)); - nir_print_shader(shader, stderr); + nir_print_shader(b.shader, stderr); /* Now remove the break. */ nir_instr_remove(&jump->instr); - nir_print_shader(shader, stderr); + nir_print_shader(b.shader, stderr); /* At this point, we should have: * @@ -151,5 +144,5 @@ TEST_F(nir_cf_test, delete_break_in_loop) EXPECT_TRUE(_mesa_set_search(block_2->predecessors, block_1)); EXPECT_TRUE(_mesa_set_search(block_3->predecessors, block_2)); - nir_metadata_require(impl, nir_metadata_dominance); + nir_metadata_require(b.impl, nir_metadata_dominance); } diff --git a/src/glsl/standalone_scaffolding.cpp b/src/glsl/standalone_scaffolding.cpp index 84266b0cb58..5ce804eed20 100644 --- a/src/glsl/standalone_scaffolding.cpp +++ b/src/glsl/standalone_scaffolding.cpp @@ -155,6 +155,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) ctx->Extensions.ARB_gpu_shader_fp64 = true; ctx->Extensions.ARB_sample_shading = true; ctx->Extensions.ARB_shader_bit_encoding = true; + ctx->Extensions.ARB_shader_draw_parameters = true; ctx->Extensions.ARB_shader_stencil_export = true; ctx->Extensions.ARB_shader_subroutine = true; ctx->Extensions.ARB_shader_texture_lod = true; diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index 9ad04ee286b..3d5150d2f53 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -77,6 +77,7 @@ i965_compiler_FILES = \ brw_vec4_surface_builder.cpp \ brw_vec4_surface_builder.h \ brw_vec4_tcs.cpp \ + brw_vec4_tes.cpp \ brw_vec4_visitor.cpp \ brw_vec4_vs_visitor.cpp \ brw_vue_map.c \ diff --git a/src/mesa/drivers/dri/i965/brw_compiler.h b/src/mesa/drivers/dri/i965/brw_compiler.h index 7e33fa05632..b66869b8a78 100644 --- a/src/mesa/drivers/dri/i965/brw_compiler.h +++ b/src/mesa/drivers/dri/i965/brw_compiler.h @@ -598,6 +598,9 @@ struct brw_vs_prog_data { bool uses_vertexid; bool uses_instanceid; + bool uses_basevertex; + bool uses_baseinstance; + bool uses_drawid; }; struct brw_tcs_prog_data diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 005c3236c88..4298252c9b7 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -374,8 +374,8 @@ brw_initialize_context_constants(struct brw_context *brw) const bool stage_exists[MESA_SHADER_STAGES] = { [MESA_SHADER_VERTEX] = true, - [MESA_SHADER_TESS_CTRL] = brw->gen >= 8, - [MESA_SHADER_TESS_EVAL] = brw->gen >= 8, + [MESA_SHADER_TESS_CTRL] = brw->gen >= 7, + [MESA_SHADER_TESS_EVAL] = brw->gen >= 7, [MESA_SHADER_GEOMETRY] = brw->gen >= 6, [MESA_SHADER_FRAGMENT] = true, [MESA_SHADER_COMPUTE] = diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 0239b6214ae..7b0340fc2ab 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -909,8 +909,13 @@ struct brw_context uint32_t pma_stall_bits; struct { - /** The value of gl_BaseVertex for the current _mesa_prim. */ - int gl_basevertex; + struct { + /** The value of gl_BaseVertex for the current _mesa_prim. */ + int gl_basevertex; + + /** The value of gl_BaseInstance for the current _mesa_prim. */ + int gl_baseinstance; + } params; /** * Buffer and offset used for GL_ARB_shader_draw_parameters @@ -918,6 +923,15 @@ struct brw_context */ drm_intel_bo *draw_params_bo; uint32_t draw_params_offset; + + /** + * The value of gl_DrawID for the current _mesa_prim. This always comes + * in from it's own vertex buffer since it's not part of the indirect + * draw parameters. + */ + int gl_drawid; + drm_intel_bo *draw_id_bo; + uint32_t draw_id_offset; } draw; struct { diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 5c18d671a0c..df7a79fcd89 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -1315,6 +1315,13 @@ enum opcode { TCS_OPCODE_SET_OUTPUT_URB_OFFSETS, TCS_OPCODE_GET_PRIMITIVE_ID, TCS_OPCODE_CREATE_BARRIER_HEADER, + TCS_OPCODE_SRC0_010_IS_ZERO, + TCS_OPCODE_RELEASE_INPUT, + TCS_OPCODE_THREAD_END, + + TES_OPCODE_GET_PRIMITIVE_ID, + TES_OPCODE_CREATE_INPUT_READ_HEADER, + TES_OPCODE_ADD_INDIRECT_URB_OFFSET, }; enum brw_urb_write_flags { diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index bc013963eee..23e71fd9ba6 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -462,9 +462,29 @@ brw_try_draw_prims(struct gl_context *ctx, } } - brw->draw.gl_basevertex = + /* Determine if we need to flag BRW_NEW_VERTICES for updating the + * gl_BaseVertexARB or gl_BaseInstanceARB values. For indirect draw, we + * always flag if the shader uses one of the values. For direct draws, + * we only flag if the values change. + */ + const int new_basevertex = prims[i].indexed ? prims[i].basevertex : prims[i].start; + const int new_baseinstance = prims[i].base_instance; + if (i > 0) { + const bool uses_draw_parameters = + brw->vs.prog_data->uses_basevertex || + brw->vs.prog_data->uses_baseinstance; + if ((uses_draw_parameters && prims[i].is_indirect) || + (brw->vs.prog_data->uses_basevertex && + brw->draw.params.gl_basevertex != new_basevertex) || + (brw->vs.prog_data->uses_baseinstance && + brw->draw.params.gl_baseinstance != new_baseinstance)) + brw->ctx.NewDriverState |= BRW_NEW_VERTICES; + } + + brw->draw.params.gl_basevertex = new_basevertex; + brw->draw.params.gl_baseinstance = new_baseinstance; drm_intel_bo_unreference(brw->draw.draw_params_bo); if (prims[i].is_indirect) { @@ -482,6 +502,18 @@ brw_try_draw_prims(struct gl_context *ctx, brw->draw.draw_params_offset = 0; } + /* gl_DrawID always needs its own vertex buffer since it's not part of + * the indirect parameter buffer. If the program uses gl_DrawID we need + * to flag BRW_NEW_VERTICES. For the first iteration, we don't have + * valid brw->vs.prog_data, but we always flag BRW_NEW_VERTICES before + * the loop. + */ + brw->draw.gl_drawid = prims[i].draw_id; + drm_intel_bo_unreference(brw->draw.draw_id_bo); + brw->draw.draw_id_bo = NULL; + if (i > 0 && brw->vs.prog_data->uses_drawid) + brw->ctx.NewDriverState |= BRW_NEW_VERTICES; + if (brw->gen < 6) brw_set_prim(brw, &prims[i]); else diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index ea0f6f29c4f..f781d8ba72d 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -592,11 +592,19 @@ void brw_prepare_shader_draw_parameters(struct brw_context *brw) { /* For non-indirect draws, upload gl_BaseVertex. */ - if (brw->vs.prog_data->uses_vertexid && brw->draw.draw_params_bo == NULL) { - intel_upload_data(brw, &brw->draw.gl_basevertex, 4, 4, + if ((brw->vs.prog_data->uses_basevertex || + brw->vs.prog_data->uses_baseinstance) && + brw->draw.draw_params_bo == NULL) { + intel_upload_data(brw, &brw->draw.params, sizeof(brw->draw.params), 4, &brw->draw.draw_params_bo, &brw->draw.draw_params_offset); } + + if (brw->vs.prog_data->uses_drawid) { + intel_upload_data(brw, &brw->draw.gl_drawid, sizeof(brw->draw.gl_drawid), 4, + &brw->draw.draw_id_bo, + &brw->draw.draw_id_offset); + } } /** @@ -658,8 +666,11 @@ brw_emit_vertices(struct brw_context *brw) brw_emit_query_begin(brw); unsigned nr_elements = brw->vb.nr_enabled; - if (brw->vs.prog_data->uses_vertexid || brw->vs.prog_data->uses_instanceid) + if (brw->vs.prog_data->uses_vertexid || brw->vs.prog_data->uses_instanceid || + brw->vs.prog_data->uses_basevertex || brw->vs.prog_data->uses_baseinstance) ++nr_elements; + if (brw->vs.prog_data->uses_drawid) + nr_elements++; /* If the VS doesn't read any inputs (calculating vertex position from * a state variable for some reason, for example), emit a single pad @@ -693,8 +704,11 @@ brw_emit_vertices(struct brw_context *brw) /* Now emit VB and VEP state packets. */ - unsigned nr_buffers = - brw->vb.nr_buffers + brw->vs.prog_data->uses_vertexid; + const bool uses_draw_params = + brw->vs.prog_data->uses_basevertex || + brw->vs.prog_data->uses_baseinstance; + const unsigned nr_buffers = brw->vb.nr_buffers + + uses_draw_params + brw->vs.prog_data->uses_drawid; if (nr_buffers) { if (brw->gen >= 6) { @@ -713,7 +727,7 @@ brw_emit_vertices(struct brw_context *brw) } - if (brw->vs.prog_data->uses_vertexid) { + if (uses_draw_params) { EMIT_VERTEX_BUFFER_STATE(brw, brw->vb.nr_buffers, brw->draw.draw_params_bo, brw->draw.draw_params_bo->size - 1, @@ -721,6 +735,16 @@ brw_emit_vertices(struct brw_context *brw) 0, /* stride */ 0); /* step rate */ } + + if (brw->vs.prog_data->uses_drawid) { + EMIT_VERTEX_BUFFER_STATE(brw, brw->vb.nr_buffers + 1, + brw->draw.draw_id_bo, + brw->draw.draw_id_bo->size - 1, + brw->draw.draw_id_offset, + 0, /* stride */ + 0); /* step rate */ + } + ADVANCE_BATCH(); } @@ -790,21 +814,25 @@ brw_emit_vertices(struct brw_context *brw) ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT)); } - if (brw->vs.prog_data->uses_vertexid || brw->vs.prog_data->uses_instanceid) { + if (brw->vs.prog_data->uses_vertexid || brw->vs.prog_data->uses_instanceid || + brw->vs.prog_data->uses_basevertex || brw->vs.prog_data->uses_baseinstance) { uint32_t dw0 = 0, dw1 = 0; uint32_t comp0 = BRW_VE1_COMPONENT_STORE_0; uint32_t comp1 = BRW_VE1_COMPONENT_STORE_0; uint32_t comp2 = BRW_VE1_COMPONENT_STORE_0; uint32_t comp3 = BRW_VE1_COMPONENT_STORE_0; - if (brw->vs.prog_data->uses_vertexid) { + if (brw->vs.prog_data->uses_basevertex) comp0 = BRW_VE1_COMPONENT_STORE_SRC; - comp2 = BRW_VE1_COMPONENT_STORE_VID; - } - if (brw->vs.prog_data->uses_instanceid) { + if (brw->vs.prog_data->uses_baseinstance) + comp1 = BRW_VE1_COMPONENT_STORE_SRC; + + if (brw->vs.prog_data->uses_vertexid) + comp2 = BRW_VE1_COMPONENT_STORE_VID; + + if (brw->vs.prog_data->uses_instanceid) comp3 = BRW_VE1_COMPONENT_STORE_IID; - } dw1 = (comp0 << BRW_VE1_COMPONENT_0_SHIFT) | (comp1 << BRW_VE1_COMPONENT_1_SHIFT) | @@ -814,11 +842,11 @@ brw_emit_vertices(struct brw_context *brw) if (brw->gen >= 6) { dw0 |= GEN6_VE0_VALID | brw->vb.nr_buffers << GEN6_VE0_INDEX_SHIFT | - BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT; + BRW_SURFACEFORMAT_R32G32_UINT << BRW_VE0_FORMAT_SHIFT; } else { dw0 |= BRW_VE0_VALID | brw->vb.nr_buffers << BRW_VE0_INDEX_SHIFT | - BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT; + BRW_SURFACEFORMAT_R32G32_UINT << BRW_VE0_FORMAT_SHIFT; dw1 |= (i * 4) << BRW_VE1_DST_OFFSET_SHIFT; } @@ -830,6 +858,30 @@ brw_emit_vertices(struct brw_context *brw) OUT_BATCH(dw1); } + if (brw->vs.prog_data->uses_drawid) { + uint32_t dw0 = 0, dw1 = 0; + + dw1 = (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->gen >= 6) { + dw0 |= GEN6_VE0_VALID | + ((brw->vb.nr_buffers + 1) << GEN6_VE0_INDEX_SHIFT) | + (BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT); + } else { + dw0 |= BRW_VE0_VALID | + ((brw->vb.nr_buffers + 1) << BRW_VE0_INDEX_SHIFT) | + (BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT); + + dw1 |= (i * 4) << BRW_VE1_DST_OFFSET_SHIFT; + } + + OUT_BATCH(dw0); + OUT_BATCH(dw1); + } + if (brw->gen >= 6 && gen6_edgeflag_input) { uint32_t format = brw_get_vertex_surface_type(brw, gen6_edgeflag_input->glarray); diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index f9a72903ef1..7675e9d299a 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1672,7 +1672,10 @@ fs_visitor::assign_vs_urb_setup() assert(stage == MESA_SHADER_VERTEX); int count = _mesa_bitcount_64(vs_prog_data->inputs_read); - if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid) + if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid || + vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance) + count++; + if (vs_prog_data->uses_drawid) count++; /* Each attribute is 4 regs. */ diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index 5c02c17d0a5..c7bbae325a1 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -222,6 +222,20 @@ emit_system_values_block(nir_block *block, void *void_visitor) *reg = *v->emit_vs_system_value(SYSTEM_VALUE_INSTANCE_ID); break; + case nir_intrinsic_load_base_instance: + assert(v->stage == MESA_SHADER_VERTEX); + reg = &v->nir_system_values[SYSTEM_VALUE_BASE_INSTANCE]; + if (reg->file == BAD_FILE) + *reg = *v->emit_vs_system_value(SYSTEM_VALUE_BASE_INSTANCE); + break; + + case nir_intrinsic_load_draw_id: + assert(v->stage == MESA_SHADER_VERTEX); + reg = &v->nir_system_values[SYSTEM_VALUE_DRAW_ID]; + if (reg->file == BAD_FILE) + *reg = *v->emit_vs_system_value(SYSTEM_VALUE_DRAW_ID); + break; + case nir_intrinsic_load_invocation_id: assert(v->stage == MESA_SHADER_GEOMETRY); reg = &v->nir_system_values[SYSTEM_VALUE_INVOCATION_ID]; @@ -1747,7 +1761,9 @@ fs_visitor::nir_emit_vs_intrinsic(const fs_builder &bld, case nir_intrinsic_load_vertex_id_zero_base: case nir_intrinsic_load_base_vertex: - case nir_intrinsic_load_instance_id: { + case nir_intrinsic_load_instance_id: + case nir_intrinsic_load_base_instance: + case nir_intrinsic_load_draw_id: { gl_system_value sv = nir_system_value_from_intrinsic(instr->intrinsic); fs_reg val = nir_system_values[sv]; assert(val.file != BAD_FILE); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 8f1fcbb233c..89e1559a196 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -43,9 +43,14 @@ fs_visitor::emit_vs_system_value(int location) switch (location) { case SYSTEM_VALUE_BASE_VERTEX: reg->reg_offset = 0; - vs_prog_data->uses_vertexid = true; + vs_prog_data->uses_basevertex = true; + break; + case SYSTEM_VALUE_BASE_INSTANCE: + reg->reg_offset = 1; + vs_prog_data->uses_baseinstance = true; break; case SYSTEM_VALUE_VERTEX_ID: + unreachable("should have been lowered"); case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE: reg->reg_offset = 2; vs_prog_data->uses_vertexid = true; @@ -54,6 +59,16 @@ fs_visitor::emit_vs_system_value(int location) reg->reg_offset = 3; vs_prog_data->uses_instanceid = true; break; + case SYSTEM_VALUE_DRAW_ID: + if (nir->info.system_values_read & + (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) | + BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE) | + BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) | + BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID))) + reg->nr += 4; + reg->reg_offset = 0; + vs_prog_data->uses_drawid = true; + break; default: unreachable("not reached"); } diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index 836cf0a69e9..6d15c60fa40 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -26,6 +26,7 @@ #include "brw_eu.h" #include "brw_fs.h" #include "brw_nir.h" +#include "brw_vec4_tes.h" #include "glsl/glsl_parser_extras.h" #include "main/shaderobj.h" #include "main/uniforms.h" @@ -86,7 +87,8 @@ brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo) compiler->scalar_stage[MESA_SHADER_VERTEX] = devinfo->gen >= 8 && !(INTEL_DEBUG & DEBUG_VEC4VS); compiler->scalar_stage[MESA_SHADER_TESS_CTRL] = false; - compiler->scalar_stage[MESA_SHADER_TESS_EVAL] = true; + compiler->scalar_stage[MESA_SHADER_TESS_EVAL] = + devinfo->gen >= 8 && env_var_as_boolean("INTEL_SCALAR_TES", true); compiler->scalar_stage[MESA_SHADER_GEOMETRY] = devinfo->gen >= 8 && env_var_as_boolean("INTEL_SCALAR_GS", false); compiler->scalar_stage[MESA_SHADER_FRAGMENT] = true; @@ -569,6 +571,18 @@ brw_instruction_name(enum opcode op) return "tcs_get_primitive_id"; case TCS_OPCODE_CREATE_BARRIER_HEADER: return "tcs_create_barrier_header"; + case TCS_OPCODE_SRC0_010_IS_ZERO: + return "tcs_src0<0,1,0>_is_zero"; + case TCS_OPCODE_RELEASE_INPUT: + return "tcs_release_input"; + case TCS_OPCODE_THREAD_END: + return "tcs_thread_end"; + case TES_OPCODE_CREATE_INPUT_READ_HEADER: + return "tes_create_input_read_header"; + case TES_OPCODE_ADD_INDIRECT_URB_OFFSET: + return "tes_add_indirect_urb_offset"; + case TES_OPCODE_GET_PRIMITIVE_ID: + return "tes_get_primitive_id"; } unreachable("not reached"); @@ -1004,6 +1018,7 @@ backend_instruction::has_side_effects() const case SHADER_OPCODE_URB_WRITE_SIMD8_MASKED_PER_SLOT: case FS_OPCODE_FB_WRITE: case SHADER_OPCODE_BARRIER: + case TCS_OPCODE_RELEASE_INPUT: return true; default: return false; @@ -1403,6 +1418,19 @@ brw_compile_tes(const struct brw_compiler *compiler, return g.get_assembly(final_assembly_size); } else { - unreachable("XXX: vec4 tessellation evalation shaders not merged yet."); + brw::vec4_tes_visitor v(compiler, log_data, key, prog_data, + nir, mem_ctx, shader_time_index); + if (!v.run()) { + if (error_str) + *error_str = ralloc_strdup(mem_ctx, v.fail_msg); + return NULL; + } + + if (unlikely(INTEL_DEBUG & DEBUG_TES)) + v.dump_instructions(); + + return brw_vec4_generate_assembly(compiler, log_data, mem_ctx, nir, + &prog_data->base, v.cfg, + final_assembly_size); } } diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 81a67d284e0..2a671a58d8c 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -196,10 +196,14 @@ static const struct brw_tracked_state *gen7_render_atoms[] = &gen7_hw_binding_tables, /* Enable hw-generated binding tables for Haswell */ &brw_vs_image_surfaces, /* Before vs push/pull constants and binding table */ + &brw_tcs_image_surfaces, /* Before tcs push/pull constants and binding table */ + &brw_tes_image_surfaces, /* Before tes push/pull constants and binding table */ &brw_gs_image_surfaces, /* Before gs push/pull constants and binding table */ &brw_wm_image_surfaces, /* Before wm push/pull constants and binding table */ &gen6_vs_push_constants, /* Before vs_state */ + &gen7_tcs_push_constants, + &gen7_tes_push_constants, &gen6_gs_push_constants, /* Before gs_state */ &gen6_wm_push_constants, /* Before wm_surfaces and constant_buffer */ @@ -209,6 +213,12 @@ static const struct brw_tracked_state *gen7_render_atoms[] = &brw_vs_pull_constants, &brw_vs_ubo_surfaces, &brw_vs_abo_surfaces, + &brw_tcs_pull_constants, + &brw_tcs_ubo_surfaces, + &brw_tcs_abo_surfaces, + &brw_tes_pull_constants, + &brw_tes_ubo_surfaces, + &brw_tes_abo_surfaces, &brw_gs_pull_constants, &brw_gs_ubo_surfaces, &brw_gs_abo_surfaces, @@ -218,11 +228,15 @@ static const struct brw_tracked_state *gen7_render_atoms[] = &gen6_renderbuffer_surfaces, &brw_texture_surfaces, &brw_vs_binding_table, + &brw_tcs_binding_table, + &brw_tes_binding_table, &brw_gs_binding_table, &brw_wm_binding_table, &brw_fs_samplers, &brw_vs_samplers, + &brw_tcs_samplers, + &brw_tes_samplers, &brw_gs_samplers, &gen6_multisample_state, diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp index 0cded0c87c6..dd223985d1c 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp @@ -157,6 +157,7 @@ vec4_instruction::is_send_from_grf() case SHADER_OPCODE_TYPED_SURFACE_WRITE: case VEC4_OPCODE_URB_READ: case TCS_OPCODE_URB_WRITE: + case TCS_OPCODE_RELEASE_INPUT: case SHADER_OPCODE_BARRIER: return true; default: @@ -189,6 +190,7 @@ vec4_instruction::has_source_and_destination_hazard() const switch (opcode) { case TCS_OPCODE_SET_INPUT_URB_OFFSETS: case TCS_OPCODE_SET_OUTPUT_URB_OFFSETS: + case TES_OPCODE_ADD_INDIRECT_URB_OFFSET: return true; default: return false; @@ -274,6 +276,7 @@ vec4_visitor::implied_mrf_writes(vec4_instruction *inst) case SHADER_OPCODE_POW: return 2; case VS_OPCODE_URB_WRITE: + case TCS_OPCODE_THREAD_END: return 1; case VS_OPCODE_PULL_CONSTANT_LOAD: return 2; @@ -1563,7 +1566,7 @@ int vec4_vs_visitor::setup_attributes(int payload_reg) { int nr_attributes; - int attribute_map[VERT_ATTRIB_MAX + 1]; + int attribute_map[VERT_ATTRIB_MAX + 2]; memset(attribute_map, 0, sizeof(attribute_map)); nr_attributes = 0; @@ -1574,12 +1577,19 @@ vec4_vs_visitor::setup_attributes(int payload_reg) } } + if (vs_prog_data->uses_drawid) { + attribute_map[VERT_ATTRIB_MAX + 1] = payload_reg + nr_attributes; + nr_attributes++; + } + /* VertexID is stored by the VF as the last vertex element, but we * don't represent it with a flag in inputs_read, so we call it * VERT_ATTRIB_MAX. */ - if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid) { + if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid || + vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance) { attribute_map[VERT_ATTRIB_MAX] = payload_reg + nr_attributes; + nr_attributes++; } lower_attributes_to_hw_regs(attribute_map, false /* interleaved */); @@ -1979,11 +1989,18 @@ brw_compile_vs(const struct brw_compiler *compiler, void *log_data, * incoming vertex attribute. So, add an extra slot. */ if (shader->info.system_values_read & - (BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) | + (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) | + BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE) | + BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) | BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID))) { nr_attributes++; } + /* gl_DrawID has its very own vec4 */ + if (shader->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID)) { + nr_attributes++; + } + /* The 3DSTATE_VS documentation lists the lower bound on "Vertex URB Entry * Read Length" as 1 in vec4 mode, and 0 in SIMD8 mode. Empirically, in * vec4 mode, the hardware appears to wedge unless we read something. diff --git a/src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp b/src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp index c31e72def67..166bc17e1e1 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp @@ -47,6 +47,8 @@ can_do_writemask(const struct brw_device_info *devinfo, case VS_OPCODE_SET_SIMD4X2_HEADER_GEN9: case TCS_OPCODE_SET_INPUT_URB_OFFSETS: case TCS_OPCODE_SET_OUTPUT_URB_OFFSETS: + case TES_OPCODE_CREATE_INPUT_READ_HEADER: + case TES_OPCODE_ADD_INDIRECT_URB_OFFSET: case VEC4_OPCODE_URB_READ: return false; default: diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp index 86ae9289df1..c6fa837dc74 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp @@ -724,6 +724,9 @@ generate_gs_set_primitive_id(struct brw_codegen *p, struct brw_reg dst) static void generate_tcs_get_instance_id(struct brw_codegen *p, struct brw_reg dst) { + const struct brw_device_info *devinfo = p->devinfo; + const bool ivb = devinfo->is_ivybridge || devinfo->is_baytrail; + /* "Instance Count" comes as part of the payload in r0.2 bits 23:17. * * Since we operate in SIMD4x2 mode, we need run half as many threads @@ -736,8 +739,8 @@ generate_tcs_get_instance_id(struct brw_codegen *p, struct brw_reg dst) brw_push_insn_state(p); brw_set_default_access_mode(p, BRW_ALIGN_1); - const int mask = INTEL_MASK(23, 17); - const int shift = 17; + const int mask = ivb ? INTEL_MASK(22, 16) : INTEL_MASK(23, 17); + const int shift = ivb ? 16 : 17; brw_AND(p, get_element_ud(dst, 0), get_element_ud(r0, 2), brw_imm_ud(mask)); brw_SHR(p, get_element_ud(dst, 0), get_element_ud(dst, 0), @@ -763,8 +766,12 @@ generate_tcs_urb_write(struct brw_codegen *p, true /* header */, false /* eot */); brw_inst_set_urb_opcode(devinfo, send, BRW_URB_OPCODE_WRITE_OWORD); brw_inst_set_urb_global_offset(devinfo, send, inst->offset); - brw_inst_set_urb_per_slot_offset(devinfo, send, 1); - brw_inst_set_urb_swizzle_control(devinfo, send, BRW_URB_SWIZZLE_INTERLEAVE); + if (inst->urb_write_flags & BRW_URB_WRITE_EOT) { + brw_inst_set_eot(devinfo, send, 1); + } else { + brw_inst_set_urb_per_slot_offset(devinfo, send, 1); + brw_inst_set_urb_swizzle_control(devinfo, send, BRW_URB_SWIZZLE_INTERLEAVE); + } /* what happens to swizzles? */ } @@ -872,6 +879,46 @@ generate_tcs_output_urb_offsets(struct brw_codegen *p, brw_pop_insn_state(p); } +static void +generate_tes_create_input_read_header(struct brw_codegen *p, + struct brw_reg dst) +{ + brw_push_insn_state(p); + brw_set_default_access_mode(p, BRW_ALIGN_1); + brw_set_default_mask_control(p, BRW_MASK_DISABLE); + + /* Initialize the register to 0 */ + brw_MOV(p, dst, brw_imm_ud(0)); + + /* Enable all the channels in m0.5 bits 15:8 */ + brw_MOV(p, get_element_ud(dst, 5), brw_imm_ud(0xff00)); + + /* Copy g1.3 (the patch URB handle) to m0.0 and m0.1. For safety, + * mask out irrelevant "Reserved" bits, as they're not marked MBZ. + */ + brw_AND(p, vec2(get_element_ud(dst, 0)), + retype(brw_vec1_grf(1, 3), BRW_REGISTER_TYPE_UD), + brw_imm_ud(0x1fff)); + brw_pop_insn_state(p); +} + +static void +generate_tes_add_indirect_urb_offset(struct brw_codegen *p, + struct brw_reg dst, + struct brw_reg header, + struct brw_reg offset) +{ + brw_push_insn_state(p); + brw_set_default_access_mode(p, BRW_ALIGN_1); + brw_set_default_mask_control(p, BRW_MASK_DISABLE); + + brw_MOV(p, dst, header); + /* m0.3-0.4: 128-bit-granular offsets into the URB from the handles */ + brw_MOV(p, vec2(get_element_ud(dst, 3)), stride(offset, 4, 1, 0)); + + brw_pop_insn_state(p); +} + static void generate_vec4_urb_read(struct brw_codegen *p, vec4_instruction *inst, @@ -897,6 +944,75 @@ generate_vec4_urb_read(struct brw_codegen *p, brw_inst_set_urb_global_offset(devinfo, send, inst->offset); } +static void +generate_tcs_release_input(struct brw_codegen *p, + struct brw_reg header, + struct brw_reg vertex, + struct brw_reg is_unpaired) +{ + const struct brw_device_info *devinfo = p->devinfo; + + assert(vertex.file == BRW_IMMEDIATE_VALUE); + assert(vertex.type == BRW_REGISTER_TYPE_UD); + + /* m0.0-0.1: URB handles */ + struct brw_reg urb_handles = + retype(brw_vec2_grf(1 + (vertex.ud >> 3), vertex.ud & 7), + BRW_REGISTER_TYPE_UD); + + brw_push_insn_state(p); + brw_set_default_access_mode(p, BRW_ALIGN_1); + brw_set_default_mask_control(p, BRW_MASK_DISABLE); + brw_MOV(p, header, brw_imm_ud(0)); + brw_MOV(p, vec2(get_element_ud(header, 0)), urb_handles); + brw_pop_insn_state(p); + + brw_inst *send = brw_next_insn(p, BRW_OPCODE_SEND); + brw_set_dest(p, send, brw_null_reg()); + brw_set_src0(p, send, header); + brw_set_message_descriptor(p, send, BRW_SFID_URB, + 1 /* mlen */, 0 /* rlen */, + true /* header */, false /* eot */); + brw_inst_set_urb_opcode(devinfo, send, BRW_URB_OPCODE_READ_OWORD); + brw_inst_set_urb_complete(devinfo, send, 1); + brw_inst_set_urb_swizzle_control(devinfo, send, is_unpaired.ud ? + BRW_URB_SWIZZLE_NONE : + BRW_URB_SWIZZLE_INTERLEAVE); +} + +static void +generate_tcs_thread_end(struct brw_codegen *p, vec4_instruction *inst) +{ + struct brw_reg header = brw_message_reg(inst->base_mrf); + + brw_push_insn_state(p); + brw_set_default_access_mode(p, BRW_ALIGN_1); + brw_set_default_mask_control(p, BRW_MASK_DISABLE); + brw_MOV(p, header, brw_imm_ud(0)); + brw_MOV(p, get_element_ud(header, 0), + retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UD)); + brw_pop_insn_state(p); + + brw_urb_WRITE(p, + brw_null_reg(), /* dest */ + inst->base_mrf, /* starting mrf reg nr */ + header, + BRW_URB_WRITE_EOT | inst->urb_write_flags, + inst->mlen, + 0, /* response len */ + 0, /* urb destination offset */ + 0); +} + +static void +generate_tes_get_primitive_id(struct brw_codegen *p, struct brw_reg dst) +{ + brw_push_insn_state(p); + brw_set_default_access_mode(p, BRW_ALIGN_1); + brw_MOV(p, dst, retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_D)); + brw_pop_insn_state(p); +} + static void generate_tcs_get_primitive_id(struct brw_codegen *p, struct brw_reg dst) { @@ -911,6 +1027,8 @@ generate_tcs_create_barrier_header(struct brw_codegen *p, struct brw_vue_prog_data *prog_data, struct brw_reg dst) { + const struct brw_device_info *devinfo = p->devinfo; + const bool ivb = devinfo->is_ivybridge || devinfo->is_baytrail; struct brw_reg m0_2 = get_element_ud(dst, 2); unsigned instances = ((struct brw_tcs_prog_data *) prog_data)->instances; @@ -921,13 +1039,13 @@ generate_tcs_create_barrier_header(struct brw_codegen *p, /* Zero the message header */ brw_MOV(p, retype(dst, BRW_REGISTER_TYPE_UD), brw_imm_ud(0u)); - /* Copy "Barrier ID" from DW0 bits 16:13 */ + /* Copy "Barrier ID" from r0.2, bits 16:13 (Gen7.5+) or 15:12 (Gen7) */ brw_AND(p, m0_2, retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_UD), - brw_imm_ud(0x1e000)); + brw_imm_ud(ivb ? INTEL_MASK(15, 12) : INTEL_MASK(16, 13))); - /* Shift it into place */ - brw_SHL(p, m0_2, get_element_ud(dst, 2), brw_imm_ud(11)); + /* Shift it up to bits 27:24. */ + brw_SHL(p, m0_2, get_element_ud(dst, 2), brw_imm_ud(ivb ? 12 : 11)); /* Set the Barrier Count and the enable bit */ brw_OR(p, m0_2, m0_2, brw_imm_ud(instances << 9 | (1 << 15))); @@ -1788,6 +1906,32 @@ generate_code(struct brw_codegen *p, generate_tcs_create_barrier_header(p, prog_data, dst); break; + case TES_OPCODE_CREATE_INPUT_READ_HEADER: + generate_tes_create_input_read_header(p, dst); + break; + + case TES_OPCODE_ADD_INDIRECT_URB_OFFSET: + generate_tes_add_indirect_urb_offset(p, dst, src[0], src[1]); + break; + + case TES_OPCODE_GET_PRIMITIVE_ID: + generate_tes_get_primitive_id(p, dst); + break; + + case TCS_OPCODE_SRC0_010_IS_ZERO: + /* If src_reg had stride like fs_reg, we wouldn't need this. */ + brw_MOV(p, brw_null_reg(), stride(src[0], 0, 1, 0)); + brw_inst_set_cond_modifier(devinfo, brw_last_inst, BRW_CONDITIONAL_Z); + break; + + case TCS_OPCODE_RELEASE_INPUT: + generate_tcs_release_input(p, dst, src[0], src[1]); + break; + + case TCS_OPCODE_THREAD_END: + generate_tcs_thread_end(p, inst); + break; + case SHADER_OPCODE_BARRIER: brw_barrier(p, src[0]); brw_WAIT(p); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index 6ea0757de87..37f517d4efd 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -78,6 +78,20 @@ vec4_visitor::nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr) glsl_type::int_type); break; + case nir_intrinsic_load_base_instance: + reg = &nir_system_values[SYSTEM_VALUE_BASE_INSTANCE]; + if (reg->file == BAD_FILE) + *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_INSTANCE, + glsl_type::int_type); + break; + + case nir_intrinsic_load_draw_id: + reg = &nir_system_values[SYSTEM_VALUE_DRAW_ID]; + if (reg->file == BAD_FILE) + *reg = *make_reg_for_system_value(SYSTEM_VALUE_DRAW_ID, + glsl_type::int_type); + break; + default: break; } @@ -669,6 +683,8 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) case nir_intrinsic_load_vertex_id_zero_base: case nir_intrinsic_load_base_vertex: case nir_intrinsic_load_instance_id: + case nir_intrinsic_load_base_instance: + case nir_intrinsic_load_draw_id: case nir_intrinsic_load_invocation_id: case nir_intrinsic_load_tess_level_inner: case nir_intrinsic_load_tess_level_outer: { diff --git a/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp b/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp index 507db749e63..fb6ca8ee5f9 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp @@ -156,18 +156,56 @@ vec4_tcs_visitor::emit_prolog() void vec4_tcs_visitor::emit_thread_end() { + vec4_instruction *inst; current_annotation = "thread end"; if (nir->info.tcs.vertices_out % 2) { emit(BRW_OPCODE_ENDIF); } + if (devinfo->gen == 7) { + struct brw_tcs_prog_data *tcs_prog_data = + (struct brw_tcs_prog_data *) prog_data; + + current_annotation = "release input vertices"; + + /* Synchronize all threads, so we know that no one is still + * using the input URB handles. + */ + if (tcs_prog_data->instances > 1) { + dst_reg header = dst_reg(this, glsl_type::uvec4_type); + emit(TCS_OPCODE_CREATE_BARRIER_HEADER, header); + emit(SHADER_OPCODE_BARRIER, dst_null_ud(), src_reg(header)); + } + + /* Make thread 0 (invocations <1, 0>) release pairs of ICP handles. + * We want to compare the bottom half of invocation_id with 0, but + * use that truth value for the top half as well. Unfortunately, + * we don't have stride in the vec4 world, nor UV immediates in + * align16, so we need an opcode to get invocation_id<0,4,0>. + */ + emit(TCS_OPCODE_SRC0_010_IS_ZERO, dst_null_d(), invocation_id); + emit(IF(BRW_PREDICATE_NORMAL)); + for (unsigned i = 0; i < key->input_vertices; i += 2) { + /* If we have an odd number of input vertices, the last will be + * unpaired. We don't want to use an interleaved URB write in + * that case. + */ + const bool is_unpaired = i == key->input_vertices - 1; + + dst_reg header(this, glsl_type::uvec4_type); + emit(TCS_OPCODE_RELEASE_INPUT, header, brw_imm_ud(i), + brw_imm_ud(is_unpaired)); + } + emit(BRW_OPCODE_ENDIF); + } + if (unlikely(INTEL_DEBUG & DEBUG_SHADER_TIME)) emit_shader_time_end(); - vec4_instruction *inst = emit(VS_OPCODE_URB_WRITE); - inst->mlen = 1; /* just the header, no data. */ - inst->urb_write_flags = BRW_URB_WRITE_EOT_COMPLETE; + inst = emit(TCS_OPCODE_THREAD_END); + inst->base_mrf = 14; + inst->mlen = 1; } diff --git a/src/mesa/drivers/dri/i965/brw_vec4_tes.cpp b/src/mesa/drivers/dri/i965/brw_vec4_tes.cpp new file mode 100644 index 00000000000..ce5fefc75a9 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_vec4_tes.cpp @@ -0,0 +1,204 @@ +/* + * Copyright © 2013 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. + */ + +/** + * \file brw_vec4_tes.cpp + * + * Tessellaton evaluation shader specific code derived from the vec4_visitor class. + */ + +#include "brw_vec4_tes.h" + +namespace brw { + +vec4_tes_visitor::vec4_tes_visitor(const struct brw_compiler *compiler, + void *log_data, + const struct brw_tes_prog_key *key, + struct brw_tes_prog_data *prog_data, + const nir_shader *shader, + void *mem_ctx, + int shader_time_index) + : vec4_visitor(compiler, log_data, &key->tex, &prog_data->base, + shader, mem_ctx, false, shader_time_index) +{ +} + + +dst_reg * +vec4_tes_visitor::make_reg_for_system_value(int location, const glsl_type *type) +{ + return NULL; +} + +void +vec4_tes_visitor::nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr) +{ + const struct brw_tes_prog_data *tes_prog_data = + (const struct brw_tes_prog_data *) prog_data; + + switch (instr->intrinsic) { + case nir_intrinsic_load_tess_level_outer: { + dst_reg dst(this, glsl_type::vec4_type); + nir_system_values[SYSTEM_VALUE_TESS_LEVEL_OUTER] = dst; + + dst_reg temp(this, glsl_type::vec4_type); + vec4_instruction *read = + emit(VEC4_OPCODE_URB_READ, temp, input_read_header); + read->offset = 1; + read->urb_write_flags = BRW_URB_WRITE_PER_SLOT_OFFSET; + emit(MOV(dst, swizzle(src_reg(temp), BRW_SWIZZLE_WZYX))); + break; + } + case nir_intrinsic_load_tess_level_inner: { + dst_reg dst(this, glsl_type::vec2_type); + nir_system_values[SYSTEM_VALUE_TESS_LEVEL_INNER] = dst; + + /* Set up the message header to reference the proper parts of the URB */ + dst_reg temp(this, glsl_type::vec4_type); + vec4_instruction *read = + emit(VEC4_OPCODE_URB_READ, temp, input_read_header); + read->urb_write_flags = BRW_URB_WRITE_PER_SLOT_OFFSET; + if (tes_prog_data->domain == BRW_TESS_DOMAIN_QUAD) { + emit(MOV(dst, swizzle(src_reg(temp), BRW_SWIZZLE_WZYX))); + } else { + read->offset = 1; + emit(MOV(dst, src_reg(temp))); + } + break; + } + default: + vec4_visitor::nir_setup_system_value_intrinsic(instr); + } +} + + +void +vec4_tes_visitor::setup_payload() +{ + int reg = 0; + + /* The payload always contains important data in r0 and r1, which contains + * the URB handles that are passed on to the URB write at the end + * of the thread. + */ + reg += 2; + + reg = setup_uniforms(reg); + + this->first_non_payload_grf = reg; +} + + +void +vec4_tes_visitor::emit_prolog() +{ + input_read_header = src_reg(this, glsl_type::uvec4_type); + emit(TES_OPCODE_CREATE_INPUT_READ_HEADER, dst_reg(input_read_header)); + + this->current_annotation = NULL; +} + + +void +vec4_tes_visitor::emit_urb_write_header(int mrf) +{ + /* No need to do anything for DS; an implied write to this MRF will be + * performed by VS_OPCODE_URB_WRITE. + */ + (void) mrf; +} + + +vec4_instruction * +vec4_tes_visitor::emit_urb_write_opcode(bool complete) +{ + /* For DS, the URB writes end the thread. */ + if (complete) { + if (INTEL_DEBUG & DEBUG_SHADER_TIME) + emit_shader_time_end(); + } + + vec4_instruction *inst = emit(VS_OPCODE_URB_WRITE); + inst->urb_write_flags = complete ? + BRW_URB_WRITE_EOT_COMPLETE : BRW_URB_WRITE_NO_FLAGS; + + return inst; +} + +void +vec4_tes_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) +{ + switch (instr->intrinsic) { + case nir_intrinsic_load_tess_coord: + /* gl_TessCoord is part of the payload in g1 channels 0-2 and 4-6. */ + emit(MOV(get_nir_dest(instr->dest, BRW_REGISTER_TYPE_F), + src_reg(brw_vec8_grf(1, 0)))); + break; + case nir_intrinsic_load_primitive_id: + emit(TES_OPCODE_GET_PRIMITIVE_ID, + get_nir_dest(instr->dest, BRW_REGISTER_TYPE_UD)); + break; + + case nir_intrinsic_load_input: + case nir_intrinsic_load_per_vertex_input: { + src_reg indirect_offset = get_indirect_offset(instr); + unsigned imm_offset = instr->const_index[0]; + src_reg header = input_read_header; + + if (indirect_offset.file != BAD_FILE) { + header = src_reg(this, glsl_type::uvec4_type); + emit(TES_OPCODE_ADD_INDIRECT_URB_OFFSET, dst_reg(header), + input_read_header, indirect_offset); + } + + dst_reg temp(this, glsl_type::ivec4_type); + vec4_instruction *read = + emit(VEC4_OPCODE_URB_READ, temp, src_reg(header)); + read->offset = imm_offset; + read->urb_write_flags = BRW_URB_WRITE_PER_SLOT_OFFSET; + + /* Copy to target. We might end up with some funky writemasks landing + * in here, but we really don't want them in the above pseudo-ops. + */ + dst_reg dst = get_nir_dest(instr->dest, BRW_REGISTER_TYPE_D); + dst.writemask = brw_writemask_for_size(instr->num_components); + emit(MOV(dst, src_reg(temp))); + break; + } + default: + vec4_visitor::nir_emit_intrinsic(instr); + } +} + + +void +vec4_tes_visitor::emit_thread_end() +{ + /* For DS, we always end the thread by emitting a single vertex. + * emit_urb_write_opcode() will take care of setting the eot flag on the + * SEND instruction. + */ + emit_vertex(); +} + +} /* namespace brw */ diff --git a/src/mesa/drivers/dri/i965/brw_vec4_tes.h b/src/mesa/drivers/dri/i965/brw_vec4_tes.h new file mode 100644 index 00000000000..4b697aa592f --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_vec4_tes.h @@ -0,0 +1,69 @@ +/* + * Copyright © 2013 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. + */ + +/** + * \file brw_vec4_tes.h + * + * The vec4 mode tessellation evaluation shader compiler backend. + */ + +#ifndef BRW_VEC4_TES_H +#define BRW_VEC4_TES_H + +#include "brw_vec4.h" + +#ifdef __cplusplus +namespace brw { + +class vec4_tes_visitor : public vec4_visitor +{ +public: + vec4_tes_visitor(const struct brw_compiler *compiler, + void *log_data, + const struct brw_tes_prog_key *key, + struct brw_tes_prog_data *prog_data, + const nir_shader *nir, + void *mem_ctx, + int shader_time_index); + +protected: + virtual dst_reg *make_reg_for_system_value(int location, + const glsl_type *type); + virtual void nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr); + virtual void nir_emit_intrinsic(nir_intrinsic_instr *instr); + + virtual void setup_payload(); + virtual void emit_prolog(); + virtual void emit_thread_end(); + + virtual void emit_urb_write_header(int mrf); + virtual vec4_instruction *emit_urb_write_opcode(bool complete); + +private: + src_reg input_read_header; +}; + +} /* namespace brw */ +#endif /* __cplusplus */ + +#endif /* BRW_VEC4_TES_H */ diff --git a/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp index fd8be7d972c..1d6914902b3 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp @@ -155,7 +155,11 @@ vec4_vs_visitor::make_reg_for_system_value(int location, switch (location) { case SYSTEM_VALUE_BASE_VERTEX: reg->writemask = WRITEMASK_X; - vs_prog_data->uses_vertexid = true; + vs_prog_data->uses_basevertex = true; + break; + case SYSTEM_VALUE_BASE_INSTANCE: + reg->writemask = WRITEMASK_Y; + vs_prog_data->uses_baseinstance = true; break; case SYSTEM_VALUE_VERTEX_ID: case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE: @@ -166,6 +170,11 @@ vec4_vs_visitor::make_reg_for_system_value(int location, reg->writemask = WRITEMASK_W; vs_prog_data->uses_instanceid = true; break; + case SYSTEM_VALUE_DRAW_ID: + reg = new(mem_ctx) dst_reg(ATTR, VERT_ATTRIB_MAX + 1); + reg->writemask = WRITEMASK_X; + vs_prog_data->uses_drawid = true; + break; default: unreachable("not reached"); } diff --git a/src/mesa/drivers/dri/i965/gen7_ds_state.c b/src/mesa/drivers/dri/i965/gen7_ds_state.c index 9a697140386..30deabb06ed 100644 --- a/src/mesa/drivers/dri/i965/gen7_ds_state.c +++ b/src/mesa/drivers/dri/i965/gen7_ds_state.c @@ -58,36 +58,64 @@ const struct brw_tracked_state gen7_tes_push_constants = { static void gen7_upload_ds_state(struct brw_context *brw) { - /* Disable the DS Unit */ - BEGIN_BATCH(7); - OUT_BATCH(_3DSTATE_CONSTANT_DS << 16 | (7 - 2)); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); + const struct brw_stage_state *stage_state = &brw->tes.base; + /* BRW_NEW_TESS_PROGRAMS */ + bool active = brw->tess_eval_program; - BEGIN_BATCH(6); - OUT_BATCH(_3DSTATE_DS << 16 | (6 - 2)); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); + /* BRW_NEW_TES_PROG_DATA */ + const struct brw_tes_prog_data *tes_prog_data = brw->tes.prog_data; + const struct brw_vue_prog_data *vue_prog_data = &tes_prog_data->base; + const struct brw_stage_prog_data *prog_data = &vue_prog_data->base; - BEGIN_BATCH(2); - OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_DS << 16 | (2 - 2)); - OUT_BATCH(brw->hw_bt_pool.next_offset); - ADVANCE_BATCH(); + const unsigned thread_count = (brw->max_ds_threads - 1) << + (brw->is_haswell ? HSW_DS_MAX_THREADS_SHIFT : GEN7_DS_MAX_THREADS_SHIFT); + + if (active) { + BEGIN_BATCH(6); + OUT_BATCH(_3DSTATE_DS << 16 | (6 - 2)); + OUT_BATCH(stage_state->prog_offset); + OUT_BATCH(SET_FIELD(DIV_ROUND_UP(stage_state->sampler_count, 4), + GEN7_DS_SAMPLER_COUNT) | + SET_FIELD(prog_data->binding_table.size_bytes / 4, + GEN7_DS_BINDING_TABLE_ENTRY_COUNT)); + if (prog_data->total_scratch) { + OUT_RELOC(stage_state->scratch_bo, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + ffs(prog_data->total_scratch) - 11); + } else { + OUT_BATCH(0); + } + OUT_BATCH(SET_FIELD(prog_data->dispatch_grf_start_reg, + GEN7_DS_DISPATCH_START_GRF) | + SET_FIELD(vue_prog_data->urb_read_length, + GEN7_DS_URB_READ_LENGTH)); + + OUT_BATCH(GEN7_DS_ENABLE | + GEN7_DS_STATISTICS_ENABLE | + thread_count | + (tes_prog_data->domain == BRW_TESS_DOMAIN_TRI ? + GEN7_DS_COMPUTE_W_COORDINATE_ENABLE : 0)); + ADVANCE_BATCH(); + } else { + BEGIN_BATCH(6); + OUT_BATCH(_3DSTATE_DS << 16 | (6 - 2)); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + ADVANCE_BATCH(); + } + brw->tes.enabled = active; } const struct brw_tracked_state gen7_ds_state = { .dirty = { - .mesa = 0, - .brw = BRW_NEW_CONTEXT, + .mesa = _NEW_TRANSFORM, + .brw = BRW_NEW_BATCH | + BRW_NEW_CONTEXT | + BRW_NEW_TESS_PROGRAMS | + BRW_NEW_TES_PROG_DATA, }, .emit = gen7_upload_ds_state, }; diff --git a/src/mesa/drivers/dri/i965/gen7_hs_state.c b/src/mesa/drivers/dri/i965/gen7_hs_state.c index 6793617b9e2..0e2b3b2604e 100644 --- a/src/mesa/drivers/dri/i965/gen7_hs_state.c +++ b/src/mesa/drivers/dri/i965/gen7_hs_state.c @@ -60,37 +60,58 @@ const struct brw_tracked_state gen7_tcs_push_constants = { static void gen7_upload_hs_state(struct brw_context *brw) { - /* Disable the HS Unit */ - BEGIN_BATCH(7); - OUT_BATCH(_3DSTATE_CONSTANT_HS << 16 | (7 - 2)); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); + const struct brw_stage_state *stage_state = &brw->tcs.base; + /* BRW_NEW_TESS_PROGRAMS */ + bool active = brw->tess_eval_program; + /* BRW_NEW_TCS_PROG_DATA */ + const struct brw_vue_prog_data *prog_data = &brw->tcs.prog_data->base; - BEGIN_BATCH(7); - OUT_BATCH(_3DSTATE_HS << 16 | (7 - 2)); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - - BEGIN_BATCH(2); - OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_HS << 16 | (2 - 2)); - OUT_BATCH(brw->hw_bt_pool.next_offset); - ADVANCE_BATCH(); + if (active) { + BEGIN_BATCH(7); + OUT_BATCH(_3DSTATE_HS << 16 | (7 - 2)); + OUT_BATCH(SET_FIELD(DIV_ROUND_UP(stage_state->sampler_count, 4), + GEN7_HS_SAMPLER_COUNT) | + SET_FIELD(prog_data->base.binding_table.size_bytes / 4, + GEN7_HS_BINDING_TABLE_ENTRY_COUNT) | + (brw->max_hs_threads - 1)); + OUT_BATCH(GEN7_HS_ENABLE | + GEN7_HS_STATISTICS_ENABLE | + SET_FIELD(brw->tcs.prog_data->instances - 1, + GEN7_HS_INSTANCE_COUNT)); + OUT_BATCH(stage_state->prog_offset); + if (prog_data->base.total_scratch) { + OUT_RELOC(stage_state->scratch_bo, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + ffs(prog_data->base.total_scratch) - 11); + } else { + OUT_BATCH(0); + } + OUT_BATCH(GEN7_HS_INCLUDE_VERTEX_HANDLES | + SET_FIELD(prog_data->base.dispatch_grf_start_reg, + GEN7_HS_DISPATCH_START_GRF)); + /* Ignore URB semaphores */ + OUT_BATCH(0); + ADVANCE_BATCH(); + } else { + BEGIN_BATCH(7); + OUT_BATCH(_3DSTATE_HS << 16 | (7 - 2)); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + ADVANCE_BATCH(); + } + brw->tcs.enabled = active; } const struct brw_tracked_state gen7_hs_state = { .dirty = { .mesa = 0, - .brw = BRW_NEW_CONTEXT, + .brw = BRW_NEW_BATCH | + BRW_NEW_TCS_PROG_DATA | + BRW_NEW_TESS_PROGRAMS, }, .emit = gen7_upload_hs_state, }; diff --git a/src/mesa/drivers/dri/i965/gen8_draw_upload.c b/src/mesa/drivers/dri/i965/gen8_draw_upload.c index 198d612c514..ff89e5f240d 100644 --- a/src/mesa/drivers/dri/i965/gen8_draw_upload.c +++ b/src/mesa/drivers/dri/i965/gen8_draw_upload.c @@ -115,7 +115,12 @@ gen8_emit_vertices(struct brw_context *brw) } /* Now emit 3DSTATE_VERTEX_BUFFERS and 3DSTATE_VERTEX_ELEMENTS packets. */ - unsigned nr_buffers = brw->vb.nr_buffers + brw->vs.prog_data->uses_vertexid; + const bool uses_draw_params = + brw->vs.prog_data->uses_basevertex || + brw->vs.prog_data->uses_baseinstance; + const unsigned nr_buffers = brw->vb.nr_buffers + + uses_draw_params + brw->vs.prog_data->uses_drawid; + if (nr_buffers) { assert(nr_buffers <= 33); @@ -135,7 +140,7 @@ gen8_emit_vertices(struct brw_context *brw) OUT_BATCH(buffer->bo->size); } - if (brw->vs.prog_data->uses_vertexid) { + if (uses_draw_params) { OUT_BATCH(brw->vb.nr_buffers << GEN6_VB0_INDEX_SHIFT | GEN7_VB0_ADDRESS_MODIFYENABLE | mocs_wb << 16); @@ -143,21 +148,33 @@ gen8_emit_vertices(struct brw_context *brw) brw->draw.draw_params_offset); OUT_BATCH(brw->draw.draw_params_bo->size); } + + if (brw->vs.prog_data->uses_drawid) { + OUT_BATCH((brw->vb.nr_buffers + 1) << GEN6_VB0_INDEX_SHIFT | + GEN7_VB0_ADDRESS_MODIFYENABLE | + mocs_wb << 16); + OUT_RELOC64(brw->draw.draw_id_bo, I915_GEM_DOMAIN_VERTEX, 0, + brw->draw.draw_id_offset); + OUT_BATCH(brw->draw.draw_id_bo->size); + } ADVANCE_BATCH(); } /* 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. + * element that is past the list in 3DSTATE_VERTEX_ELEMENTS. However if + * we're using draw parameters then we need an element for the those + * values. 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; + const bool needs_sgvs_element = (brw->vs.prog_data->uses_basevertex || + brw->vs.prog_data->uses_baseinstance || + ((brw->vs.prog_data->uses_instanceid || + brw->vs.prog_data->uses_vertexid) && + uses_edge_flag)); + const unsigned nr_elements = + brw->vb.nr_enabled + needs_sgvs_element + brw->vs.prog_data->uses_drawid; /* The hardware allows one more VERTEX_ELEMENTS than VERTEX_BUFFERS, * presumably for VertexID/InstanceID. @@ -212,12 +229,13 @@ gen8_emit_vertices(struct brw_context *brw) } if (needs_sgvs_element) { - if (brw->vs.prog_data->uses_vertexid) { + if (brw->vs.prog_data->uses_basevertex || + brw->vs.prog_data->uses_baseinstance) { OUT_BATCH(GEN6_VE0_VALID | brw->vb.nr_buffers << GEN6_VE0_INDEX_SHIFT | - BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT); + BRW_SURFACEFORMAT_R32G32_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_SRC << 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 { @@ -229,6 +247,16 @@ gen8_emit_vertices(struct brw_context *brw) } } + if (brw->vs.prog_data->uses_drawid) { + OUT_BATCH(GEN6_VE0_VALID | + ((brw->vb.nr_buffers + 1) << 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)); + } + if (gen6_edgeflag_input) { uint32_t format = brw_get_vertex_surface_type(brw, gen6_edgeflag_input->glarray); @@ -266,6 +294,15 @@ gen8_emit_vertices(struct brw_context *brw) OUT_BATCH(buffer->step_rate); ADVANCE_BATCH(); } + + if (brw->vs.prog_data->uses_drawid) { + const unsigned element = brw->vb.nr_enabled + needs_sgvs_element; + BEGIN_BATCH(3); + OUT_BATCH(_3DSTATE_VF_INSTANCING << 16 | (3 - 2)); + OUT_BATCH(element); + OUT_BATCH(0); + ADVANCE_BATCH(); + } } const struct brw_tracked_state gen8_vertices = { diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c index 06672c1b4db..e1338e92e15 100644 --- a/src/mesa/drivers/dri/i965/intel_extensions.c +++ b/src/mesa/drivers/dri/i965/intel_extensions.c @@ -203,6 +203,7 @@ intelInitExtensions(struct gl_context *ctx) ctx->Extensions.ARB_point_sprite = true; ctx->Extensions.ARB_seamless_cube_map = true; ctx->Extensions.ARB_shader_bit_encoding = true; + ctx->Extensions.ARB_shader_draw_parameters = true; ctx->Extensions.ARB_shader_texture_lod = true; ctx->Extensions.ARB_shadow = true; ctx->Extensions.ARB_sync = true; @@ -333,6 +334,7 @@ intelInitExtensions(struct gl_context *ctx) ctx->Extensions.ARB_shader_image_load_store = true; ctx->Extensions.ARB_shader_image_size = true; ctx->Extensions.ARB_shader_texture_image_samples = true; + ctx->Extensions.ARB_tessellation_shader = true; ctx->Extensions.ARB_texture_compression_bptc = true; ctx->Extensions.ARB_texture_view = true; ctx->Extensions.ARB_shader_storage_buffer_object = true; @@ -362,7 +364,6 @@ intelInitExtensions(struct gl_context *ctx) if (brw->gen >= 8) { ctx->Extensions.ARB_stencil_texturing = true; - ctx->Extensions.ARB_tessellation_shader = true; } if (brw->gen >= 9) { diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h index 52a4ed63c0d..789b55a3c8d 100644 --- a/src/mesa/main/extensions_table.h +++ b/src/mesa/main/extensions_table.h @@ -96,6 +96,7 @@ EXT(ARB_separate_shader_objects , dummy_true EXT(ARB_shader_atomic_counters , ARB_shader_atomic_counters , GLL, GLC, x , x , 2011) EXT(ARB_shader_bit_encoding , ARB_shader_bit_encoding , GLL, GLC, x , x , 2010) EXT(ARB_shader_clock , ARB_shader_clock , GLL, GLC, x , x , 2015) +EXT(ARB_shader_draw_parameters , ARB_shader_draw_parameters , GLL, GLC, x , x , 2013) EXT(ARB_shader_image_load_store , ARB_shader_image_load_store , GLL, GLC, x , x , 2011) EXT(ARB_shader_image_size , ARB_shader_image_size , GLL, GLC, x , x , 2012) EXT(ARB_shader_objects , dummy_true , GLL, GLC, x , x , 2002) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 26dfac1ab90..3f28d3313b1 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3717,6 +3717,7 @@ struct gl_extensions GLboolean ARB_shader_atomic_counters; GLboolean ARB_shader_bit_encoding; GLboolean ARB_shader_clock; + GLboolean ARB_shader_draw_parameters; GLboolean ARB_shader_image_load_store; GLboolean ARB_shader_image_size; GLboolean ARB_shader_precision; diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c index 54e55da6def..72c9e97d721 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c @@ -1083,11 +1083,11 @@ prog_to_nir(const struct gl_program *prog, c = rzalloc(NULL, struct ptn_compile); if (!c) return NULL; - s = nir_shader_create(NULL, stage, options); - if (!s) - goto fail; c->prog = prog; + nir_builder_init_simple_shader(&c->build, NULL, stage, options); + s = c->build.shader; + if (prog->Parameters->NumParameters > 0) { c->parameters = rzalloc(s, nir_variable); c->parameters->type = @@ -1098,13 +1098,6 @@ prog_to_nir(const struct gl_program *prog, exec_list_push_tail(&s->uniforms, &c->parameters->node); } - nir_function *func = nir_function_create(s, "main"); - nir_function_impl *impl = nir_function_impl_create(func); - - c->build.shader = s; - c->build.impl = impl; - c->build.cursor = nir_after_cf_list(&impl->body); - setup_registers_and_variables(c); if (unlikely(c->error)) goto fail; diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 89ad6cd8c28..5a6be08185f 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -4328,6 +4328,8 @@ const unsigned _mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { TGSI_SEMANTIC_INSTANCEID, TGSI_SEMANTIC_VERTEXID_NOBASE, TGSI_SEMANTIC_BASEVERTEX, + 0, /* SYSTEM_VALUE_BASE_INSTANCE */ + 0, /* SYSTEM_VALUE_DRAW_ID */ /* Geometry shader */ diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 00e843c9a0f..cef3b8cd792 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -58,6 +58,7 @@ struct _mesa_prim { GLint basevertex; GLuint num_instances; GLuint base_instance; + GLuint draw_id; GLsizeiptr indirect_offset; }; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index e27fdd90532..502b2885892 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -1341,6 +1341,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, prim[i].indexed = 1; prim[i].num_instances = 1; prim[i].base_instance = 0; + prim[i].draw_id = i; prim[i].is_indirect = 0; if (basevertex != NULL) prim[i].basevertex = basevertex[i]; @@ -1371,6 +1372,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, prim[0].indexed = 1; prim[0].num_instances = 1; prim[0].base_instance = 0; + prim[0].draw_id = i; prim[0].is_indirect = 0; if (basevertex != NULL) prim[0].basevertex = basevertex[i]; @@ -1598,6 +1600,7 @@ vbo_validated_multidrawarraysindirect(struct gl_context *ctx, prim[i].mode = mode; prim[i].indirect_offset = offset; prim[i].is_indirect = 1; + prim[i].draw_id = i; } check_buffers_are_unmapped(exec->array.inputs); @@ -1684,6 +1687,7 @@ vbo_validated_multidrawelementsindirect(struct gl_context *ctx, prim[i].indexed = 1; prim[i].indirect_offset = offset; prim[i].is_indirect = 1; + prim[i].draw_id = i; } check_buffers_are_unmapped(exec->array.inputs); diff --git a/src/vulkan/anv_meta.c b/src/vulkan/anv_meta.c index c1d600a3ed8..5b564eb4dc2 100644 --- a/src/vulkan/anv_meta.c +++ b/src/vulkan/anv_meta.c @@ -30,7 +30,7 @@ #include "anv_meta.h" #include "anv_meta_clear.h" #include "anv_private.h" -#include "anv_nir_builder.h" +#include "glsl/nir/nir_builder.h" struct anv_render_pass anv_meta_dummy_renderpass = {0}; @@ -41,7 +41,7 @@ build_nir_vertex_shader(bool attr_flat) const struct glsl_type *vertex_type = glsl_vec4_type(); - nir_builder_init_simple_shader(&b, MESA_SHADER_VERTEX); + nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_VERTEX, NULL); nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in, vertex_type, "a_pos"); @@ -73,7 +73,7 @@ build_nir_copy_fragment_shader(enum glsl_sampler_dim tex_dim) { nir_builder b; - nir_builder_init_simple_shader(&b, MESA_SHADER_FRAGMENT); + nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL); const struct glsl_type *color_type = glsl_vec4_type(); diff --git a/src/vulkan/anv_meta_clear.c b/src/vulkan/anv_meta_clear.c index 4ce45feb9e6..8e1470e1531 100644 --- a/src/vulkan/anv_meta_clear.c +++ b/src/vulkan/anv_meta_clear.c @@ -23,8 +23,8 @@ #include "anv_meta.h" #include "anv_meta_clear.h" -#include "anv_nir_builder.h" #include "anv_private.h" +#include "glsl/nir/nir_builder.h" /** Vertex attributes for color clears. */ struct color_clear_vattrs { @@ -66,8 +66,8 @@ build_color_shaders(struct nir_shader **out_vs, nir_builder vs_b; nir_builder fs_b; - nir_builder_init_simple_shader(&vs_b, MESA_SHADER_VERTEX); - nir_builder_init_simple_shader(&fs_b, MESA_SHADER_FRAGMENT); + nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL); + nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL); const struct glsl_type *position_type = glsl_vec4_type(); const struct glsl_type *color_type = glsl_vec4_type(); @@ -372,8 +372,8 @@ build_depthstencil_shaders(struct nir_shader **out_vs, nir_builder vs_b; nir_builder fs_b; - nir_builder_init_simple_shader(&vs_b, MESA_SHADER_VERTEX); - nir_builder_init_simple_shader(&fs_b, MESA_SHADER_FRAGMENT); + nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL); + nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL); const struct glsl_type *position_type = glsl_vec4_type(); diff --git a/src/vulkan/anv_nir_builder.h b/src/vulkan/anv_nir_builder.h deleted file mode 100644 index d0218791106..00000000000 --- a/src/vulkan/anv_nir_builder.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ - -#include "anv_nir.h" -#include "glsl/nir/nir_builder.h" -#include "util/ralloc.h" - -/* This file includes NIR helpers used by meta shaders in the Vulkan - * driver. Eventually, these will all be merged into nir_builder. - * However, for now, keeping them in their own file helps to prevent merge - * conflicts. - */ - -static inline void -nir_builder_init_simple_shader(nir_builder *b, gl_shader_stage stage) -{ - b->shader = nir_shader_create(NULL, stage, NULL); - - nir_function *func = - nir_function_create(b->shader, ralloc_strdup(b->shader, "main")); - - b->impl = nir_function_impl_create(func); - b->cursor = nir_after_cf_list(&b->impl->body); -}