From e41e33fdb8737a92c008f8e165cf755bf7ecc78d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 12 Jan 2018 12:31:14 -0800 Subject: [PATCH] broadcom/vc5: Port the draw-time state emission to V3D 4.1. --- src/gallium/drivers/vc5/Makefile.sources | 2 +- src/gallium/drivers/vc5/meson.build | 2 +- src/gallium/drivers/vc5/v3dx_context.h | 1 + src/gallium/drivers/vc5/vc5_context.h | 1 - src/gallium/drivers/vc5/vc5_draw.c | 6 +- src/gallium/drivers/vc5/vc5_emit.c | 87 ++++++++++++++++++------ src/gallium/drivers/vc5/vc5_screen.c | 4 +- 7 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/gallium/drivers/vc5/Makefile.sources b/src/gallium/drivers/vc5/Makefile.sources index 252431b54b5..f5cd8d79f85 100644 --- a/src/gallium/drivers/vc5/Makefile.sources +++ b/src/gallium/drivers/vc5/Makefile.sources @@ -7,7 +7,6 @@ C_SOURCES := \ vc5_context.c \ vc5_context.h \ vc5_drm.h \ - vc5_emit.c \ vc5_fence.c \ vc5_formats.c \ vc5_job.c \ @@ -27,6 +26,7 @@ VC5_PER_VERSION_SOURCES = \ v3dx_format_table.c \ v3dx_simulator.c \ vc5_draw.c \ + vc5_emit.c \ vc5_rcl.c \ vc5_state.c \ $() diff --git a/src/gallium/drivers/vc5/meson.build b/src/gallium/drivers/vc5/meson.build index aa74e624bdb..005bf2f9b8e 100644 --- a/src/gallium/drivers/vc5/meson.build +++ b/src/gallium/drivers/vc5/meson.build @@ -26,7 +26,6 @@ files_libvc5 = files( 'vc5_cl.h', 'vc5_context.c', 'vc5_context.h', - 'vc5_emit.c', 'vc5_fence.c', 'vc5_formats.c', 'vc5_job.c', @@ -47,6 +46,7 @@ files_per_version = files( 'v3dx_format_table.c', 'v3dx_simulator.c', 'vc5_draw.c', + 'vc5_emit.c', 'vc5_rcl.c', 'vc5_state.c', ) diff --git a/src/gallium/drivers/vc5/v3dx_context.h b/src/gallium/drivers/vc5/v3dx_context.h index f92712dcf79..addc7433b37 100644 --- a/src/gallium/drivers/vc5/v3dx_context.h +++ b/src/gallium/drivers/vc5/v3dx_context.h @@ -29,6 +29,7 @@ struct v3d_hw; struct vc5_format; +void v3dX(emit_state)(struct pipe_context *pctx); void v3dX(emit_rcl)(struct vc5_job *job); void v3dX(draw_init)(struct pipe_context *pctx); void v3dX(state_init)(struct pipe_context *pctx); diff --git a/src/gallium/drivers/vc5/vc5_context.h b/src/gallium/drivers/vc5/vc5_context.h index e4c2eb551bd..18fc27c5147 100644 --- a/src/gallium/drivers/vc5/vc5_context.h +++ b/src/gallium/drivers/vc5/vc5_context.h @@ -492,7 +492,6 @@ void vc5_flush_jobs_writing_resource(struct vc5_context *vc5, struct pipe_resource *prsc); void vc5_flush_jobs_reading_resource(struct vc5_context *vc5, struct pipe_resource *prsc); -void vc5_emit_state(struct pipe_context *pctx); void vc5_update_compiled_shaders(struct vc5_context *vc5, uint8_t prim_mode); bool vc5_rt_format_supported(const struct v3d_device_info *devinfo, diff --git a/src/gallium/drivers/vc5/vc5_draw.c b/src/gallium/drivers/vc5/vc5_draw.c index 39378280823..7a409c14d4c 100644 --- a/src/gallium/drivers/vc5/vc5_draw.c +++ b/src/gallium/drivers/vc5/vc5_draw.c @@ -385,7 +385,11 @@ vc5_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) vc5_start_draw(vc5); vc5_update_compiled_shaders(vc5, info->mode); - vc5_emit_state(pctx); +#if V3D_VERSION >= 41 + v3d41_emit_state(pctx); +#else + v3d33_emit_state(pctx); +#endif if (vc5->dirty & (VC5_DIRTY_VTXBUF | VC5_DIRTY_VTXSTATE | diff --git a/src/gallium/drivers/vc5/vc5_emit.c b/src/gallium/drivers/vc5/vc5_emit.c index 53fa01b3f42..ae47fda81ff 100644 --- a/src/gallium/drivers/vc5/vc5_emit.c +++ b/src/gallium/drivers/vc5/vc5_emit.c @@ -24,7 +24,6 @@ #include "util/u_format.h" #include "util/u_half.h" #include "vc5_context.h" -#define V3D_VERSION 33 #include "broadcom/common/v3d_macros.h" #include "broadcom/cle/v3dx_pack.h" #include "broadcom/compiler/v3d_compiler.h" @@ -108,6 +107,7 @@ swizzled_border_color(const struct v3d_device_info *devinfo, } } +#if V3D_VERSION < 40 static uint32_t translate_swizzle(unsigned char pipe_swizzle) { @@ -258,6 +258,7 @@ emit_textures(struct vc5_context *vc5, struct vc5_texture_stateobj *stage_tex) emit_one_texture(vc5, stage_tex, i); } } +#endif /* V3D_VERSION < 40 */ static uint32_t translate_colormask(struct vc5_context *vc5, uint32_t colormask, int rt) @@ -271,8 +272,39 @@ translate_colormask(struct vc5_context *vc5, uint32_t colormask, int rt) return (~colormask) & 0xf; } +static void +emit_rt_blend(struct vc5_context *vc5, struct vc5_job *job, + struct pipe_blend_state *blend, int rt) +{ + cl_emit(&job->bcl, BLEND_CONFIG, config) { + struct pipe_rt_blend_state *rtblend = &blend->rt[rt]; + +#if V3D_VERSION >= 40 + config.render_target_mask = 1 << rt; +#else + assert(rt == 0); +#endif + + config.colour_blend_mode = rtblend->rgb_func; + config.colour_blend_dst_factor = + vc5_factor(rtblend->rgb_dst_factor, + vc5->blend_dst_alpha_one); + config.colour_blend_src_factor = + vc5_factor(rtblend->rgb_src_factor, + vc5->blend_dst_alpha_one); + + config.alpha_blend_mode = rtblend->alpha_func; + config.alpha_blend_dst_factor = + vc5_factor(rtblend->alpha_dst_factor, + vc5->blend_dst_alpha_one); + config.alpha_blend_src_factor = + vc5_factor(rtblend->alpha_src_factor, + vc5->blend_dst_alpha_one); + } +} + void -vc5_emit_state(struct pipe_context *pctx) +v3dX(emit_state)(struct pipe_context *pctx) { struct vc5_context *vc5 = vc5_context(pctx); struct vc5_job *job = vc5->job; @@ -421,24 +453,11 @@ vc5_emit_state(struct pipe_context *pctx) if (vc5->dirty & VC5_DIRTY_BLEND && vc5->blend->rt[0].blend_enable) { struct pipe_blend_state *blend = vc5->blend; - cl_emit(&job->bcl, BLEND_CONFIG, config) { - struct pipe_rt_blend_state *rtblend = &blend->rt[0]; - - config.colour_blend_mode = rtblend->rgb_func; - config.colour_blend_dst_factor = - vc5_factor(rtblend->rgb_dst_factor, - vc5->blend_dst_alpha_one); - config.colour_blend_src_factor = - vc5_factor(rtblend->rgb_src_factor, - vc5->blend_dst_alpha_one); - - config.alpha_blend_mode = rtblend->alpha_func; - config.alpha_blend_dst_factor = - vc5_factor(rtblend->alpha_dst_factor, - vc5->blend_dst_alpha_one); - config.alpha_blend_src_factor = - vc5_factor(rtblend->alpha_src_factor, - vc5->blend_dst_alpha_one); + if (blend->independent_blend_enable) { + for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) + emit_rt_blend(vc5, job, blend, i); + } else { + emit_rt_blend(vc5, job, blend, 0); } } @@ -502,11 +521,16 @@ vc5_emit_state(struct pipe_context *pctx) } } +#if V3D_VERSION < 40 + /* Pre-4.x, we have texture state that depends on both the sampler and + * the view, so we merge them together at draw time. + */ if (vc5->dirty & VC5_DIRTY_FRAGTEX) emit_textures(vc5, &vc5->fragtex); if (vc5->dirty & VC5_DIRTY_VERTTEX) emit_textures(vc5, &vc5->verttex); +#endif if (vc5->dirty & VC5_DIRTY_FLAT_SHADE_FLAGS) { bool emitted_any = false; @@ -549,13 +573,22 @@ vc5_emit_state(struct pipe_context *pctx) struct vc5_streamout_stateobj *so = &vc5->streamout; if (so->num_targets) { +#if V3D_VERSION >= 40 + cl_emit(&job->bcl, TRANSFORM_FEEDBACK_SPECS, tfe) { + tfe.number_of_16_bit_output_data_specs_following = + vc5->prog.bind_vs->num_tf_specs; + tfe.enable = + (vc5->prog.bind_vs->num_tf_specs != 0 && + vc5->active_queries); + }; +#else /* V3D_VERSION < 40 */ cl_emit(&job->bcl, TRANSFORM_FEEDBACK_ENABLE, tfe) { tfe.number_of_32_bit_output_buffer_address_following = so->num_targets; tfe.number_of_16_bit_output_data_specs_following = vc5->prog.bind_vs->num_tf_specs; }; - +#endif /* V3D_VERSION < 40 */ for (int i = 0; i < vc5->prog.bind_vs->num_tf_specs; i++) { cl_emit_prepacked(&job->bcl, &vc5->prog.bind_vs->tf_specs[i]); @@ -567,12 +600,22 @@ vc5_emit_state(struct pipe_context *pctx) struct vc5_resource *rsc = vc5_resource(target->buffer); +#if V3D_VERSION >= 40 + cl_emit(&job->bcl, TRANSFORM_FEEDBACK_BUFFER, output) { + output.buffer_address = + cl_address(rsc->bo, + target->buffer_offset); + output.buffer_size_in_32_bit_words = + target->buffer_size >> 2; + output.buffer_number = i; + } +#else /* V3D_VERSION < 40 */ cl_emit(&job->bcl, TRANSFORM_FEEDBACK_OUTPUT_ADDRESS, output) { output.address = cl_address(rsc->bo, target->buffer_offset); }; - +#endif /* V3D_VERSION < 40 */ vc5_job_add_write_resource(vc5->job, target->buffer); /* XXX: buffer_size? */ diff --git a/src/gallium/drivers/vc5/vc5_screen.c b/src/gallium/drivers/vc5/vc5_screen.c index 1e794bc223f..b55272edac7 100644 --- a/src/gallium/drivers/vc5/vc5_screen.c +++ b/src/gallium/drivers/vc5/vc5_screen.c @@ -102,7 +102,6 @@ vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_START_INSTANCE: case PIPE_CAP_TGSI_INSTANCEID: case PIPE_CAP_SM3: - case PIPE_CAP_INDEP_BLEND_ENABLE: /* XXX */ case PIPE_CAP_TEXTURE_QUERY_LOD: case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: @@ -116,6 +115,9 @@ vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET: return 1; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return screen->devinfo.ver >= 40; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: return 256; -- 2.30.2