From 35946d50cee3212f374472f1a9d7793ea9c5c15b Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 14 Feb 2022 21:01:40 +0900 Subject: [PATCH] vrend: Do not pass GL_BGRA vertex array for ES This also fixes size parameter of glMapBufferRange in vrend_draw_bind_vertex_legacy. Signed-off-by: Akihiko Odaki Reviewed-by: Gert Wollny --- src/vrend_renderer.c | 24 +++++++++++++++-------- src/vrend_shader.c | 45 ++++++++++++++++++++++++++++++-------------- src/vrend_shader.h | 1 + 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index c07625a..7e1c85b 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -553,6 +553,7 @@ struct vrend_vertex_element_array { GLuint id; uint32_t signed_int_bitmask; uint32_t unsigned_int_bitmask; + uint32_t zyxw_bitmask; struct vrend_sub_context *owning_sub; }; @@ -2912,12 +2913,13 @@ int vrend_create_vertex_elements_state(struct vrend_context *ctx, v->elements[i].type = type; if (desc->channel[0].normalized) v->elements[i].norm = GL_TRUE; - if (desc->nr_channels == 4 && desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_Z) - v->elements[i].nr_chan = GL_BGRA; - else if (elements[i].src_format == PIPE_FORMAT_R11G11B10_FLOAT) + if (elements[i].src_format == PIPE_FORMAT_R11G11B10_FLOAT) v->elements[i].nr_chan = 3; else v->elements[i].nr_chan = desc->nr_channels; + + if (desc->nr_channels == 4 && desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_Z) + v->zyxw_bitmask |= 1 << i; } if (has_feature(feat_gles31_vertex_attrib_binding)) { @@ -2925,15 +2927,16 @@ int vrend_create_vertex_elements_state(struct vrend_context *ctx, glBindVertexArray(v->id); for (i = 0; i < num_elements; i++) { struct vrend_vertex_element *ve = &v->elements[i]; + GLint size = !vrend_state.use_gles && (v->zyxw_bitmask & (1 << i)) ? GL_BGRA : ve->nr_chan; if (util_format_is_pure_integer(ve->base.src_format)) { UPDATE_INT_SIGN_MASK(ve->base.src_format, i, v->signed_int_bitmask, v->unsigned_int_bitmask); - glVertexAttribIFormat(i, ve->nr_chan, ve->type, ve->base.src_offset); + glVertexAttribIFormat(i, size, ve->type, ve->base.src_offset); } else - glVertexAttribFormat(i, ve->nr_chan, ve->type, ve->norm, ve->base.src_offset); + glVertexAttribFormat(i, size, ve->type, ve->norm, ve->base.src_offset); glVertexAttribBinding(i, ve->base.vertex_buffer_index); glVertexBindingDivisor(i, ve->base.instance_divisor); glEnableVertexAttribArray(i); @@ -3575,6 +3578,10 @@ static inline void vrend_fill_shader_key(struct vrend_sub_context *sub_ctx, key->flatshade = sub_ctx->rs_state.flatshade ? true : false; } + if (vrend_state.use_gles && sub_ctx->ve && type == PIPE_SHADER_VERTEX) { + key->vs.attrib_zyxw_bitmask = sub_ctx->ve->zyxw_bitmask; + } + key->gs_present = !!sub_ctx->shaders[PIPE_SHADER_GEOMETRY] || type == PIPE_SHADER_GEOMETRY; key->tcs_present = !!sub_ctx->shaders[PIPE_SHADER_TESS_CTRL] || type == PIPE_SHADER_TESS_CTRL; key->tes_present = !!sub_ctx->shaders[PIPE_SHADER_TESS_EVAL] || type == PIPE_SHADER_TESS_EVAL; @@ -4280,18 +4287,19 @@ static void vrend_draw_bind_vertex_legacy(struct vrend_context *ctx, glVertexAttrib3fv(loc, data); break; case 4: - default: glVertexAttrib4fv(loc, data); break; } glUnmapBuffer(GL_ARRAY_BUFFER); disable_bitmask |= (1 << loc); } else { + GLint size = !vrend_state.use_gles && (va->zyxw_bitmask & (1 << i)) ? GL_BGRA : ve->nr_chan; + enable_bitmask |= (1 << loc); if (util_format_is_pure_integer(ve->base.src_format)) { - glVertexAttribIPointer(loc, ve->nr_chan, ve->type, vbo->base.stride, (void *)(unsigned long)(ve->base.src_offset + vbo->base.buffer_offset)); + glVertexAttribIPointer(loc, size, ve->type, vbo->base.stride, (void *)(unsigned long)(ve->base.src_offset + vbo->base.buffer_offset)); } else { - glVertexAttribPointer(loc, ve->nr_chan, ve->type, ve->norm, vbo->base.stride, (void *)(unsigned long)(ve->base.src_offset + vbo->base.buffer_offset)); + glVertexAttribPointer(loc, size, ve->type, ve->norm, vbo->base.stride, (void *)(unsigned long)(ve->base.src_offset + vbo->base.buffer_offset)); } glVertexAttribDivisorARB(loc, ve->base.instance_divisor); } diff --git a/src/vrend_shader.c b/src/vrend_shader.c index f0a1865..d91afa4 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -4096,12 +4096,28 @@ static void get_tesslevel_as_source(struct vrend_strbuf *src_buf, const char *pr name, reg->SwizzleW); } +static void get_source_swizzle(const struct tgsi_full_src_register *src, char swizzle[8]) +{ + if (src->Register.SwizzleX != TGSI_SWIZZLE_X || + src->Register.SwizzleY != TGSI_SWIZZLE_Y || + src->Register.SwizzleZ != TGSI_SWIZZLE_Z || + src->Register.SwizzleW != TGSI_SWIZZLE_W) { + *swizzle++ = '.'; + *swizzle++ = get_swiz_char(src->Register.SwizzleX); + *swizzle++ = get_swiz_char(src->Register.SwizzleY); + *swizzle++ = get_swiz_char(src->Register.SwizzleZ); + *swizzle++ = get_swiz_char(src->Register.SwizzleW); + } + + *swizzle++ = 0; +} + // TODO Consider exposing non-const ctx-> members as args to make *ctx const static bool get_source_info(struct dump_ctx *ctx, const struct tgsi_full_instruction *inst, struct source_info *sinfo, - struct vrend_strbuf srcs[4], char src_swizzle0[10]) + struct vrend_strbuf srcs[4], char src_swizzle0[16]) { bool stprefix = false; @@ -4136,7 +4152,7 @@ get_source_info(struct dump_ctx *ctx, for (uint32_t i = 0; i < inst->Instruction.NumSrcRegs; i++) { const struct tgsi_full_src_register *src = &inst->Src[i]; struct vrend_strbuf *src_buf = &srcs[i]; - char swizzle[8] = ""; + char swizzle[16] = ""; int usage_mask = 0; char *swizzle_writer = swizzle; char prefix[6] = ""; @@ -4178,23 +4194,24 @@ get_source_info(struct dump_ctx *ctx, usage_mask |= 1 << src->Register.SwizzleZ; usage_mask |= 1 << src->Register.SwizzleW; - if (src->Register.SwizzleX != TGSI_SWIZZLE_X || - src->Register.SwizzleY != TGSI_SWIZZLE_Y || - src->Register.SwizzleZ != TGSI_SWIZZLE_Z || - src->Register.SwizzleW != TGSI_SWIZZLE_W) { - swizzle_writer[swz_idx++] = '.'; - swizzle_writer[swz_idx++] = get_swiz_char(src->Register.SwizzleX); - swizzle_writer[swz_idx++] = get_swiz_char(src->Register.SwizzleY); - swizzle_writer[swz_idx++] = get_swiz_char(src->Register.SwizzleZ); - swizzle_writer[swz_idx++] = get_swiz_char(src->Register.SwizzleW); - } - swizzle_writer[swz_idx] = 0; + get_source_swizzle(src, swizzle_writer + swz_idx); if (src->Register.File == TGSI_FILE_INPUT) { for (uint32_t j = 0; j < ctx->num_inputs; j++) if (ctx->inputs[j].first <= src->Register.Index && ctx->inputs[j].last >= src->Register.Index && (ctx->inputs[j].usage_mask & usage_mask)) { + if (ctx->prog_type == TGSI_PROCESSOR_VERTEX) { + if (ctx->key->vs.attrib_zyxw_bitmask & (1 << ctx->inputs[j].first)) { + swizzle_writer[swz_idx++] = '.'; + swizzle_writer[swz_idx++] = 'z'; + swizzle_writer[swz_idx++] = 'y'; + swizzle_writer[swz_idx++] = 'x'; + swizzle_writer[swz_idx++] = 'w'; + } + get_source_swizzle(src, swizzle_writer + swz_idx); + } + if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && ctx->key->color_two_side && ctx->inputs[j].name == TGSI_SEMANTIC_COLOR) strbuf_fmt(src_buf, "%s(%s%s%d%s%s)", get_string(stypeprefix), prefix, "realcolor", ctx->inputs[j].sid, arrayname, swizzle); @@ -5054,7 +5071,7 @@ iter_instruction(struct tgsi_iterate_context *iter, char fp64_dsts[3][255]; uint instno = ctx->instno++; char writemask[6] = ""; - char src_swizzle0[10]; + char src_swizzle0[16]; sinfo.svec4 = VEC4; diff --git a/src/vrend_shader.h b/src/vrend_shader.h index d754f47..e011d68 100644 --- a/src/vrend_shader.h +++ b/src/vrend_shader.h @@ -171,6 +171,7 @@ struct vrend_shader_key { struct { uint32_t attrib_signed_int_bitmask; uint32_t attrib_unsigned_int_bitmask; + uint32_t attrib_zyxw_bitmask; uint32_t fog_fixup_mask; } vs;