#include "pipe/p_screen.h"
#include "util/u_inlines.h"
#include "util/ralloc.h"
+#include "intel/blorp/blorp.h"
#include "iris_context.h"
#include "iris_resource.h"
#include "iris_screen.h"
static void
-iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
+blorp_surf_for_resource(struct blorp_surf *surf,
+ struct pipe_resource *p_res,
+ enum isl_aux_usage aux_usage,
+ bool is_render_target)
+{
+ struct iris_resource *res = (void *) p_res;
+
+ *surf = (struct blorp_surf) {
+ .surf = &res->surf,
+ .addr = (struct blorp_address) {
+ .buffer = res->bo,
+ .offset = 0, // XXX: ???
+ .reloc_flags = is_render_target ? EXEC_OBJECT_WRITE : 0,
+ .mocs = I915_MOCS_CACHED, // XXX: BDW MOCS, PTE MOCS
+ },
+ .aux_usage = aux_usage,
+ };
+
+ assert(surf->aux_usage == ISL_AUX_USAGE_NONE);
+}
+
+static enum isl_format
+iris_get_blorp_format(enum pipe_format pf)
{
+ switch (pf) {
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ return ISL_FORMAT_R24_UNORM_X8_TYPELESS;
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ return ISL_FORMAT_R32_FLOAT;
+ default:
+ return iris_isl_format_for_pipe_format(pf);
+ }
}
+static void
+iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
+{
+ struct iris_context *ice = (void *) ctx;
+ struct blorp_surf src_surf, dst_surf;
+ blorp_surf_for_resource(&src_surf, info->src.resource, ISL_AUX_USAGE_NONE,
+ false);
+ blorp_surf_for_resource(&dst_surf, info->dst.resource, ISL_AUX_USAGE_NONE,
+ true);
+
+ enum isl_format src_isl_format = iris_get_blorp_format(info->src.format);
+ enum isl_format dst_isl_format = iris_get_blorp_format(info->dst.format);
+
+ // XXX: ???
+ unsigned dst_layer = 0;
+ unsigned src_layer = 0;
+
+ struct isl_swizzle src_isl_swizzle = ISL_SWIZZLE_IDENTITY;
+
+ int src_x0 = info->src.box.x;
+ int src_x1 = info->src.box.x + info->src.box.width;
+ int src_y0 = info->src.box.y;
+ int src_y1 = info->src.box.y + info->src.box.height;
+ int dst_x0 = info->dst.box.x;
+ int dst_x1 = info->dst.box.x + info->dst.box.width;
+ int dst_y0 = info->dst.box.y;
+ int dst_y1 = info->dst.box.y + info->dst.box.height;
+ bool mirror_x = false;
+ bool mirror_y = false;
+ GLenum filter =
+ info->filter == PIPE_TEX_FILTER_LINEAR ? GL_LINEAR : GL_NEAREST;
+
+ struct blorp_batch blorp_batch;
+ blorp_batch_init(&ice->blorp, &blorp_batch, &ice->render_batch, 0);
+ blorp_blit(&blorp_batch, &src_surf, info->src.level, src_layer,
+ src_isl_format, src_isl_swizzle,
+ &dst_surf, info->dst.level, dst_layer,
+ dst_isl_format, ISL_SWIZZLE_IDENTITY,
+ src_x0, src_y0, src_x1, src_y1,
+ dst_x0, dst_y0, dst_x1, dst_y1,
+ filter, mirror_x, mirror_y);
+
+ blorp_batch_finish(&blorp_batch);
+}
static boolean
iris_generate_mipmap(struct pipe_context *ctx,
}
static uint64_t
-blorp_emit_reloc(struct blorp_batch *blorp_batch, UNUSED void *location,
- struct blorp_address addr, uint32_t delta)
+combine_and_pin_address(struct blorp_batch *blorp_batch,
+ struct blorp_address addr)
{
struct iris_batch *batch = blorp_batch->driver_batch;
struct iris_bo *bo = addr.buffer;
- uint64_t result = addr.offset + delta;
- if (bo) {
- iris_use_pinned_bo(batch, bo, addr.reloc_flags & RELOC_WRITE);
- /* Assume this is a general address, not relative to a base. */
- result += bo->gtt_offset;
- }
+ iris_use_pinned_bo(batch, bo, addr.reloc_flags & RELOC_WRITE);
- return result;
+ /* Assume this is a general address, not relative to a base. */
+ return bo->gtt_offset + addr.offset;
+}
+
+static uint64_t
+blorp_emit_reloc(struct blorp_batch *blorp_batch, UNUSED void *location,
+ struct blorp_address addr, uint32_t delta)
+{
+ return combine_and_pin_address(blorp_batch, addr) + delta;
}
static void
blorp_surface_reloc(struct blorp_batch *blorp_batch, uint32_t ss_offset,
struct blorp_address addr, uint32_t delta)
{
- /* Don't do anything, blorp_alloc_binding_table already added the BO. */
+ /* Let blorp_get_surface_address do the pinning. */
+}
+
+static uint64_t
+blorp_get_surface_address(struct blorp_batch *blorp_batch,
+ struct blorp_address addr)
+{
+ return combine_and_pin_address(blorp_batch, addr);
}
UNUSED static struct blorp_address
return map;
}
+/**
+ * See vf_invalidate_for_vb_48b_transitions in iris_state.c.
+ * XXX: actually add this
+ */
+static void
+blorp_vf_invalidate_for_vb_48b_transitions(struct blorp_batch *batch,
+ const struct blorp_address *addrs,
+ unsigned num_vbs)
+{
+#if 0
+ struct iris_context *ice = blorp_batch->blorp->driver_ctx;
+ struct iris_batch *batch = blorp_batch->driver_batch;
+ bool need_invalidate = false;
+
+ for (unsigned i = 0; i < num_vbs; i++) {
+ struct iris_bo *bo = addrs[i].buffer;
+ uint16_t high_bits = bo ? bo->gtt_offset >> 32u : 0;
+
+ if (high_bits != ice->state.last_vbo_high_bits[i]) {
+ need_invalidate = true;
+ ice->state.last_vbo_high_bits[i] = high_bits;
+ }
+ }
+
+ if (need_invalidate) {
+ iris_emit_pipe_control_flush(batch, PIPE_CONTROL_VF_CACHE_INVALIDATE);
+ }
+#endif
+}
+
static struct blorp_address
blorp_get_workaround_page(struct blorp_batch *blorp_batch)
{
void
genX(init_blorp)(struct iris_context *ice)
{
+ struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
+
+ blorp_init(&ice->blorp, ice, &screen->isl_dev);
+ ice->blorp.compiler = screen->compiler;
+
ice->vtbl.blorp_exec = iris_blorp_exec;
}