#include "util/u_surface.h"
#include "util/u_blitter.h"
#include "v3d_context.h"
+#include "v3d_tiling.h"
#if 0
static struct pipe_surface *
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.
*/
/** 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;
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);
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;
+ }
+}