From: Eric Anholt Date: Wed, 10 Jan 2018 23:49:47 +0000 (-0800) Subject: broadcom/vc5: Update state setup for V3D 4.1. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=af9753e246c2a4371a289b44064483ece8d1ad5d;p=mesa.git broadcom/vc5: Update state setup for V3D 4.1. --- diff --git a/src/gallium/drivers/vc5/Makefile.sources b/src/gallium/drivers/vc5/Makefile.sources index 45c4ccd67f6..252431b54b5 100644 --- a/src/gallium/drivers/vc5/Makefile.sources +++ b/src/gallium/drivers/vc5/Makefile.sources @@ -18,7 +18,6 @@ C_SOURCES := \ vc5_screen.c \ vc5_screen.h \ vc5_simulator.c \ - vc5_state.c \ vc5_tiling.c \ vc5_tiling.h \ vc5_uniforms.c \ @@ -29,4 +28,5 @@ VC5_PER_VERSION_SOURCES = \ v3dx_simulator.c \ vc5_draw.c \ vc5_rcl.c \ + vc5_state.c \ $() diff --git a/src/gallium/drivers/vc5/meson.build b/src/gallium/drivers/vc5/meson.build index e0dd45802a5..aa74e624bdb 100644 --- a/src/gallium/drivers/vc5/meson.build +++ b/src/gallium/drivers/vc5/meson.build @@ -38,7 +38,6 @@ files_libvc5 = files( 'vc5_screen.h', 'vc5_simulator.c', 'vc5_simulator_wrapper.cpp', - 'vc5_state.c', 'vc5_tiling.c', 'vc5_tiling.h', 'vc5_uniforms.c', @@ -49,6 +48,7 @@ files_per_version = files( 'v3dx_simulator.c', 'vc5_draw.c', 'vc5_rcl.c', + 'vc5_state.c', ) v3dv3_c_args = [] diff --git a/src/gallium/drivers/vc5/v3dx_context.h b/src/gallium/drivers/vc5/v3dx_context.h index 445038c76b3..f92712dcf79 100644 --- a/src/gallium/drivers/vc5/v3dx_context.h +++ b/src/gallium/drivers/vc5/v3dx_context.h @@ -31,6 +31,7 @@ struct vc5_format; void v3dX(emit_rcl)(struct vc5_job *job); void v3dX(draw_init)(struct pipe_context *pctx); +void v3dX(state_init)(struct pipe_context *pctx); void v3dX(simulator_init_regs)(struct v3d_hw *v3d); int v3dX(simulator_get_param_ioctl)(struct v3d_hw *v3d, diff --git a/src/gallium/drivers/vc5/vc5_context.c b/src/gallium/drivers/vc5/vc5_context.c index f6ae0ad989b..9403f8ffdd4 100644 --- a/src/gallium/drivers/vc5/vc5_context.c +++ b/src/gallium/drivers/vc5/vc5_context.c @@ -134,11 +134,13 @@ vc5_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) pctx->flush = vc5_pipe_flush; pctx->invalidate_resource = vc5_invalidate_resource; - if (screen->devinfo.ver >= 41) + if (screen->devinfo.ver >= 41) { v3d41_draw_init(pctx); - else + v3d41_state_init(pctx); + } else { v3d33_draw_init(pctx); - vc5_state_init(pctx); + v3d33_state_init(pctx); + } vc5_program_init(pctx); vc5_query_init(pctx); vc5_resource_context_init(pctx); diff --git a/src/gallium/drivers/vc5/vc5_context.h b/src/gallium/drivers/vc5/vc5_context.h index 508c894071a..e4c2eb551bd 100644 --- a/src/gallium/drivers/vc5/vc5_context.h +++ b/src/gallium/drivers/vc5/vc5_context.h @@ -93,6 +93,8 @@ struct vc5_sampler_view { uint8_t swizzle[4]; uint8_t texture_shader_state[32]; + /* V3D 4.x: Texture state struct. */ + struct vc5_bo *bo; }; struct vc5_sampler_state { @@ -100,7 +102,10 @@ struct vc5_sampler_state { uint32_t p0; uint32_t p1; + /* V3D 3.x: Packed texture state. */ uint8_t texture_shader_state[32]; + /* V3D 4.x: Sampler state struct. */ + struct vc5_bo *bo; }; struct vc5_texture_stateobj { @@ -446,7 +451,6 @@ vc5_sampler_state(struct pipe_sampler_state *psampler) struct pipe_context *vc5_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags); -void vc5_state_init(struct pipe_context *pctx); void vc5_program_init(struct pipe_context *pctx); void vc5_program_fini(struct pipe_context *pctx); void vc5_query_init(struct pipe_context *pctx); diff --git a/src/gallium/drivers/vc5/vc5_state.c b/src/gallium/drivers/vc5/vc5_state.c index 79795c765aa..81ae33d7178 100644 --- a/src/gallium/drivers/vc5/vc5_state.c +++ b/src/gallium/drivers/vc5/vc5_state.c @@ -31,7 +31,6 @@ #include "util/u_helpers.h" #include "vc5_context.h" -#define V3D_VERSION 33 #include "broadcom/common/v3d_macros.h" #include "broadcom/cle/v3dx_pack.h" @@ -503,6 +502,7 @@ static void * vc5_create_sampler_state(struct pipe_context *pctx, const struct pipe_sampler_state *cso) { + MAYBE_UNUSED struct vc5_context *vc5 = vc5_context(pctx); struct vc5_sampler_state *so = CALLOC_STRUCT(vc5_sampler_state); if (!so) @@ -514,6 +514,62 @@ vc5_create_sampler_state(struct pipe_context *pctx, (cso->mag_img_filter == PIPE_TEX_MIPFILTER_NEAREST || cso->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST); +#if V3D_VERSION >= 40 + so->bo = vc5_bo_alloc(vc5->screen, cl_packet_length(SAMPLER_STATE), + "sampler"); + void *map = vc5_bo_map(so->bo); + + v3dx_pack(map, SAMPLER_STATE, sampler) { + sampler.wrap_i_border = false; + + sampler.wrap_s = translate_wrap(cso->wrap_s, either_nearest); + sampler.wrap_t = translate_wrap(cso->wrap_t, either_nearest); + sampler.wrap_r = translate_wrap(cso->wrap_r, either_nearest); + + sampler.fixed_bias = cso->lod_bias; + sampler.depth_compare_function = cso->compare_func; + + sampler.min_filter_nearest = + cso->min_img_filter == PIPE_TEX_FILTER_NEAREST; + sampler.mag_filter_nearest = + cso->mag_img_filter == PIPE_TEX_FILTER_NEAREST; + sampler.mip_filter_nearest = + cso->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST; + + sampler.min_level_of_detail = MIN2(MAX2(0, cso->min_lod), + 15); + sampler.max_level_of_detail = MIN2(cso->max_lod, 15); + + if (cso->max_anisotropy) { + sampler.anisotropy_enable = true; + + if (cso->max_anisotropy > 8) + sampler.maximum_anisotropy = 3; + else if (cso->max_anisotropy > 4) + sampler.maximum_anisotropy = 2; + else if (cso->max_anisotropy > 2) + sampler.maximum_anisotropy = 1; + } + + sampler.border_colour_mode = V3D_BORDER_COLOUR_FOLLOWS; + /* XXX: The border colour field is in the TMU blending format + * (32, f16, or i16), and we need to customize it based on + * that. + * + * XXX: for compat alpha formats, we need the alpha field to + * be in the red channel. + */ + sampler.border_colour_red = + util_float_to_half(cso->border_color.f[0]); + sampler.border_colour_green = + util_float_to_half(cso->border_color.f[1]); + sampler.border_colour_blue = + util_float_to_half(cso->border_color.f[2]); + sampler.border_colour_alpha = + util_float_to_half(cso->border_color.f[3]); + } + +#else /* V3D_VERSION < 40 */ v3dx_pack(&so->p0, TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1, p0) { p0.s_wrap_mode = translate_wrap(cso->wrap_s, either_nearest); p0.t_wrap_mode = translate_wrap(cso->wrap_t, either_nearest); @@ -524,7 +580,7 @@ vc5_create_sampler_state(struct pipe_context *pctx, tex.depth_compare_function = cso->compare_func; tex.fixed_bias = cso->lod_bias; } - +#endif /* V3D_VERSION < 40 */ return so; } @@ -553,6 +609,37 @@ vc5_sampler_states_bind(struct pipe_context *pctx, stage_tex->num_samplers = new_nr; } +static void +vc5_sampler_state_delete(struct pipe_context *pctx, + void *hwcso) +{ + struct pipe_sampler_state *psampler = hwcso; + struct vc5_sampler_state *sampler = vc5_sampler_state(psampler); + + vc5_bo_unreference(&sampler->bo); + free(psampler); +} + +#if V3D_VERSION >= 40 +static uint32_t +translate_swizzle(unsigned char pipe_swizzle) +{ + switch (pipe_swizzle) { + case PIPE_SWIZZLE_0: + return 0; + case PIPE_SWIZZLE_1: + return 1; + case PIPE_SWIZZLE_X: + case PIPE_SWIZZLE_Y: + case PIPE_SWIZZLE_Z: + case PIPE_SWIZZLE_W: + return 2 + pipe_swizzle; + default: + unreachable("unknown swizzle"); + } +} +#endif + static struct pipe_sampler_view * vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, const struct pipe_sampler_view *cso) @@ -589,9 +676,29 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, int msaa_scale = prsc->nr_samples > 1 ? 2 : 1; +#if V3D_VERSION >= 40 + so->bo = vc5_bo_alloc(vc5->screen, cl_packet_length(SAMPLER_STATE), + "sampler"); + void *map = vc5_bo_map(so->bo); + + v3dx_pack(map, TEXTURE_SHADER_STATE, tex) { +#else /* V3D_VERSION < 40 */ v3dx_pack(&so->texture_shader_state, TEXTURE_SHADER_STATE, tex) { +#endif + tex.image_width = prsc->width0 * msaa_scale; tex.image_height = prsc->height0 * msaa_scale; + +#if V3D_VERSION >= 40 + /* On 4.x, the height of a 1D texture is redefined to be the + * upper 14 bits of the width (which is only usable with txf). + */ + if (prsc->target == PIPE_TEXTURE_1D || + prsc->target == PIPE_TEXTURE_1D_ARRAY) { + tex.image_height = tex.image_width >> 14; + } +#endif + if (prsc->target == PIPE_TEXTURE_3D) { tex.image_depth = prsc->depth0; } else { @@ -602,6 +709,21 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, tex.srgb = util_format_is_srgb(cso->format); tex.base_level = cso->u.tex.first_level; +#if V3D_VERSION >= 40 + tex.max_level = cso->u.tex.last_level; + /* Note that we don't have a job to reference the texture's sBO + * at state create time, so any time this sampler view is used + * we need to add the texture to the job. + */ + tex.texture_base_pointer = cl_address(NULL, + rsc->bo->offset + + rsc->slices[0].offset), + + tex.swizzle_r = translate_swizzle(so->swizzle[0]); + tex.swizzle_g = translate_swizzle(so->swizzle[1]); + tex.swizzle_b = translate_swizzle(so->swizzle[2]); + tex.swizzle_a = translate_swizzle(so->swizzle[3]); +#endif tex.array_stride_64_byte_aligned = rsc->cube_map_stride / 64; if (prsc->nr_samples > 1) { @@ -661,6 +783,13 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, VC5_TILING_UIF_NO_XOR); tex.level_0_xor_enable = (rsc->slices[0].tiling == VC5_TILING_UIF_XOR); + +#if V3D_VERSION >= 40 + if (tex.uif_xor_disable || + tex.level_0_is_strictly_uif) { + tex.extended = true; + } +#endif /* V3D_VERSION >= 40 */ }; return &so->base; @@ -668,10 +797,13 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, static void vc5_sampler_view_destroy(struct pipe_context *pctx, - struct pipe_sampler_view *view) + struct pipe_sampler_view *psview) { - pipe_resource_reference(&view->texture, NULL); - free(view); + struct vc5_sampler_view *sview = vc5_sampler_view(psview); + + vc5_bo_unreference(&sview->bo); + pipe_resource_reference(&psview->texture, NULL); + free(psview); } static void @@ -754,7 +886,7 @@ vc5_set_stream_output_targets(struct pipe_context *pctx, } void -vc5_state_init(struct pipe_context *pctx) +v3dX(state_init)(struct pipe_context *pctx) { pctx->set_blend_color = vc5_set_blend_color; pctx->set_stencil_ref = vc5_set_stencil_ref; @@ -785,7 +917,7 @@ vc5_state_init(struct pipe_context *pctx) pctx->bind_vertex_elements_state = vc5_vertex_state_bind; pctx->create_sampler_state = vc5_create_sampler_state; - pctx->delete_sampler_state = vc5_generic_cso_state_delete; + pctx->delete_sampler_state = vc5_sampler_state_delete; pctx->bind_sampler_states = vc5_sampler_states_bind; pctx->create_sampler_view = vc5_create_sampler_view; diff --git a/src/gallium/drivers/vc5/vc5_uniforms.c b/src/gallium/drivers/vc5/vc5_uniforms.c index 676ab1a32c9..faf49dbc359 100644 --- a/src/gallium/drivers/vc5/vc5_uniforms.c +++ b/src/gallium/drivers/vc5/vc5_uniforms.c @@ -170,7 +170,7 @@ vc5_upload_ubo(struct vc5_context *vc5, } /** - * Writes the P0 (CFG_MODE=1) texture parameter. + * Writes the V3D 3.x P0 (CFG_MODE=1) texture parameter. * * Some bits of this field are dependent on the type of sample being done by * the shader, while other bits are dependent on the sampler state. We OR the @@ -189,6 +189,7 @@ write_texture_p0(struct vc5_job *job, cl_aligned_u32(uniforms, shader_data | sampler->p0); } +/** Writes the V3D 3.x P1 (CFG_MODE=1) texture parameter. */ static void write_texture_p1(struct vc5_job *job, struct vc5_cl_out **uniforms, @@ -216,6 +217,46 @@ write_texture_p1(struct vc5_job *job, cl_aligned_u32(uniforms, p1 | packed | sview->p1); } +/** Writes the V3D 4.x TMU configuration parameter 0. */ +static void +write_tmu_p0(struct vc5_job *job, + struct vc5_cl_out **uniforms, + struct vc5_texture_stateobj *texstate, + uint32_t data) +{ + /* Extract the texture unit from the top bits, and the compiler's + * packed p0 from the bottom. + */ + uint32_t unit = data >> 24; + uint32_t p0 = data & 0x00ffffff; + + struct pipe_sampler_view *psview = texstate->textures[unit]; + struct vc5_sampler_view *sview = vc5_sampler_view(psview); + struct vc5_resource *rsc = vc5_resource(psview->texture); + + cl_aligned_reloc(&job->indirect, uniforms, sview->bo, p0); + vc5_job_add_bo(job, rsc->bo); +} + +/** Writes the V3D 4.x TMU configuration parameter 1. */ +static void +write_tmu_p1(struct vc5_job *job, + struct vc5_cl_out **uniforms, + struct vc5_texture_stateobj *texstate, + uint32_t data) +{ + /* Extract the texture unit from the top bits, and the compiler's + * packed p1 from the bottom. + */ + uint32_t unit = data >> 24; + uint32_t p0 = data & 0x00ffffff; + + struct pipe_sampler_state *psampler = texstate->samplers[unit]; + struct vc5_sampler_state *sampler = vc5_sampler_state(psampler); + + cl_aligned_reloc(&job->indirect, uniforms, sampler->bo, p0); +} + struct vc5_cl_reloc vc5_write_uniforms(struct vc5_context *vc5, struct vc5_compiled_shader *shader, struct vc5_constbuf_stateobj *cb, @@ -266,6 +307,16 @@ vc5_write_uniforms(struct vc5_context *vc5, struct vc5_compiled_shader *shader, vc5->clip.ucp[uinfo->data[i] / 4][uinfo->data[i] % 4]); break; + case QUNIFORM_TMU_CONFIG_P0: + write_tmu_p0(job, &uniforms, texstate, + uinfo->data[i]); + break; + + case QUNIFORM_TMU_CONFIG_P1: + write_tmu_p1(job, &uniforms, texstate, + uinfo->data[i]); + break; + case QUNIFORM_TEXTURE_CONFIG_P1: write_texture_p1(job, &uniforms, texstate, uinfo->data[i]); @@ -388,6 +439,8 @@ vc5_set_shader_uniform_dirty_flags(struct vc5_compiled_shader *shader) dirty |= VC5_DIRTY_CLIP; break; + case QUNIFORM_TMU_CONFIG_P0: + case QUNIFORM_TMU_CONFIG_P1: case QUNIFORM_TEXTURE_CONFIG_P1: case QUNIFORM_TEXTURE_BORDER_COLOR: case QUNIFORM_TEXTURE_FIRST_LEVEL: