v3d: Use the TFU to do generatemipmap.
This is a separate, dedicated hardware unit for texture layout conversions and mipmap generation.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include "util/u_surface.h"
|
||||
#include "util/u_blitter.h"
|
||||
#include "v3d_context.h"
|
||||
#include "v3d_tiling.h"
|
||||
|
||||
#if 0
|
||||
static struct pipe_surface *
|
||||
@@ -316,6 +317,109 @@ v3d_stencil_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
|
||||
pipe_sampler_view_reference(&src_view, NULL);
|
||||
}
|
||||
|
||||
/* Disable level 0 write, just write following mipmaps */
|
||||
#define V3D_TFU_IOA_DIMTW (1 << 0)
|
||||
#define V3D_TFU_IOA_FORMAT_SHIFT 3
|
||||
#define V3D_TFU_IOA_FORMAT_LINEARTILE 3
|
||||
#define V3D_TFU_IOA_FORMAT_UBLINEAR_1_COLUMN 4
|
||||
#define V3D_TFU_IOA_FORMAT_UBLINEAR_2_COLUMN 5
|
||||
#define V3D_TFU_IOA_FORMAT_UIF_NO_XOR 6
|
||||
#define V3D_TFU_IOA_FORMAT_UIF_XOR 7
|
||||
|
||||
#define V3D_TFU_ICFG_NUMMM_SHIFT 5
|
||||
#define V3D_TFU_ICFG_TTYPE_SHIFT 9
|
||||
|
||||
#define V3D_TFU_ICFG_FORMAT_SHIFT 18
|
||||
#define V3D_TFU_ICFG_FORMAT_RASTER 0
|
||||
#define V3D_TFU_ICFG_FORMAT_SAND_128 1
|
||||
#define V3D_TFU_ICFG_FORMAT_SAND_256 2
|
||||
#define V3D_TFU_ICFG_FORMAT_LINEARTILE 11
|
||||
#define V3D_TFU_ICFG_FORMAT_UBLINEAR_1_COLUMN 12
|
||||
#define V3D_TFU_ICFG_FORMAT_UBLINEAR_2_COLUMN 13
|
||||
#define V3D_TFU_ICFG_FORMAT_UIF_NO_XOR 14
|
||||
#define V3D_TFU_ICFG_FORMAT_UIF_XOR 15
|
||||
|
||||
boolean
|
||||
v3d_generate_mipmap(struct pipe_context *pctx,
|
||||
struct pipe_resource *prsc,
|
||||
enum pipe_format format,
|
||||
unsigned int base_level,
|
||||
unsigned int last_level,
|
||||
unsigned int first_layer,
|
||||
unsigned int last_layer)
|
||||
{
|
||||
struct v3d_context *v3d = v3d_context(pctx);
|
||||
struct v3d_screen *screen = v3d->screen;
|
||||
struct v3d_resource *rsc = v3d_resource(prsc);
|
||||
struct v3d_resource_slice *base_slice = &rsc->slices[base_level];
|
||||
int width = u_minify(prsc->width0, base_level);
|
||||
int height = u_minify(prsc->height0, base_level);
|
||||
uint32_t tex_format = v3d_get_tex_format(&screen->devinfo,
|
||||
prsc->format);
|
||||
|
||||
if (!v3d_tfu_supports_tex_format(&screen->devinfo, tex_format))
|
||||
return false;
|
||||
|
||||
if (prsc->target != PIPE_TEXTURE_2D)
|
||||
return false;
|
||||
/* Since we don't support array or 3D textures, there should be only
|
||||
* one layer.
|
||||
*/
|
||||
int layer = first_layer;
|
||||
assert(first_layer == last_layer);
|
||||
|
||||
/* Can't write to raster. */
|
||||
if (base_slice->tiling == VC5_TILING_RASTER)
|
||||
return false;
|
||||
|
||||
v3d_flush_jobs_reading_resource(v3d, prsc);
|
||||
|
||||
struct drm_v3d_submit_tfu tfu = {
|
||||
.ios = (height << 16) | width,
|
||||
.bo_handles = { rsc->bo->handle },
|
||||
.in_sync = v3d->out_sync,
|
||||
.out_sync = v3d->out_sync,
|
||||
};
|
||||
uint32_t offset = (rsc->bo->offset +
|
||||
v3d_layer_offset(prsc, base_level, layer));
|
||||
tfu.iia |= offset;
|
||||
tfu.icfg |= ((V3D_TFU_ICFG_FORMAT_LINEARTILE +
|
||||
(base_slice->tiling - VC5_TILING_LINEARTILE)) <<
|
||||
V3D_TFU_ICFG_FORMAT_SHIFT);
|
||||
|
||||
tfu.ioa |= offset;
|
||||
tfu.ioa |= V3D_TFU_IOA_DIMTW;
|
||||
tfu.ioa |= ((V3D_TFU_IOA_FORMAT_LINEARTILE +
|
||||
(base_slice->tiling - VC5_TILING_LINEARTILE)) <<
|
||||
V3D_TFU_IOA_FORMAT_SHIFT);
|
||||
|
||||
tfu.icfg |= tex_format << V3D_TFU_ICFG_TTYPE_SHIFT;
|
||||
tfu.icfg |= (last_level - base_level) << V3D_TFU_ICFG_NUMMM_SHIFT;
|
||||
|
||||
switch (base_slice->tiling) {
|
||||
case VC5_TILING_UIF_NO_XOR:
|
||||
case VC5_TILING_UIF_XOR:
|
||||
tfu.iis |= (base_slice->padded_height /
|
||||
(2 * v3d_utile_height(rsc->cpp)));
|
||||
break;
|
||||
case VC5_TILING_RASTER:
|
||||
tfu.iis |= base_slice->stride;
|
||||
break;
|
||||
case VC5_TILING_LINEARTILE:
|
||||
case VC5_TILING_UBLINEAR_1_COLUMN:
|
||||
case VC5_TILING_UBLINEAR_2_COLUMN:
|
||||
break;
|
||||
}
|
||||
|
||||
int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_SUBMIT_TFU, &tfu);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to submit TFU job: %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Optimal hardware path for blitting pixels.
|
||||
* Scaling, format conversion, up- and downsampling (resolve) are allowed.
|
||||
*/
|
||||
|
@@ -365,7 +365,7 @@ struct v3d_context {
|
||||
/** Maximum index buffer valid for the current shader_rec. */
|
||||
uint32_t max_index;
|
||||
|
||||
/** Sync object that our RCL will update as its out_sync. */
|
||||
/** Sync object that our RCL or TFU job will update as its out_sync. */
|
||||
uint32_t out_sync;
|
||||
|
||||
struct u_upload_mgr *uploader;
|
||||
@@ -526,10 +526,19 @@ void v3d_get_internal_type_bpp_for_output_format(const struct v3d_device_info *d
|
||||
uint32_t format,
|
||||
uint32_t *type,
|
||||
uint32_t *bpp);
|
||||
bool v3d_tfu_supports_tex_format(const struct v3d_device_info *devinfo,
|
||||
uint32_t tex_format);
|
||||
|
||||
void v3d_init_query_functions(struct v3d_context *v3d);
|
||||
void v3d_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info);
|
||||
void v3d_blitter_save(struct v3d_context *v3d);
|
||||
boolean v3d_generate_mipmap(struct pipe_context *pctx,
|
||||
struct pipe_resource *prsc,
|
||||
enum pipe_format format,
|
||||
unsigned int base_level,
|
||||
unsigned int last_level,
|
||||
unsigned int first_layer,
|
||||
unsigned int last_layer);
|
||||
|
||||
struct v3d_fence *v3d_fence_create(struct v3d_context *v3d);
|
||||
|
||||
|
@@ -142,3 +142,14 @@ v3d_get_internal_type_bpp_for_output_format(const struct v3d_device_info *devinf
|
||||
type, bpp);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
v3d_tfu_supports_tex_format(const struct v3d_device_info *devinfo,
|
||||
uint32_t tex_format)
|
||||
{
|
||||
if (devinfo->ver >= 41) {
|
||||
return v3d41_tfu_supports_tex_format(tex_format);
|
||||
} else {
|
||||
return v3d33_tfu_supports_tex_format(tex_format);
|
||||
}
|
||||
}
|
||||
|
@@ -985,5 +985,6 @@ v3d_resource_context_init(struct pipe_context *pctx)
|
||||
pctx->surface_destroy = v3d_surface_destroy;
|
||||
pctx->resource_copy_region = util_resource_copy_region;
|
||||
pctx->blit = v3d_blit;
|
||||
pctx->generate_mipmap = v3d_generate_mipmap;
|
||||
pctx->flush_resource = v3d_flush_resource;
|
||||
}
|
||||
|
@@ -79,6 +79,20 @@ v3d_screen_destroy(struct pipe_screen *pscreen)
|
||||
ralloc_free(pscreen);
|
||||
}
|
||||
|
||||
static bool
|
||||
v3d_has_feature(struct v3d_screen *screen, enum drm_v3d_param feature)
|
||||
{
|
||||
struct drm_v3d_get_param p = {
|
||||
.param = feature,
|
||||
};
|
||||
int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &p);
|
||||
|
||||
if (ret != 0)
|
||||
return false;
|
||||
|
||||
return p.value;
|
||||
}
|
||||
|
||||
static int
|
||||
v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
{
|
||||
@@ -113,6 +127,9 @@ v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
|
||||
return 1;
|
||||
|
||||
case PIPE_CAP_GENERATE_MIPMAP:
|
||||
return v3d_has_feature(screen,DRM_V3D_PARAM_SUPPORTS_TFU);
|
||||
|
||||
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
||||
return screen->devinfo.ver >= 40;
|
||||
|
||||
|
@@ -48,3 +48,4 @@ const struct v3d_format *v3dX(get_format_desc)(enum pipe_format f);
|
||||
void v3dX(get_internal_type_bpp_for_output_format)(uint32_t format,
|
||||
uint32_t *type,
|
||||
uint32_t *bpp);
|
||||
bool v3dX(tfu_supports_tex_format)(uint32_t tex_format);
|
||||
|
@@ -318,3 +318,34 @@ v3dX(get_internal_type_bpp_for_output_format)(uint32_t format,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
v3dX(tfu_supports_tex_format)(enum V3DX(Texture_Data_Formats) format)
|
||||
{
|
||||
switch (format) {
|
||||
case TEXTURE_DATA_FORMAT_R8:
|
||||
case TEXTURE_DATA_FORMAT_R8_SNORM:
|
||||
case TEXTURE_DATA_FORMAT_RG8:
|
||||
case TEXTURE_DATA_FORMAT_RG8_SNORM:
|
||||
case TEXTURE_DATA_FORMAT_RGBA8:
|
||||
case TEXTURE_DATA_FORMAT_RGBA8_SNORM:
|
||||
case TEXTURE_DATA_FORMAT_RGB565:
|
||||
case TEXTURE_DATA_FORMAT_RGBA4:
|
||||
case TEXTURE_DATA_FORMAT_RGB5_A1:
|
||||
case TEXTURE_DATA_FORMAT_RGB10_A2:
|
||||
case TEXTURE_DATA_FORMAT_R16:
|
||||
case TEXTURE_DATA_FORMAT_R16_SNORM:
|
||||
case TEXTURE_DATA_FORMAT_RG16:
|
||||
case TEXTURE_DATA_FORMAT_RG16_SNORM:
|
||||
case TEXTURE_DATA_FORMAT_RGBA16:
|
||||
case TEXTURE_DATA_FORMAT_RGBA16_SNORM:
|
||||
case TEXTURE_DATA_FORMAT_R16F:
|
||||
case TEXTURE_DATA_FORMAT_RG16F:
|
||||
case TEXTURE_DATA_FORMAT_RGBA16F:
|
||||
case TEXTURE_DATA_FORMAT_R11F_G11F_B10F:
|
||||
case TEXTURE_DATA_FORMAT_R4:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user