diff options
Diffstat (limited to 'src/gallium/drivers/v3d/v3dx_state.c')
-rw-r--r-- | src/gallium/drivers/v3d/v3dx_state.c | 439 |
1 files changed, 233 insertions, 206 deletions
diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index 3315421b9b5..389c7443003 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -35,6 +35,7 @@ #include "v3d_context.h" #include "broadcom/common/v3d_tiling.h" #include "broadcom/common/v3d_macros.h" +#include "broadcom/common/v3d_util.h" #include "broadcom/compiler/v3d_compiler.h" #include "broadcom/cle/v3dx_pack.h" @@ -105,15 +106,19 @@ v3d_create_rasterizer_state(struct pipe_context *pctx, v3dx_pack(&so->depth_offset, DEPTH_OFFSET, depth) { depth.depth_offset_factor = cso->offset_scale; depth.depth_offset_units = cso->offset_units; + depth.limit = cso->offset_clamp; } - /* The HW treats polygon offset units based on a Z24 buffer, so we + /* V3d 4.x treats polygon offset units based on a Z24 buffer, so we * need to scale up offset_units if we're only Z16. */ +#if V3D_VERSION == 42 v3dx_pack(&so->depth_offset_z16, DEPTH_OFFSET, depth) { depth.depth_offset_factor = cso->offset_scale; depth.depth_offset_units = cso->offset_units * 256.0; + depth.limit = cso->offset_clamp; } +#endif return so; } @@ -131,17 +136,14 @@ v3d_create_blend_state(struct pipe_context *pctx, so->base = *cso; + uint32_t max_rts = V3D_MAX_RENDER_TARGETS(V3D_VERSION); if (cso->independent_blend_enable) { - for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++) { + for (int i = 0; i < max_rts; i++) { so->blend_enables |= cso->rt[i].blend_enable << i; - - /* V3D 4.x is when we got independent blend enables. */ - assert(V3D_VERSION >= 40 || - cso->rt[i].blend_enable == cso->rt[0].blend_enable); } } else { if (cso->rt[0].blend_enable) - so->blend_enables = (1 << V3D_MAX_DRAW_BUFFERS) - 1; + so->blend_enables = (1 << max_rts) - 1; } return so; @@ -201,7 +203,7 @@ v3d_create_depth_stencil_alpha_state(struct pipe_context *pctx, (cso->stencil[0].zfail_op != PIPE_STENCIL_OP_KEEP || cso->stencil[0].func != PIPE_FUNC_ALWAYS || (cso->stencil[1].enabled && - (cso->stencil[1].zfail_op != PIPE_STENCIL_OP_KEEP && + (cso->stencil[1].zfail_op != PIPE_STENCIL_OP_KEEP || cso->stencil[1].func != PIPE_FUNC_ALWAYS)))) { so->ez_state = V3D_EZ_DISABLED; } @@ -289,18 +291,14 @@ v3d_set_viewport_states(struct pipe_context *pctx, static void v3d_set_vertex_buffers(struct pipe_context *pctx, - unsigned start_slot, unsigned count, - unsigned unbind_num_trailing_slots, - bool take_ownership, + unsigned count, const struct pipe_vertex_buffer *vb) { struct v3d_context *v3d = v3d_context(pctx); struct v3d_vertexbuf_stateobj *so = &v3d->vertexbuf; util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, - start_slot, count, - unbind_num_trailing_slots, - take_ownership); + count, true); so->count = util_last_bit(so->enabled_mask); v3d->dirty |= V3D_DIRTY_VTXBUF; @@ -330,6 +328,20 @@ v3d_zsa_state_bind(struct pipe_context *pctx, void *hwcso) v3d->dirty |= V3D_DIRTY_ZSA; } + +static bool +needs_default_attribute_values(void) +{ +#if V3D_VERSION == 42 + /* FIXME: on vulkan we are able to refine even further, as we know in + * advance when we create the pipeline if we have an integer vertex + * attrib. Pending to check if we could do something similar here. + */ + return true; +#endif + return false; +} + static void * v3d_vertex_state_create(struct pipe_context *pctx, unsigned num_elements, const struct pipe_vertex_element *elements) @@ -407,24 +419,29 @@ v3d_vertex_state_create(struct pipe_context *pctx, unsigned num_elements, } } - /* Set up the default attribute values in case any of the vertex - * elements use them. - */ - uint32_t *attrs; - u_upload_alloc(v3d->state_uploader, 0, - V3D_MAX_VS_INPUTS * sizeof(float), 16, - &so->defaults_offset, &so->defaults, (void **)&attrs); - - for (int i = 0; i < V3D_MAX_VS_INPUTS / 4; i++) { - attrs[i * 4 + 0] = 0; - attrs[i * 4 + 1] = 0; - attrs[i * 4 + 2] = 0; - if (i < so->num_elements && - util_format_is_pure_integer(so->pipe[i].src_format)) { - attrs[i * 4 + 3] = 1; - } else { - attrs[i * 4 + 3] = fui(1.0); + if (needs_default_attribute_values()) { + /* Set up the default attribute values in case any of the vertex + * elements use them. + */ + uint32_t *attrs; + u_upload_alloc(v3d->state_uploader, 0, + V3D_MAX_VS_INPUTS * sizeof(float), 16, + &so->defaults_offset, &so->defaults, (void **)&attrs); + + for (int i = 0; i < V3D_MAX_VS_INPUTS / 4; i++) { + attrs[i * 4 + 0] = 0; + attrs[i * 4 + 1] = 0; + attrs[i * 4 + 2] = 0; + if (i < so->num_elements && + util_format_is_pure_integer(so->pipe[i].src_format)) { + attrs[i * 4 + 3] = 1; + } else { + attrs[i * 4 + 3] = fui(1.0); + } } + } else { + so->defaults = NULL; + so->defaults_offset = 0; } u_upload_unmap(v3d->state_uploader); @@ -449,7 +466,7 @@ v3d_vertex_state_bind(struct pipe_context *pctx, void *hwcso) } static void -v3d_set_constant_buffer(struct pipe_context *pctx, uint shader, uint index, +v3d_set_constant_buffer(struct pipe_context *pctx, enum pipe_shader_type shader, uint index, bool take_ownership, const struct pipe_constant_buffer *cb) { @@ -489,18 +506,10 @@ v3d_set_framebuffer_state(struct pipe_context *pctx, struct pipe_surface *cbuf = v3d->framebuffer.cbufs[i]; if (!cbuf) continue; - struct v3d_surface *v3d_cbuf = v3d_surface(cbuf); const struct util_format_description *desc = util_format_description(cbuf->format); - /* For BGRA8 formats (DRI window system default format), we - * need to swap R and B, since the HW's format is RGBA8. On - * V3D 4.1+, the RCL can swap R and B on load/store. - */ - if (v3d->screen->devinfo.ver < 41 && v3d_cbuf->swap_rb) - v3d->swap_color_rb |= 1 << i; - if (desc->swizzle[3] == PIPE_SWIZZLE_1) v3d->blend_dst_alpha_one |= 1 << i; } @@ -527,7 +536,6 @@ translate_wrap(uint32_t pipe_wrap) } } -#if V3D_VERSION >= 40 static void v3d_upload_sampler_state_variant(void *map, const struct pipe_sampler_state *cso, @@ -541,8 +549,9 @@ v3d_upload_sampler_state_variant(void *map, sampler.wrap_r = translate_wrap(cso->wrap_r); sampler.fixed_bias = cso->lod_bias; - sampler.depth_compare_function = cso->compare_func; - + sampler.depth_compare_function = cso->compare_mode ? + cso->compare_func : + V3D_COMPARE_FUNC_NEVER; sampler.min_filter_nearest = cso->min_img_filter == PIPE_TEX_FILTER_NEAREST; sampler.mag_filter_nearest = @@ -579,8 +588,12 @@ v3d_upload_sampler_state_variant(void *map, sampler.maximum_anisotropy = 1; } - if (variant == V3D_SAMPLER_STATE_BORDER_0) { + if (variant == V3D_SAMPLER_STATE_BORDER_0000) { sampler.border_color_mode = V3D_BORDER_COLOR_0000; + } else if (variant == V3D_SAMPLER_STATE_BORDER_0001) { + sampler.border_color_mode = V3D_BORDER_COLOR_0001; + } else if (variant == V3D_SAMPLER_STATE_BORDER_1111) { + sampler.border_color_mode = V3D_BORDER_COLOR_1111; } else { sampler.border_color_mode = V3D_BORDER_COLOR_FOLLOWS; @@ -687,25 +700,25 @@ v3d_upload_sampler_state_variant(void *map, break; } - if (variant >= V3D_SAMPLER_STATE_32) { - sampler.border_color_word_0 = border.ui[0]; - sampler.border_color_word_1 = border.ui[1]; - sampler.border_color_word_2 = border.ui[2]; - sampler.border_color_word_3 = border.ui[3]; - } else { - sampler.border_color_word_0 = - _mesa_float_to_half(border.f[0]); - sampler.border_color_word_1 = - _mesa_float_to_half(border.f[1]); - sampler.border_color_word_2 = - _mesa_float_to_half(border.f[2]); - sampler.border_color_word_3 = - _mesa_float_to_half(border.f[3]); +#if V3D_VERSION == 42 + /* The TMU in V3D 7.x always takes 32-bit floats and handles conversions + * for us. In V3D 4.x we need to manually convert floating point color + * values to the expected format. + */ + if (variant < V3D_SAMPLER_STATE_32) { + border.ui[0] = _mesa_float_to_half(border.f[0]); + border.ui[1] = _mesa_float_to_half(border.f[1]); + border.ui[2] = _mesa_float_to_half(border.f[2]); + border.ui[3] = _mesa_float_to_half(border.f[3]); } +#endif + sampler.border_color_word_0 = border.ui[0]; + sampler.border_color_word_1 = border.ui[1]; + sampler.border_color_word_2 = border.ui[2]; + sampler.border_color_word_3 = border.ui[3]; } } } -#endif static void * v3d_create_sampler_state(struct pipe_context *pctx, @@ -726,13 +739,33 @@ v3d_create_sampler_state(struct pipe_context *pctx, bool uses_border_color = (wrap_s == V3D_WRAP_MODE_BORDER || wrap_t == V3D_WRAP_MODE_BORDER || wrap_r == V3D_WRAP_MODE_BORDER); - so->border_color_variants = (uses_border_color && - (cso->border_color.ui[0] != 0 || - cso->border_color.ui[1] != 0 || - cso->border_color.ui[2] != 0 || - cso->border_color.ui[3] != 0)); -#if V3D_VERSION >= 40 + so->border_color_variants = false; + + /* This is the variant with the default hardware settings */ + enum v3d_sampler_state_variant border_variant = V3D_SAMPLER_STATE_BORDER_0000; + + if (uses_border_color) { + if (cso->border_color.ui[0] == 0 && + cso->border_color.ui[1] == 0 && + cso->border_color.ui[2] == 0 && + cso->border_color.ui[3] == 0) { + border_variant = V3D_SAMPLER_STATE_BORDER_0000; + } else if (cso->border_color.ui[0] == 0 && + cso->border_color.ui[1] == 0 && + cso->border_color.ui[2] == 0 && + cso->border_color.ui[3] == 0x3F800000) { + border_variant = V3D_SAMPLER_STATE_BORDER_0001; + } else if (cso->border_color.ui[0] == 0x3F800000 && + cso->border_color.ui[1] == 0x3F800000 && + cso->border_color.ui[2] == 0x3F800000 && + cso->border_color.ui[3] == 0x3F800000) { + border_variant = V3D_SAMPLER_STATE_BORDER_1111; + } else { + so->border_color_variants = true; + } + } + void *map; int sampler_align = so->border_color_variants ? 32 : 8; int sampler_size = align(cl_packet_length(SAMPLER_STATE), sampler_align); @@ -748,21 +781,10 @@ v3d_create_sampler_state(struct pipe_context *pctx, so->sampler_state_offset[i] = so->sampler_state_offset[0] + i * sampler_size; v3d_upload_sampler_state_variant(map + i * sampler_size, - cso, i); - } - -#else /* V3D_VERSION < 40 */ - v3dx_pack(&so->p0, TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1, p0) { - p0.s_wrap_mode = wrap_s; - p0.t_wrap_mode = wrap_t; - p0.r_wrap_mode = wrap_r; + cso, + so->border_color_variants ? i : border_variant); } - v3dx_pack(&so->texture_shader_state, TEXTURE_SHADER_STATE, tex) { - tex.depth_compare_function = cso->compare_func; - tex.fixed_bias = cso->lod_bias; - } -#endif /* V3D_VERSION < 40 */ return so; } @@ -804,40 +826,56 @@ v3d_sampler_state_delete(struct pipe_context *pctx, free(psampler); } -#if V3D_VERSION >= 40 -static uint32_t -translate_swizzle(unsigned char pipe_swizzle) +static void +v3d_setup_texture_shader_state_from_buffer(struct V3DX(TEXTURE_SHADER_STATE) *tex, + struct pipe_resource *prsc, + enum pipe_format format, + unsigned offset, + unsigned size) { - 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"); - } + struct v3d_resource *rsc = v3d_resource(prsc); + + tex->image_depth = 1; + tex->image_width = size / util_format_get_blocksize(format); + + /* 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). + */ + tex->image_height = tex->image_width >> 14; + + tex->image_width &= (1 << 14) - 1; + tex->image_height &= (1 << 14) - 1; + + /* 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 + offset); } -#endif static void -v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex, +v3d_setup_texture_shader_state(const struct v3d_device_info *devinfo, + struct V3DX(TEXTURE_SHADER_STATE) *tex, struct pipe_resource *prsc, int base_level, int last_level, - int first_layer, int last_layer) + int first_layer, int last_layer, + bool sampling_cube_array) { + /* Due to ARB_texture_view, a cubemap array can be seen as 2D texture + * array. + */ + assert(!sampling_cube_array || + prsc->target == PIPE_TEXTURE_CUBE_ARRAY || + prsc->target == PIPE_TEXTURE_2D_ARRAY); + struct v3d_resource *rsc = v3d_resource(prsc); int msaa_scale = prsc->nr_samples > 1 ? 2 : 1; 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 + /* 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 || @@ -847,7 +885,6 @@ v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex, tex->image_width &= (1 << 14) - 1; tex->image_height &= (1 << 14) - 1; -#endif if (prsc->target == PIPE_TEXTURE_3D) { tex->image_depth = prsc->depth0; @@ -855,20 +892,36 @@ v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex, tex->image_depth = (last_layer - first_layer) + 1; } + /* Empirical testing with CTS shows that when we are sampling from + * cube arrays we want to set image depth to layers / 6, but not when + * doing image load/store or sampling from 2d image arrays. + */ + if (sampling_cube_array) { + assert(tex->image_depth % 6 == 0); + tex->image_depth /= 6; + } + tex->base_level = base_level; -#if V3D_VERSION >= 40 + tex->max_level = 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 + - v3d_layer_offset(prsc, 0, first_layer)); -#endif + const uint32_t base_offset = rsc->bo->offset + + v3d_layer_offset(prsc, 0, first_layer); + + tex->texture_base_pointer = cl_address(NULL, base_offset); tex->array_stride_64_byte_aligned = rsc->cube_map_stride / 64; +#if V3D_VERSION >= 71 + tex->chroma_offset_x = 1; + tex->chroma_offset_y = 1; + /* See comment in XML field definition for rationale of the shifts */ + tex->texture_base_pointer_cb = base_offset >> 6; + tex->texture_base_pointer_cr = base_offset >> 6; +#endif + /* Since other platform devices may produce UIF images even * when they're not big enough for V3D to assume they're UIF, * we force images with level 0 as UIF to be always treated @@ -882,12 +935,10 @@ v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex, if (tex->level_0_is_strictly_uif) tex->level_0_ub_pad = rsc->slices[0].ub_pad; -#if V3D_VERSION >= 40 if (tex->uif_xor_disable || tex->level_0_is_strictly_uif) { tex->extended = true; } -#endif /* V3D_VERSION >= 40 */ } void @@ -895,86 +946,53 @@ v3dX(create_texture_shader_state_bo)(struct v3d_context *v3d, struct v3d_sampler_view *so) { struct pipe_resource *prsc = so->texture; + struct v3d_resource *rsc = v3d_resource(prsc); const struct pipe_sampler_view *cso = &so->base; struct v3d_screen *screen = v3d->screen; void *map; -#if V3D_VERSION >= 40 + assert(so->serial_id != rsc->serial_id); + v3d_bo_unreference(&so->bo); so->bo = v3d_bo_alloc(v3d->screen, cl_packet_length(TEXTURE_SHADER_STATE), "sampler"); map = v3d_bo_map(so->bo); -#else /* V3D_VERSION < 40 */ - STATIC_ASSERT(sizeof(so->texture_shader_state) >= - cl_packet_length(TEXTURE_SHADER_STATE)); - map = &so->texture_shader_state; -#endif v3dx_pack(map, TEXTURE_SHADER_STATE, tex) { - v3d_setup_texture_shader_state(&tex, prsc, - cso->u.tex.first_level, - cso->u.tex.last_level, - cso->u.tex.first_layer, - cso->u.tex.last_layer); - - tex.srgb = util_format_is_srgb(cso->format); - -#if V3D_VERSION >= 40 - 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]); + if (prsc->target != PIPE_BUFFER) { + v3d_setup_texture_shader_state(&v3d->screen->devinfo, + &tex, prsc, + cso->u.tex.first_level, + cso->u.tex.last_level, + cso->u.tex.first_layer, + cso->u.tex.last_layer, + cso->target == PIPE_TEXTURE_CUBE_ARRAY); + } else { + v3d_setup_texture_shader_state_from_buffer(&tex, prsc, + cso->format, + cso->u.buf.offset, + cso->u.buf.size); + } + + bool is_srgb = util_format_is_srgb(cso->format); +#if V3D_VERSION == 42 + tex.srgb = is_srgb; +#endif +#if V3D_VERSION >= 71 + tex.transfer_func = is_srgb ? TRANSFER_FUNC_SRGB : TRANSFER_FUNC_NONE; #endif - if (prsc->nr_samples > 1 && V3D_VERSION < 40) { - /* Using texture views to reinterpret formats on our - * MSAA textures won't work, because we don't lay out - * the bits in memory as it's expected -- for example, - * RGBA8 and RGB10_A2 are compatible in the - * ARB_texture_view spec, but in HW we lay them out as - * 32bpp RGBA8 and 64bpp RGBA16F. Just assert for now - * to catch failures. - * - * We explicitly allow remapping S8Z24 to RGBA8888 for - * v3d_blit.c's stencil blits. - */ - assert((util_format_linear(cso->format) == - util_format_linear(prsc->format)) || - (prsc->format == PIPE_FORMAT_S8_UINT_Z24_UNORM && - cso->format == PIPE_FORMAT_R8G8B8A8_UNORM)); - uint32_t output_image_format = - v3d_get_rt_format(&screen->devinfo, cso->format); - uint32_t internal_type; - uint32_t internal_bpp; - v3d_get_internal_type_bpp_for_output_format(&screen->devinfo, - output_image_format, - &internal_type, - &internal_bpp); - - switch (internal_type) { - case V3D_INTERNAL_TYPE_8: - tex.texture_type = TEXTURE_DATA_FORMAT_RGBA8; - break; - case V3D_INTERNAL_TYPE_16F: - tex.texture_type = TEXTURE_DATA_FORMAT_RGBA16F; - break; - default: - unreachable("Bad MSAA texture type"); - } + tex.swizzle_r = v3d_translate_pipe_swizzle(so->swizzle[0]); + tex.swizzle_g = v3d_translate_pipe_swizzle(so->swizzle[1]); + tex.swizzle_b = v3d_translate_pipe_swizzle(so->swizzle[2]); + tex.swizzle_a = v3d_translate_pipe_swizzle(so->swizzle[3]); - /* sRGB was stored in the tile buffer as linear and - * would have been encoded to sRGB on resolved tile - * buffer store. Note that this means we would need - * shader code if we wanted to read an MSAA sRGB - * texture without sRGB decode. - */ - tex.srgb = false; - } else { - tex.texture_type = v3d_get_tex_format(&screen->devinfo, - cso->format); - } + tex.texture_type = v3d_get_tex_format(&screen->devinfo, + cso->format); }; + + so->serial_id = rsc->serial_id; } static struct pipe_sampler_view * @@ -1007,8 +1025,8 @@ v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, v3d_get_format_swizzle(&screen->devinfo, so->base.format); util_format_compose_swizzles(fmt_swizzle, view_swizzle, so->swizzle); + pipe_reference_init(&so->base.reference, 1); so->base.texture = prsc; - so->base.reference.count = 1; so->base.context = pctx; if (rsc->separate_stencil && @@ -1025,7 +1043,6 @@ v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, if (sample_format == PIPE_FORMAT_S8_UINT_Z24_UNORM) sample_format = PIPE_FORMAT_X8Z24_UNORM; -#if V3D_VERSION >= 40 const struct util_format_description *desc = util_format_description(sample_format); @@ -1061,8 +1078,7 @@ v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, } } } else { - if (v3d_get_tex_return_size(&screen->devinfo, sample_format, - PIPE_TEX_COMPARE_NONE) == 32) { + if (v3d_get_tex_return_size(&screen->devinfo, sample_format) == 32) { if (util_format_is_alpha(sample_format)) so->sampler_variant = V3D_SAMPLER_STATE_32_A; else @@ -1087,13 +1103,13 @@ v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, V3D_SAMPLER_STATE_F16); } } -#endif /* V3D still doesn't support sampling from raster textures, so we will * have to copy to a temporary tiled texture. */ if (!rsc->tiled && !(prsc->target == PIPE_TEXTURE_1D || - prsc->target == PIPE_TEXTURE_1D_ARRAY)) { + prsc->target == PIPE_TEXTURE_1D_ARRAY || + prsc->target == PIPE_BUFFER)) { struct v3d_resource *shadow_parent = rsc; struct pipe_resource tmpl = { .target = prsc->target, @@ -1128,7 +1144,7 @@ v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, pipe_resource_reference(&so->texture, prsc); } - v3d_create_texture_shader_state_bo(v3d, so); + v3dX(create_texture_shader_state_bo)(v3d, so); return &so->base; } @@ -1169,6 +1185,18 @@ v3d_set_sampler_views(struct pipe_context *pctx, } else { pipe_sampler_view_reference(&stage_tex->textures[i], views[i]); } + /* If our sampler serial doesn't match our texture serial it + * means the texture has been updated with a new BO, in which + * case we need to update the sampler state to point to the + * new BO as well + */ + if (stage_tex->textures[i]) { + struct v3d_sampler_view *so = + v3d_sampler_view(stage_tex->textures[i]); + struct v3d_resource *rsc = v3d_resource(so->texture); + if (so->serial_id != rsc->serial_id) + v3dX(create_texture_shader_state_bo)(v3d, so); + } } for (; i < stage_tex->num_textures; i++) { @@ -1230,9 +1258,12 @@ v3d_set_stream_output_targets(struct pipe_context *pctx, if (num_targets == 0 && so->num_targets > 0) v3d_update_primitive_counters(ctx); + /* If offset is (unsigned) -1, it means continue appending to the + * buffer at the existing offset. + */ for (i = 0; i < num_targets; i++) { - if (offsets[i] != -1) - so->offsets[i] = offsets[i]; + if (offsets[i] != (unsigned)-1) + v3d_stream_output_target(targets[i])->offset = offsets[i]; pipe_so_target_reference(&so->targets[i], targets[i]); } @@ -1243,14 +1274,8 @@ v3d_set_stream_output_targets(struct pipe_context *pctx, so->num_targets = num_targets; /* Create primitive counters BO if needed */ - if (num_targets > 0 && !ctx->prim_counts) { - /* Init all 7 counters and 1 padding to 0 */ - uint32_t zeroes[8] = { 0 }; - u_upload_data(ctx->uploader, - 0, sizeof(zeroes), 32, zeroes, - &ctx->prim_counts_offset, - &ctx->prim_counts); - } + if (num_targets > 0) + v3d_ensure_prim_counts_allocated(ctx); ctx->dirty |= V3D_DIRTY_STREAMOUT; } @@ -1308,7 +1333,6 @@ v3d_create_image_view_texture_shader_state(struct v3d_context *v3d, struct v3d_shaderimg_stateobj *so, int img) { -#if V3D_VERSION >= 40 struct v3d_image_view *iview = &so->si[img]; void *map; @@ -1321,26 +1345,29 @@ v3d_create_image_view_texture_shader_state(struct v3d_context *v3d, struct pipe_resource *prsc = iview->base.resource; v3dx_pack(map, TEXTURE_SHADER_STATE, tex) { - v3d_setup_texture_shader_state(&tex, prsc, - iview->base.u.tex.level, - iview->base.u.tex.level, - iview->base.u.tex.first_layer, - iview->base.u.tex.last_layer); + if (prsc->target != PIPE_BUFFER) { + v3d_setup_texture_shader_state(&v3d->screen->devinfo, + &tex, prsc, + iview->base.u.tex.level, + iview->base.u.tex.level, + iview->base.u.tex.first_layer, + iview->base.u.tex.last_layer, + false); + } else { + v3d_setup_texture_shader_state_from_buffer(&tex, prsc, + iview->base.format, + iview->base.u.buf.offset, + iview->base.u.buf.size); + } - tex.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X); - tex.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y); - tex.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z); - tex.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W); + tex.swizzle_r = v3d_translate_pipe_swizzle(PIPE_SWIZZLE_X); + tex.swizzle_g = v3d_translate_pipe_swizzle(PIPE_SWIZZLE_Y); + tex.swizzle_b = v3d_translate_pipe_swizzle(PIPE_SWIZZLE_Z); + tex.swizzle_a = v3d_translate_pipe_swizzle(PIPE_SWIZZLE_W); tex.texture_type = v3d_get_tex_format(&v3d->screen->devinfo, iview->base.format); }; -#else /* V3D_VERSION < 40 */ - /* V3D 3.x doesn't use support shader image load/store operations on - * textures, so it would get lowered in the shader to general memory - * acceses. - */ -#endif } static void |