diff options
author | Rob Clark <[email protected]> | 2017-09-14 15:03:11 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2017-10-02 09:25:57 -0400 |
commit | 16ac70bdcf29d075e11f1ebc54405d0ea19b561c (patch) | |
tree | 64eb7ba0401f49a7fa5dd85cced0808d6747e84c /src/gallium/drivers | |
parent | 146c2b7c28ad62e837a9ca8123c2829bd07ca77a (diff) |
freedreno/a5xx: align height to GMEM
Similar to the way width/pitch alignment works, it seems like we need to
do similar for height. Otherwise the BLIT from system memory to GMEM
can over-fetch beyond the end of the buffer, triggering a fault.
I'm not sure if there is a better solution yet. Possibly we could fall
back to pre-a5xx style DRAW packets for cases where BLIT might over-
fetch. (We in theory have that problem already with rendering to higher
mipmap levels, although fortunately those tend to use GMEM bypass.)
This fixes issues reported with glamor.
Reported-by: [email protected]
Cc: 17.2 <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_resource.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 79d831c6d75..5aa90ced69c 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -704,8 +704,9 @@ static uint32_t setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format format) { struct pipe_resource *prsc = &rsc->base.b; + struct fd_screen *screen = fd_screen(prsc->screen); enum util_format_layout layout = util_format_description(format)->layout; - uint32_t pitchalign = fd_screen(prsc->screen)->gmem_alignw; + uint32_t pitchalign = screen->gmem_alignw; uint32_t level, size = 0; uint32_t width = prsc->width0; uint32_t height = prsc->height0; @@ -715,6 +716,9 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format forma */ uint32_t layers_in_level = rsc->layer_first ? 1 : prsc->array_size; + if (is_a5xx(screen) && (rsc->base.b.target >= PIPE_TEXTURE_2D)) + height = align(height, screen->gmem_alignh); + for (level = 0; level <= prsc->last_level; level++) { struct fd_resource_slice *slice = fd_resource_slice(rsc, level); uint32_t blocks; |