diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c index 7934eb0490e6fd371ca39f6a097a898fcb3a8919..3aa2b00c822f984464e869f8bb09928d11a88281 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c @@ -120,6 +120,11 @@ etna_lower_io(nir_shader *shader, struct etna_shader_variant *v) nir_ssa_def *ssa = nir_imul(&b, intr->src[0].ssa, nir_imm_int(&b, 16)); nir_instr_rewrite_src(instr, &intr->src[0], nir_src_for_ssa(ssa)); } break; + case nir_intrinsic_load_vertex_id: + case nir_intrinsic_load_instance_id: + /* detect use of vertex_id/instance_id */ + v->vs_id_in_reg = v->infile.num_reg; + break; default: break; } diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 5652107f4dc4eeab894084c517223f5ec3d03473..533b4033adc1c88f583e4118dfaeaa63119cb17b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -327,7 +327,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) if (ctx->specs.halti >= 2) { /* On HALTI2+ (GC3000 and higher) only use instanced drawing commands, as the blob does */ - etna_draw_instanced(ctx->stream, info->index_size, draw_mode, 1, + etna_draw_instanced(ctx->stream, info->index_size, draw_mode, info->instance_count, info->count, info->index_size ? info->index_bias : info->start); } else { if (info->index_size) diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c index 4982cdb907496b4dd7dd3c0d0a8e934a27d9ac98..e60437d8ec926dc0e27b1a1d5443b9aba1a72e07 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c @@ -132,6 +132,7 @@ emit_halti5_only_state(struct etna_context *ctx, int vs_output_count) etna_coalesce_start(stream, &coalesce); if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { /* Magic states (load balancing, inter-unit sync, buffers) */ + /*007C4*/ EMIT_STATE(FE_HALTI5_ID_CONFIG, ctx->shader_state.FE_HALTI5_ID_CONFIG); /*00870*/ EMIT_STATE(VS_HALTI5_OUTPUT_COUNT, vs_output_count | ((vs_output_count * 0x10) << 8)); /*008A0*/ EMIT_STATE(VS_HALTI5_UNK008A0, 0x0001000e | ((0x110/vs_output_count) << 20)); for (int x = 0; x < 4; ++x) { @@ -327,11 +328,6 @@ etna_emit_state(struct etna_context *ctx) /*14640*/ EMIT_STATE(NFE_VERTEX_STREAMS_CONTROL(x), ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_CONTROL); } } - for (int x = 0; x < ctx->vertex_buffer.count; ++x) { - if (ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR.bo) { - /*14680*/ EMIT_STATE(NFE_VERTEX_STREAMS_VERTEX_DIVISOR(x), ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_VERTEX_DIVISOR); - } - } } else if(ctx->specs.stream_count > 1) { /* hw w/ multiple vertex streams */ for (int x = 0; x < ctx->vertex_buffer.count; ++x) { /*00680*/ EMIT_STATE_RELOC(FE_VERTEX_STREAMS_BASE_ADDR(x), &ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR); @@ -346,6 +342,13 @@ etna_emit_state(struct etna_context *ctx) /*00650*/ EMIT_STATE(FE_VERTEX_STREAM_CONTROL, ctx->vertex_buffer.cvb[0].FE_VERTEX_STREAM_CONTROL); } } + /* gallium has instance divisor as part of elements state */ + if ((dirty & (ETNA_DIRTY_VERTEX_ELEMENTS)) && ctx->specs.halti >= 2) { + for (int x = 0; x < ctx->vertex_elements->num_buffers; ++x) { + /*14680*/ EMIT_STATE(NFE_VERTEX_STREAMS_VERTEX_DIVISOR(x), ctx->vertex_elements->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[x]); + } + } + if (unlikely(dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_RASTERIZER))) { /*00804*/ EMIT_STATE(VS_OUTPUT_COUNT, vs_output_count); diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h b/src/gallium/drivers/etnaviv/etnaviv_internal.h index 25f6a38ab987ac663190997d32808c61920dc334..c868cafab8d18b4fe1d212c79ea075499331e370 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_internal.h +++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h @@ -228,12 +228,13 @@ struct compiled_vertex_elements_state { uint32_t NFE_GENERIC_ATTRIB_CONFIG0[VIVS_NFE_GENERIC_ATTRIB__LEN]; uint32_t NFE_GENERIC_ATTRIB_SCALE[VIVS_NFE_GENERIC_ATTRIB__LEN]; uint32_t NFE_GENERIC_ATTRIB_CONFIG1[VIVS_NFE_GENERIC_ATTRIB__LEN]; + unsigned num_buffers; + uint32_t NFE_VERTEX_STREAMS_VERTEX_DIVISOR[VIVS_NFE_VERTEX_STREAMS__LEN]; }; /* Compiled context->set_vertex_buffer result */ struct compiled_set_vertex_buffer { uint32_t FE_VERTEX_STREAM_CONTROL; - uint32_t FE_VERTEX_STREAM_VERTEX_DIVISOR; struct etna_reloc FE_VERTEX_STREAM_BASE_ADDR; }; @@ -264,6 +265,7 @@ struct compiled_shader_state { uint32_t GL_VARYING_NUM_COMPONENTS; uint32_t GL_VARYING_COMPONENT_USE[2]; uint32_t GL_HALTI5_SH_SPECIALS; + uint32_t FE_HALTI5_ID_CONFIG; unsigned vs_inst_mem_size; unsigned ps_inst_mem_size; uint32_t *VS_INST_MEM; diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index df537f285bf8225ca507e9c7897dbce2286f3a6e..3f687c4314ab4ff75229cc5183c561caa200f28f 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -190,6 +190,9 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 255; case PIPE_CAP_MAX_VERTEX_BUFFERS: return screen->specs.stream_count; + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: + return VIV_FEATURE(screen, chipMinorFeatures4, HALTI2); + /* Texturing. */ case PIPE_CAP_TEXTURE_SHADOW_MAP: diff --git a/src/gallium/drivers/etnaviv/etnaviv_shader.c b/src/gallium/drivers/etnaviv/etnaviv_shader.c index 937a83c89798f5863417db6c8ed7397d6cb4d522..6f6f8d2b9f4ad71eb9e9009f347253215047d307 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_shader.c +++ b/src/gallium/drivers/etnaviv/etnaviv_shader.c @@ -284,6 +284,20 @@ etna_shader_update_vs_inputs(struct compiled_shader_state *cs, etna_bitarray_set(vs_input, 8, idx, cur_temp++); } + if (vs->vs_id_in_reg >= 0) { + cs->VS_INPUT_COUNT = VIVS_VS_INPUT_COUNT_COUNT(num_vs_inputs + 1) | + VIVS_VS_INPUT_COUNT_UNK8(vs->input_count_unk8) | + VIVS_VS_INPUT_COUNT_ID_ENABLE; + + etna_bitarray_set(vs_input, 8, num_vs_inputs, vs->vs_id_in_reg); + + cs->FE_HALTI5_ID_CONFIG = + VIVS_FE_HALTI5_ID_CONFIG_VERTEX_ID_ENABLE | + VIVS_FE_HALTI5_ID_CONFIG_INSTANCE_ID_ENABLE | + VIVS_FE_HALTI5_ID_CONFIG_VERTEX_ID_REG(vs->vs_id_in_reg * 4) | + VIVS_FE_HALTI5_ID_CONFIG_INSTANCE_ID_REG(vs->vs_id_in_reg * 4 + 1); + } + for (int idx = 0; idx < ARRAY_SIZE(cs->VS_INPUT); ++idx) cs->VS_INPUT[idx] = vs_input[idx]; diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index 67f9512f74ec533f7b1aeb8930e492c3a627b45e..12f2648c5667da46b8a3a3b4c8a031efd0e346b0 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -543,29 +543,14 @@ etna_vertex_elements_state_create(struct pipe_context *pctx, /* XXX could minimize number of consecutive stretches here by sorting, and * permuting the inputs in shader or does Mesa do this already? */ - /* Check that vertex element binding is compatible with hardware; thus - * elements[idx].vertex_buffer_index are < stream_count. If not, the binding - * uses more streams than is supported, and u_vbuf should have done some - * reorganization for compatibility. */ - - /* TODO: does mesa this for us? */ - bool incompatible = false; - for (unsigned idx = 0; idx < num_elements; ++idx) { - if (elements[idx].vertex_buffer_index >= ctx->specs.stream_count || elements[idx].instance_divisor > 0) - incompatible = true; - } - cs->num_elements = num_elements; - if (incompatible || num_elements == 0) { - DBG("Error: zero vertex elements, or more vertex buffers used than supported"); - FREE(cs); - return NULL; - } unsigned start_offset = 0; /* start of current consecutive stretch */ bool nonconsecutive = true; /* previous value of nonconsecutive */ + uint32_t buffer_mask = 0; /* mask of buffer_idx already seen */ for (unsigned idx = 0; idx < num_elements; ++idx) { + unsigned buffer_idx = elements[idx].vertex_buffer_index; unsigned element_size = util_format_get_blocksize(elements[idx].src_format); unsigned end_offset = elements[idx].src_offset + element_size; uint32_t format_type, normalize; @@ -573,12 +558,15 @@ etna_vertex_elements_state_create(struct pipe_context *pctx, if (nonconsecutive) start_offset = elements[idx].src_offset; + /* guaranteed by PIPE_CAP_MAX_VERTEX_BUFFERS */ + assert(buffer_idx < ctx->specs.stream_count); + /* maximum vertex size is 256 bytes */ assert(element_size != 0 && (end_offset - start_offset) < 256); /* check whether next element is consecutive to this one */ nonconsecutive = (idx == (num_elements - 1)) || - elements[idx + 1].vertex_buffer_index != elements[idx].vertex_buffer_index || + elements[idx + 1].vertex_buffer_index != buffer_idx || end_offset != elements[idx + 1].src_offset; format_type = translate_vertex_format_type(elements[idx].src_format); @@ -593,7 +581,7 @@ etna_vertex_elements_state_create(struct pipe_context *pctx, format_type | VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(util_format_get_nr_components(elements[idx].src_format)) | normalize | VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(ENDIAN_MODE_NO_SWAP) | - VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(elements[idx].vertex_buffer_index) | + VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(buffer_idx) | VIVS_FE_VERTEX_ELEMENT_CONFIG_START(elements[idx].src_offset) | VIVS_FE_VERTEX_ELEMENT_CONFIG_END(end_offset - start_offset); } else { /* HALTI5 spread vertex attrib config over two registers */ @@ -601,7 +589,7 @@ etna_vertex_elements_state_create(struct pipe_context *pctx, format_type | VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM(util_format_get_nr_components(elements[idx].src_format)) | normalize | VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN(ENDIAN_MODE_NO_SWAP) | - VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM(elements[idx].vertex_buffer_index) | + VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM(buffer_idx) | VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START(elements[idx].src_offset); cs->NFE_GENERIC_ATTRIB_CONFIG1[idx] = COND(nonconsecutive, VIVS_NFE_GENERIC_ATTRIB_CONFIG1_NONCONSECUTIVE) | @@ -612,6 +600,15 @@ etna_vertex_elements_state_create(struct pipe_context *pctx, cs->NFE_GENERIC_ATTRIB_SCALE[idx] = 1; else cs->NFE_GENERIC_ATTRIB_SCALE[idx] = fui(1.0f); + + /* instance_divisor is part of elements state but should be the same for all buffers */ + if (buffer_mask & 1 << buffer_idx) + assert(cs->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[buffer_idx] == elements[idx].instance_divisor); + else + cs->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[buffer_idx] = elements[idx].instance_divisor; + + buffer_mask |= 1 << buffer_idx; + cs->num_buffers = MAX2(cs->num_buffers, buffer_idx + 1); } return cs; diff --git a/src/gallium/drivers/etnaviv/hw/state_3d.xml.h b/src/gallium/drivers/etnaviv/hw/state_3d.xml.h index 197b6a2f7b71674675dba5034f2324ba31e9d205..15bf478b9cfcd4c2fad9e9800251e4461cf9565a 100644 --- a/src/gallium/drivers/etnaviv/hw/state_3d.xml.h +++ b/src/gallium/drivers/etnaviv/hw/state_3d.xml.h @@ -10,15 +10,15 @@ git clone git://0x04.net/rules-ng-ng The rules-ng-ng source files this header was generated from are: - state.xml ( 26666 bytes, from 2019-08-12 13:32:55) - common.xml ( 35468 bytes, from 2019-08-09 17:16:20) -- common_3d.xml ( 14991 bytes, from 2019-09-12 20:32:47) -- state_hi.xml ( 30396 bytes, from 2019-09-12 20:21:39) +- common_3d.xml ( 15058 bytes, from 2019-09-12 20:37:35) +- state_hi.xml ( 30552 bytes, from 2020-01-06 02:44:00) - copyright.xml ( 1597 bytes, from 2019-08-09 17:34:08) - state_2d.xml ( 51552 bytes, from 2019-08-09 17:34:00) -- state_3d.xml ( 83069 bytes, from 2019-09-12 20:28:49) +- state_3d.xml ( 83644 bytes, from 2020-01-06 02:44:06) - state_blt.xml ( 14252 bytes, from 2019-09-12 20:21:39) - state_vg.xml ( 5975 bytes, from 2019-08-09 17:33:52) -Copyright (C) 2012-2019 by the following authors: +Copyright (C) 2012-2020 by the following authors: - Wladimir J. van der Laan - Christian Gmeiner - Lucas Stach @@ -167,6 +167,7 @@ DEALINGS IN THE SOFTWARE. #define VIVS_VS_INPUT_COUNT_UNK8__MASK 0x00001f00 #define VIVS_VS_INPUT_COUNT_UNK8__SHIFT 8 #define VIVS_VS_INPUT_COUNT_UNK8(x) (((x) << VIVS_VS_INPUT_COUNT_UNK8__SHIFT) & VIVS_VS_INPUT_COUNT_UNK8__MASK) +#define VIVS_VS_INPUT_COUNT_ID_ENABLE 0x80000000 #define VIVS_VS_TEMP_REGISTER_CONTROL 0x0000080c #define VIVS_VS_TEMP_REGISTER_CONTROL_NUM_TEMPS__MASK 0x0000003f @@ -1233,6 +1234,7 @@ DEALINGS IN THE SOFTWARE. #define VIVS_RS_SOURCE_STRIDE_STRIDE__MASK 0x0003ffff #define VIVS_RS_SOURCE_STRIDE_STRIDE__SHIFT 0 #define VIVS_RS_SOURCE_STRIDE_STRIDE(x) (((x) << VIVS_RS_SOURCE_STRIDE_STRIDE__SHIFT) & VIVS_RS_SOURCE_STRIDE_STRIDE__MASK) +#define VIVS_RS_SOURCE_STRIDE_UNK29 0x20000000 #define VIVS_RS_SOURCE_STRIDE_MULTI 0x40000000 #define VIVS_RS_SOURCE_STRIDE_TILING 0x80000000 @@ -1536,6 +1538,27 @@ DEALINGS IN THE SOFTWARE. #define VIVS_TE_SAMPLER_UNK02240(i0) (0x00002240 + 0x4*(i0)) +#define VIVS_TE_SAMPLER_ASTC0(i0) (0x00002280 + 0x4*(i0)) +#define VIVS_TE_SAMPLER_ASTC0_ASTC_FORMAT__MASK 0x0000000f +#define VIVS_TE_SAMPLER_ASTC0_ASTC_FORMAT__SHIFT 0 +#define VIVS_TE_SAMPLER_ASTC0_ASTC_FORMAT(x) (((x) << VIVS_TE_SAMPLER_ASTC0_ASTC_FORMAT__SHIFT) & VIVS_TE_SAMPLER_ASTC0_ASTC_FORMAT__MASK) +#define VIVS_TE_SAMPLER_ASTC0_ASTC_SRGB 0x00000010 +#define VIVS_TE_SAMPLER_ASTC0_UNK8__MASK 0x0000ff00 +#define VIVS_TE_SAMPLER_ASTC0_UNK8__SHIFT 8 +#define VIVS_TE_SAMPLER_ASTC0_UNK8(x) (((x) << VIVS_TE_SAMPLER_ASTC0_UNK8__SHIFT) & VIVS_TE_SAMPLER_ASTC0_UNK8__MASK) +#define VIVS_TE_SAMPLER_ASTC0_UNK16__MASK 0x00ff0000 +#define VIVS_TE_SAMPLER_ASTC0_UNK16__SHIFT 16 +#define VIVS_TE_SAMPLER_ASTC0_UNK16(x) (((x) << VIVS_TE_SAMPLER_ASTC0_UNK16__SHIFT) & VIVS_TE_SAMPLER_ASTC0_UNK16__MASK) +#define VIVS_TE_SAMPLER_ASTC0_UNK24__MASK 0xff000000 +#define VIVS_TE_SAMPLER_ASTC0_UNK24__SHIFT 24 +#define VIVS_TE_SAMPLER_ASTC0_UNK24(x) (((x) << VIVS_TE_SAMPLER_ASTC0_UNK24__SHIFT) & VIVS_TE_SAMPLER_ASTC0_UNK24__MASK) + +#define VIVS_TE_SAMPLER_ASTC1(i0) (0x00002300 + 0x4*(i0)) + +#define VIVS_TE_SAMPLER_ASTC2(i0) (0x00002380 + 0x4*(i0)) + +#define VIVS_TE_SAMPLER_ASTC3(i0) (0x00002340 + 0x4*(i0)) + #define VIVS_TE_SAMPLER_LOD_ADDR(i0, i1) (0x00002400 + 0x4*(i0) + 0x40*(i1)) #define VIVS_TE_SAMPLER_LOD_ADDR__ESIZE 0x00000040 #define VIVS_TE_SAMPLER_LOD_ADDR__LEN 0x0000000e @@ -1616,7 +1639,9 @@ DEALINGS IN THE SOFTWARE. #define VIVS_NTE_SAMPLER_UNK10200(i0) (0x00010200 + 0x4*(i0)) -#define VIVS_NTE_SAMPLER_UNK10280(i0) (0x00010280 + 0x4*(i0)) +#define VIVS_NTE_SAMPLER_LINEAR_STRIDE(i0, i1) (0x00010280 + 0x4*(i0) + 0x4*(i1)) +#define VIVS_NTE_SAMPLER_LINEAR_STRIDE__ESIZE 0x00000004 +#define VIVS_NTE_SAMPLER_LINEAR_STRIDE__LEN 0x00000020 #define VIVS_NTE_SAMPLER_3D_CONFIG(i0) (0x00010300 + 0x4*(i0)) #define VIVS_NTE_SAMPLER_3D_CONFIG_DEPTH__MASK 0x00003fff @@ -1678,7 +1703,7 @@ DEALINGS IN THE SOFTWARE. #define VIVS_NTE_SAMPLER_ASTC2(i0) (0x00010600 + 0x4*(i0)) -#define VIVS_NTE_SAMPLER_ASTC3(i0) (0x00010600 + 0x4*(i0)) +#define VIVS_NTE_SAMPLER_ASTC3(i0) (0x00010680 + 0x4*(i0)) #define VIVS_NTE_SAMPLER_BASELOD(i0) (0x00010700 + 0x4*(i0)) #define VIVS_NTE_SAMPLER_BASELOD_BASELOD__MASK 0x0000000f