C_SOURCES := \
core/ilo_buffer.h \
+ core/ilo_builder.c \
+ core/ilo_builder.h \
+ core/ilo_builder_3d.h \
+ core/ilo_builder_3d_bottom.h \
+ core/ilo_builder_3d_top.h \
+ core/ilo_builder_blt.h \
+ core/ilo_builder_decode.c \
+ core/ilo_builder_media.h \
+ core/ilo_builder_mi.h \
+ core/ilo_builder_render.h \
core/ilo_core.h \
core/ilo_debug.c \
core/ilo_debug.h \
ilo_blitter_blt.c \
ilo_blitter_pipe.c \
ilo_blitter_rectlist.c \
- ilo_builder.c \
- ilo_builder.h \
- ilo_builder_3d.h \
- ilo_builder_3d_bottom.h \
- ilo_builder_3d_top.h \
- ilo_builder_blt.h \
- ilo_builder_decode.c \
- ilo_builder_media.h \
- ilo_builder_mi.h \
- ilo_builder_render.h \
ilo_common.h \
ilo_context.c \
ilo_context.h \
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "ilo_builder.h"
+#include "ilo_builder_render.h" /* for ilo_builder_batch_patch_sba() */
+
+enum ilo_builder_writer_flags {
+ /*
+ * When this bit is set, ilo_builder_begin() will not realllocate. New
+ * data will be appended instead.
+ */
+ WRITER_FLAG_APPEND = 1 << 0,
+
+ /*
+ * When this bit is set, the writer grows when full. When not, callers
+ * must make sure the writer never needs to grow.
+ */
+ WRITER_FLAG_GROW = 1 << 1,
+
+ /*
+ * The writer will be mapped directly.
+ */
+ WRITER_FLAG_MAP = 1 << 2,
+};
+
+/**
+ * Set the initial size and flags of a writer.
+ */
+static void
+ilo_builder_writer_init(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ switch (which) {
+ case ILO_BUILDER_WRITER_BATCH:
+ writer->size = sizeof(uint32_t) * 8192;
+ break;
+ case ILO_BUILDER_WRITER_INSTRUCTION:
+ /*
+ * The EUs pretch some instructions. But since the kernel invalidates
+ * the instruction cache between batch buffers, we can set
+ * WRITER_FLAG_APPEND without worrying the EUs would see invalid
+ * instructions prefetched.
+ */
+ writer->flags = WRITER_FLAG_APPEND | WRITER_FLAG_GROW;
+ writer->size = 8192;
+ break;
+ default:
+ assert(!"unknown builder writer");
+ return;
+ break;
+ }
+
+ if (builder->dev->has_llc)
+ writer->flags |= WRITER_FLAG_MAP;
+}
+
+/**
+ * Free all resources used by a writer. Note that the initial size is not
+ * reset.
+ */
+static void
+ilo_builder_writer_reset(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ if (writer->ptr) {
+ if (writer->flags & WRITER_FLAG_MAP)
+ intel_bo_unmap(writer->bo);
+ else
+ FREE(writer->ptr);
+
+ writer->ptr = NULL;
+ }
+
+ intel_bo_unref(writer->bo);
+ writer->bo = NULL;
+
+ writer->used = 0;
+ writer->stolen = 0;
+
+ if (writer->items) {
+ FREE(writer->items);
+ writer->item_alloc = 0;
+ writer->item_used = 0;
+ }
+}
+
+/**
+ * Discard everything written so far.
+ */
+void
+ilo_builder_writer_discard(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ intel_bo_truncate_relocs(writer->bo, 0);
+ writer->used = 0;
+ writer->stolen = 0;
+ writer->item_used = 0;
+}
+
+static struct intel_bo *
+alloc_writer_bo(struct intel_winsys *winsys,
+ enum ilo_builder_writer_type which,
+ unsigned size)
+{
+ static const char *writer_names[ILO_BUILDER_WRITER_COUNT] = {
+ [ILO_BUILDER_WRITER_BATCH] = "batch",
+ [ILO_BUILDER_WRITER_INSTRUCTION] = "instruction",
+ };
+
+ return intel_winsys_alloc_bo(winsys, writer_names[which], size, true);
+}
+
+static void *
+map_writer_bo(struct intel_bo *bo, unsigned flags)
+{
+ assert(flags & WRITER_FLAG_MAP);
+
+ if (flags & WRITER_FLAG_APPEND)
+ return intel_bo_map_gtt_async(bo);
+ else
+ return intel_bo_map(bo, true);
+}
+
+/**
+ * Allocate and map the buffer for writing.
+ */
+static bool
+ilo_builder_writer_alloc_and_map(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ /* allocate a new bo when not appending */
+ if (!(writer->flags & WRITER_FLAG_APPEND) || !writer->bo) {
+ struct intel_bo *bo;
+
+ bo = alloc_writer_bo(builder->winsys, which, writer->size);
+ if (bo) {
+ intel_bo_unref(writer->bo);
+ writer->bo = bo;
+ } else if (writer->bo) {
+ /* reuse the old bo */
+ ilo_builder_writer_discard(builder, which);
+ } else {
+ return false;
+ }
+
+ writer->used = 0;
+ writer->stolen = 0;
+ writer->item_used = 0;
+ }
+
+ /* map the bo or allocate the staging system memory */
+ if (writer->flags & WRITER_FLAG_MAP)
+ writer->ptr = map_writer_bo(writer->bo, writer->flags);
+ else if (!writer->ptr)
+ writer->ptr = MALLOC(writer->size);
+
+ return (writer->ptr != NULL);
+}
+
+/**
+ * Unmap the buffer for submission.
+ */
+static bool
+ilo_builder_writer_unmap(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+ unsigned offset;
+ int err = 0;
+
+ if (writer->flags & WRITER_FLAG_MAP) {
+ intel_bo_unmap(writer->bo);
+ writer->ptr = NULL;
+ return true;
+ }
+
+ offset = builder->begin_used[which];
+ if (writer->used > offset) {
+ err = intel_bo_pwrite(writer->bo, offset, writer->used - offset,
+ (char *) writer->ptr + offset);
+ }
+
+ if (writer->stolen && !err) {
+ const unsigned offset = writer->size - writer->stolen;
+ err = intel_bo_pwrite(writer->bo, offset, writer->stolen,
+ (const char *) writer->ptr + offset);
+ }
+
+ /* keep writer->ptr */
+
+ return !err;
+}
+
+/**
+ * Grow a mapped writer to at least \p new_size.
+ */
+bool
+ilo_builder_writer_grow(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ unsigned new_size, bool preserve)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+ struct intel_bo *new_bo;
+ void *new_ptr;
+
+ if (!(writer->flags & WRITER_FLAG_GROW))
+ return false;
+
+ /* stolen data may already be referenced and cannot be moved */
+ if (writer->stolen)
+ return false;
+
+ if (new_size < writer->size << 1)
+ new_size = writer->size << 1;
+ /* STATE_BASE_ADDRESS requires page-aligned buffers */
+ new_size = align(new_size, 4096);
+
+ new_bo = alloc_writer_bo(builder->winsys, which, new_size);
+ if (!new_bo)
+ return false;
+
+ /* map and copy the data over */
+ if (writer->flags & WRITER_FLAG_MAP) {
+ new_ptr = map_writer_bo(new_bo, writer->flags);
+
+ /*
+ * When WRITER_FLAG_APPEND and WRITER_FLAG_GROW are both set, we may end
+ * up copying between two GTT-mapped BOs. That is slow. The issue
+ * could be solved by adding intel_bo_map_async(), or callers may choose
+ * to manually grow the writer without preserving the data.
+ */
+ if (new_ptr && preserve)
+ memcpy(new_ptr, writer->ptr, writer->used);
+ } else if (preserve) {
+ new_ptr = REALLOC(writer->ptr, writer->size, new_size);
+ } else {
+ new_ptr = MALLOC(new_size);
+ }
+
+ if (!new_ptr) {
+ intel_bo_unref(new_bo);
+ return false;
+ }
+
+ if (writer->flags & WRITER_FLAG_MAP)
+ intel_bo_unmap(writer->bo);
+ else if (!preserve)
+ FREE(writer->ptr);
+
+ intel_bo_unref(writer->bo);
+
+ writer->size = new_size;
+ writer->bo = new_bo;
+ writer->ptr = new_ptr;
+
+ return true;
+}
+
+/**
+ * Record an item for later decoding.
+ */
+bool
+ilo_builder_writer_record(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ enum ilo_builder_item_type type,
+ unsigned offset, unsigned size)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+ struct ilo_builder_item *item;
+
+ if (writer->item_used == writer->item_alloc) {
+ const unsigned new_alloc = (writer->item_alloc) ?
+ writer->item_alloc << 1 : 256;
+ struct ilo_builder_item *items;
+
+ items = REALLOC(writer->items,
+ sizeof(writer->items[0]) * writer->item_alloc,
+ sizeof(writer->items[0]) * new_alloc);
+ if (!items)
+ return false;
+
+ writer->items = items;
+ writer->item_alloc = new_alloc;
+ }
+
+ item = &writer->items[writer->item_used++];
+ item->type = type;
+ item->offset = offset;
+ item->size = size;
+
+ return true;
+}
+
+/**
+ * Initialize the builder.
+ */
+void
+ilo_builder_init(struct ilo_builder *builder,
+ const struct ilo_dev *dev,
+ struct intel_winsys *winsys)
+{
+ int i;
+
+ memset(builder, 0, sizeof(*builder));
+
+ builder->dev = dev;
+ builder->winsys = winsys;
+
+ /* gen6_SURFACE_STATE() may override this */
+ switch (ilo_dev_gen(dev)) {
+ case ILO_GEN(8):
+ builder->mocs = GEN8_MOCS_MT_WB | GEN8_MOCS_CT_L3;
+ break;
+ case ILO_GEN(7.5):
+ case ILO_GEN(7):
+ builder->mocs = GEN7_MOCS_L3_WB;
+ break;
+ default:
+ builder->mocs = 0;
+ break;
+ }
+
+ for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++)
+ ilo_builder_writer_init(builder, i);
+}
+
+/**
+ * Reset the builder and free all resources used. After resetting, the
+ * builder behaves as if it is newly initialized, except for potentially
+ * larger initial bo sizes.
+ */
+void
+ilo_builder_reset(struct ilo_builder *builder)
+{
+ int i;
+
+ for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++)
+ ilo_builder_writer_reset(builder, i);
+}
+
+/**
+ * Allocate and map the BOs. It may re-allocate or reuse existing BOs if
+ * there is any.
+ *
+ * Most builder functions can only be called after ilo_builder_begin() and
+ * before ilo_builder_end().
+ */
+bool
+ilo_builder_begin(struct ilo_builder *builder)
+{
+ int i;
+
+ for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++) {
+ if (!ilo_builder_writer_alloc_and_map(builder, i)) {
+ ilo_builder_reset(builder);
+ return false;
+ }
+
+ builder->begin_used[i] = builder->writers[i].used;
+ }
+
+ builder->unrecoverable_error = false;
+ builder->sba_instruction_pos = 0;
+
+ return true;
+}
+
+/**
+ * Unmap BOs and make sure the written data landed the BOs. The batch buffer
+ * ready for submission is returned.
+ */
+struct intel_bo *
+ilo_builder_end(struct ilo_builder *builder, unsigned *used)
+{
+ struct ilo_builder_writer *bat;
+ int i;
+
+ ilo_builder_batch_patch_sba(builder);
+
+ assert(ilo_builder_validate(builder, 0, NULL));
+
+ for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++) {
+ if (!ilo_builder_writer_unmap(builder, i))
+ builder->unrecoverable_error = true;
+ }
+
+ if (builder->unrecoverable_error)
+ return NULL;
+
+ bat = &builder->writers[ILO_BUILDER_WRITER_BATCH];
+
+ *used = bat->used;
+
+ return bat->bo;
+}
+
+/**
+ * Return true if the builder is in a valid state, after accounting for the
+ * additional BOs specified. The additional BOs can be listed to avoid
+ * snapshotting and restoring when they are known ahead of time.
+ *
+ * The number of additional BOs should not be more than a few. Like two, for
+ * copying between two BOs.
+ *
+ * Callers must make sure the builder is in a valid state when
+ * ilo_builder_end() is called.
+ */
+bool
+ilo_builder_validate(struct ilo_builder *builder,
+ unsigned bo_count, struct intel_bo **bos)
+{
+ const unsigned max_bo_count = 2;
+ struct intel_bo *bos_to_submit[ILO_BUILDER_WRITER_COUNT + max_bo_count];
+ int i;
+
+ for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++)
+ bos_to_submit[i] = builder->writers[i].bo;
+
+ if (bo_count) {
+ assert(bo_count <= max_bo_count);
+ if (bo_count > max_bo_count)
+ return false;
+
+ memcpy(&bos_to_submit[ILO_BUILDER_WRITER_COUNT],
+ bos, sizeof(*bos) * bo_count);
+ i += bo_count;
+ }
+
+ return intel_winsys_can_submit_bo(builder->winsys, bos_to_submit, i);
+}
+
+/**
+ * Take a snapshot of the writer state.
+ */
+void
+ilo_builder_batch_snapshot(const struct ilo_builder *builder,
+ struct ilo_builder_snapshot *snapshot)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ const struct ilo_builder_writer *writer = &builder->writers[which];
+
+ snapshot->reloc_count = intel_bo_get_reloc_count(writer->bo);
+ snapshot->used = writer->used;
+ snapshot->stolen = writer->stolen;
+ snapshot->item_used = writer->item_used;
+}
+
+/**
+ * Restore the writer state to when the snapshot was taken, except that it
+ * does not (unnecessarily) shrink BOs or the item array.
+ */
+void
+ilo_builder_batch_restore(struct ilo_builder *builder,
+ const struct ilo_builder_snapshot *snapshot)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ intel_bo_truncate_relocs(writer->bo, snapshot->reloc_count);
+ writer->used = snapshot->used;
+ writer->stolen = snapshot->stolen;
+ writer->item_used = snapshot->item_used;
+}
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_BUILDER_H
+#define ILO_BUILDER_H
+
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_debug.h"
+#include "ilo_dev.h"
+
+enum ilo_builder_writer_type {
+ ILO_BUILDER_WRITER_BATCH,
+ ILO_BUILDER_WRITER_INSTRUCTION,
+
+ ILO_BUILDER_WRITER_COUNT,
+};
+
+enum ilo_builder_item_type {
+ /* for dynamic buffer */
+ ILO_BUILDER_ITEM_BLOB,
+ ILO_BUILDER_ITEM_CLIP_VIEWPORT,
+ ILO_BUILDER_ITEM_SF_VIEWPORT,
+ ILO_BUILDER_ITEM_SCISSOR_RECT,
+ ILO_BUILDER_ITEM_CC_VIEWPORT,
+ ILO_BUILDER_ITEM_COLOR_CALC,
+ ILO_BUILDER_ITEM_DEPTH_STENCIL,
+ ILO_BUILDER_ITEM_BLEND,
+ ILO_BUILDER_ITEM_SAMPLER,
+ ILO_BUILDER_ITEM_INTERFACE_DESCRIPTOR,
+
+ /* for surface buffer */
+ ILO_BUILDER_ITEM_SURFACE,
+ ILO_BUILDER_ITEM_BINDING_TABLE,
+
+ /* for instruction buffer */
+ ILO_BUILDER_ITEM_KERNEL,
+
+ ILO_BUILDER_ITEM_COUNT,
+};
+
+struct ilo_builder_item {
+ enum ilo_builder_item_type type;
+ unsigned offset;
+ unsigned size;
+};
+
+struct ilo_builder_writer {
+ /* internal flags */
+ unsigned flags;
+
+ unsigned size;
+ struct intel_bo *bo;
+ void *ptr;
+
+ /* data written to the bottom */
+ unsigned used;
+ /* data written to the top */
+ unsigned stolen;
+
+ /* for decoding */
+ struct ilo_builder_item *items;
+ unsigned item_alloc;
+ unsigned item_used;
+};
+
+/**
+ * A snapshot of the writer state.
+ */
+struct ilo_builder_snapshot {
+ unsigned reloc_count;
+
+ unsigned used;
+ unsigned stolen;
+ unsigned item_used;
+};
+
+struct ilo_builder {
+ const struct ilo_dev *dev;
+ struct intel_winsys *winsys;
+ uint32_t mocs;
+
+ struct ilo_builder_writer writers[ILO_BUILDER_WRITER_COUNT];
+ bool unrecoverable_error;
+
+ /* for writers that have their data appended */
+ unsigned begin_used[ILO_BUILDER_WRITER_COUNT];
+
+ /* for STATE_BASE_ADDRESS */
+ unsigned sba_instruction_pos;
+};
+
+void
+ilo_builder_init(struct ilo_builder *builder,
+ const struct ilo_dev *dev,
+ struct intel_winsys *winsys);
+
+void
+ilo_builder_reset(struct ilo_builder *builder);
+
+void
+ilo_builder_decode(struct ilo_builder *builder);
+
+bool
+ilo_builder_begin(struct ilo_builder *builder);
+
+struct intel_bo *
+ilo_builder_end(struct ilo_builder *builder, unsigned *used);
+
+bool
+ilo_builder_validate(struct ilo_builder *builder,
+ unsigned bo_count, struct intel_bo **bos);
+
+/**
+ * Return true if the builder has a relocation entry for \p bo.
+ */
+static inline bool
+ilo_builder_has_reloc(const struct ilo_builder *builder,
+ struct intel_bo *bo)
+{
+ int i;
+
+ for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++) {
+ const struct ilo_builder_writer *writer = &builder->writers[i];
+ if (intel_bo_has_reloc(writer->bo, bo))
+ return true;
+ }
+
+ return false;
+}
+
+void
+ilo_builder_writer_discard(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which);
+
+bool
+ilo_builder_writer_grow(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ unsigned new_size, bool preserve);
+
+bool
+ilo_builder_writer_record(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ enum ilo_builder_item_type type,
+ unsigned offset, unsigned size);
+
+static inline void
+ilo_builder_writer_checked_record(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ enum ilo_builder_item_type item,
+ unsigned offset, unsigned size)
+{
+ if (unlikely(ilo_debug & (ILO_DEBUG_BATCH | ILO_DEBUG_HANG))) {
+ if (!ilo_builder_writer_record(builder, which, item, offset, size)) {
+ builder->unrecoverable_error = true;
+ builder->writers[which].item_used = 0;
+ }
+ }
+}
+
+/**
+ * Return an offset to a region that is aligned to \p alignment and has at
+ * least \p size bytes. The region is reserved from the bottom.
+ */
+static inline unsigned
+ilo_builder_writer_reserve_bottom(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ unsigned alignment, unsigned size)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+ unsigned offset;
+
+ assert(alignment && util_is_power_of_two(alignment));
+ offset = align(writer->used, alignment);
+
+ if (unlikely(offset + size > writer->size - writer->stolen)) {
+ if (!ilo_builder_writer_grow(builder, which,
+ offset + size + writer->stolen, true)) {
+ builder->unrecoverable_error = true;
+ ilo_builder_writer_discard(builder, which);
+ offset = 0;
+ }
+
+ assert(offset + size <= writer->size - writer->stolen);
+ }
+
+ return offset;
+}
+
+/**
+ * Similar to ilo_builder_writer_reserve_bottom(), but reserve from the top.
+ */
+static inline unsigned
+ilo_builder_writer_reserve_top(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ unsigned alignment, unsigned size)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+ unsigned offset;
+
+ assert(alignment && util_is_power_of_two(alignment));
+ offset = (writer->size - writer->stolen - size) & ~(alignment - 1);
+
+ if (unlikely(offset < writer->used ||
+ size > writer->size - writer->stolen)) {
+ if (!ilo_builder_writer_grow(builder, which,
+ align(writer->used, alignment) + size + writer->stolen, true)) {
+ builder->unrecoverable_error = true;
+ ilo_builder_writer_discard(builder, which);
+ }
+
+ offset = (writer->size - writer->stolen - size) & ~(alignment - 1);
+ assert(offset + size <= writer->size - writer->stolen);
+ }
+
+ return offset;
+}
+
+/**
+ * Add a relocation entry to the writer.
+ */
+static inline void
+ilo_builder_writer_reloc(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ unsigned offset, struct intel_bo *bo,
+ unsigned bo_offset, unsigned reloc_flags,
+ bool write_presumed_offset_hi)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+ uint64_t presumed_offset;
+ int err;
+
+ if (write_presumed_offset_hi)
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+ else
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ assert(offset + sizeof(uint32_t) <= writer->used ||
+ (offset >= writer->size - writer->stolen &&
+ offset + sizeof(uint32_t) <= writer->size));
+
+ err = intel_bo_add_reloc(writer->bo, offset, bo, bo_offset,
+ reloc_flags, &presumed_offset);
+ if (unlikely(err))
+ builder->unrecoverable_error = true;
+
+ if (write_presumed_offset_hi) {
+ *((uint64_t *) ((char *) writer->ptr + offset)) = presumed_offset;
+ } else {
+ /* 32-bit addressing */
+ assert(presumed_offset == (uint64_t) ((uint32_t) presumed_offset));
+ *((uint32_t *) ((char *) writer->ptr + offset)) = presumed_offset;
+ }
+}
+
+/**
+ * Reserve a region from the dynamic buffer. Both the offset, in bytes, and
+ * the pointer to the reserved region are returned. The pointer is only valid
+ * until the next reserve call.
+ *
+ * Note that \p alignment is in bytes and \p len is in DWords.
+ */
+static inline uint32_t
+ilo_builder_dynamic_pointer(struct ilo_builder *builder,
+ enum ilo_builder_item_type item,
+ unsigned alignment, unsigned len,
+ uint32_t **dw)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ const unsigned size = len << 2;
+ const unsigned offset = ilo_builder_writer_reserve_top(builder,
+ which, alignment, size);
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ /* all states are at least aligned to 32-bytes */
+ if (item != ILO_BUILDER_ITEM_BLOB)
+ assert(alignment % 32 == 0);
+
+ *dw = (uint32_t *) ((char *) writer->ptr + offset);
+
+ writer->stolen = writer->size - offset;
+
+ ilo_builder_writer_checked_record(builder, which, item, offset, size);
+
+ return offset;
+}
+
+/**
+ * Write a dynamic state to the dynamic buffer.
+ */
+static inline uint32_t
+ilo_builder_dynamic_write(struct ilo_builder *builder,
+ enum ilo_builder_item_type item,
+ unsigned alignment, unsigned len,
+ const uint32_t *dw)
+{
+ uint32_t offset, *dst;
+
+ offset = ilo_builder_dynamic_pointer(builder, item, alignment, len, &dst);
+ memcpy(dst, dw, len << 2);
+
+ return offset;
+}
+
+/**
+ * Reserve some space from the top (for prefetches).
+ */
+static inline void
+ilo_builder_dynamic_pad_top(struct ilo_builder *builder, unsigned len)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ const unsigned size = len << 2;
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ if (writer->stolen < size) {
+ ilo_builder_writer_reserve_top(builder, which,
+ 1, size - writer->stolen);
+ writer->stolen = size;
+ }
+}
+
+static inline unsigned
+ilo_builder_dynamic_used(const struct ilo_builder *builder)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ const struct ilo_builder_writer *writer = &builder->writers[which];
+
+ return writer->stolen >> 2;
+}
+
+/**
+ * Reserve a region from the surface buffer. Both the offset, in bytes, and
+ * the pointer to the reserved region are returned. The pointer is only valid
+ * until the next reserve call.
+ *
+ * Note that \p alignment is in bytes and \p len is in DWords.
+ */
+static inline uint32_t
+ilo_builder_surface_pointer(struct ilo_builder *builder,
+ enum ilo_builder_item_type item,
+ unsigned alignment, unsigned len,
+ uint32_t **dw)
+{
+ assert(item == ILO_BUILDER_ITEM_SURFACE ||
+ item == ILO_BUILDER_ITEM_BINDING_TABLE);
+
+ return ilo_builder_dynamic_pointer(builder, item, alignment, len, dw);
+}
+
+/**
+ * Add a relocation entry for a DWord of a surface state.
+ */
+static inline void
+ilo_builder_surface_reloc(struct ilo_builder *builder,
+ uint32_t offset, unsigned dw_index,
+ struct intel_bo *bo, unsigned bo_offset,
+ unsigned reloc_flags)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+
+ ilo_builder_writer_reloc(builder, which, offset + (dw_index << 2),
+ bo, bo_offset, reloc_flags, false);
+}
+
+static inline void
+ilo_builder_surface_reloc64(struct ilo_builder *builder,
+ uint32_t offset, unsigned dw_index,
+ struct intel_bo *bo, unsigned bo_offset,
+ unsigned reloc_flags)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+
+ ilo_builder_writer_reloc(builder, which, offset + (dw_index << 2),
+ bo, bo_offset, reloc_flags, true);
+}
+
+static inline unsigned
+ilo_builder_surface_used(const struct ilo_builder *builder)
+{
+ return ilo_builder_dynamic_used(builder);
+}
+
+/**
+ * Write a kernel to the instruction buffer. The offset, in bytes, of the
+ * kernel is returned.
+ */
+static inline uint32_t
+ilo_builder_instruction_write(struct ilo_builder *builder,
+ unsigned size, const void *kernel)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_INSTRUCTION;
+ /*
+ * From the Sandy Bridge PRM, volume 4 part 2, page 112:
+ *
+ * "Due to prefetch of the instruction stream, the EUs may attempt to
+ * access up to 8 instructions (128 bytes) beyond the end of the
+ * kernel program - possibly into the next memory page. Although
+ * these instructions will not be executed, software must account for
+ * the prefetch in order to avoid invalid page access faults."
+ */
+ const unsigned reserved_size = size + 128;
+ /* kernels are aligned to 64 bytes */
+ const unsigned alignment = 64;
+ const unsigned offset = ilo_builder_writer_reserve_bottom(builder,
+ which, alignment, reserved_size);
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ memcpy((char *) writer->ptr + offset, kernel, size);
+
+ writer->used = offset + size;
+
+ ilo_builder_writer_checked_record(builder, which,
+ ILO_BUILDER_ITEM_KERNEL, offset, size);
+
+ return offset;
+}
+
+/**
+ * Reserve a region from the batch buffer. Both the offset, in DWords, and
+ * the pointer to the reserved region are returned. The pointer is only valid
+ * until the next reserve call.
+ *
+ * Note that \p len is in DWords.
+ */
+static inline unsigned
+ilo_builder_batch_pointer(struct ilo_builder *builder,
+ unsigned len, uint32_t **dw)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ /*
+ * We know the batch bo is always aligned. Using 1 here should allow the
+ * compiler to optimize away aligning.
+ */
+ const unsigned alignment = 1;
+ const unsigned size = len << 2;
+ const unsigned offset = ilo_builder_writer_reserve_bottom(builder,
+ which, alignment, size);
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ assert(offset % 4 == 0);
+ *dw = (uint32_t *) ((char *) writer->ptr + offset);
+
+ writer->used = offset + size;
+
+ return offset >> 2;
+}
+
+/**
+ * Write a command to the batch buffer.
+ */
+static inline unsigned
+ilo_builder_batch_write(struct ilo_builder *builder,
+ unsigned len, const uint32_t *dw)
+{
+ unsigned pos;
+ uint32_t *dst;
+
+ pos = ilo_builder_batch_pointer(builder, len, &dst);
+ memcpy(dst, dw, len << 2);
+
+ return pos;
+}
+
+/**
+ * Add a relocation entry for a DWord of a command.
+ */
+static inline void
+ilo_builder_batch_reloc(struct ilo_builder *builder, unsigned pos,
+ struct intel_bo *bo, unsigned bo_offset,
+ unsigned reloc_flags)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+
+ ilo_builder_writer_reloc(builder, which, pos << 2,
+ bo, bo_offset, reloc_flags, false);
+}
+
+static inline void
+ilo_builder_batch_reloc64(struct ilo_builder *builder, unsigned pos,
+ struct intel_bo *bo, unsigned bo_offset,
+ unsigned reloc_flags)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+
+ ilo_builder_writer_reloc(builder, which, pos << 2,
+ bo, bo_offset, reloc_flags, true);
+}
+
+static inline unsigned
+ilo_builder_batch_used(const struct ilo_builder *builder)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ const struct ilo_builder_writer *writer = &builder->writers[which];
+
+ return writer->used >> 2;
+}
+
+static inline unsigned
+ilo_builder_batch_space(const struct ilo_builder *builder)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ const struct ilo_builder_writer *writer = &builder->writers[which];
+
+ return (writer->size - writer->stolen - writer->used) >> 2;
+}
+
+static inline void
+ilo_builder_batch_discard(struct ilo_builder *builder)
+{
+ ilo_builder_writer_discard(builder, ILO_BUILDER_WRITER_BATCH);
+}
+
+static inline void
+ilo_builder_batch_print_stats(const struct ilo_builder *builder)
+{
+ const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
+ const struct ilo_builder_writer *writer = &builder->writers[which];
+
+ ilo_printf("%d+%d bytes (%d%% full)\n",
+ writer->used, writer->stolen,
+ (writer->used + writer->stolen) * 100 / writer->size);
+}
+
+void
+ilo_builder_batch_snapshot(const struct ilo_builder *builder,
+ struct ilo_builder_snapshot *snapshot);
+
+void
+ilo_builder_batch_restore(struct ilo_builder *builder,
+ const struct ilo_builder_snapshot *snapshot);
+
+#endif /* ILO_BUILDER_H */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_BUILDER_3D_H
+#define ILO_BUILDER_3D_H
+
+#include "genhw/genhw.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+#include "ilo_builder_3d_top.h"
+#include "ilo_builder_3d_bottom.h"
+
+static inline void
+gen6_3DPRIMITIVE(struct ilo_builder *builder,
+ const struct pipe_draw_info *info,
+ const struct ilo_ib_state *ib)
+{
+ const uint8_t cmd_len = 6;
+ const int prim = gen6_3d_translate_pipe_prim(info->mode);
+ const int vb_access = (info->indexed) ?
+ GEN6_3DPRIM_DW0_ACCESS_RANDOM : GEN6_3DPRIM_DW0_ACCESS_SEQUENTIAL;
+ const uint32_t vb_start = info->start +
+ ((info->indexed) ? ib->draw_start_offset : 0);
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) |
+ vb_access |
+ prim << GEN6_3DPRIM_DW0_TYPE__SHIFT |
+ (cmd_len - 2);
+ dw[1] = info->count;
+ dw[2] = vb_start;
+ dw[3] = info->instance_count;
+ dw[4] = info->start_instance;
+ dw[5] = info->index_bias;
+}
+
+static inline void
+gen7_3DPRIMITIVE(struct ilo_builder *builder,
+ const struct pipe_draw_info *info,
+ const struct ilo_ib_state *ib)
+{
+ const uint8_t cmd_len = 7;
+ const int prim = gen6_3d_translate_pipe_prim(info->mode);
+ const int vb_access = (info->indexed) ?
+ GEN7_3DPRIM_DW1_ACCESS_RANDOM : GEN7_3DPRIM_DW1_ACCESS_SEQUENTIAL;
+ const uint32_t vb_start = info->start +
+ ((info->indexed) ? ib->draw_start_offset : 0);
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) | (cmd_len - 2);
+ dw[1] = vb_access | prim;
+ dw[2] = info->count;
+ dw[3] = vb_start;
+ dw[4] = info->instance_count;
+ dw[5] = info->start_instance;
+ dw[6] = info->index_bias;
+}
+
+#endif /* ILO_BUILDER_3D_H */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_BUILDER_3D_BOTTOM_H
+#define ILO_BUILDER_3D_BOTTOM_H
+
+#include "genhw/genhw.h"
+#include "../ilo_shader.h"
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+#include "ilo_format.h"
+#include "ilo_builder.h"
+#include "ilo_builder_3d_top.h"
+
+static inline void
+gen6_3DSTATE_CLIP(struct ilo_builder *builder,
+ const struct ilo_rasterizer_state *rasterizer,
+ const struct ilo_shader_state *fs,
+ bool enable_guardband,
+ int num_viewports)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t dw1, dw2, dw3, *dw;
+ int interps;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ dw1 = rasterizer->clip.payload[0];
+ dw2 = rasterizer->clip.payload[1];
+ dw3 = rasterizer->clip.payload[2];
+
+ if (enable_guardband && rasterizer->clip.can_enable_guardband)
+ dw2 |= GEN6_CLIP_DW2_GB_TEST_ENABLE;
+
+ interps = (fs) ? ilo_shader_get_kernel_param(fs,
+ ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) : 0;
+
+ if (interps & (GEN6_INTERP_NONPERSPECTIVE_PIXEL |
+ GEN6_INTERP_NONPERSPECTIVE_CENTROID |
+ GEN6_INTERP_NONPERSPECTIVE_SAMPLE))
+ dw2 |= GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE;
+
+ dw3 |= GEN6_CLIP_DW3_RTAINDEX_FORCED_ZERO |
+ (num_viewports - 1);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CLIP) | (cmd_len - 2);
+ dw[1] = dw1;
+ dw[2] = dw2;
+ dw[3] = dw3;
+}
+
+static inline void
+gen6_disable_3DSTATE_CLIP(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CLIP) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+}
+
+static inline void
+gen7_internal_3dstate_sf(struct ilo_builder *builder,
+ uint8_t cmd_len, uint32_t *dw,
+ const struct ilo_rasterizer_sf *sf,
+ int num_samples)
+{
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ assert(cmd_len == 7);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
+
+ if (!sf) {
+ dw[1] = 0;
+ dw[2] = (num_samples > 1) ? GEN7_SF_DW2_MSRASTMODE_ON_PATTERN : 0;
+ dw[3] = 0;
+ dw[4] = 0;
+ dw[5] = 0;
+ dw[6] = 0;
+
+ return;
+ }
+
+ /* see rasterizer_init_sf_gen6() */
+ STATIC_ASSERT(Elements(sf->payload) >= 3);
+ dw[1] = sf->payload[0];
+ dw[2] = sf->payload[1];
+ dw[3] = sf->payload[2];
+
+ if (num_samples > 1)
+ dw[2] |= sf->dw_msaa;
+
+ dw[4] = sf->dw_depth_offset_const;
+ dw[5] = sf->dw_depth_offset_scale;
+ dw[6] = sf->dw_depth_offset_clamp;
+}
+
+static inline void
+gen8_internal_3dstate_sbe(struct ilo_builder *builder,
+ uint8_t cmd_len, uint32_t *dw,
+ const struct ilo_shader_state *fs,
+ int sprite_coord_mode)
+{
+ const struct ilo_kernel_routing *routing;
+ int vue_offset, vue_len, out_count;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(cmd_len == 4);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) | (cmd_len - 2);
+
+ if (!fs) {
+ dw[1] = 1 << GEN7_SBE_DW1_URB_READ_LEN__SHIFT;
+ dw[2] = 0;
+ dw[3] = 0;
+ return;
+ }
+
+ routing = ilo_shader_get_kernel_routing(fs);
+
+ vue_offset = routing->source_skip;
+ assert(vue_offset % 2 == 0);
+ vue_offset /= 2;
+
+ vue_len = (routing->source_len + 1) / 2;
+ if (!vue_len)
+ vue_len = 1;
+
+ out_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT);
+ assert(out_count <= 32);
+
+ dw[1] = out_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
+ vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[1] |= GEN8_SBE_DW1_USE_URB_READ_LEN |
+ GEN8_SBE_DW1_USE_URB_READ_OFFSET |
+ vue_offset << GEN8_SBE_DW1_URB_READ_OFFSET__SHIFT;
+ } else {
+ dw[1] |= vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
+ }
+
+ if (routing->swizzle_enable)
+ dw[1] |= GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE;
+
+ switch (sprite_coord_mode) {
+ case PIPE_SPRITE_COORD_UPPER_LEFT:
+ dw[1] |= GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_UPPERLEFT;
+ break;
+ case PIPE_SPRITE_COORD_LOWER_LEFT:
+ dw[1] |= GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_LOWERLEFT;
+ break;
+ }
+
+ /*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 268:
+ *
+ * "This field (Point Sprite Texture Coordinate Enable) must be
+ * programmed to 0 when non-point primitives are rendered."
+ *
+ * TODO We do not check that yet.
+ */
+ dw[2] = routing->point_sprite_enable;
+
+ dw[3] = routing->const_interp_enable;
+}
+
+static inline void
+gen8_internal_3dstate_sbe_swiz(struct ilo_builder *builder,
+ uint8_t cmd_len, uint32_t *dw,
+ const struct ilo_shader_state *fs)
+{
+ const struct ilo_kernel_routing *routing;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(cmd_len == 11);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_SBE_SWIZ) | (cmd_len - 2);
+
+ if (!fs) {
+ memset(&dw[1], 0, sizeof(*dw) * (cmd_len - 1));
+ return;
+ }
+
+ routing = ilo_shader_get_kernel_routing(fs);
+
+ STATIC_ASSERT(sizeof(routing->swizzles) >= sizeof(*dw) * 8);
+ memcpy(&dw[1], routing->swizzles, sizeof(*dw) * 8);
+
+ /* WrapShortest enables */
+ dw[9] = 0;
+ dw[10] = 0;
+}
+
+static inline void
+gen6_3DSTATE_SF(struct ilo_builder *builder,
+ const struct ilo_rasterizer_state *rasterizer,
+ const struct ilo_shader_state *fs,
+ int sample_count)
+{
+ const uint8_t cmd_len = 20;
+ uint32_t gen8_3dstate_sbe[4], gen8_3dstate_sbe_swiz[11];
+ uint32_t gen7_3dstate_sf[7];
+ const struct ilo_rasterizer_sf *sf;
+ int sprite_coord_mode;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ sf = (rasterizer) ? &rasterizer->sf : NULL;
+ sprite_coord_mode = (rasterizer) ? rasterizer->state.sprite_coord_mode : 0;
+
+ gen8_internal_3dstate_sbe(builder, Elements(gen8_3dstate_sbe),
+ gen8_3dstate_sbe, fs, sprite_coord_mode);
+ gen8_internal_3dstate_sbe_swiz(builder, Elements(gen8_3dstate_sbe_swiz),
+ gen8_3dstate_sbe_swiz, fs);
+ gen7_internal_3dstate_sf(builder, Elements(gen7_3dstate_sf),
+ gen7_3dstate_sf, sf, sample_count);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
+ dw[1] = gen8_3dstate_sbe[1];
+ memcpy(&dw[2], &gen7_3dstate_sf[1], sizeof(*dw) * 6);
+ memcpy(&dw[8], &gen8_3dstate_sbe_swiz[1], sizeof(*dw) * 8);
+ dw[16] = gen8_3dstate_sbe[2];
+ dw[17] = gen8_3dstate_sbe[3];
+ dw[18] = gen8_3dstate_sbe_swiz[9];
+ dw[19] = gen8_3dstate_sbe_swiz[10];
+}
+
+static inline void
+gen7_3DSTATE_SF(struct ilo_builder *builder,
+ const struct ilo_rasterizer_sf *sf,
+ enum pipe_format zs_format,
+ int sample_count)
+{
+ const uint8_t cmd_len = 7;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ gen7_internal_3dstate_sf(builder, cmd_len, dw, sf, sample_count);
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
+ int hw_format;
+
+ /* separate stencil */
+ switch (zs_format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ hw_format = GEN6_ZFORMAT_D16_UNORM;
+ break;
+ case PIPE_FORMAT_Z32_FLOAT:
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ hw_format = GEN6_ZFORMAT_D32_FLOAT;
+ break;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ hw_format = GEN6_ZFORMAT_D24_UNORM_X8_UINT;
+ break;
+ default:
+ /* FLOAT surface is assumed when there is no depth buffer */
+ hw_format = GEN6_ZFORMAT_D32_FLOAT;
+ break;
+ }
+
+ dw[1] |= hw_format << GEN7_SF_DW1_DEPTH_FORMAT__SHIFT;
+ }
+}
+
+static inline void
+gen8_3DSTATE_SF(struct ilo_builder *builder,
+ const struct ilo_rasterizer_sf *sf)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
+
+ /* see rasterizer_init_sf_gen8() */
+ STATIC_ASSERT(Elements(sf->payload) >= 3);
+ dw[1] = sf->payload[0];
+ dw[2] = sf->payload[1];
+ dw[3] = sf->payload[2];
+}
+
+static inline void
+gen7_3DSTATE_SBE(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs,
+ int sprite_coord_mode)
+{
+ const uint8_t cmd_len = 14;
+ uint32_t gen8_3dstate_sbe[4], gen8_3dstate_sbe_swiz[11];
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ gen8_internal_3dstate_sbe(builder, Elements(gen8_3dstate_sbe),
+ gen8_3dstate_sbe, fs, sprite_coord_mode);
+ gen8_internal_3dstate_sbe_swiz(builder, Elements(gen8_3dstate_sbe_swiz),
+ gen8_3dstate_sbe_swiz, fs);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) | (cmd_len - 2);
+ dw[1] = gen8_3dstate_sbe[1];
+ memcpy(&dw[2], &gen8_3dstate_sbe_swiz[1], sizeof(*dw) * 8);
+ dw[10] = gen8_3dstate_sbe[2];
+ dw[11] = gen8_3dstate_sbe[3];
+ dw[12] = gen8_3dstate_sbe_swiz[9];
+ dw[13] = gen8_3dstate_sbe_swiz[10];
+}
+
+static inline void
+gen8_3DSTATE_SBE(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs,
+ int sprite_coord_mode)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ gen8_internal_3dstate_sbe(builder, cmd_len, dw, fs, sprite_coord_mode);
+}
+
+static inline void
+gen8_3DSTATE_SBE_SWIZ(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs)
+{
+ const uint8_t cmd_len = 11;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ gen8_internal_3dstate_sbe_swiz(builder, cmd_len, dw, fs);
+}
+
+static inline void
+gen8_3DSTATE_RASTER(struct ilo_builder *builder,
+ const struct ilo_rasterizer_sf *sf)
+{
+ const uint8_t cmd_len = 5;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_RASTER) | (cmd_len - 2);
+ dw[1] = sf->dw_raster;
+ dw[2] = sf->dw_depth_offset_const;
+ dw[3] = sf->dw_depth_offset_scale;
+ dw[4] = sf->dw_depth_offset_clamp;
+}
+
+static inline void
+gen6_3DSTATE_WM(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs,
+ const struct ilo_rasterizer_state *rasterizer,
+ bool dual_blend, bool cc_may_kill)
+{
+ const uint8_t cmd_len = 9;
+ const int num_samples = 1;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw2, dw4, dw5, dw6, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ cso = ilo_shader_get_kernel_cso(fs);
+ dw2 = cso->payload[0];
+ dw4 = cso->payload[1];
+ dw5 = cso->payload[2];
+ dw6 = cso->payload[3];
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 248:
+ *
+ * "This bit (Statistics Enable) must be disabled if either of these
+ * bits is set: Depth Buffer Clear , Hierarchical Depth Buffer Resolve
+ * Enable or Depth Buffer Resolve Enable."
+ */
+ dw4 |= GEN6_WM_DW4_STATISTICS;
+
+ if (cc_may_kill)
+ dw5 |= GEN6_WM_DW5_PS_KILL_PIXEL | GEN6_WM_DW5_PS_DISPATCH_ENABLE;
+
+ if (dual_blend)
+ dw5 |= GEN6_WM_DW5_PS_DUAL_SOURCE_BLEND;
+
+ dw5 |= rasterizer->wm.payload[0];
+
+ dw6 |= rasterizer->wm.payload[1];
+
+ if (num_samples > 1) {
+ dw6 |= rasterizer->wm.dw_msaa_rast |
+ rasterizer->wm.dw_msaa_disp;
+ }
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
+ dw[1] = ilo_shader_get_kernel_offset(fs);
+ dw[2] = dw2;
+ dw[3] = 0; /* scratch */
+ dw[4] = dw4;
+ dw[5] = dw5;
+ dw[6] = dw6;
+ dw[7] = 0; /* kernel 1 */
+ dw[8] = 0; /* kernel 2 */
+}
+
+static inline void
+gen6_hiz_3DSTATE_WM(struct ilo_builder *builder, uint32_t hiz_op)
+{
+ const uint8_t cmd_len = 9;
+ const int max_threads = (builder->dev->gt == 2) ? 80 : 40;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw[4] = hiz_op;
+ /* honor the valid range even if dispatching is disabled */
+ dw[5] = (max_threads - 1) << GEN6_WM_DW5_MAX_THREADS__SHIFT;
+ dw[6] = 0;
+ dw[7] = 0;
+ dw[8] = 0;
+}
+
+static inline void
+gen7_3DSTATE_WM(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs,
+ const struct ilo_rasterizer_state *rasterizer,
+ bool cc_may_kill)
+{
+ const uint8_t cmd_len = 3;
+ const int num_samples = 1;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw1, dw2, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ /* see rasterizer_init_wm_gen7() */
+ dw1 = rasterizer->wm.payload[0];
+ dw2 = rasterizer->wm.payload[1];
+
+ /* see fs_init_cso_gen7() */
+ cso = ilo_shader_get_kernel_cso(fs);
+ dw1 |= cso->payload[3];
+
+ dw1 |= GEN7_WM_DW1_STATISTICS;
+
+ if (cc_may_kill)
+ dw1 |= GEN7_WM_DW1_PS_DISPATCH_ENABLE | GEN7_WM_DW1_PS_KILL_PIXEL;
+
+ if (num_samples > 1) {
+ dw1 |= rasterizer->wm.dw_msaa_rast;
+ dw2 |= rasterizer->wm.dw_msaa_disp;
+ }
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
+ dw[1] = dw1;
+ dw[2] = dw2;
+}
+
+static inline void
+gen8_3DSTATE_WM(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs,
+ const struct ilo_rasterizer_state *rasterizer)
+{
+ const uint8_t cmd_len = 2;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw1, interps, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ /* see rasterizer_get_wm_gen8() */
+ dw1 = rasterizer->wm.payload[0];
+ dw1 |= GEN7_WM_DW1_STATISTICS;
+
+ /* see fs_init_cso_gen8() */
+ cso = ilo_shader_get_kernel_cso(fs);
+ interps = cso->payload[4];
+
+ assert(!(dw1 & interps));
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
+ dw[1] = dw1 | interps;
+}
+
+static inline void
+gen7_hiz_3DSTATE_WM(struct ilo_builder *builder, uint32_t hiz_op)
+{
+ const uint8_t cmd_len = 3;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
+ dw[1] = hiz_op;
+ dw[2] = 0;
+}
+
+static inline void
+gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_builder *builder,
+ const struct ilo_dsa_state *dsa)
+{
+ const uint8_t cmd_len = 3;
+ uint32_t dw1, dw2, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ dw1 = dsa->payload[0];
+ dw2 = dsa->payload[1];
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_DEPTH_STENCIL) | (cmd_len - 2);
+ dw[1] = dw1;
+ dw[2] = dw2;
+}
+
+static inline void
+gen8_3DSTATE_WM_HZ_OP(struct ilo_builder *builder, uint32_t op,
+ uint16_t width, uint16_t height, int sample_count)
+{
+ const uint8_t cmd_len = 5;
+ const uint32_t sample_mask = ((1 << sample_count) - 1) | 0x1;
+ uint32_t dw1, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ dw1 = op;
+
+ switch (sample_count) {
+ case 0:
+ case 1:
+ dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_1;
+ break;
+ case 2:
+ dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_2;
+ break;
+ case 4:
+ dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_4;
+ break;
+ case 8:
+ dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_8;
+ break;
+ case 16:
+ dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_16;
+ break;
+ default:
+ assert(!"unsupported sample count");
+ dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_1;
+ break;
+ }
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_HZ_OP) | (cmd_len - 2);
+ dw[1] = dw1;
+ dw[2] = 0;
+ /* exclusive? */
+ dw[3] = height << 16 | width;
+ dw[4] = sample_mask;
+}
+
+static inline void
+gen8_disable_3DSTATE_WM_HZ_OP(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 5;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_HZ_OP) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw[4] = 0;
+}
+
+static inline void
+gen8_3DSTATE_WM_CHROMAKEY(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_CHROMAKEY) | (cmd_len - 2);
+ dw[1] = 0;
+}
+
+static inline void
+gen7_3DSTATE_PS(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs,
+ bool dual_blend)
+{
+ const uint8_t cmd_len = 8;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw2, dw4, dw5, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ /* see fs_init_cso_gen7() */
+ cso = ilo_shader_get_kernel_cso(fs);
+ dw2 = cso->payload[0];
+ dw4 = cso->payload[1];
+ dw5 = cso->payload[2];
+
+ if (dual_blend)
+ dw4 |= GEN7_PS_DW4_DUAL_SOURCE_BLEND;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
+ dw[1] = ilo_shader_get_kernel_offset(fs);
+ dw[2] = dw2;
+ dw[3] = 0; /* scratch */
+ dw[4] = dw4;
+ dw[5] = dw5;
+ dw[6] = 0; /* kernel 1 */
+ dw[7] = 0; /* kernel 2 */
+}
+
+static inline void
+gen7_disable_3DSTATE_PS(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 8;
+ int max_threads;
+ uint32_t dw4, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ /* GPU hangs if none of the dispatch enable bits is set */
+ dw4 = GEN6_PS_DISPATCH_8 << GEN7_PS_DW4_DISPATCH_MODE__SHIFT;
+
+ /* see brwCreateContext() */
+ switch (ilo_dev_gen(builder->dev)) {
+ case ILO_GEN(7.5):
+ max_threads = (builder->dev->gt == 3) ? 408 :
+ (builder->dev->gt == 2) ? 204 : 102;
+ dw4 |= (max_threads - 1) << GEN75_PS_DW4_MAX_THREADS__SHIFT;
+ break;
+ case ILO_GEN(7):
+ default:
+ max_threads = (builder->dev->gt == 2) ? 172 : 48;
+ dw4 |= (max_threads - 1) << GEN7_PS_DW4_MAX_THREADS__SHIFT;
+ break;
+ }
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw[4] = dw4;
+ dw[5] = 0;
+ dw[6] = 0;
+ dw[7] = 0;
+}
+
+static inline void
+gen8_3DSTATE_PS(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs)
+{
+ const uint8_t cmd_len = 12;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw3, dw6, dw7, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ /* see fs_init_cso_gen8() */
+ cso = ilo_shader_get_kernel_cso(fs);
+ dw3 = cso->payload[0];
+ dw6 = cso->payload[1];
+ dw7 = cso->payload[2];
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
+ dw[1] = ilo_shader_get_kernel_offset(fs);
+ dw[2] = 0;
+ dw[3] = dw3;
+ dw[4] = 0; /* scratch */
+ dw[5] = 0;
+ dw[6] = dw6;
+ dw[7] = dw7;
+ dw[8] = 0; /* kernel 1 */
+ dw[9] = 0;
+ dw[10] = 0; /* kernel 2 */
+ dw[11] = 0;
+}
+
+static inline void
+gen8_3DSTATE_PS_EXTRA(struct ilo_builder *builder,
+ const struct ilo_shader_state *fs,
+ bool cc_may_kill, bool per_sample)
+{
+ const uint8_t cmd_len = 2;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw1, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ /* see fs_init_cso_gen8() */
+ cso = ilo_shader_get_kernel_cso(fs);
+ dw1 = cso->payload[3];
+
+ if (cc_may_kill)
+ dw1 |= GEN8_PSX_DW1_DISPATCH_ENABLE | GEN8_PSX_DW1_KILL_PIXEL;
+ if (per_sample)
+ dw1 |= GEN8_PSX_DW1_PER_SAMPLE;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_EXTRA) | (cmd_len - 2);
+ dw[1] = dw1;
+}
+
+static inline void
+gen8_3DSTATE_PS_BLEND(struct ilo_builder *builder,
+ const struct ilo_blend_state *blend,
+ const struct ilo_fb_state *fb,
+ const struct ilo_dsa_state *dsa)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t dw1, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ dw1 = 0;
+ if (blend->alpha_to_coverage && fb->num_samples > 1)
+ dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE;
+
+ if (fb->state.nr_cbufs && fb->state.cbufs[0]) {
+ const struct ilo_fb_blend_caps *caps = &fb->blend_caps[0];
+
+ dw1 |= GEN8_PS_BLEND_DW1_WRITABLE_RT;
+ if (caps->can_blend) {
+ if (caps->dst_alpha_forced_one)
+ dw1 |= blend->dw_ps_blend_dst_alpha_forced_one;
+ else
+ dw1 |= blend->dw_ps_blend;
+ }
+
+ if (caps->can_alpha_test)
+ dw1 |= dsa->dw_ps_blend_alpha;
+ } else {
+ dw1 |= dsa->dw_ps_blend_alpha;
+ }
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_BLEND) | (cmd_len - 2);
+ dw[1] = dw1;
+}
+
+static inline void
+gen6_3DSTATE_CONSTANT_PS(struct ilo_builder *builder,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
+ bufs, sizes, num_bufs);
+}
+
+static inline void
+gen7_3DSTATE_CONSTANT_PS(struct ilo_builder *builder,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
+ bufs, sizes, num_bufs);
+}
+
+static inline void
+gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(struct ilo_builder *builder,
+ uint32_t binding_table)
+{
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_PS,
+ binding_table);
+}
+
+static inline void
+gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(struct ilo_builder *builder,
+ uint32_t sampler_state)
+{
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_PS,
+ sampler_state);
+}
+
+static inline void
+gen6_3DSTATE_MULTISAMPLE(struct ilo_builder *builder,
+ int num_samples, const uint32_t *pattern,
+ bool pixel_location_center)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 3;
+ uint32_t dw1, dw2, dw3, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ dw1 = (pixel_location_center) ? GEN6_MULTISAMPLE_DW1_PIXLOC_CENTER :
+ GEN6_MULTISAMPLE_DW1_PIXLOC_UL_CORNER;
+
+ switch (num_samples) {
+ case 0:
+ case 1:
+ dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
+ dw2 = 0;
+ dw3 = 0;
+ break;
+ case 4:
+ dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
+ dw2 = pattern[0];
+ dw3 = 0;
+ break;
+ case 8:
+ assert(ilo_dev_gen(builder->dev) >= ILO_GEN(7));
+ dw1 |= GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
+ dw2 = pattern[0];
+ dw3 = pattern[1];
+ break;
+ default:
+ assert(!"unsupported sample count");
+ dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
+ dw2 = 0;
+ dw3 = 0;
+ break;
+ }
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE) | (cmd_len - 2);
+ dw[1] = dw1;
+ dw[2] = dw2;
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
+ dw[3] = dw3;
+}
+
+static inline void
+gen8_3DSTATE_MULTISAMPLE(struct ilo_builder *builder,
+ int num_samples,
+ bool pixel_location_center)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t dw1, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ dw1 = (pixel_location_center) ? GEN6_MULTISAMPLE_DW1_PIXLOC_CENTER :
+ GEN6_MULTISAMPLE_DW1_PIXLOC_UL_CORNER;
+
+ switch (num_samples) {
+ case 0:
+ case 1:
+ dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
+ break;
+ case 2:
+ dw1 |= GEN8_MULTISAMPLE_DW1_NUMSAMPLES_2;
+ break;
+ case 4:
+ dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
+ break;
+ case 8:
+ dw1 |= GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
+ break;
+ case 16:
+ dw1 |= GEN8_MULTISAMPLE_DW1_NUMSAMPLES_16;
+ break;
+ default:
+ assert(!"unsupported sample count");
+ dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
+ break;
+ }
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE) | (cmd_len - 2);
+ dw[1] = dw1;
+}
+
+static inline void
+gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_builder *builder,
+ const uint32_t *pattern_1x,
+ const uint32_t *pattern_2x,
+ const uint32_t *pattern_4x,
+ const uint32_t *pattern_8x,
+ const uint32_t *pattern_16x)
+{
+ const uint8_t cmd_len = 9;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_SAMPLE_PATTERN) | (cmd_len - 2);
+ dw[1] = pattern_16x[3];
+ dw[2] = pattern_16x[2];
+ dw[3] = pattern_16x[1];
+ dw[4] = pattern_16x[0];
+ dw[5] = pattern_8x[1];
+ dw[6] = pattern_8x[0];
+ dw[7] = pattern_4x[0];
+ dw[8] = pattern_1x[0] << 16 |
+ pattern_2x[0];
+}
+
+static inline void
+gen6_3DSTATE_SAMPLE_MASK(struct ilo_builder *builder,
+ unsigned sample_mask)
+{
+ const uint8_t cmd_len = 2;
+ const unsigned valid_mask = 0xf;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ sample_mask &= valid_mask;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK) | (cmd_len - 2);
+ dw[1] = sample_mask;
+}
+
+static inline void
+gen7_3DSTATE_SAMPLE_MASK(struct ilo_builder *builder,
+ unsigned sample_mask,
+ int num_samples)
+{
+ const uint8_t cmd_len = 2;
+ const unsigned valid_mask = ((1 << num_samples) - 1) | 0x1;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ /*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 294:
+ *
+ * "If Number of Multisamples is NUMSAMPLES_1, bits 7:1 of this field
+ * (Sample Mask) must be zero.
+ *
+ * If Number of Multisamples is NUMSAMPLES_4, bits 7:4 of this field
+ * must be zero."
+ */
+ sample_mask &= valid_mask;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK) | (cmd_len - 2);
+ dw[1] = sample_mask;
+}
+
+static inline void
+gen6_3DSTATE_DRAWING_RECTANGLE(struct ilo_builder *builder,
+ unsigned x, unsigned y,
+ unsigned width, unsigned height)
+{
+ const uint8_t cmd_len = 4;
+ unsigned xmax = x + width - 1;
+ unsigned ymax = y + height - 1;
+ unsigned rect_limit;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
+ rect_limit = 16383;
+ }
+ else {
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 230:
+ *
+ * "[DevSNB] Errata: This field (Clipped Drawing Rectangle Y Min)
+ * must be an even number"
+ */
+ assert(y % 2 == 0);
+
+ rect_limit = 8191;
+ }
+
+ if (x > rect_limit) x = rect_limit;
+ if (y > rect_limit) y = rect_limit;
+ if (xmax > rect_limit) xmax = rect_limit;
+ if (ymax > rect_limit) ymax = rect_limit;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_DRAWING_RECTANGLE) | (cmd_len - 2);
+ dw[1] = y << 16 | x;
+ dw[2] = ymax << 16 | xmax;
+ /*
+ * There is no need to set the origin. It is intended to support front
+ * buffer rendering.
+ */
+ dw[3] = 0;
+}
+
+static inline void
+gen6_3DSTATE_POLY_STIPPLE_OFFSET(struct ilo_builder *builder,
+ int x_offset, int y_offset)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(x_offset >= 0 && x_offset <= 31);
+ assert(y_offset >= 0 && y_offset <= 31);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_POLY_STIPPLE_OFFSET) | (cmd_len - 2);
+ dw[1] = x_offset << 8 | y_offset;
+}
+
+static inline void
+gen6_3DSTATE_POLY_STIPPLE_PATTERN(struct ilo_builder *builder,
+ const struct pipe_poly_stipple *pattern)
+{
+ const uint8_t cmd_len = 33;
+ uint32_t *dw;
+ int i;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_POLY_STIPPLE_PATTERN) | (cmd_len - 2);
+ dw++;
+
+ STATIC_ASSERT(Elements(pattern->stipple) == 32);
+ for (i = 0; i < 32; i++)
+ dw[i] = pattern->stipple[i];
+}
+
+static inline void
+gen6_3DSTATE_LINE_STIPPLE(struct ilo_builder *builder,
+ unsigned pattern, unsigned factor)
+{
+ const uint8_t cmd_len = 3;
+ unsigned inverse;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert((pattern & 0xffff) == pattern);
+ assert(factor >= 1 && factor <= 256);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_LINE_STIPPLE) | (cmd_len - 2);
+ dw[1] = pattern;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
+ /* in U1.16 */
+ inverse = 65536 / factor;
+
+ dw[2] = inverse << GEN7_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
+ factor;
+ }
+ else {
+ /* in U1.13 */
+ inverse = 8192 / factor;
+
+ dw[2] = inverse << GEN6_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
+ factor;
+ }
+}
+
+static inline void
+gen6_3DSTATE_AA_LINE_PARAMETERS(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 3;
+ const uint32_t dw[3] = {
+ GEN6_RENDER_CMD(3D, 3DSTATE_AA_LINE_PARAMETERS) | (cmd_len - 2),
+ 0 << GEN6_AA_LINE_DW1_BIAS__SHIFT | 0,
+ 0 << GEN6_AA_LINE_DW2_CAP_BIAS__SHIFT | 0,
+ };
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ ilo_builder_batch_write(builder, cmd_len, dw);
+}
+
+static inline void
+gen6_3DSTATE_DEPTH_BUFFER(struct ilo_builder *builder,
+ const struct ilo_zs_surface *zs,
+ bool aligned_8x4)
+{
+ const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
+ GEN7_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER) :
+ GEN6_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER);
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 7;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = cmd | (cmd_len - 2);
+ dw[1] = zs->payload[0];
+ dw[2] = 0;
+
+ /* see ilo_gpe_init_zs_surface() */
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[3] = 0;
+ dw[4] = (aligned_8x4) ? zs->dw_aligned_8x4 : zs->payload[2];
+ dw[5] = zs->payload[3];
+ dw[6] = zs->payload[4];
+ dw[7] = zs->payload[5];
+
+ dw[5] |= builder->mocs << GEN8_DEPTH_DW5_MOCS__SHIFT;
+
+ if (zs->bo) {
+ ilo_builder_batch_reloc64(builder, pos + 2, zs->bo,
+ zs->payload[1], INTEL_RELOC_WRITE);
+ }
+ } else {
+ dw[3] = (aligned_8x4) ? zs->dw_aligned_8x4 : zs->payload[2];
+ dw[4] = zs->payload[3];
+ dw[5] = zs->payload[4];
+ dw[6] = zs->payload[5];
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
+ dw[4] |= builder->mocs << GEN7_DEPTH_DW4_MOCS__SHIFT;
+ else
+ dw[6] |= builder->mocs << GEN6_DEPTH_DW6_MOCS__SHIFT;
+
+ if (zs->bo) {
+ ilo_builder_batch_reloc(builder, pos + 2, zs->bo,
+ zs->payload[1], INTEL_RELOC_WRITE);
+ }
+ }
+}
+
+static inline void
+gen6_3DSTATE_STENCIL_BUFFER(struct ilo_builder *builder,
+ const struct ilo_zs_surface *zs)
+{
+ const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
+ GEN7_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER) :
+ GEN6_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER);
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = cmd | (cmd_len - 2);
+ /* see ilo_gpe_init_zs_surface() */
+ dw[1] = zs->payload[6];
+ dw[2] = 0;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[1] |= builder->mocs << GEN8_STENCIL_DW1_MOCS__SHIFT;
+
+ dw[3] = 0;
+ dw[4] = zs->payload[8];
+
+ if (zs->separate_s8_bo) {
+ ilo_builder_batch_reloc64(builder, pos + 2,
+ zs->separate_s8_bo, zs->payload[7], INTEL_RELOC_WRITE);
+ }
+ } else {
+ dw[1] |= builder->mocs << GEN6_STENCIL_DW1_MOCS__SHIFT;
+
+ if (zs->separate_s8_bo) {
+ ilo_builder_batch_reloc(builder, pos + 2,
+ zs->separate_s8_bo, zs->payload[7], INTEL_RELOC_WRITE);
+ }
+ }
+}
+
+static inline void
+gen6_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_builder *builder,
+ const struct ilo_zs_surface *zs)
+{
+ const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
+ GEN7_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER) :
+ GEN6_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER);
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = cmd | (cmd_len - 2);
+ /* see ilo_gpe_init_zs_surface() */
+ dw[1] = zs->payload[9];
+ dw[2] = 0;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[1] |= builder->mocs << GEN8_HIZ_DW1_MOCS__SHIFT;
+
+ dw[3] = 0;
+ dw[4] = zs->payload[11];
+
+ if (zs->hiz_bo) {
+ ilo_builder_batch_reloc64(builder, pos + 2,
+ zs->hiz_bo, zs->payload[10], INTEL_RELOC_WRITE);
+ }
+ } else {
+ dw[1] |= builder->mocs << GEN6_HIZ_DW1_MOCS__SHIFT;
+
+ if (zs->hiz_bo) {
+ ilo_builder_batch_reloc(builder, pos + 2,
+ zs->hiz_bo, zs->payload[10], INTEL_RELOC_WRITE);
+ }
+ }
+}
+
+static inline void
+gen6_3DSTATE_CLEAR_PARAMS(struct ilo_builder *builder,
+ uint32_t clear_val)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CLEAR_PARAMS) |
+ GEN6_CLEAR_PARAMS_DW0_VALID |
+ (cmd_len - 2);
+ dw[1] = clear_val;
+}
+
+static inline void
+gen7_3DSTATE_CLEAR_PARAMS(struct ilo_builder *builder,
+ uint32_t clear_val)
+{
+ const uint8_t cmd_len = 3;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_CLEAR_PARAMS) | (cmd_len - 2);
+ dw[1] = clear_val;
+ dw[2] = GEN7_CLEAR_PARAMS_DW2_VALID;
+}
+
+static inline void
+gen6_3DSTATE_VIEWPORT_STATE_POINTERS(struct ilo_builder *builder,
+ uint32_t clip_viewport,
+ uint32_t sf_viewport,
+ uint32_t cc_viewport)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VIEWPORT_STATE_POINTERS) |
+ GEN6_VP_PTR_DW0_CLIP_CHANGED |
+ GEN6_VP_PTR_DW0_SF_CHANGED |
+ GEN6_VP_PTR_DW0_CC_CHANGED |
+ (cmd_len - 2);
+ dw[1] = clip_viewport;
+ dw[2] = sf_viewport;
+ dw[3] = cc_viewport;
+}
+
+static inline void
+gen6_3DSTATE_SCISSOR_STATE_POINTERS(struct ilo_builder *builder,
+ uint32_t scissor_rect)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SCISSOR_STATE_POINTERS) |
+ (cmd_len - 2);
+ dw[1] = scissor_rect;
+}
+
+static inline void
+gen6_3DSTATE_CC_STATE_POINTERS(struct ilo_builder *builder,
+ uint32_t blend_state,
+ uint32_t depth_stencil_state,
+ uint32_t color_calc_state)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CC_STATE_POINTERS) | (cmd_len - 2);
+ dw[1] = blend_state | GEN6_CC_PTR_DW1_BLEND_CHANGED;
+ dw[2] = depth_stencil_state | GEN6_CC_PTR_DW2_ZS_CHANGED;
+ dw[3] = color_calc_state | GEN6_CC_PTR_DW3_CC_CHANGED;
+}
+
+static inline void
+gen7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP(struct ilo_builder *builder,
+ uint32_t sf_clip_viewport)
+{
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
+ sf_clip_viewport);
+}
+
+static inline void
+gen7_3DSTATE_VIEWPORT_STATE_POINTERS_CC(struct ilo_builder *builder,
+ uint32_t cc_viewport)
+{
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
+ cc_viewport);
+}
+
+static inline void
+gen7_3DSTATE_CC_STATE_POINTERS(struct ilo_builder *builder,
+ uint32_t color_calc_state)
+{
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
+ color_calc_state |= 1;
+
+ gen7_3dstate_pointer(builder,
+ GEN6_RENDER_OPCODE_3DSTATE_CC_STATE_POINTERS, color_calc_state);
+}
+
+static inline void
+gen7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(struct ilo_builder *builder,
+ uint32_t depth_stencil_state)
+{
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_DEPTH_STENCIL_STATE_POINTERS,
+ depth_stencil_state);
+}
+
+static inline void
+gen7_3DSTATE_BLEND_STATE_POINTERS(struct ilo_builder *builder,
+ uint32_t blend_state)
+{
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
+ blend_state |= 1;
+
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_BLEND_STATE_POINTERS,
+ blend_state);
+}
+
+static inline uint32_t
+gen6_CLIP_VIEWPORT(struct ilo_builder *builder,
+ const struct ilo_viewport_cso *viewports,
+ unsigned num_viewports)
+{
+ const int state_align = 32;
+ const int state_len = 4 * num_viewports;
+ uint32_t state_offset, *dw;
+ unsigned i;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 193:
+ *
+ * "The viewport-related state is stored as an array of up to 16
+ * elements..."
+ */
+ assert(num_viewports && num_viewports <= 16);
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_CLIP_VIEWPORT, state_align, state_len, &dw);
+
+ for (i = 0; i < num_viewports; i++) {
+ const struct ilo_viewport_cso *vp = &viewports[i];
+
+ dw[0] = fui(vp->min_gbx);
+ dw[1] = fui(vp->max_gbx);
+ dw[2] = fui(vp->min_gby);
+ dw[3] = fui(vp->max_gby);
+
+ dw += 4;
+ }
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen6_SF_VIEWPORT(struct ilo_builder *builder,
+ const struct ilo_viewport_cso *viewports,
+ unsigned num_viewports)
+{
+ const int state_align = 32;
+ const int state_len = 8 * num_viewports;
+ uint32_t state_offset, *dw;
+ unsigned i;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 262:
+ *
+ * "The viewport-specific state used by the SF unit (SF_VIEWPORT) is
+ * stored as an array of up to 16 elements..."
+ */
+ assert(num_viewports && num_viewports <= 16);
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_SF_VIEWPORT, state_align, state_len, &dw);
+
+ for (i = 0; i < num_viewports; i++) {
+ const struct ilo_viewport_cso *vp = &viewports[i];
+
+ dw[0] = fui(vp->m00);
+ dw[1] = fui(vp->m11);
+ dw[2] = fui(vp->m22);
+ dw[3] = fui(vp->m30);
+ dw[4] = fui(vp->m31);
+ dw[5] = fui(vp->m32);
+ dw[6] = 0;
+ dw[7] = 0;
+
+ dw += 8;
+ }
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen7_SF_CLIP_VIEWPORT(struct ilo_builder *builder,
+ const struct ilo_viewport_cso *viewports,
+ unsigned num_viewports)
+{
+ const int state_align = 64;
+ const int state_len = 16 * num_viewports;
+ uint32_t state_offset, *dw;
+ unsigned i;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ /*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 270:
+ *
+ * "The viewport-specific state used by both the SF and CL units
+ * (SF_CLIP_VIEWPORT) is stored as an array of up to 16 elements, each
+ * of which contains the DWords described below. The start of each
+ * element is spaced 16 DWords apart. The location of first element of
+ * the array, as specified by both Pointer to SF_VIEWPORT and Pointer
+ * to CLIP_VIEWPORT, is aligned to a 64-byte boundary."
+ */
+ assert(num_viewports && num_viewports <= 16);
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_SF_VIEWPORT, state_align, state_len, &dw);
+
+ for (i = 0; i < num_viewports; i++) {
+ const struct ilo_viewport_cso *vp = &viewports[i];
+
+ dw[0] = fui(vp->m00);
+ dw[1] = fui(vp->m11);
+ dw[2] = fui(vp->m22);
+ dw[3] = fui(vp->m30);
+ dw[4] = fui(vp->m31);
+ dw[5] = fui(vp->m32);
+ dw[6] = 0;
+ dw[7] = 0;
+
+ dw[8] = fui(vp->min_gbx);
+ dw[9] = fui(vp->max_gbx);
+ dw[10] = fui(vp->min_gby);
+ dw[11] = fui(vp->max_gby);
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[12] = fui(vp->min_x);
+ dw[13] = fui(vp->max_x - 1.0f);
+ dw[14] = fui(vp->min_y);
+ dw[15] = fui(vp->max_y - 1.0f);
+ } else {
+ dw[12] = 0;
+ dw[13] = 0;
+ dw[14] = 0;
+ dw[15] = 0;
+ }
+
+ dw += 16;
+ }
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen6_CC_VIEWPORT(struct ilo_builder *builder,
+ const struct ilo_viewport_cso *viewports,
+ unsigned num_viewports)
+{
+ const int state_align = 32;
+ const int state_len = 2 * num_viewports;
+ uint32_t state_offset, *dw;
+ unsigned i;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 385:
+ *
+ * "The viewport state is stored as an array of up to 16 elements..."
+ */
+ assert(num_viewports && num_viewports <= 16);
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_CC_VIEWPORT, state_align, state_len, &dw);
+
+ for (i = 0; i < num_viewports; i++) {
+ const struct ilo_viewport_cso *vp = &viewports[i];
+
+ dw[0] = fui(vp->min_z);
+ dw[1] = fui(vp->max_z);
+
+ dw += 2;
+ }
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen6_SCISSOR_RECT(struct ilo_builder *builder,
+ const struct ilo_scissor_state *scissor,
+ unsigned num_viewports)
+{
+ const int state_align = 32;
+ const int state_len = 2 * num_viewports;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 263:
+ *
+ * "The viewport-specific state used by the SF unit (SCISSOR_RECT) is
+ * stored as an array of up to 16 elements..."
+ */
+ assert(num_viewports && num_viewports <= 16);
+ assert(Elements(scissor->payload) >= state_len);
+
+ return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_SCISSOR_RECT,
+ state_align, state_len, scissor->payload);
+}
+
+static inline uint32_t
+gen6_COLOR_CALC_STATE(struct ilo_builder *builder,
+ const struct pipe_stencil_ref *stencil_ref,
+ ubyte alpha_ref,
+ const struct pipe_blend_color *blend_color)
+{
+ const int state_align = 64;
+ const int state_len = 6;
+ uint32_t state_offset, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_COLOR_CALC, state_align, state_len, &dw);
+
+ dw[0] = stencil_ref->ref_value[0] << 24 |
+ stencil_ref->ref_value[1] << 16 |
+ GEN6_CC_DW0_ALPHATEST_UNORM8;
+ dw[1] = alpha_ref;
+ dw[2] = fui(blend_color->color[0]);
+ dw[3] = fui(blend_color->color[1]);
+ dw[4] = fui(blend_color->color[2]);
+ dw[5] = fui(blend_color->color[3]);
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen6_DEPTH_STENCIL_STATE(struct ilo_builder *builder,
+ const struct ilo_dsa_state *dsa)
+{
+ const int state_align = 64;
+ const int state_len = 3;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ STATIC_ASSERT(Elements(dsa->payload) >= state_len);
+
+ return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_DEPTH_STENCIL,
+ state_align, state_len, dsa->payload);
+}
+
+static inline uint32_t
+gen6_BLEND_STATE(struct ilo_builder *builder,
+ const struct ilo_blend_state *blend,
+ const struct ilo_fb_state *fb,
+ const struct ilo_dsa_state *dsa)
+{
+ const int state_align = 64;
+ int state_len;
+ uint32_t state_offset, *dw;
+ unsigned num_targets, i;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 376:
+ *
+ * "The blend state is stored as an array of up to 8 elements..."
+ */
+ num_targets = fb->state.nr_cbufs;
+ assert(num_targets <= 8);
+
+ if (!num_targets) {
+ if (!dsa->dw_blend_alpha)
+ return 0;
+ /* to be able to reference alpha func */
+ num_targets = 1;
+ }
+
+ state_len = 2 * num_targets;
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
+
+ for (i = 0; i < num_targets; i++) {
+ const struct ilo_blend_cso *cso = &blend->cso[i];
+
+ dw[0] = cso->payload[0];
+ dw[1] = cso->payload[1] | blend->dw_shared;
+
+ if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) {
+ const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
+
+ if (caps->can_blend) {
+ if (caps->dst_alpha_forced_one)
+ dw[0] |= cso->dw_blend_dst_alpha_forced_one;
+ else
+ dw[0] |= cso->dw_blend;
+ }
+
+ if (caps->can_logicop)
+ dw[1] |= blend->dw_logicop;
+
+ if (caps->can_alpha_test)
+ dw[1] |= dsa->dw_blend_alpha;
+ } else {
+ dw[1] |= GEN6_RT_DW1_WRITE_DISABLE_A |
+ GEN6_RT_DW1_WRITE_DISABLE_R |
+ GEN6_RT_DW1_WRITE_DISABLE_G |
+ GEN6_RT_DW1_WRITE_DISABLE_B |
+ dsa->dw_blend_alpha;
+ }
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 356:
+ *
+ * "When NumSamples = 1, AlphaToCoverage and AlphaToCoverage
+ * Dither both must be disabled."
+ *
+ * There is no such limitation on GEN7, or for AlphaToOne. But GL
+ * requires that anyway.
+ */
+ if (fb->num_samples > 1)
+ dw[1] |= blend->dw_alpha_mod;
+
+ dw += 2;
+ }
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen8_BLEND_STATE(struct ilo_builder *builder,
+ const struct ilo_blend_state *blend,
+ const struct ilo_fb_state *fb,
+ const struct ilo_dsa_state *dsa)
+{
+ const int state_align = 64;
+ const int state_len = 1 + 2 * fb->state.nr_cbufs;
+ uint32_t state_offset, *dw;
+ unsigned i;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ assert(fb->state.nr_cbufs <= 8);
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
+
+ dw[0] = blend->dw_shared;
+ if (fb->num_samples > 1)
+ dw[0] |= blend->dw_alpha_mod;
+ if (!fb->state.nr_cbufs || fb->blend_caps[0].can_alpha_test)
+ dw[0] |= dsa->dw_blend_alpha;
+ dw++;
+
+ for (i = 0; i < fb->state.nr_cbufs; i++) {
+ const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
+ const struct ilo_blend_cso *cso = &blend->cso[i];
+
+ dw[0] = cso->payload[0];
+ dw[1] = cso->payload[1];
+
+ if (fb->state.cbufs[i]) {
+ if (caps->can_blend) {
+ if (caps->dst_alpha_forced_one)
+ dw[0] |= cso->dw_blend_dst_alpha_forced_one;
+ else
+ dw[0] |= cso->dw_blend;
+ }
+
+ if (caps->can_logicop)
+ dw[1] |= blend->dw_logicop;
+ } else {
+ dw[0] |= GEN8_RT_DW0_WRITE_DISABLE_A |
+ GEN8_RT_DW0_WRITE_DISABLE_R |
+ GEN8_RT_DW0_WRITE_DISABLE_G |
+ GEN8_RT_DW0_WRITE_DISABLE_B;
+ }
+
+ dw += 2;
+ }
+
+ return state_offset;
+}
+
+#endif /* ILO_BUILDER_3D_BOTTOM_H */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_BUILDER_3D_TOP_H
+#define ILO_BUILDER_3D_TOP_H
+
+#include "genhw/genhw.h"
+#include "../ilo_resource.h"
+#include "../ilo_shader.h"
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+#include "ilo_state_3d.h"
+#include "ilo_builder.h"
+
+static inline void
+gen6_3DSTATE_URB(struct ilo_builder *builder,
+ int vs_total_size, int gs_total_size,
+ int vs_entry_size, int gs_entry_size)
+{
+ const uint8_t cmd_len = 3;
+ const int row_size = 128; /* 1024 bits */
+ int vs_alloc_size, gs_alloc_size;
+ int vs_num_entries, gs_num_entries;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ /* in 1024-bit URB rows */
+ vs_alloc_size = (vs_entry_size + row_size - 1) / row_size;
+ gs_alloc_size = (gs_entry_size + row_size - 1) / row_size;
+
+ /* the valid range is [1, 5] */
+ if (!vs_alloc_size)
+ vs_alloc_size = 1;
+ if (!gs_alloc_size)
+ gs_alloc_size = 1;
+ assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
+
+ /* the valid range is [24, 256] in multiples of 4 */
+ vs_num_entries = (vs_total_size / row_size / vs_alloc_size) & ~3;
+ if (vs_num_entries > 256)
+ vs_num_entries = 256;
+ assert(vs_num_entries >= 24);
+
+ /* the valid range is [0, 256] in multiples of 4 */
+ gs_num_entries = (gs_total_size / row_size / gs_alloc_size) & ~3;
+ if (gs_num_entries > 256)
+ gs_num_entries = 256;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_URB) | (cmd_len - 2);
+ dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
+ vs_num_entries << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
+ dw[2] = gs_num_entries << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
+ (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
+}
+
+static inline void
+gen7_3dstate_push_constant_alloc(struct ilo_builder *builder,
+ int subop, int offset, int size)
+{
+ const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
+ GEN6_RENDER_SUBTYPE_3D |
+ subop;
+ const uint8_t cmd_len = 2;
+ const int slice_count = ((ilo_dev_gen(builder->dev) == ILO_GEN(7.5) &&
+ builder->dev->gt == 3) ||
+ ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 2 : 1;
+ uint32_t *dw;
+ int end;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ /* VS, HS, DS, GS, and PS variants */
+ assert(subop >= GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_VS &&
+ subop <= GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_PS);
+
+ /*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 68:
+ *
+ * "(A table that says the maximum size of each constant buffer is
+ * 16KB")
+ *
+ * From the Ivy Bridge PRM, volume 2 part 1, page 115:
+ *
+ * "The sum of the Constant Buffer Offset and the Constant Buffer Size
+ * may not exceed the maximum value of the Constant Buffer Size."
+ *
+ * Thus, the valid range of buffer end is [0KB, 16KB].
+ */
+ end = (offset + size) / 1024;
+ if (end > 16 * slice_count) {
+ assert(!"invalid constant buffer end");
+ end = 16 * slice_count;
+ }
+
+ /* the valid range of buffer offset is [0KB, 15KB] */
+ offset = (offset + 1023) / 1024;
+ if (offset > 15 * slice_count) {
+ assert(!"invalid constant buffer offset");
+ offset = 15 * slice_count;
+ }
+
+ if (offset > end) {
+ assert(!size);
+ offset = end;
+ }
+
+ /* the valid range of buffer size is [0KB, 15KB] */
+ size = end - offset;
+ if (size > 15 * slice_count) {
+ assert(!"invalid constant buffer size");
+ size = 15 * slice_count;
+ }
+
+ assert(offset % slice_count == 0 && size % slice_count == 0);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = cmd | (cmd_len - 2);
+ dw[1] = offset << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
+ size;
+}
+
+static inline void
+gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(struct ilo_builder *builder,
+ int offset, int size)
+{
+ gen7_3dstate_push_constant_alloc(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_VS, offset, size);
+}
+
+static inline void
+gen7_3DSTATE_PUSH_CONSTANT_ALLOC_HS(struct ilo_builder *builder,
+ int offset, int size)
+{
+ gen7_3dstate_push_constant_alloc(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_HS, offset, size);
+}
+
+static inline void
+gen7_3DSTATE_PUSH_CONSTANT_ALLOC_DS(struct ilo_builder *builder,
+ int offset, int size)
+{
+ gen7_3dstate_push_constant_alloc(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_DS, offset, size);
+}
+
+static inline void
+gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(struct ilo_builder *builder,
+ int offset, int size)
+{
+ gen7_3dstate_push_constant_alloc(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_GS, offset, size);
+}
+
+static inline void
+gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(struct ilo_builder *builder,
+ int offset, int size)
+{
+ gen7_3dstate_push_constant_alloc(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_PS, offset, size);
+}
+
+static inline void
+gen7_3dstate_urb(struct ilo_builder *builder,
+ int subop, int offset, int size,
+ int entry_size)
+{
+ const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
+ GEN6_RENDER_SUBTYPE_3D |
+ subop;
+ const uint8_t cmd_len = 2;
+ const int row_size = 64; /* 512 bits */
+ int alloc_size, num_entries, min_entries, max_entries;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ /* VS, HS, DS, and GS variants */
+ assert(subop >= GEN7_RENDER_OPCODE_3DSTATE_URB_VS &&
+ subop <= GEN7_RENDER_OPCODE_3DSTATE_URB_GS);
+
+ /* in multiples of 8KB */
+ assert(offset % 8192 == 0);
+ offset /= 8192;
+
+ /* in multiple of 512-bit rows */
+ alloc_size = (entry_size + row_size - 1) / row_size;
+ if (!alloc_size)
+ alloc_size = 1;
+
+ /*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 34:
+ *
+ * "VS URB Entry Allocation Size equal to 4(5 512-bit URB rows) may
+ * cause performance to decrease due to banking in the URB. Element
+ * sizes of 16 to 20 should be programmed with six 512-bit URB rows."
+ */
+ if (subop == GEN7_RENDER_OPCODE_3DSTATE_URB_VS && alloc_size == 5)
+ alloc_size = 6;
+
+ /* in multiples of 8 */
+ num_entries = (size / row_size / alloc_size) & ~7;
+
+ switch (subop) {
+ case GEN7_RENDER_OPCODE_3DSTATE_URB_VS:
+ switch (ilo_dev_gen(builder->dev)) {
+ case ILO_GEN(8):
+ max_entries = 2560;
+ min_entries = 64;
+ break;
+ case ILO_GEN(7.5):
+ max_entries = (builder->dev->gt >= 2) ? 1664 : 640;
+ min_entries = (builder->dev->gt >= 2) ? 64 : 32;
+ break;
+ case ILO_GEN(7):
+ default:
+ max_entries = (builder->dev->gt == 2) ? 704 : 512;
+ min_entries = 32;
+ break;
+ }
+
+ assert(num_entries >= min_entries);
+ if (num_entries > max_entries)
+ num_entries = max_entries;
+ break;
+ case GEN7_RENDER_OPCODE_3DSTATE_URB_HS:
+ max_entries = (builder->dev->gt == 2) ? 64 : 32;
+ if (num_entries > max_entries)
+ num_entries = max_entries;
+ break;
+ case GEN7_RENDER_OPCODE_3DSTATE_URB_DS:
+ if (num_entries)
+ assert(num_entries >= 138);
+ break;
+ case GEN7_RENDER_OPCODE_3DSTATE_URB_GS:
+ switch (ilo_dev_gen(builder->dev)) {
+ case ILO_GEN(8):
+ max_entries = 960;
+ break;
+ case ILO_GEN(7.5):
+ max_entries = (builder->dev->gt >= 2) ? 640 : 256;
+ break;
+ case ILO_GEN(7):
+ default:
+ max_entries = (builder->dev->gt == 2) ? 320 : 192;
+ break;
+ }
+
+ if (num_entries > max_entries)
+ num_entries = max_entries;
+ break;
+ default:
+ break;
+ }
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = cmd | (cmd_len - 2);
+ dw[1] = offset << GEN7_URB_DW1_OFFSET__SHIFT |
+ (alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
+ num_entries;
+}
+
+static inline void
+gen7_3DSTATE_URB_VS(struct ilo_builder *builder,
+ int offset, int size, int entry_size)
+{
+ gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_VS,
+ offset, size, entry_size);
+}
+
+static inline void
+gen7_3DSTATE_URB_HS(struct ilo_builder *builder,
+ int offset, int size, int entry_size)
+{
+ gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_HS,
+ offset, size, entry_size);
+}
+
+static inline void
+gen7_3DSTATE_URB_DS(struct ilo_builder *builder,
+ int offset, int size, int entry_size)
+{
+ gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_DS,
+ offset, size, entry_size);
+}
+
+static inline void
+gen7_3DSTATE_URB_GS(struct ilo_builder *builder,
+ int offset, int size, int entry_size)
+{
+ gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_GS,
+ offset, size, entry_size);
+}
+
+static inline void
+gen75_3DSTATE_VF(struct ilo_builder *builder,
+ bool enable_cut_index,
+ uint32_t cut_index)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7.5, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2);
+ if (enable_cut_index)
+ dw[0] |= GEN75_VF_DW0_CUT_INDEX_ENABLE;
+
+ dw[1] = cut_index;
+}
+
+static inline void
+gen6_3DSTATE_VF_STATISTICS(struct ilo_builder *builder,
+ bool enable)
+{
+ const uint8_t cmd_len = 1;
+ const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, 3DSTATE_VF_STATISTICS) |
+ enable;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ ilo_builder_batch_write(builder, cmd_len, &dw0);
+}
+
+/**
+ * Translate a pipe primitive type to the matching hardware primitive type.
+ */
+static inline int
+gen6_3d_translate_pipe_prim(unsigned prim)
+{
+ static const int prim_mapping[ILO_PRIM_MAX] = {
+ [PIPE_PRIM_POINTS] = GEN6_3DPRIM_POINTLIST,
+ [PIPE_PRIM_LINES] = GEN6_3DPRIM_LINELIST,
+ [PIPE_PRIM_LINE_LOOP] = GEN6_3DPRIM_LINELOOP,
+ [PIPE_PRIM_LINE_STRIP] = GEN6_3DPRIM_LINESTRIP,
+ [PIPE_PRIM_TRIANGLES] = GEN6_3DPRIM_TRILIST,
+ [PIPE_PRIM_TRIANGLE_STRIP] = GEN6_3DPRIM_TRISTRIP,
+ [PIPE_PRIM_TRIANGLE_FAN] = GEN6_3DPRIM_TRIFAN,
+ [PIPE_PRIM_QUADS] = GEN6_3DPRIM_QUADLIST,
+ [PIPE_PRIM_QUAD_STRIP] = GEN6_3DPRIM_QUADSTRIP,
+ [PIPE_PRIM_POLYGON] = GEN6_3DPRIM_POLYGON,
+ [PIPE_PRIM_LINES_ADJACENCY] = GEN6_3DPRIM_LINELIST_ADJ,
+ [PIPE_PRIM_LINE_STRIP_ADJACENCY] = GEN6_3DPRIM_LINESTRIP_ADJ,
+ [PIPE_PRIM_TRIANGLES_ADJACENCY] = GEN6_3DPRIM_TRILIST_ADJ,
+ [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY] = GEN6_3DPRIM_TRISTRIP_ADJ,
+ [ILO_PRIM_RECTANGLES] = GEN6_3DPRIM_RECTLIST,
+ };
+
+ assert(prim_mapping[prim]);
+
+ return prim_mapping[prim];
+}
+
+static inline void
+gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, unsigned pipe_prim)
+{
+ const uint8_t cmd_len = 2;
+ const int prim = gen6_3d_translate_pipe_prim(pipe_prim);
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_TOPOLOGY) | (cmd_len - 2);
+ dw[1] = prim;
+}
+
+static inline void
+gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder,
+ int vb_index, uint32_t step_rate)
+{
+ const uint8_t cmd_len = 3;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_INSTANCING) | (cmd_len - 2);
+ dw[1] = vb_index;
+ if (step_rate)
+ dw[1] |= GEN8_INSTANCING_DW1_ENABLE;
+ dw[2] = step_rate;
+}
+
+static inline void
+gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
+ bool vid_enable, int vid_ve, int vid_comp,
+ bool iid_enable, int iid_ve, int iid_comp)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_SGVS) | (cmd_len - 2);
+ dw[1] = 0;
+
+ if (iid_enable) {
+ dw[1] |= GEN8_SGVS_DW1_IID_ENABLE |
+ vid_comp << GEN8_SGVS_DW1_IID_VE_COMP__SHIFT |
+ vid_ve << GEN8_SGVS_DW1_IID_VE_INDEX__SHIFT;
+ }
+
+ if (vid_enable) {
+ dw[1] |= GEN8_SGVS_DW1_VID_ENABLE |
+ vid_comp << GEN8_SGVS_DW1_VID_VE_COMP__SHIFT |
+ vid_ve << GEN8_SGVS_DW1_VID_VE_INDEX__SHIFT;
+ }
+}
+
+static inline void
+gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
+ const struct ilo_ve_state *ve,
+ const struct ilo_vb_state *vb)
+{
+ uint8_t cmd_len;
+ uint32_t *dw;
+ unsigned pos, hw_idx;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 82:
+ *
+ * "From 1 to 33 VBs can be specified..."
+ */
+ assert(ve->vb_count <= 33);
+
+ if (!ve->vb_count)
+ return;
+
+ cmd_len = 1 + 4 * ve->vb_count;
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
+ dw++;
+ pos++;
+
+ for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) {
+ const unsigned instance_divisor = ve->instance_divisors[hw_idx];
+ const unsigned pipe_idx = ve->vb_mapping[hw_idx];
+ const struct pipe_vertex_buffer *cso = &vb->states[pipe_idx];
+
+ dw[0] = hw_idx << GEN6_VB_DW0_INDEX__SHIFT;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
+ dw[0] |= builder->mocs << GEN8_VB_DW0_MOCS__SHIFT;
+ else
+ dw[0] |= builder->mocs << GEN6_VB_DW0_MOCS__SHIFT;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
+ dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
+
+ if (instance_divisor)
+ dw[0] |= GEN6_VB_DW0_ACCESS_INSTANCEDATA;
+ else
+ dw[0] |= GEN6_VB_DW0_ACCESS_VERTEXDATA;
+
+ /* use null vb if there is no buffer or the stride is out of range */
+ if (!cso->buffer || cso->stride > 2048) {
+ dw[0] |= GEN6_VB_DW0_IS_NULL;
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ?
+ 0 : instance_divisor;
+
+ continue;
+ }
+
+ dw[0] |= cso->stride << GEN6_VB_DW0_PITCH__SHIFT;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
+ const uint32_t start_offset = cso->buffer_offset;
+
+ ilo_builder_batch_reloc64(builder, pos + 1,
+ buf->bo, start_offset, 0);
+ dw[3] = buf->bo_size;
+ } else {
+ const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
+ const uint32_t start_offset = cso->buffer_offset;
+ const uint32_t end_offset = buf->bo_size - 1;
+
+ dw[3] = instance_divisor;
+
+ ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
+ ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
+ }
+
+ dw += 4;
+ pos += 4;
+ }
+}
+
+/* the user vertex buffer must be uploaded with gen6_user_vertex_buffer() */
+static inline void
+gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
+ uint32_t vb_begin, uint32_t vb_end,
+ uint32_t stride)
+{
+ const struct ilo_builder_writer *bat =
+ &builder->writers[ILO_BUILDER_WRITER_BATCH];
+ const uint8_t cmd_len = 1 + 4;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
+ dw++;
+ pos++;
+
+ /* VERTEX_BUFFER_STATE */
+ dw[0] = 0 << GEN6_VB_DW0_INDEX__SHIFT |
+ GEN6_VB_DW0_ACCESS_VERTEXDATA |
+ stride << GEN6_VB_DW0_PITCH__SHIFT;
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
+ dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
+
+ dw[3] = 0;
+
+ ilo_builder_batch_reloc(builder, pos + 1, bat->bo, vb_begin, 0);
+ ilo_builder_batch_reloc(builder, pos + 2, bat->bo, vb_end, 0);
+}
+
+static inline void
+gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder,
+ const struct ilo_ve_state *ve)
+{
+ uint8_t cmd_len;
+ uint32_t *dw;
+ unsigned i;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 92:
+ *
+ * "At least one VERTEX_ELEMENT_STATE structure must be included."
+ *
+ * From the Sandy Bridge PRM, volume 2 part 1, page 93:
+ *
+ * "Up to 34 (DevSNB+) vertex elements are supported."
+ */
+ assert(ve->count + ve->prepend_nosrc_cso >= 1);
+ assert(ve->count + ve->prepend_nosrc_cso <= 34);
+
+ STATIC_ASSERT(Elements(ve->cso[0].payload) == 2);
+
+ cmd_len = 1 + 2 * (ve->count + ve->prepend_nosrc_cso);
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2);
+ dw++;
+
+ if (ve->prepend_nosrc_cso) {
+ memcpy(dw, ve->nosrc_cso.payload, sizeof(ve->nosrc_cso.payload));
+ dw += 2;
+ }
+
+ for (i = 0; i < ve->count - ve->last_cso_edgeflag; i++) {
+ memcpy(dw, ve->cso[i].payload, sizeof(ve->cso[i].payload));
+ dw += 2;
+ }
+
+ if (ve->last_cso_edgeflag)
+ memcpy(dw, ve->edgeflag_cso.payload, sizeof(ve->edgeflag_cso.payload));
+}
+
+static inline void
+gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
+ const struct ilo_ib_state *ib,
+ bool enable_cut_index)
+{
+ const uint8_t cmd_len = 3;
+ struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
+ uint32_t start_offset, end_offset;
+ int format;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ if (!buf)
+ return;
+
+ /* this is moved to the new 3DSTATE_VF */
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5))
+ assert(!enable_cut_index);
+
+ switch (ib->hw_index_size) {
+ case 4:
+ format = GEN6_IB_DW0_FORMAT_DWORD;
+ break;
+ case 2:
+ format = GEN6_IB_DW0_FORMAT_WORD;
+ break;
+ case 1:
+ format = GEN6_IB_DW0_FORMAT_BYTE;
+ break;
+ default:
+ assert(!"unknown index size");
+ format = GEN6_IB_DW0_FORMAT_BYTE;
+ break;
+ }
+
+ /*
+ * set start_offset to 0 here and adjust pipe_draw_info::start with
+ * ib->draw_start_offset in 3DPRIMITIVE
+ */
+ start_offset = 0;
+ end_offset = buf->bo_size;
+
+ /* end_offset must also be aligned and is inclusive */
+ end_offset -= (end_offset % ib->hw_index_size);
+ end_offset--;
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) |
+ builder->mocs << GEN6_IB_DW0_MOCS__SHIFT |
+ format;
+ if (enable_cut_index)
+ dw[0] |= GEN6_IB_DW0_CUT_INDEX_ENABLE;
+
+ ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
+ ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
+}
+
+static inline void
+gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
+ const struct ilo_ib_state *ib)
+{
+ const uint8_t cmd_len = 5;
+ struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
+ int format;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ if (!buf)
+ return;
+
+ switch (ib->hw_index_size) {
+ case 4:
+ format = GEN8_IB_DW1_FORMAT_DWORD;
+ break;
+ case 2:
+ format = GEN8_IB_DW1_FORMAT_WORD;
+ break;
+ case 1:
+ format = GEN8_IB_DW1_FORMAT_BYTE;
+ break;
+ default:
+ assert(!"unknown index size");
+ format = GEN8_IB_DW1_FORMAT_BYTE;
+ break;
+ }
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2);
+ dw[1] = format |
+ builder->mocs << GEN8_IB_DW1_MOCS__SHIFT;
+ dw[4] = buf->bo_size;
+
+ /* ignore ib->offset here in favor of adjusting 3DPRIMITIVE */
+ ilo_builder_batch_reloc64(builder, pos + 2, buf->bo, 0, 0);
+}
+
+static inline void
+gen6_3DSTATE_VS(struct ilo_builder *builder,
+ const struct ilo_shader_state *vs)
+{
+ const uint8_t cmd_len = 6;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw2, dw4, dw5, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ cso = ilo_shader_get_kernel_cso(vs);
+ dw2 = cso->payload[0];
+ dw4 = cso->payload[1];
+ dw5 = cso->payload[2];
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
+ dw[1] = ilo_shader_get_kernel_offset(vs);
+ dw[2] = dw2;
+ dw[3] = 0; /* scratch */
+ dw[4] = dw4;
+ dw[5] = dw5;
+}
+
+static inline void
+gen8_3DSTATE_VS(struct ilo_builder *builder,
+ const struct ilo_shader_state *vs,
+ uint32_t clip_plane_enable)
+{
+ const uint8_t cmd_len = 9;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw3, dw6, dw7, dw8, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ cso = ilo_shader_get_kernel_cso(vs);
+ dw3 = cso->payload[0];
+ dw6 = cso->payload[1];
+ dw7 = cso->payload[2];
+ dw8 = clip_plane_enable << GEN8_VS_DW8_UCP_CLIP_ENABLES__SHIFT;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
+ dw[1] = ilo_shader_get_kernel_offset(vs);
+ dw[2] = 0;
+ dw[3] = dw3;
+ dw[4] = 0; /* scratch */
+ dw[5] = 0;
+ dw[6] = dw6;
+ dw[7] = dw7;
+ dw[8] = dw8;
+}
+
+static inline void
+gen6_disable_3DSTATE_VS(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 6;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw[4] = 0;
+ dw[5] = 0;
+}
+
+static inline void
+gen7_disable_3DSTATE_HS(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 9 : 7;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw[4] = 0;
+ dw[5] = 0;
+ dw[6] = 0;
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[7] = 0;
+ dw[8] = 0;
+ }
+}
+
+static inline void
+gen7_3DSTATE_TE(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+}
+
+static inline void
+gen7_disable_3DSTATE_DS(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 9 : 6;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw[4] = 0;
+ dw[5] = 0;
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[6] = 0;
+ dw[7] = 0;
+ dw[8] = 0;
+ }
+}
+
+static inline void
+gen6_3DSTATE_GS(struct ilo_builder *builder,
+ const struct ilo_shader_state *gs)
+{
+ const uint8_t cmd_len = 7;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw2, dw4, dw5, dw6, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ cso = ilo_shader_get_kernel_cso(gs);
+ dw2 = cso->payload[0];
+ dw4 = cso->payload[1];
+ dw5 = cso->payload[2];
+ dw6 = cso->payload[3];
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
+ dw[1] = ilo_shader_get_kernel_offset(gs);
+ dw[2] = dw2;
+ dw[3] = 0; /* scratch */
+ dw[4] = dw4;
+ dw[5] = dw5;
+ dw[6] = dw6;
+}
+
+static inline void
+gen6_so_3DSTATE_GS(struct ilo_builder *builder,
+ const struct ilo_shader_state *vs,
+ int verts_per_prim)
+{
+ const uint8_t cmd_len = 7;
+ struct ilo_shader_cso cso;
+ enum ilo_kernel_param param;
+ uint32_t dw2, dw4, dw5, dw6, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ assert(ilo_shader_get_kernel_param(vs, ILO_KERNEL_VS_GEN6_SO));
+
+ switch (verts_per_prim) {
+ case 1:
+ param = ILO_KERNEL_VS_GEN6_SO_POINT_OFFSET;
+ break;
+ case 2:
+ param = ILO_KERNEL_VS_GEN6_SO_LINE_OFFSET;
+ break;
+ default:
+ param = ILO_KERNEL_VS_GEN6_SO_TRI_OFFSET;
+ break;
+ }
+
+ /* cannot use VS's CSO */
+ ilo_gpe_init_gs_cso(builder->dev, vs, &cso);
+ dw2 = cso.payload[0];
+ dw4 = cso.payload[1];
+ dw5 = cso.payload[2];
+ dw6 = cso.payload[3];
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
+ dw[1] = ilo_shader_get_kernel_offset(vs) +
+ ilo_shader_get_kernel_param(vs, param);
+ dw[2] = dw2;
+ dw[3] = 0;
+ dw[4] = dw4;
+ dw[5] = dw5;
+ dw[6] = dw6;
+}
+
+static inline void
+gen6_disable_3DSTATE_GS(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 7;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ /* honor the valid range of URB read length */
+ dw[4] = 1 << GEN6_GS_DW4_URB_READ_LEN__SHIFT;
+ dw[5] = GEN6_GS_DW5_STATISTICS;
+ dw[6] = 0;
+}
+
+static inline void
+gen6_3DSTATE_GS_SVB_INDEX(struct ilo_builder *builder,
+ int index, unsigned svbi,
+ unsigned max_svbi,
+ bool load_vertex_count)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+ assert(index >= 0 && index < 4);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS_SVB_INDEX) | (cmd_len - 2);
+
+ dw[1] = index << GEN6_SVBI_DW1_INDEX__SHIFT;
+ if (load_vertex_count)
+ dw[1] |= GEN6_SVBI_DW1_LOAD_INTERNAL_VERTEX_COUNT;
+
+ dw[2] = svbi;
+ dw[3] = max_svbi;
+}
+
+static inline void
+gen7_3DSTATE_GS(struct ilo_builder *builder,
+ const struct ilo_shader_state *gs)
+{
+ const uint8_t cmd_len = 7;
+ const struct ilo_shader_cso *cso;
+ uint32_t dw2, dw4, dw5, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ cso = ilo_shader_get_kernel_cso(gs);
+ dw2 = cso->payload[0];
+ dw4 = cso->payload[1];
+ dw5 = cso->payload[2];
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
+ dw[1] = ilo_shader_get_kernel_offset(gs);
+ dw[2] = dw2;
+ dw[3] = 0; /* scratch */
+ dw[4] = dw4;
+ dw[5] = dw5;
+ dw[6] = 0;
+}
+
+static inline void
+gen7_disable_3DSTATE_GS(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 10 : 7;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw[4] = 0;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[7] = GEN8_GS_DW7_STATISTICS;
+ dw[8] = 0;
+ dw[9] = 0;
+ } else {
+ dw[5] = GEN7_GS_DW5_STATISTICS;
+ dw[6] = 0;
+ }
+}
+
+static inline void
+gen7_3DSTATE_STREAMOUT(struct ilo_builder *builder,
+ int render_stream,
+ bool render_disable,
+ int vertex_attrib_count,
+ const int *buf_strides)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
+ uint32_t *dw;
+ int buf_mask;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_STREAMOUT) | (cmd_len - 2);
+
+ dw[1] = render_stream << GEN7_SO_DW1_RENDER_STREAM_SELECT__SHIFT;
+ if (render_disable)
+ dw[1] |= GEN7_SO_DW1_RENDER_DISABLE;
+
+ if (buf_strides) {
+ buf_mask = ((bool) buf_strides[3]) << 3 |
+ ((bool) buf_strides[2]) << 2 |
+ ((bool) buf_strides[1]) << 1 |
+ ((bool) buf_strides[0]);
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[3] = buf_strides[1] << 16 | buf_strides[0];
+ dw[4] = buf_strides[3] << 16 | buf_strides[1];
+ }
+ } else {
+ buf_mask = 0;
+ }
+
+ if (buf_mask) {
+ int read_len;
+
+ dw[1] |= GEN7_SO_DW1_SO_ENABLE |
+ GEN7_SO_DW1_STATISTICS;
+ /* API_OPENGL */
+ if (true)
+ dw[1] |= GEN7_SO_DW1_REORDER_TRAILING;
+ if (ilo_dev_gen(builder->dev) < ILO_GEN(8))
+ dw[1] |= buf_mask << GEN7_SO_DW1_BUFFER_ENABLES__SHIFT;
+
+ read_len = (vertex_attrib_count + 1) / 2;
+ if (!read_len)
+ read_len = 1;
+
+ dw[2] = 0 << GEN7_SO_DW2_STREAM3_READ_OFFSET__SHIFT |
+ (read_len - 1) << GEN7_SO_DW2_STREAM3_READ_LEN__SHIFT |
+ 0 << GEN7_SO_DW2_STREAM2_READ_OFFSET__SHIFT |
+ (read_len - 1) << GEN7_SO_DW2_STREAM2_READ_LEN__SHIFT |
+ 0 << GEN7_SO_DW2_STREAM1_READ_OFFSET__SHIFT |
+ (read_len - 1) << GEN7_SO_DW2_STREAM1_READ_LEN__SHIFT |
+ 0 << GEN7_SO_DW2_STREAM0_READ_OFFSET__SHIFT |
+ (read_len - 1) << GEN7_SO_DW2_STREAM0_READ_LEN__SHIFT;
+ } else {
+ dw[2] = 0;
+ }
+}
+
+static inline void
+gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
+ const struct pipe_stream_output_info *so_info)
+{
+ /*
+ * Note that "DWord Length" has 9 bits for this command and the type of
+ * cmd_len cannot be uint8_t.
+ */
+ uint16_t cmd_len;
+ struct {
+ int buf_selects;
+ int decl_count;
+ uint16_t decls[128];
+ } streams[4];
+ unsigned buf_offsets[PIPE_MAX_SO_BUFFERS];
+ int hw_decl_count, i;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ memset(streams, 0, sizeof(streams));
+ memset(buf_offsets, 0, sizeof(buf_offsets));
+
+ for (i = 0; i < so_info->num_outputs; i++) {
+ unsigned decl, st, buf, reg, mask;
+
+ st = so_info->output[i].stream;
+ buf = so_info->output[i].output_buffer;
+
+ /* pad with holes */
+ while (buf_offsets[buf] < so_info->output[i].dst_offset) {
+ int num_dwords;
+
+ num_dwords = so_info->output[i].dst_offset - buf_offsets[buf];
+ if (num_dwords > 4)
+ num_dwords = 4;
+
+ decl = buf << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
+ GEN7_SO_DECL_HOLE_FLAG |
+ ((1 << num_dwords) - 1) << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
+
+ assert(streams[st].decl_count < Elements(streams[st].decls));
+ streams[st].decls[streams[st].decl_count++] = decl;
+ buf_offsets[buf] += num_dwords;
+ }
+ assert(buf_offsets[buf] == so_info->output[i].dst_offset);
+
+ reg = so_info->output[i].register_index;
+ mask = ((1 << so_info->output[i].num_components) - 1) <<
+ so_info->output[i].start_component;
+
+ decl = buf << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
+ reg << GEN7_SO_DECL_REG_INDEX__SHIFT |
+ mask << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
+
+ assert(streams[st].decl_count < Elements(streams[st].decls));
+
+ streams[st].buf_selects |= 1 << buf;
+ streams[st].decls[streams[st].decl_count++] = decl;
+ buf_offsets[buf] += so_info->output[i].num_components;
+ }
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) {
+ hw_decl_count = MAX4(streams[0].decl_count, streams[1].decl_count,
+ streams[2].decl_count, streams[3].decl_count);
+ } else {
+ /*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 201:
+ *
+ * "Errata: All 128 decls for all four streams must be included
+ * whenever this command is issued. The "Num Entries [n]" fields
+ * still contain the actual numbers of valid decls."
+ */
+ hw_decl_count = 128;
+ }
+
+ cmd_len = 3 + 2 * hw_decl_count;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_DECL_LIST) | (cmd_len - 2);
+ dw[1] = streams[3].buf_selects << GEN7_SO_DECL_DW1_STREAM3_BUFFER_SELECTS__SHIFT |
+ streams[2].buf_selects << GEN7_SO_DECL_DW1_STREAM2_BUFFER_SELECTS__SHIFT |
+ streams[1].buf_selects << GEN7_SO_DECL_DW1_STREAM1_BUFFER_SELECTS__SHIFT |
+ streams[0].buf_selects << GEN7_SO_DECL_DW1_STREAM0_BUFFER_SELECTS__SHIFT;
+ dw[2] = streams[3].decl_count << GEN7_SO_DECL_DW2_STREAM3_ENTRY_COUNT__SHIFT |
+ streams[2].decl_count << GEN7_SO_DECL_DW2_STREAM2_ENTRY_COUNT__SHIFT |
+ streams[1].decl_count << GEN7_SO_DECL_DW2_STREAM1_ENTRY_COUNT__SHIFT |
+ streams[0].decl_count << GEN7_SO_DECL_DW2_STREAM0_ENTRY_COUNT__SHIFT;
+ dw += 3;
+
+ for (i = 0; i < hw_decl_count; i++) {
+ dw[0] = streams[1].decls[i] << 16 | streams[0].decls[i];
+ dw[1] = streams[3].decls[i] << 16 | streams[2].decls[i];
+ dw += 2;
+ }
+}
+
+static inline void
+gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index, int stride,
+ const struct pipe_stream_output_target *so_target)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
+ struct ilo_buffer *buf;
+ int start, end;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ buf = ilo_buffer(so_target->buffer);
+
+ /* DWord-aligned */
+ assert(stride % 4 == 0);
+ assert(so_target->buffer_offset % 4 == 0);
+
+ stride &= ~3;
+ start = so_target->buffer_offset & ~3;
+ end = (start + so_target->buffer_size) & ~3;
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
+ dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT |
+ stride;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[1] |= builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
+
+ dw[4] = end - start;
+ dw[5] = 0;
+ dw[6] = 0;
+ dw[7] = 0;
+
+ ilo_builder_batch_reloc64(builder, pos + 2,
+ buf->bo, start, INTEL_RELOC_WRITE);
+ } else {
+ dw[1] |= builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT;
+
+ ilo_builder_batch_reloc(builder, pos + 2,
+ buf->bo, start, INTEL_RELOC_WRITE);
+ ilo_builder_batch_reloc(builder, pos + 3,
+ buf->bo, end, INTEL_RELOC_WRITE);
+ }
+}
+
+static inline void
+gen7_disable_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
+ dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT;
+ dw[2] = 0;
+ dw[3] = 0;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[4] = 0;
+ dw[5] = 0;
+ dw[6] = 0;
+ dw[7] = 0;
+ }
+}
+
+static inline void
+gen6_3DSTATE_BINDING_TABLE_POINTERS(struct ilo_builder *builder,
+ uint32_t vs_binding_table,
+ uint32_t gs_binding_table,
+ uint32_t ps_binding_table)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_BINDING_TABLE_POINTERS) |
+ GEN6_BINDING_TABLE_PTR_DW0_VS_CHANGED |
+ GEN6_BINDING_TABLE_PTR_DW0_GS_CHANGED |
+ GEN6_BINDING_TABLE_PTR_DW0_PS_CHANGED |
+ (cmd_len - 2);
+ dw[1] = vs_binding_table;
+ dw[2] = gs_binding_table;
+ dw[3] = ps_binding_table;
+}
+
+static inline void
+gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct ilo_builder *builder,
+ uint32_t vs_sampler_state,
+ uint32_t gs_sampler_state,
+ uint32_t ps_sampler_state)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLER_STATE_POINTERS) |
+ GEN6_SAMPLER_PTR_DW0_VS_CHANGED |
+ GEN6_SAMPLER_PTR_DW0_GS_CHANGED |
+ GEN6_SAMPLER_PTR_DW0_PS_CHANGED |
+ (cmd_len - 2);
+ dw[1] = vs_sampler_state;
+ dw[2] = gs_sampler_state;
+ dw[3] = ps_sampler_state;
+}
+
+static inline void
+gen7_3dstate_pointer(struct ilo_builder *builder,
+ int subop, uint32_t pointer)
+{
+ const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
+ GEN6_RENDER_SUBTYPE_3D |
+ subop;
+ const uint8_t cmd_len = 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = cmd | (cmd_len - 2);
+ dw[1] = pointer;
+}
+
+static inline void
+gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(struct ilo_builder *builder,
+ uint32_t binding_table)
+{
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_VS,
+ binding_table);
+}
+
+static inline void
+gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(struct ilo_builder *builder,
+ uint32_t binding_table)
+{
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_HS,
+ binding_table);
+}
+
+static inline void
+gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(struct ilo_builder *builder,
+ uint32_t binding_table)
+{
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_DS,
+ binding_table);
+}
+
+static inline void
+gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(struct ilo_builder *builder,
+ uint32_t binding_table)
+{
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_GS,
+ binding_table);
+}
+
+static inline void
+gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(struct ilo_builder *builder,
+ uint32_t sampler_state)
+{
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_VS,
+ sampler_state);
+}
+
+static inline void
+gen7_3DSTATE_SAMPLER_STATE_POINTERS_HS(struct ilo_builder *builder,
+ uint32_t sampler_state)
+{
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_HS,
+ sampler_state);
+}
+
+static inline void
+gen7_3DSTATE_SAMPLER_STATE_POINTERS_DS(struct ilo_builder *builder,
+ uint32_t sampler_state)
+{
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_DS,
+ sampler_state);
+}
+
+static inline void
+gen7_3DSTATE_SAMPLER_STATE_POINTERS_GS(struct ilo_builder *builder,
+ uint32_t sampler_state)
+{
+ gen7_3dstate_pointer(builder,
+ GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_GS,
+ sampler_state);
+}
+
+static inline void
+gen6_3dstate_constant(struct ilo_builder *builder, int subop,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
+ GEN6_RENDER_SUBTYPE_3D |
+ subop;
+ const uint8_t cmd_len = 5;
+ unsigned buf_enabled = 0x0;
+ uint32_t buf_dw[4], *dw;
+ int max_read_length, total_read_length;
+ int i;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ assert(num_bufs <= 4);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 138:
+ *
+ * "(3DSTATE_CONSTANT_VS) The sum of all four read length fields (each
+ * incremented to represent the actual read length) must be less than
+ * or equal to 32"
+ *
+ * From the Sandy Bridge PRM, volume 2 part 1, page 161:
+ *
+ * "(3DSTATE_CONSTANT_GS) The sum of all four read length fields (each
+ * incremented to represent the actual read length) must be less than
+ * or equal to 64"
+ *
+ * From the Sandy Bridge PRM, volume 2 part 1, page 287:
+ *
+ * "(3DSTATE_CONSTANT_PS) The sum of all four read length fields (each
+ * incremented to represent the actual read length) must be less than
+ * or equal to 64"
+ */
+ switch (subop) {
+ case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS:
+ max_read_length = 32;
+ break;
+ case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS:
+ case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS:
+ max_read_length = 64;
+ break;
+ default:
+ assert(!"unknown pcb subop");
+ max_read_length = 0;
+ break;
+ }
+
+ total_read_length = 0;
+ for (i = 0; i < 4; i++) {
+ if (i < num_bufs && sizes[i]) {
+ /* in 256-bit units */
+ const int read_len = (sizes[i] + 31) / 32;
+
+ assert(bufs[i] % 32 == 0);
+ assert(read_len <= 32);
+
+ buf_enabled |= 1 << i;
+ buf_dw[i] = bufs[i] | (read_len - 1);
+
+ total_read_length += read_len;
+ } else {
+ buf_dw[i] = 0;
+ }
+ }
+
+ assert(total_read_length <= max_read_length);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = cmd | (cmd_len - 2) |
+ buf_enabled << GEN6_CONSTANT_DW0_BUFFER_ENABLES__SHIFT |
+ builder->mocs << GEN6_CONSTANT_DW0_MOCS__SHIFT;
+
+ memcpy(&dw[1], buf_dw, sizeof(buf_dw));
+}
+
+static inline void
+gen6_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
+ bufs, sizes, num_bufs);
+}
+
+static inline void
+gen6_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
+ bufs, sizes, num_bufs);
+}
+
+static inline void
+gen7_3dstate_constant(struct ilo_builder *builder,
+ int subop,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
+ GEN6_RENDER_SUBTYPE_3D |
+ subop;
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 11 : 7;
+ uint32_t payload[6], *dw;
+ int total_read_length, i;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ /* VS, HS, DS, GS, and PS variants */
+ assert(subop >= GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS &&
+ subop <= GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS &&
+ subop != GEN6_RENDER_OPCODE_3DSTATE_SAMPLE_MASK);
+
+ assert(num_bufs <= 4);
+
+ payload[0] = 0;
+ payload[1] = 0;
+
+ total_read_length = 0;
+ for (i = 0; i < 4; i++) {
+ int read_len;
+
+ /*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 112:
+ *
+ * "Constant buffers must be enabled in order from Constant Buffer 0
+ * to Constant Buffer 3 within this command. For example, it is
+ * not allowed to enable Constant Buffer 1 by programming a
+ * non-zero value in the VS Constant Buffer 1 Read Length without a
+ * non-zero value in VS Constant Buffer 0 Read Length."
+ */
+ if (i >= num_bufs || !sizes[i]) {
+ for (; i < 4; i++) {
+ assert(i >= num_bufs || !sizes[i]);
+ payload[2 + i] = 0;
+ }
+ break;
+ }
+
+ /* read lengths are in 256-bit units */
+ read_len = (sizes[i] + 31) / 32;
+ /* the lower 5 bits are used for memory object control state */
+ assert(bufs[i] % 32 == 0);
+
+ payload[i / 2] |= read_len << ((i % 2) ? 16 : 0);
+ payload[2 + i] = bufs[i];
+
+ total_read_length += read_len;
+ }
+
+ /*
+ * From the Ivy Bridge PRM, volume 2 part 1, page 113:
+ *
+ * "The sum of all four read length fields must be less than or equal
+ * to the size of 64"
+ */
+ assert(total_read_length <= 64);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = cmd | (cmd_len - 2);
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[1] = payload[0];
+ dw[2] = payload[1];
+ dw[3] = payload[2];
+ dw[4] = 0;
+ dw[5] = payload[3];
+ dw[6] = 0;
+ dw[7] = payload[4];
+ dw[8] = 0;
+ dw[9] = payload[5];
+ dw[10] = 0;
+ } else {
+ payload[2] |= builder->mocs << GEN7_CONSTANT_DW_ADDR_MOCS__SHIFT;
+
+ memcpy(&dw[1], payload, sizeof(payload));
+ }
+}
+
+static inline void
+gen7_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
+ bufs, sizes, num_bufs);
+}
+
+static inline void
+gen7_3DSTATE_CONSTANT_HS(struct ilo_builder *builder,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_HS,
+ bufs, sizes, num_bufs);
+}
+
+static inline void
+gen7_3DSTATE_CONSTANT_DS(struct ilo_builder *builder,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS,
+ bufs, sizes, num_bufs);
+}
+
+static inline void
+gen7_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
+ const uint32_t *bufs, const int *sizes,
+ int num_bufs)
+{
+ gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
+ bufs, sizes, num_bufs);
+}
+
+static inline uint32_t
+gen6_BINDING_TABLE_STATE(struct ilo_builder *builder,
+ const uint32_t *surface_states,
+ int num_surface_states)
+{
+ const int state_align = 32;
+ const int state_len = num_surface_states;
+ uint32_t state_offset, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ /*
+ * From the Sandy Bridge PRM, volume 4 part 1, page 69:
+ *
+ * "It is stored as an array of up to 256 elements..."
+ */
+ assert(num_surface_states <= 256);
+
+ if (!num_surface_states)
+ return 0;
+
+ state_offset = ilo_builder_surface_pointer(builder,
+ ILO_BUILDER_ITEM_BINDING_TABLE, state_align, state_len, &dw);
+ memcpy(dw, surface_states, state_len << 2);
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen6_SURFACE_STATE(struct ilo_builder *builder,
+ const struct ilo_view_surface *surf,
+ bool for_render)
+{
+ int state_align, state_len;
+ uint32_t state_offset, *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ state_align = 64;
+ state_len = 13;
+
+ state_offset = ilo_builder_surface_pointer(builder,
+ ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
+ memcpy(dw, surf->payload, state_len << 2);
+
+ if (surf->bo) {
+ const uint32_t mocs = (surf->scanout) ?
+ (GEN8_MOCS_MT_PTE | GEN8_MOCS_CT_L3) : builder->mocs;
+
+ dw[1] |= mocs << GEN8_SURFACE_DW1_MOCS__SHIFT;
+
+ ilo_builder_surface_reloc64(builder, state_offset, 8, surf->bo,
+ surf->payload[8], (for_render) ? INTEL_RELOC_WRITE : 0);
+ }
+ } else {
+ state_align = 32;
+ state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 8 : 6;
+
+ state_offset = ilo_builder_surface_pointer(builder,
+ ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
+ memcpy(dw, surf->payload, state_len << 2);
+
+ if (surf->bo) {
+ /*
+ * For scanouts, we should not enable caching in LLC. Since we only
+ * enable that on Gen8+, we are fine here.
+ */
+ dw[5] |= builder->mocs << GEN6_SURFACE_DW5_MOCS__SHIFT;
+
+ ilo_builder_surface_reloc(builder, state_offset, 1, surf->bo,
+ surf->payload[1], (for_render) ? INTEL_RELOC_WRITE : 0);
+ }
+ }
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen6_so_SURFACE_STATE(struct ilo_builder *builder,
+ const struct pipe_stream_output_target *so,
+ const struct pipe_stream_output_info *so_info,
+ int so_index)
+{
+ struct ilo_buffer *buf = ilo_buffer(so->buffer);
+ unsigned bo_offset, struct_size;
+ enum pipe_format elem_format;
+ struct ilo_view_surface surf;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 6);
+
+ bo_offset = so->buffer_offset + so_info->output[so_index].dst_offset * 4;
+ struct_size = so_info->stride[so_info->output[so_index].output_buffer] * 4;
+
+ switch (so_info->output[so_index].num_components) {
+ case 1:
+ elem_format = PIPE_FORMAT_R32_FLOAT;
+ break;
+ case 2:
+ elem_format = PIPE_FORMAT_R32G32_FLOAT;
+ break;
+ case 3:
+ elem_format = PIPE_FORMAT_R32G32B32_FLOAT;
+ break;
+ case 4:
+ elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ break;
+ default:
+ assert(!"unexpected SO components length");
+ elem_format = PIPE_FORMAT_R32_FLOAT;
+ break;
+ }
+
+ ilo_gpe_init_view_surface_for_buffer(builder->dev, buf, bo_offset,
+ so->buffer_size, struct_size, elem_format, false, true, &surf);
+
+ return gen6_SURFACE_STATE(builder, &surf, false);
+}
+
+static inline uint32_t
+gen6_SAMPLER_STATE(struct ilo_builder *builder,
+ const struct ilo_sampler_cso * const *samplers,
+ const struct pipe_sampler_view * const *views,
+ const uint32_t *sampler_border_colors,
+ int num_samplers)
+{
+ const int state_align = 32;
+ const int state_len = 4 * num_samplers;
+ uint32_t state_offset, *dw;
+ int i;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ /*
+ * From the Sandy Bridge PRM, volume 4 part 1, page 101:
+ *
+ * "The sampler state is stored as an array of up to 16 elements..."
+ */
+ assert(num_samplers <= 16);
+
+ if (!num_samplers)
+ return 0;
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 132:
+ *
+ * "(Sampler Count of 3DSTATE_VS) Specifies how many samplers (in
+ * multiples of 4) the vertex shader 0 kernel uses. Used only for
+ * prefetching the associated sampler state entries.
+ *
+ * It also applies to other shader stages.
+ */
+ ilo_builder_dynamic_pad_top(builder, 4 * (4 - (num_samplers % 4)));
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_SAMPLER, state_align, state_len, &dw);
+
+ for (i = 0; i < num_samplers; i++) {
+ const struct ilo_sampler_cso *sampler = samplers[i];
+ const struct pipe_sampler_view *view = views[i];
+ const uint32_t border_color = sampler_border_colors[i];
+ uint32_t dw_filter, dw_wrap;
+
+ /* there may be holes */
+ if (!sampler || !view) {
+ /* disabled sampler */
+ dw[0] = 1 << 31;
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw += 4;
+
+ continue;
+ }
+
+ /* determine filter and wrap modes */
+ switch (view->texture->target) {
+ case PIPE_TEXTURE_1D:
+ dw_filter = (sampler->anisotropic) ?
+ sampler->dw_filter_aniso : sampler->dw_filter;
+ dw_wrap = sampler->dw_wrap_1d;
+ break;
+ case PIPE_TEXTURE_3D:
+ /*
+ * From the Sandy Bridge PRM, volume 4 part 1, page 103:
+ *
+ * "Only MAPFILTER_NEAREST and MAPFILTER_LINEAR are supported for
+ * surfaces of type SURFTYPE_3D."
+ */
+ dw_filter = sampler->dw_filter;
+ dw_wrap = sampler->dw_wrap;
+ break;
+ case PIPE_TEXTURE_CUBE:
+ dw_filter = (sampler->anisotropic) ?
+ sampler->dw_filter_aniso : sampler->dw_filter;
+ dw_wrap = sampler->dw_wrap_cube;
+ break;
+ default:
+ dw_filter = (sampler->anisotropic) ?
+ sampler->dw_filter_aniso : sampler->dw_filter;
+ dw_wrap = sampler->dw_wrap;
+ break;
+ }
+
+ dw[0] = sampler->payload[0];
+ dw[1] = sampler->payload[1];
+ assert(!(border_color & 0x1f));
+ dw[2] = border_color;
+ dw[3] = sampler->payload[2];
+
+ dw[0] |= dw_filter;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
+ dw[3] |= dw_wrap;
+ }
+ else {
+ /*
+ * From the Sandy Bridge PRM, volume 4 part 1, page 21:
+ *
+ * "[DevSNB] Errata: Incorrect behavior is observed in cases
+ * where the min and mag mode filters are different and
+ * SurfMinLOD is nonzero. The determination of MagMode uses the
+ * following equation instead of the one in the above
+ * pseudocode: MagMode = (LOD + SurfMinLOD - Base <= 0)"
+ *
+ * As a way to work around that, we set Base to
+ * view->u.tex.first_level.
+ */
+ dw[0] |= view->u.tex.first_level << 22;
+
+ dw[1] |= dw_wrap;
+ }
+
+ dw += 4;
+ }
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder *builder,
+ const struct ilo_sampler_cso *sampler)
+{
+ const int state_align =
+ (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 64 : 32;
+ const int state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 12;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(Elements(sampler->payload) >= 3 + state_len);
+
+ /* see ilo_gpe_init_sampler_cso() */
+ return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
+ state_align, state_len, &sampler->payload[3]);
+}
+
+static inline uint32_t
+gen6_push_constant_buffer(struct ilo_builder *builder,
+ int size, void **pcb)
+{
+ /*
+ * For all VS, GS, FS, and CS push constant buffers, they must be aligned
+ * to 32 bytes, and their sizes are specified in 256-bit units.
+ */
+ const int state_align = 32;
+ const int state_len = align(size, 32) / 4;
+ uint32_t state_offset;
+ char *buf;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_BLOB, state_align, state_len, (uint32_t **) &buf);
+
+ /* zero out the unused range */
+ if (size < state_len * 4)
+ memset(&buf[size], 0, state_len * 4 - size);
+
+ if (pcb)
+ *pcb = buf;
+
+ return state_offset;
+}
+
+static inline uint32_t
+gen6_user_vertex_buffer(struct ilo_builder *builder,
+ int size, const void *vertices)
+{
+ const int state_align = 8;
+ const int state_len = size / 4;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ assert(size % 4 == 0);
+
+ return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
+ state_align, state_len, vertices);
+}
+
+#endif /* ILO_BUILDER_3D_TOP_H */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_BUILDER_BLT_H
+#define ILO_BUILDER_BLT_H
+
+#include "genhw/genhw.h"
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+#include "ilo_builder.h"
+
+enum gen6_blt_mask {
+ GEN6_BLT_MASK_8,
+ GEN6_BLT_MASK_16,
+ GEN6_BLT_MASK_32,
+ GEN6_BLT_MASK_32_LO,
+ GEN6_BLT_MASK_32_HI,
+};
+
+struct gen6_blt_bo {
+ struct intel_bo *bo;
+ uint32_t offset;
+ int16_t pitch;
+};
+
+struct gen6_blt_xy_bo {
+ struct intel_bo *bo;
+ uint32_t offset;
+ int16_t pitch;
+
+ enum gen_surface_tiling tiling;
+ int16_t x, y;
+};
+
+/*
+ * From the Sandy Bridge PRM, volume 1 part 5, page 7:
+ *
+ * "The BLT engine is capable of transferring very large quantities of
+ * graphics data. Any graphics data read from and written to the
+ * destination is permitted to represent a number of pixels that occupies
+ * up to 65,536 scan lines and up to 32,768 bytes per scan line at the
+ * destination. The maximum number of pixels that may be represented per
+ * scan line's worth of graphics data depends on the color depth."
+ */
+static const int gen6_blt_max_bytes_per_scanline = 32768;
+static const int gen6_blt_max_scanlines = 65536;
+
+static inline uint32_t
+gen6_blt_translate_value_mask(enum gen6_blt_mask value_mask)
+{
+ switch (value_mask) {
+ case GEN6_BLT_MASK_8: return GEN6_BLITTER_BR13_FORMAT_8;
+ case GEN6_BLT_MASK_16: return GEN6_BLITTER_BR13_FORMAT_565;
+ default: return GEN6_BLITTER_BR13_FORMAT_8888;
+ }
+}
+
+static inline uint32_t
+gen6_blt_translate_value_cpp(enum gen6_blt_mask value_mask)
+{
+ switch (value_mask) {
+ case GEN6_BLT_MASK_8: return 1;
+ case GEN6_BLT_MASK_16: return 2;
+ default: return 4;
+ }
+}
+
+static inline uint32_t
+gen6_blt_translate_write_mask(enum gen6_blt_mask write_mask)
+{
+ switch (write_mask) {
+ case GEN6_BLT_MASK_32: return GEN6_BLITTER_BR00_WRITE_RGB |
+ GEN6_BLITTER_BR00_WRITE_A;
+ case GEN6_BLT_MASK_32_LO: return GEN6_BLITTER_BR00_WRITE_RGB;
+ case GEN6_BLT_MASK_32_HI: return GEN6_BLITTER_BR00_WRITE_A;
+ default: return 0;
+ }
+}
+
+static inline void
+gen6_COLOR_BLT(struct ilo_builder *builder,
+ const struct gen6_blt_bo *dst, uint32_t pattern,
+ uint16_t width, uint16_t height, uint8_t rop,
+ enum gen6_blt_mask value_mask,
+ enum gen6_blt_mask write_mask)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
+ const int cpp = gen6_blt_translate_value_cpp(value_mask);
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(width < gen6_blt_max_bytes_per_scanline);
+ assert(height < gen6_blt_max_scanlines);
+ /* offsets are naturally aligned and pitches are dword-aligned */
+ assert(dst->offset % cpp == 0 && dst->pitch % 4 == 0);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_BLITTER_CMD(COLOR_BLT) |
+ gen6_blt_translate_write_mask(write_mask) |
+ (cmd_len - 2);
+ dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
+ gen6_blt_translate_value_mask(value_mask) |
+ dst->pitch;
+ dw[2] = height << 16 | width;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[5] = pattern;
+
+ ilo_builder_batch_reloc64(builder, pos + 3,
+ dst->bo, dst->offset, INTEL_RELOC_WRITE);
+ } else {
+ dw[4] = pattern;
+
+ ilo_builder_batch_reloc(builder, pos + 3,
+ dst->bo, dst->offset, INTEL_RELOC_WRITE);
+ }
+}
+
+static inline void
+gen6_XY_COLOR_BLT(struct ilo_builder *builder,
+ const struct gen6_blt_xy_bo *dst, uint32_t pattern,
+ uint16_t width, uint16_t height, uint8_t rop,
+ enum gen6_blt_mask value_mask,
+ enum gen6_blt_mask write_mask)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 7 : 6;
+ const int cpp = gen6_blt_translate_value_cpp(value_mask);
+ int dst_align = 4, dst_pitch_shift = 0;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(width * cpp < gen6_blt_max_bytes_per_scanline);
+ assert(height < gen6_blt_max_scanlines);
+ /* INT16_MAX */
+ assert(dst->x + width <= 32767 && dst->y + height <= 32767);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_BLITTER_CMD(XY_COLOR_BLT) |
+ gen6_blt_translate_write_mask(write_mask) |
+ (cmd_len - 2);
+
+ if (dst->tiling != GEN6_TILING_NONE) {
+ dw[0] |= GEN6_BLITTER_BR00_DST_TILED;
+
+ assert(dst->tiling == GEN6_TILING_X || dst->tiling == GEN6_TILING_Y);
+ dst_align = (dst->tiling == GEN6_TILING_Y) ? 128 : 512;
+ /* in dwords when tiled */
+ dst_pitch_shift = 2;
+ }
+
+ assert(dst->offset % dst_align == 0 && dst->pitch % dst_align == 0);
+
+ dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
+ gen6_blt_translate_value_mask(value_mask) |
+ dst->pitch >> dst_pitch_shift;
+ dw[2] = dst->y << 16 | dst->x;
+ dw[3] = (dst->y + height) << 16 | (dst->x + width);
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[6] = pattern;
+
+ ilo_builder_batch_reloc64(builder, pos + 4,
+ dst->bo, dst->offset, INTEL_RELOC_WRITE);
+ } else {
+ dw[5] = pattern;
+
+ ilo_builder_batch_reloc(builder, pos + 4,
+ dst->bo, dst->offset, INTEL_RELOC_WRITE);
+ }
+}
+
+static inline void
+gen6_SRC_COPY_BLT(struct ilo_builder *builder,
+ const struct gen6_blt_bo *dst,
+ const struct gen6_blt_bo *src,
+ uint16_t width, uint16_t height, uint8_t rop,
+ enum gen6_blt_mask value_mask,
+ enum gen6_blt_mask write_mask)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 6;
+ const int cpp = gen6_blt_translate_value_cpp(value_mask);
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(width < gen6_blt_max_bytes_per_scanline);
+ assert(height < gen6_blt_max_scanlines);
+ /* offsets are naturally aligned and pitches are dword-aligned */
+ assert(dst->offset % cpp == 0 && dst->pitch % 4 == 0);
+ assert(src->offset % cpp == 0 && src->pitch % 4 == 0);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_BLITTER_CMD(SRC_COPY_BLT) |
+ gen6_blt_translate_write_mask(write_mask) |
+ (cmd_len - 2);
+ dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
+ gen6_blt_translate_value_mask(value_mask) |
+ dst->pitch;
+ dw[2] = height << 16 | width;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[5] = src->pitch;
+
+ ilo_builder_batch_reloc64(builder, pos + 3,
+ dst->bo, dst->offset, INTEL_RELOC_WRITE);
+ ilo_builder_batch_reloc64(builder, pos + 6, src->bo, src->offset, 0);
+ } else {
+ dw[4] = src->pitch;
+
+ ilo_builder_batch_reloc(builder, pos + 3,
+ dst->bo, dst->offset, INTEL_RELOC_WRITE);
+ ilo_builder_batch_reloc(builder, pos + 5, src->bo, src->offset, 0);
+ }
+}
+
+static inline void
+gen6_XY_SRC_COPY_BLT(struct ilo_builder *builder,
+ const struct gen6_blt_xy_bo *dst,
+ const struct gen6_blt_xy_bo *src,
+ uint16_t width, uint16_t height, uint8_t rop,
+ enum gen6_blt_mask value_mask,
+ enum gen6_blt_mask write_mask)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 10 : 8;
+ const int cpp = gen6_blt_translate_value_cpp(value_mask);
+ int dst_align = 4, dst_pitch_shift = 0;
+ int src_align = 4, src_pitch_shift = 0;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(width * cpp < gen6_blt_max_bytes_per_scanline);
+ assert(height < gen6_blt_max_scanlines);
+ /* INT16_MAX */
+ assert(dst->x + width <= 32767 && dst->y + height <= 32767);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_BLITTER_CMD(XY_SRC_COPY_BLT) |
+ gen6_blt_translate_write_mask(write_mask) |
+ (cmd_len - 2);
+
+ if (dst->tiling != GEN6_TILING_NONE) {
+ dw[0] |= GEN6_BLITTER_BR00_DST_TILED;
+
+ assert(dst->tiling == GEN6_TILING_X || dst->tiling == GEN6_TILING_Y);
+ dst_align = (dst->tiling == GEN6_TILING_Y) ? 128 : 512;
+ /* in dwords when tiled */
+ dst_pitch_shift = 2;
+ }
+
+ if (src->tiling != GEN6_TILING_NONE) {
+ dw[0] |= GEN6_BLITTER_BR00_SRC_TILED;
+
+ assert(src->tiling == GEN6_TILING_X || src->tiling == GEN6_TILING_Y);
+ src_align = (src->tiling == GEN6_TILING_Y) ? 128 : 512;
+ /* in dwords when tiled */
+ src_pitch_shift = 2;
+ }
+
+ assert(dst->offset % dst_align == 0 && dst->pitch % dst_align == 0);
+ assert(src->offset % src_align == 0 && src->pitch % src_align == 0);
+
+ dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
+ gen6_blt_translate_value_mask(value_mask) |
+ dst->pitch >> dst_pitch_shift;
+ dw[2] = dst->y << 16 | dst->x;
+ dw[3] = (dst->y + height) << 16 | (dst->x + width);
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[6] = src->y << 16 | src->x;
+ dw[7] = src->pitch >> src_pitch_shift;
+
+ ilo_builder_batch_reloc64(builder, pos + 4,
+ dst->bo, dst->offset, INTEL_RELOC_WRITE);
+ ilo_builder_batch_reloc64(builder, pos + 8, src->bo, src->offset, 0);
+ } else {
+ dw[5] = src->y << 16 | src->x;
+ dw[6] = src->pitch >> src_pitch_shift;
+
+ ilo_builder_batch_reloc(builder, pos + 4,
+ dst->bo, dst->offset, INTEL_RELOC_WRITE);
+ ilo_builder_batch_reloc(builder, pos + 7, src->bo, src->offset, 0);
+ }
+}
+
+#endif /* ILO_BUILDER_BLT_H */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "genhw/genhw.h"
+#include "../shader/toy_compiler.h"
+
+#include "intel_winsys.h"
+#include "ilo_builder.h"
+
+static const uint32_t *
+writer_pointer(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ unsigned offset)
+{
+ const struct ilo_builder_writer *writer = &builder->writers[which];
+ return (const uint32_t *) ((const char *) writer->ptr + offset);
+}
+
+static uint32_t _util_printf_format(5, 6)
+writer_dw(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ unsigned offset, unsigned dw_index,
+ const char *format, ...)
+{
+ const uint32_t *dw = writer_pointer(builder, which, offset);
+ va_list ap;
+ char desc[16];
+ int len;
+
+ ilo_printf("0x%08x: 0x%08x: ",
+ offset + (dw_index << 2), dw[dw_index]);
+
+ va_start(ap, format);
+ len = vsnprintf(desc, sizeof(desc), format, ap);
+ va_end(ap);
+
+ if (len >= sizeof(desc)) {
+ len = sizeof(desc) - 1;
+ desc[len] = '\0';
+ }
+
+ if (desc[len - 1] == '\n') {
+ desc[len - 1] = '\0';
+ ilo_printf("%8s: \n", desc);
+ } else {
+ ilo_printf("%8s: ", desc);
+ }
+
+ return dw[dw_index];
+}
+
+static void
+writer_decode_blob(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t);
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i += 4) {
+ const uint32_t *dw = writer_pointer(builder, which, offset);
+
+ writer_dw(builder, which, offset, 0, "BLOB%d", i / 4);
+
+ switch (count - i) {
+ case 1:
+ ilo_printf("(%10.4f, %10c, %10c, %10c) "
+ "(0x%08x, %10c, %10c, %10c)\n",
+ uif(dw[0]), 'X', 'X', 'X',
+ dw[0], 'X', 'X', 'X');
+ break;
+ case 2:
+ ilo_printf("(%10.4f, %10.4f, %10c, %10c) "
+ "(0x%08x, 0x%08x, %10c, %10c)\n",
+ uif(dw[0]), uif(dw[1]), 'X', 'X',
+ dw[0], dw[1], 'X', 'X');
+ break;
+ case 3:
+ ilo_printf("(%10.4f, %10.4f, %10.4f, %10c) "
+ "(0x%08x, 0x%08x, 0x%08x, %10c)\n",
+ uif(dw[0]), uif(dw[1]), uif(dw[2]), 'X',
+ dw[0], dw[1], dw[2], 'X');
+ break;
+ default:
+ ilo_printf("(%10.4f, %10.4f, %10.4f, %10.4f) "
+ "(0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
+ uif(dw[0]), uif(dw[1]), uif(dw[2]), uif(dw[3]),
+ dw[0], dw[1], dw[2], dw[3]);
+ break;
+ }
+
+ offset += state_size * 4;
+ }
+}
+
+static void
+writer_decode_clip_viewport(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 4;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ uint32_t dw;
+
+ dw = writer_dw(builder, which, offset, 0, "CLIP VP%d", i);
+ ilo_printf("xmin = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 1, "CLIP VP%d", i);
+ ilo_printf("xmax = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 2, "CLIP VP%d", i);
+ ilo_printf("ymin = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 3, "CLIP VP%d", i);
+ ilo_printf("ymax = %f\n", uif(dw));
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_sf_clip_viewport_gen7(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 16;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ uint32_t dw;
+
+ dw = writer_dw(builder, which, offset, 0, "SF_CLIP VP%d", i);
+ ilo_printf("m00 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 1, "SF_CLIP VP%d", i);
+ ilo_printf("m11 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 2, "SF_CLIP VP%d", i);
+ ilo_printf("m22 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 3, "SF_CLIP VP%d", i);
+ ilo_printf("m30 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 4, "SF_CLIP VP%d", i);
+ ilo_printf("m31 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 5, "SF_CLIP VP%d", i);
+ ilo_printf("m32 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 8, "SF_CLIP VP%d", i);
+ ilo_printf("guardband xmin = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 9, "SF_CLIP VP%d", i);
+ ilo_printf("guardband xmax = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 10, "SF_CLIP VP%d", i);
+ ilo_printf("guardband ymin = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 11, "SF_CLIP VP%d", i);
+ ilo_printf("guardband ymax = %f\n", uif(dw));
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw = writer_dw(builder, which, offset, 12, "SF_CLIP VP%d", i);
+ ilo_printf("extent xmin = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 13, "SF_CLIP VP%d", i);
+ ilo_printf("extent xmax = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 14, "SF_CLIP VP%d", i);
+ ilo_printf("extent ymin = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 15, "SF_CLIP VP%d", i);
+ ilo_printf("extent ymax = %f\n", uif(dw));
+ }
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_sf_viewport_gen6(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 8;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ uint32_t dw;
+
+ dw = writer_dw(builder, which, offset, 0, "SF VP%d", i);
+ ilo_printf("m00 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 1, "SF VP%d", i);
+ ilo_printf("m11 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 2, "SF VP%d", i);
+ ilo_printf("m22 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 3, "SF VP%d", i);
+ ilo_printf("m30 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 4, "SF VP%d", i);
+ ilo_printf("m31 = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 5, "SF VP%d", i);
+ ilo_printf("m32 = %f\n", uif(dw));
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_sf_viewport(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
+ writer_decode_sf_clip_viewport_gen7(builder, which, item);
+ else
+ writer_decode_sf_viewport_gen6(builder, which, item);
+}
+
+static void
+writer_decode_scissor_rect(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 2;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ uint32_t dw;
+
+ dw = writer_dw(builder, which, offset, 0, "SCISSOR%d", i);
+ ilo_printf("xmin %d, ymin %d\n",
+ GEN_EXTRACT(dw, GEN6_SCISSOR_DW0_MIN_X),
+ GEN_EXTRACT(dw, GEN6_SCISSOR_DW0_MIN_Y));
+
+ dw = writer_dw(builder, which, offset, 1, "SCISSOR%d", i);
+ ilo_printf("xmax %d, ymax %d\n",
+ GEN_EXTRACT(dw, GEN6_SCISSOR_DW1_MAX_X),
+ GEN_EXTRACT(dw, GEN6_SCISSOR_DW1_MAX_Y));
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_cc_viewport(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 2;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ uint32_t dw;
+
+ dw = writer_dw(builder, which, offset, 0, "CC VP%d", i);
+ ilo_printf("min_depth = %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, offset, 1, "CC VP%d", i);
+ ilo_printf("max_depth = %f\n", uif(dw));
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_color_calc(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ uint32_t dw;
+
+ dw = writer_dw(builder, which, item->offset, 0, "CC");
+ ilo_printf("alpha test format %s, round disable %d, "
+ "stencil ref %d, bf stencil ref %d\n",
+ GEN_EXTRACT(dw, GEN6_CC_DW0_ALPHATEST) ? "FLOAT32" : "UNORM8",
+ (bool) (dw & GEN6_CC_DW0_ROUND_DISABLE_DISABLE),
+ GEN_EXTRACT(dw, GEN6_CC_DW0_STENCIL0_REF),
+ GEN_EXTRACT(dw, GEN6_CC_DW0_STENCIL1_REF));
+
+ writer_dw(builder, which, item->offset, 1, "CC\n");
+
+ dw = writer_dw(builder, which, item->offset, 2, "CC");
+ ilo_printf("constant red %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, item->offset, 3, "CC");
+ ilo_printf("constant green %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, item->offset, 4, "CC");
+ ilo_printf("constant blue %f\n", uif(dw));
+
+ dw = writer_dw(builder, which, item->offset, 5, "CC");
+ ilo_printf("constant alpha %f\n", uif(dw));
+}
+
+static void
+writer_decode_depth_stencil(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ uint32_t dw;
+
+ dw = writer_dw(builder, which, item->offset, 0, "D_S");
+ ilo_printf("stencil %sable, func %d, write %sable\n",
+ (dw & GEN6_ZS_DW0_STENCIL_TEST_ENABLE) ? "en" : "dis",
+ GEN_EXTRACT(dw, GEN6_ZS_DW0_STENCIL0_FUNC),
+ (dw & GEN6_ZS_DW0_STENCIL_WRITE_ENABLE) ? "en" : "dis");
+
+ dw = writer_dw(builder, which, item->offset, 1, "D_S");
+ ilo_printf("stencil test mask 0x%x, write mask 0x%x\n",
+ GEN_EXTRACT(dw, GEN6_ZS_DW1_STENCIL0_VALUEMASK),
+ GEN_EXTRACT(dw, GEN6_ZS_DW1_STENCIL0_WRITEMASK));
+
+ dw = writer_dw(builder, which, item->offset, 2, "D_S");
+ ilo_printf("depth test %sable, func %d, write %sable\n",
+ (dw & GEN6_ZS_DW2_DEPTH_TEST_ENABLE) ? "en" : "dis",
+ GEN_EXTRACT(dw, GEN6_ZS_DW2_DEPTH_FUNC),
+ (dw & GEN6_ZS_DW2_DEPTH_WRITE_ENABLE) ? "en" : "dis");
+}
+
+static void
+writer_decode_blend(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 2;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ writer_dw(builder, which, offset, 0, "BLEND\n");
+ offset += 4;
+ }
+
+ for (i = 0; i < count; i++) {
+ writer_dw(builder, which, offset, 0, "BLEND%d\n", i);
+ writer_dw(builder, which, offset, 1, "BLEND%d\n", i);
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_sampler(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 4;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ writer_dw(builder, which, offset, 0, "WM SAMP%d", i);
+ ilo_printf("filtering\n");
+
+ writer_dw(builder, which, offset, 1, "WM SAMP%d", i);
+ ilo_printf("wrapping, lod\n");
+
+ writer_dw(builder, which, offset, 2, "WM SAMP%d", i);
+ ilo_printf("default color pointer\n");
+
+ writer_dw(builder, which, offset, 3, "WM SAMP%d", i);
+ ilo_printf("chroma key, aniso\n");
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_interface_descriptor(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 8;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ writer_dw(builder, which, offset, 0, "IDRT[%d]", i);
+ ilo_printf("kernel\n");
+
+ writer_dw(builder, which, offset, 1, "IDRT[%d]", i);
+ ilo_printf("spf, fp mode\n");
+
+ writer_dw(builder, which, offset, 2, "IDRT[%d]", i);
+ ilo_printf("sampler\n");
+
+ writer_dw(builder, which, offset, 3, "IDRT[%d]", i);
+ ilo_printf("binding table\n");
+
+ writer_dw(builder, which, offset, 4, "IDRT[%d]", i);
+ ilo_printf("curbe read len\n");
+
+ writer_dw(builder, which, offset, 5, "IDRT[%d]", i);
+ ilo_printf("rounding mode, slm size\n");
+
+ writer_dw(builder, which, offset, 6, "IDRT[%d]", i);
+ ilo_printf("cross-thread curbe read len\n");
+
+ writer_dw(builder, which, offset, 7, "IDRT[%d]", i);
+ ilo_printf("mbz\n");
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_surface_gen7(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ uint32_t dw;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw = writer_dw(builder, which, item->offset, 0, "SURF");
+ ilo_printf("type 0x%x, format 0x%x, tiling %d, %s array\n",
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW0_TYPE),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW0_FORMAT),
+ GEN_EXTRACT(dw, GEN8_SURFACE_DW0_TILING),
+ (dw & GEN7_SURFACE_DW0_IS_ARRAY) ? "is" : "not");
+
+ writer_dw(builder, which, item->offset, 1, "SURF");
+ ilo_printf("qpitch\n");
+ } else {
+ dw = writer_dw(builder, which, item->offset, 0, "SURF");
+ ilo_printf("type 0x%x, format 0x%x, tiling %d, %s array\n",
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW0_TYPE),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW0_FORMAT),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW0_TILING),
+ (dw & GEN7_SURFACE_DW0_IS_ARRAY) ? "is" : "not");
+
+ writer_dw(builder, which, item->offset, 1, "SURF");
+ ilo_printf("offset\n");
+ }
+
+ dw = writer_dw(builder, which, item->offset, 2, "SURF");
+ ilo_printf("%dx%d size\n",
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW2_WIDTH),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW2_HEIGHT));
+
+ dw = writer_dw(builder, which, item->offset, 3, "SURF");
+ ilo_printf("depth %d, pitch %d\n",
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW3_DEPTH),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW3_PITCH));
+
+ dw = writer_dw(builder, which, item->offset, 4, "SURF");
+ ilo_printf("min array element %d, array extent %d\n",
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW4_MIN_ARRAY_ELEMENT),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW4_RT_VIEW_EXTENT));
+
+ dw = writer_dw(builder, which, item->offset, 5, "SURF");
+ ilo_printf("mip base %d, mips %d, x,y offset: %d,%d\n",
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW5_MIN_LOD),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW5_MIP_COUNT_LOD),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW5_X_OFFSET),
+ GEN_EXTRACT(dw, GEN7_SURFACE_DW5_Y_OFFSET));
+
+ writer_dw(builder, which, item->offset, 6, "SURF\n");
+ writer_dw(builder, which, item->offset, 7, "SURF\n");
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ writer_dw(builder, which, item->offset, 8, "SURF\n");
+ writer_dw(builder, which, item->offset, 9, "SURF\n");
+ writer_dw(builder, which, item->offset, 10, "SURF\n");
+ writer_dw(builder, which, item->offset, 11, "SURF\n");
+ writer_dw(builder, which, item->offset, 12, "SURF\n");
+ }
+}
+
+static void
+writer_decode_surface_gen6(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ uint32_t dw;
+
+ dw = writer_dw(builder, which, item->offset, 0, "SURF");
+ ilo_printf("type 0x%x, format 0x%x\n",
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW0_TYPE),
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW0_FORMAT));
+
+ writer_dw(builder, which, item->offset, 1, "SURF");
+ ilo_printf("offset\n");
+
+ dw = writer_dw(builder, which, item->offset, 2, "SURF");
+ ilo_printf("%dx%d size, %d mips\n",
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW2_WIDTH),
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW2_HEIGHT),
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW2_MIP_COUNT_LOD));
+
+ dw = writer_dw(builder, which, item->offset, 3, "SURF");
+ ilo_printf("pitch %d, tiling %d\n",
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW3_PITCH),
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW3_TILING));
+
+ dw = writer_dw(builder, which, item->offset, 4, "SURF");
+ ilo_printf("mip base %d\n",
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW4_MIN_LOD));
+
+ dw = writer_dw(builder, which, item->offset, 5, "SURF");
+ ilo_printf("x,y offset: %d,%d\n",
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW5_X_OFFSET),
+ GEN_EXTRACT(dw, GEN6_SURFACE_DW5_Y_OFFSET));
+}
+
+static void
+writer_decode_surface(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
+ writer_decode_surface_gen7(builder, which, item);
+ else
+ writer_decode_surface_gen6(builder, which, item);
+}
+
+static void
+writer_decode_binding_table(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const unsigned state_size = sizeof(uint32_t) * 1;
+ const unsigned count = item->size / state_size;
+ unsigned offset = item->offset;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ writer_dw(builder, which, offset, 0, "BIND");
+ ilo_printf("BINDING_TABLE_STATE[%d]\n", i);
+
+ offset += state_size;
+ }
+}
+
+static void
+writer_decode_kernel(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item)
+{
+ const void *kernel;
+
+ ilo_printf("0x%08x:\n", item->offset);
+ kernel = (const void *) writer_pointer(builder, which, item->offset);
+ toy_compiler_disassemble(builder->dev, kernel, item->size, true);
+}
+
+static const struct {
+ void (*func)(const struct ilo_builder *builder,
+ enum ilo_builder_writer_type which,
+ const struct ilo_builder_item *item);
+} writer_decode_table[ILO_BUILDER_ITEM_COUNT] = {
+ [ILO_BUILDER_ITEM_BLOB] = { writer_decode_blob },
+ [ILO_BUILDER_ITEM_CLIP_VIEWPORT] = { writer_decode_clip_viewport },
+ [ILO_BUILDER_ITEM_SF_VIEWPORT] = { writer_decode_sf_viewport },
+ [ILO_BUILDER_ITEM_SCISSOR_RECT] = { writer_decode_scissor_rect },
+ [ILO_BUILDER_ITEM_CC_VIEWPORT] = { writer_decode_cc_viewport },
+ [ILO_BUILDER_ITEM_COLOR_CALC] = { writer_decode_color_calc },
+ [ILO_BUILDER_ITEM_DEPTH_STENCIL] = { writer_decode_depth_stencil },
+ [ILO_BUILDER_ITEM_BLEND] = { writer_decode_blend },
+ [ILO_BUILDER_ITEM_SAMPLER] = { writer_decode_sampler },
+ [ILO_BUILDER_ITEM_INTERFACE_DESCRIPTOR] = { writer_decode_interface_descriptor },
+ [ILO_BUILDER_ITEM_SURFACE] = { writer_decode_surface },
+ [ILO_BUILDER_ITEM_BINDING_TABLE] = { writer_decode_binding_table },
+ [ILO_BUILDER_ITEM_KERNEL] = { writer_decode_kernel },
+};
+
+static void
+ilo_builder_writer_decode_items(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+ int i;
+
+ if (!writer->item_used)
+ return;
+
+ writer->ptr = intel_bo_map(writer->bo, false);
+ if (!writer->ptr)
+ return;
+
+ for (i = 0; i < writer->item_used; i++) {
+ const struct ilo_builder_item *item = &writer->items[i];
+
+ writer_decode_table[item->type].func(builder, which, item);
+ }
+
+ intel_bo_unmap(writer->bo);
+ writer->ptr = NULL;
+}
+
+static void
+ilo_builder_writer_decode(struct ilo_builder *builder,
+ enum ilo_builder_writer_type which)
+{
+ struct ilo_builder_writer *writer = &builder->writers[which];
+
+ assert(writer->bo && !writer->ptr);
+
+ switch (which) {
+ case ILO_BUILDER_WRITER_BATCH:
+ ilo_printf("decoding batch buffer: %d bytes\n", writer->used);
+ if (writer->used)
+ intel_winsys_decode_bo(builder->winsys, writer->bo, writer->used);
+
+ ilo_printf("decoding dynamic/surface buffer: %d states\n",
+ writer->item_used);
+ ilo_builder_writer_decode_items(builder, which);
+ break;
+ case ILO_BUILDER_WRITER_INSTRUCTION:
+ if (true) {
+ ilo_printf("skipping instruction buffer: %d kernels\n",
+ writer->item_used);
+ } else {
+ ilo_printf("decoding instruction buffer: %d kernels\n",
+ writer->item_used);
+
+ ilo_builder_writer_decode_items(builder, which);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Decode the builder according to the recorded items. This can be called
+ * only after a successful ilo_builder_end().
+ */
+void
+ilo_builder_decode(struct ilo_builder *builder)
+{
+ int i;
+
+ assert(!builder->unrecoverable_error);
+
+ for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++)
+ ilo_builder_writer_decode(builder, i);
+}
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_BUILDER_MEDIA_H
+#define ILO_BUILDER_MEDIA_H
+
+#include "genhw/genhw.h"
+#include "../ilo_shader.h"
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+#include "ilo_builder.h"
+
+struct gen6_idrt_data {
+ const struct ilo_shader_state *cs;
+
+ uint32_t sampler_offset;
+ uint32_t binding_table_offset;
+
+ unsigned curbe_size;
+ unsigned thread_group_size;
+};
+
+static inline void
+gen6_MEDIA_VFE_STATE(struct ilo_builder *builder,
+ unsigned curbe_alloc, bool use_slm)
+{
+ const uint8_t cmd_len = 8;
+ const unsigned idrt_alloc =
+ ((ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) ? 64 : 32) * 32;
+ int max_threads;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ max_threads = builder->dev->thread_count;
+
+ curbe_alloc = align(curbe_alloc, 32);
+ assert(idrt_alloc + curbe_alloc <= builder->dev->urb_size / (use_slm + 1));
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_VFE_STATE) | (cmd_len - 2);
+ dw[1] = 0; /* scratch */
+
+ dw[2] = (max_threads - 1) << GEN6_VFE_DW2_MAX_THREADS__SHIFT |
+ 0 << GEN6_VFE_DW2_URB_ENTRY_COUNT__SHIFT |
+ GEN6_VFE_DW2_RESET_GATEWAY_TIMER |
+ GEN6_VFE_DW2_BYPASS_GATEWAY_CONTROL;
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
+ dw[2] |= GEN7_VFE_DW2_GPGPU_MODE;
+
+ dw[3] = 0;
+
+ dw[4] = 0 << GEN6_VFE_DW4_URB_ENTRY_SIZE__SHIFT |
+ (curbe_alloc / 32);
+
+ dw[5] = 0;
+ dw[6] = 0;
+ dw[7] = 0;
+}
+
+static inline void
+gen6_MEDIA_CURBE_LOAD(struct ilo_builder *builder,
+ uint32_t offset, unsigned size)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ assert(offset % 32 == 0 && size % 32 == 0);
+ /* GPU hangs if size is zero */
+ assert(size);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_CURBE_LOAD) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = size;
+ dw[3] = offset;
+}
+
+static inline void
+gen6_MEDIA_INTERFACE_DESCRIPTOR_LOAD(struct ilo_builder *builder,
+ uint32_t offset, unsigned size)
+{
+ const uint8_t cmd_len = 4;
+ const unsigned idrt_alloc =
+ ((ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) ? 64 : 32) * 32;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ assert(offset % 32 == 0 && size % 32 == 0);
+ assert(size && size <= idrt_alloc);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_INTERFACE_DESCRIPTOR_LOAD) |
+ (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = size;
+ dw[3] = offset;
+}
+
+static inline void
+gen6_MEDIA_STATE_FLUSH(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_STATE_FLUSH) | (cmd_len - 2);
+ dw[1] = 0;
+}
+
+static inline void
+gen7_GPGPU_WALKER(struct ilo_builder *builder,
+ const unsigned thread_group_offset[3],
+ const unsigned thread_group_dim[3],
+ unsigned thread_group_size,
+ unsigned simd_size)
+{
+ const uint8_t cmd_len = 11;
+ uint32_t right_execmask, bottom_execmask;
+ unsigned thread_count;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ assert(simd_size == 16 || simd_size == 8);
+
+ thread_count = (thread_group_size + simd_size - 1) / simd_size;
+ assert(thread_count <= 64);
+
+ right_execmask = thread_group_size % simd_size;
+ if (right_execmask)
+ right_execmask = (1 << right_execmask) - 1;
+ else
+ right_execmask = (1 << simd_size) - 1;
+
+ bottom_execmask = 0xffffffff;
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_RENDER_CMD(MEDIA, GPGPU_WALKER) | (cmd_len - 2);
+ dw[1] = 0; /* always first IDRT */
+
+ dw[2] = (thread_count - 1) << GEN7_GPGPU_DW2_THREAD_MAX_X__SHIFT;
+ if (simd_size == 16)
+ dw[2] |= GEN7_GPGPU_DW2_SIMD_SIZE_SIMD16;
+ else
+ dw[2] |= GEN7_GPGPU_DW2_SIMD_SIZE_SIMD8;
+
+ dw[3] = thread_group_offset[0];
+ dw[4] = thread_group_dim[0];
+ dw[5] = thread_group_offset[1];
+ dw[6] = thread_group_dim[1];
+ dw[7] = thread_group_offset[2];
+ dw[8] = thread_group_dim[2];
+
+ dw[9] = right_execmask;
+ dw[10] = bottom_execmask;
+}
+
+static inline uint32_t
+gen6_INTERFACE_DESCRIPTOR_DATA(struct ilo_builder *builder,
+ const struct gen6_idrt_data *data,
+ int idrt_count)
+{
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 2, page 34:
+ *
+ * "(Interface Descriptor Total Length) This field must have the same
+ * alignment as the Interface Descriptor Data Start Address.
+ *
+ * It must be DQWord (32-byte) aligned..."
+ *
+ * From the Sandy Bridge PRM, volume 2 part 2, page 35:
+ *
+ * "(Interface Descriptor Data Start Address) Specifies the 32-byte
+ * aligned address of the Interface Descriptor data."
+ */
+ const int state_align = 32;
+ const int state_len = (32 / 4) * idrt_count;
+ uint32_t state_offset, *dw;
+ int i;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 7.5);
+
+ state_offset = ilo_builder_dynamic_pointer(builder,
+ ILO_BUILDER_ITEM_INTERFACE_DESCRIPTOR, state_align, state_len, &dw);
+
+ for (i = 0; i < idrt_count; i++) {
+ const struct gen6_idrt_data *idrt = &data[i];
+ const struct ilo_shader_state *cs = idrt->cs;
+ unsigned sampler_count, bt_size, slm_size;
+
+ sampler_count =
+ ilo_shader_get_kernel_param(cs, ILO_KERNEL_SAMPLER_COUNT);
+ assert(sampler_count <= 16);
+ sampler_count = (sampler_count + 3) / 4;
+
+ bt_size =
+ ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TOTAL_COUNT);
+ if (bt_size > 31)
+ bt_size = 31;
+
+ slm_size = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_LOCAL_SIZE);
+
+ assert(idrt->curbe_size / 32 <= 63);
+
+ dw[0] = ilo_shader_get_kernel_offset(idrt->cs);
+ dw[1] = 0;
+ dw[2] = idrt->sampler_offset |
+ sampler_count << GEN6_IDRT_DW2_SAMPLER_COUNT__SHIFT;
+ dw[3] = idrt->binding_table_offset |
+ bt_size << GEN6_IDRT_DW3_BINDING_TABLE_SIZE__SHIFT;
+
+ dw[4] = (idrt->curbe_size / 32) << GEN6_IDRT_DW4_CURBE_READ_LEN__SHIFT |
+ 0 << GEN6_IDRT_DW4_CURBE_READ_OFFSET__SHIFT;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
+ dw[5] = GEN7_IDRT_DW5_ROUNDING_MODE_RTNE;
+
+ if (slm_size) {
+ assert(slm_size <= 64 * 1024);
+ slm_size = util_next_power_of_two((slm_size + 4095) / 4096);
+
+ dw[5] |= GEN7_IDRT_DW5_BARRIER_ENABLE |
+ slm_size << GEN7_IDRT_DW5_SLM_SIZE__SHIFT |
+ idrt->thread_group_size <<
+ GEN7_IDRT_DW5_THREAD_GROUP_SIZE__SHIFT;
+ }
+ } else {
+ dw[5] = 0;
+ }
+
+ dw[6] = 0;
+ dw[7] = 0;
+
+ dw += 8;
+ }
+
+ return state_offset;
+}
+
+#endif /* ILO_BUILDER_MEDIA_H */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_BUILDER_MI_H
+#define ILO_BUILDER_MI_H
+
+#include "genhw/genhw.h"
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+#include "ilo_builder.h"
+
+static inline void
+gen6_MI_STORE_DATA_IMM(struct ilo_builder *builder,
+ struct intel_bo *bo, uint32_t bo_offset,
+ uint64_t val)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
+ uint32_t reloc_flags = INTEL_RELOC_WRITE;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(bo_offset % 8 == 0);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_MI_CMD(MI_STORE_DATA_IMM) | (cmd_len - 2);
+ /* must use GGTT on GEN6 as in PIPE_CONTROL */
+ if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
+ dw[0] |= GEN6_MI_STORE_DATA_IMM_DW0_USE_GGTT;
+ reloc_flags |= INTEL_RELOC_GGTT;
+ }
+
+ dw[1] = 0; /* MBZ */
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[4] = (uint32_t) val;
+ dw[5] = (uint32_t) (val >> 32);
+
+ ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, reloc_flags);
+ } else {
+ dw[3] = (uint32_t) val;
+ dw[4] = (uint32_t) (val >> 32);
+
+ ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, reloc_flags);
+ }
+}
+
+static inline void
+gen6_MI_LOAD_REGISTER_IMM(struct ilo_builder *builder,
+ uint32_t reg, uint32_t val)
+{
+ const uint8_t cmd_len = 3;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(reg % 4 == 0);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_MI_CMD(MI_LOAD_REGISTER_IMM) | (cmd_len - 2);
+ dw[1] = reg;
+ dw[2] = val;
+}
+
+static inline void
+gen6_MI_STORE_REGISTER_MEM(struct ilo_builder *builder, uint32_t reg,
+ struct intel_bo *bo, uint32_t bo_offset)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 4 : 3;
+ uint32_t reloc_flags = INTEL_RELOC_WRITE;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ assert(reg % 4 == 0 && bo_offset % 4 == 0);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_MI_CMD(MI_STORE_REGISTER_MEM) | (cmd_len - 2);
+ dw[1] = reg;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, reloc_flags);
+ } else {
+ /* must use GGTT on Gen6 as in PIPE_CONTROL */
+ if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
+ dw[0] |= GEN6_MI_STORE_REGISTER_MEM_DW0_USE_GGTT;
+ reloc_flags |= INTEL_RELOC_GGTT;
+ }
+
+ ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, reloc_flags);
+ }
+}
+
+static inline void
+gen6_MI_FLUSH_DW(struct ilo_builder *builder)
+{
+ const uint8_t cmd_len = 4;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_MI_CMD(MI_FLUSH_DW) | (cmd_len - 2);
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+}
+
+static inline void
+gen6_MI_REPORT_PERF_COUNT(struct ilo_builder *builder,
+ struct intel_bo *bo, uint32_t bo_offset,
+ uint32_t report_id)
+{
+ const uint8_t cmd_len = 3;
+ uint32_t reloc_flags = INTEL_RELOC_WRITE;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ assert(bo_offset % 64 == 0);
+
+ /* must use GGTT on GEN6 as in PIPE_CONTROL */
+ if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
+ bo_offset |= GEN6_MI_REPORT_PERF_COUNT_DW1_USE_GGTT;
+ reloc_flags |= INTEL_RELOC_GGTT;
+ }
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_MI_CMD(MI_REPORT_PERF_COUNT) | (cmd_len - 2);
+ dw[2] = report_id;
+
+ ilo_builder_batch_reloc(builder, pos + 1, bo, bo_offset, reloc_flags);
+}
+
+static inline void
+gen7_MI_LOAD_REGISTER_MEM(struct ilo_builder *builder, uint32_t reg,
+ struct intel_bo *bo, uint32_t bo_offset)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 4 : 3;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 7, 8);
+
+ assert(reg % 4 == 0 && bo_offset % 4 == 0);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN7_MI_CMD(MI_LOAD_REGISTER_MEM) | (cmd_len - 2);
+ dw[1] = reg;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
+ ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, 0);
+ else
+ ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, 0);
+}
+
+/**
+ * Add a MI_BATCH_BUFFER_END to the batch buffer. Pad with MI_NOOP if
+ * necessary.
+ */
+static inline void
+gen6_mi_batch_buffer_end(struct ilo_builder *builder)
+{
+ /*
+ * From the Sandy Bridge PRM, volume 1 part 1, page 107:
+ *
+ * "The batch buffer must be QWord aligned and a multiple of QWords in
+ * length."
+ */
+ const bool pad = !(builder->writers[ILO_BUILDER_WRITER_BATCH].used & 0x7);
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ if (pad) {
+ ilo_builder_batch_pointer(builder, 2, &dw);
+ dw[0] = GEN6_MI_CMD(MI_BATCH_BUFFER_END);
+ dw[1] = GEN6_MI_CMD(MI_NOOP);
+ } else {
+ ilo_builder_batch_pointer(builder, 1, &dw);
+ dw[0] = GEN6_MI_CMD(MI_BATCH_BUFFER_END);
+ }
+}
+
+#endif /* ILO_BUILDER_MI_H */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_BUILDER_RENDER_H
+#define ILO_BUILDER_RENDER_H
+
+#include "genhw/genhw.h"
+#include "intel_winsys.h"
+
+#include "ilo_core.h"
+#include "ilo_dev.h"
+#include "ilo_builder.h"
+
+static inline void
+gen6_STATE_SIP(struct ilo_builder *builder, uint32_t sip)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 3 : 2;
+ uint32_t *dw;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(COMMON, STATE_SIP) | (cmd_len - 2);
+ dw[1] = sip;
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
+ dw[2] = 0;
+}
+
+static inline void
+gen6_PIPELINE_SELECT(struct ilo_builder *builder, int pipeline)
+{
+ const uint8_t cmd_len = 1;
+ const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, PIPELINE_SELECT) |
+ pipeline;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ switch (pipeline) {
+ case GEN6_PIPELINE_SELECT_DW0_SELECT_3D:
+ case GEN6_PIPELINE_SELECT_DW0_SELECT_MEDIA:
+ break;
+ case GEN7_PIPELINE_SELECT_DW0_SELECT_GPGPU:
+ assert(ilo_dev_gen(builder->dev) >= ILO_GEN(7));
+ break;
+ default:
+ assert(!"unknown pipeline");
+ break;
+ }
+
+ ilo_builder_batch_write(builder, cmd_len, &dw0);
+}
+
+static inline void
+gen6_PIPE_CONTROL(struct ilo_builder *builder, uint32_t dw1,
+ struct intel_bo *bo, uint32_t bo_offset,
+ uint64_t imm)
+{
+ const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
+ uint32_t reloc_flags = INTEL_RELOC_WRITE;
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 8);
+
+ if (dw1 & GEN6_PIPE_CONTROL_CS_STALL) {
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 73:
+ *
+ * "1 of the following must also be set (when CS stall is set):
+ *
+ * * Depth Cache Flush Enable ([0] of DW1)
+ * * Stall at Pixel Scoreboard ([1] of DW1)
+ * * Depth Stall ([13] of DW1)
+ * * Post-Sync Operation ([13] of DW1)
+ * * Render Target Cache Flush Enable ([12] of DW1)
+ * * Notify Enable ([8] of DW1)"
+ *
+ * From the Ivy Bridge PRM, volume 2 part 1, page 61:
+ *
+ * "One of the following must also be set (when CS stall is set):
+ *
+ * * Render Target Cache Flush Enable ([12] of DW1)
+ * * Depth Cache Flush Enable ([0] of DW1)
+ * * Stall at Pixel Scoreboard ([1] of DW1)
+ * * Depth Stall ([13] of DW1)
+ * * Post-Sync Operation ([13] of DW1)"
+ */
+ uint32_t bit_test = GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
+ GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
+ GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
+ GEN6_PIPE_CONTROL_DEPTH_STALL;
+
+ /* post-sync op */
+ bit_test |= GEN6_PIPE_CONTROL_WRITE_IMM |
+ GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT |
+ GEN6_PIPE_CONTROL_WRITE_TIMESTAMP;
+
+ if (ilo_dev_gen(builder->dev) == ILO_GEN(6))
+ bit_test |= GEN6_PIPE_CONTROL_NOTIFY_ENABLE;
+
+ assert(dw1 & bit_test);
+ }
+
+ if (dw1 & GEN6_PIPE_CONTROL_DEPTH_STALL) {
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 73:
+ *
+ * "Following bits must be clear (when Depth Stall is set):
+ *
+ * * Render Target Cache Flush Enable ([12] of DW1)
+ * * Depth Cache Flush Enable ([0] of DW1)"
+ */
+ assert(!(dw1 & (GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
+ GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH)));
+ }
+
+ switch (dw1 & GEN6_PIPE_CONTROL_WRITE__MASK) {
+ case GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT:
+ case GEN6_PIPE_CONTROL_WRITE_TIMESTAMP:
+ assert(!imm);
+ break;
+ default:
+ break;
+ }
+
+ assert(bo_offset % 8 == 0);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(3D, PIPE_CONTROL) | (cmd_len - 2);
+ dw[1] = dw1;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ dw[4] = (uint32_t) imm;
+ dw[5] = (uint32_t) (imm >> 32);
+
+ if (bo) {
+ ilo_builder_batch_reloc64(builder, pos + 2,
+ bo, bo_offset, reloc_flags);
+ } else {
+ dw[2] = 0;
+ dw[3] = 0;
+ }
+
+ } else {
+ dw[3] = (uint32_t) imm;
+ dw[4] = (uint32_t) (imm >> 32);
+
+ if (bo) {
+ /*
+ * From the Sandy Bridge PRM, volume 1 part 3, page 19:
+ *
+ * "[DevSNB] PPGTT memory writes by MI_* (such as
+ * MI_STORE_DATA_IMM) and PIPE_CONTROL are not supported."
+ */
+ if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
+ bo_offset |= GEN6_PIPE_CONTROL_DW2_USE_GGTT;
+ reloc_flags |= INTEL_RELOC_GGTT;
+ }
+
+ ilo_builder_batch_reloc(builder, pos + 2,
+ bo, bo_offset, reloc_flags);
+ } else {
+ dw[2] = 0;
+ }
+ }
+}
+
+static inline void
+ilo_builder_batch_patch_sba(struct ilo_builder *builder)
+{
+ const struct ilo_builder_writer *inst =
+ &builder->writers[ILO_BUILDER_WRITER_INSTRUCTION];
+
+ if (!builder->sba_instruction_pos)
+ return;
+
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ ilo_builder_batch_reloc64(builder, builder->sba_instruction_pos,
+ inst->bo,
+ builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
+ 0);
+ } else {
+ ilo_builder_batch_reloc(builder, builder->sba_instruction_pos, inst->bo,
+ builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
+ 0);
+ }
+}
+
+/**
+ * Add a STATE_BASE_ADDRESS to the batch buffer. The relocation entry for the
+ * instruction buffer is not added until ilo_builder_end() or next
+ * gen6_state_base_address().
+ */
+static inline void
+gen6_state_base_address(struct ilo_builder *builder, bool init_all)
+{
+ const uint8_t cmd_len = 10;
+ const struct ilo_builder_writer *bat =
+ &builder->writers[ILO_BUILDER_WRITER_BATCH];
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 6, 7.5);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(COMMON, STATE_BASE_ADDRESS) | (cmd_len - 2);
+ dw[1] = builder->mocs << GEN6_SBA_MOCS__SHIFT |
+ builder->mocs << GEN6_SBA_DW1_GENERAL_STATELESS_MOCS__SHIFT |
+ init_all;
+
+ ilo_builder_batch_reloc(builder, pos + 2, bat->bo,
+ builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
+ 0);
+ ilo_builder_batch_reloc(builder, pos + 3, bat->bo,
+ builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
+ 0);
+
+ dw[4] = builder->mocs << GEN6_SBA_MOCS__SHIFT | init_all;
+
+ /*
+ * Since the instruction writer has WRITER_FLAG_APPEND set, it is tempting
+ * not to set Instruction Base Address. The problem is that we do not know
+ * if the bo has been or will be moved by the kernel. We need a relocation
+ * entry because of that.
+ *
+ * And since we also set WRITER_FLAG_GROW, we have to wait until
+ * ilo_builder_end(), when the final bo is known, to add the relocation
+ * entry.
+ */
+ ilo_builder_batch_patch_sba(builder);
+ builder->sba_instruction_pos = pos + 5;
+
+ /* skip range checks */
+ dw[6] = init_all;
+ dw[7] = 0xfffff000 + init_all;
+ dw[8] = 0xfffff000 + init_all;
+ dw[9] = init_all;
+}
+
+static inline void
+gen8_state_base_address(struct ilo_builder *builder, bool init_all)
+{
+ const uint8_t cmd_len = 16;
+ const struct ilo_builder_writer *bat =
+ &builder->writers[ILO_BUILDER_WRITER_BATCH];
+ uint32_t *dw;
+ unsigned pos;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+ dw[0] = GEN6_RENDER_CMD(COMMON, STATE_BASE_ADDRESS) | (cmd_len - 2);
+ dw[1] = builder->mocs << GEN8_SBA_MOCS__SHIFT | init_all;
+ dw[2] = 0;
+ dw[3] = builder->mocs << GEN8_SBA_DW3_STATELESS_MOCS__SHIFT;
+ ilo_builder_batch_reloc64(builder, pos + 4, bat->bo,
+ builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
+ 0);
+ ilo_builder_batch_reloc64(builder, pos + 6, bat->bo,
+ builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
+ 0);
+ dw[8] = builder->mocs << GEN8_SBA_MOCS__SHIFT | init_all;
+ dw[9] = 0;
+
+ ilo_builder_batch_patch_sba(builder);
+ builder->sba_instruction_pos = pos + 10;
+
+ /* skip range checks */
+ dw[12] = 0xfffff000 + init_all;
+ dw[13] = 0xfffff000 + init_all;
+ dw[14] = 0xfffff000 + init_all;
+ dw[15] = 0xfffff000 + init_all;
+}
+
+#endif /* ILO_BUILDER_RENDER_H */
*/
#include "genhw/genhw.h"
+#include "core/ilo_builder_mi.h"
+#include "core/ilo_builder_blt.h"
#include "util/u_pack_color.h"
-#include "ilo_builder_mi.h"
-#include "ilo_builder_blt.h"
#include "ilo_context.h"
#include "ilo_cp.h"
#include "ilo_blit.h"
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include "ilo_builder.h"
-#include "ilo_builder_render.h" /* for ilo_builder_batch_patch_sba() */
-
-enum ilo_builder_writer_flags {
- /*
- * When this bit is set, ilo_builder_begin() will not realllocate. New
- * data will be appended instead.
- */
- WRITER_FLAG_APPEND = 1 << 0,
-
- /*
- * When this bit is set, the writer grows when full. When not, callers
- * must make sure the writer never needs to grow.
- */
- WRITER_FLAG_GROW = 1 << 1,
-
- /*
- * The writer will be mapped directly.
- */
- WRITER_FLAG_MAP = 1 << 2,
-};
-
-/**
- * Set the initial size and flags of a writer.
- */
-static void
-ilo_builder_writer_init(struct ilo_builder *builder,
- enum ilo_builder_writer_type which)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- switch (which) {
- case ILO_BUILDER_WRITER_BATCH:
- writer->size = sizeof(uint32_t) * 8192;
- break;
- case ILO_BUILDER_WRITER_INSTRUCTION:
- /*
- * The EUs pretch some instructions. But since the kernel invalidates
- * the instruction cache between batch buffers, we can set
- * WRITER_FLAG_APPEND without worrying the EUs would see invalid
- * instructions prefetched.
- */
- writer->flags = WRITER_FLAG_APPEND | WRITER_FLAG_GROW;
- writer->size = 8192;
- break;
- default:
- assert(!"unknown builder writer");
- return;
- break;
- }
-
- if (builder->dev->has_llc)
- writer->flags |= WRITER_FLAG_MAP;
-}
-
-/**
- * Free all resources used by a writer. Note that the initial size is not
- * reset.
- */
-static void
-ilo_builder_writer_reset(struct ilo_builder *builder,
- enum ilo_builder_writer_type which)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- if (writer->ptr) {
- if (writer->flags & WRITER_FLAG_MAP)
- intel_bo_unmap(writer->bo);
- else
- FREE(writer->ptr);
-
- writer->ptr = NULL;
- }
-
- intel_bo_unref(writer->bo);
- writer->bo = NULL;
-
- writer->used = 0;
- writer->stolen = 0;
-
- if (writer->items) {
- FREE(writer->items);
- writer->item_alloc = 0;
- writer->item_used = 0;
- }
-}
-
-/**
- * Discard everything written so far.
- */
-void
-ilo_builder_writer_discard(struct ilo_builder *builder,
- enum ilo_builder_writer_type which)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- intel_bo_truncate_relocs(writer->bo, 0);
- writer->used = 0;
- writer->stolen = 0;
- writer->item_used = 0;
-}
-
-static struct intel_bo *
-alloc_writer_bo(struct intel_winsys *winsys,
- enum ilo_builder_writer_type which,
- unsigned size)
-{
- static const char *writer_names[ILO_BUILDER_WRITER_COUNT] = {
- [ILO_BUILDER_WRITER_BATCH] = "batch",
- [ILO_BUILDER_WRITER_INSTRUCTION] = "instruction",
- };
-
- return intel_winsys_alloc_bo(winsys, writer_names[which], size, true);
-}
-
-static void *
-map_writer_bo(struct intel_bo *bo, unsigned flags)
-{
- assert(flags & WRITER_FLAG_MAP);
-
- if (flags & WRITER_FLAG_APPEND)
- return intel_bo_map_gtt_async(bo);
- else
- return intel_bo_map(bo, true);
-}
-
-/**
- * Allocate and map the buffer for writing.
- */
-static bool
-ilo_builder_writer_alloc_and_map(struct ilo_builder *builder,
- enum ilo_builder_writer_type which)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- /* allocate a new bo when not appending */
- if (!(writer->flags & WRITER_FLAG_APPEND) || !writer->bo) {
- struct intel_bo *bo;
-
- bo = alloc_writer_bo(builder->winsys, which, writer->size);
- if (bo) {
- intel_bo_unref(writer->bo);
- writer->bo = bo;
- } else if (writer->bo) {
- /* reuse the old bo */
- ilo_builder_writer_discard(builder, which);
- } else {
- return false;
- }
-
- writer->used = 0;
- writer->stolen = 0;
- writer->item_used = 0;
- }
-
- /* map the bo or allocate the staging system memory */
- if (writer->flags & WRITER_FLAG_MAP)
- writer->ptr = map_writer_bo(writer->bo, writer->flags);
- else if (!writer->ptr)
- writer->ptr = MALLOC(writer->size);
-
- return (writer->ptr != NULL);
-}
-
-/**
- * Unmap the buffer for submission.
- */
-static bool
-ilo_builder_writer_unmap(struct ilo_builder *builder,
- enum ilo_builder_writer_type which)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
- unsigned offset;
- int err = 0;
-
- if (writer->flags & WRITER_FLAG_MAP) {
- intel_bo_unmap(writer->bo);
- writer->ptr = NULL;
- return true;
- }
-
- offset = builder->begin_used[which];
- if (writer->used > offset) {
- err = intel_bo_pwrite(writer->bo, offset, writer->used - offset,
- (char *) writer->ptr + offset);
- }
-
- if (writer->stolen && !err) {
- const unsigned offset = writer->size - writer->stolen;
- err = intel_bo_pwrite(writer->bo, offset, writer->stolen,
- (const char *) writer->ptr + offset);
- }
-
- /* keep writer->ptr */
-
- return !err;
-}
-
-/**
- * Grow a mapped writer to at least \p new_size.
- */
-bool
-ilo_builder_writer_grow(struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- unsigned new_size, bool preserve)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
- struct intel_bo *new_bo;
- void *new_ptr;
-
- if (!(writer->flags & WRITER_FLAG_GROW))
- return false;
-
- /* stolen data may already be referenced and cannot be moved */
- if (writer->stolen)
- return false;
-
- if (new_size < writer->size << 1)
- new_size = writer->size << 1;
- /* STATE_BASE_ADDRESS requires page-aligned buffers */
- new_size = align(new_size, 4096);
-
- new_bo = alloc_writer_bo(builder->winsys, which, new_size);
- if (!new_bo)
- return false;
-
- /* map and copy the data over */
- if (writer->flags & WRITER_FLAG_MAP) {
- new_ptr = map_writer_bo(new_bo, writer->flags);
-
- /*
- * When WRITER_FLAG_APPEND and WRITER_FLAG_GROW are both set, we may end
- * up copying between two GTT-mapped BOs. That is slow. The issue
- * could be solved by adding intel_bo_map_async(), or callers may choose
- * to manually grow the writer without preserving the data.
- */
- if (new_ptr && preserve)
- memcpy(new_ptr, writer->ptr, writer->used);
- } else if (preserve) {
- new_ptr = REALLOC(writer->ptr, writer->size, new_size);
- } else {
- new_ptr = MALLOC(new_size);
- }
-
- if (!new_ptr) {
- intel_bo_unref(new_bo);
- return false;
- }
-
- if (writer->flags & WRITER_FLAG_MAP)
- intel_bo_unmap(writer->bo);
- else if (!preserve)
- FREE(writer->ptr);
-
- intel_bo_unref(writer->bo);
-
- writer->size = new_size;
- writer->bo = new_bo;
- writer->ptr = new_ptr;
-
- return true;
-}
-
-/**
- * Record an item for later decoding.
- */
-bool
-ilo_builder_writer_record(struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- enum ilo_builder_item_type type,
- unsigned offset, unsigned size)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
- struct ilo_builder_item *item;
-
- if (writer->item_used == writer->item_alloc) {
- const unsigned new_alloc = (writer->item_alloc) ?
- writer->item_alloc << 1 : 256;
- struct ilo_builder_item *items;
-
- items = REALLOC(writer->items,
- sizeof(writer->items[0]) * writer->item_alloc,
- sizeof(writer->items[0]) * new_alloc);
- if (!items)
- return false;
-
- writer->items = items;
- writer->item_alloc = new_alloc;
- }
-
- item = &writer->items[writer->item_used++];
- item->type = type;
- item->offset = offset;
- item->size = size;
-
- return true;
-}
-
-/**
- * Initialize the builder.
- */
-void
-ilo_builder_init(struct ilo_builder *builder,
- const struct ilo_dev *dev,
- struct intel_winsys *winsys)
-{
- int i;
-
- memset(builder, 0, sizeof(*builder));
-
- builder->dev = dev;
- builder->winsys = winsys;
-
- /* gen6_SURFACE_STATE() may override this */
- switch (ilo_dev_gen(dev)) {
- case ILO_GEN(8):
- builder->mocs = GEN8_MOCS_MT_WB | GEN8_MOCS_CT_L3;
- break;
- case ILO_GEN(7.5):
- case ILO_GEN(7):
- builder->mocs = GEN7_MOCS_L3_WB;
- break;
- default:
- builder->mocs = 0;
- break;
- }
-
- for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++)
- ilo_builder_writer_init(builder, i);
-}
-
-/**
- * Reset the builder and free all resources used. After resetting, the
- * builder behaves as if it is newly initialized, except for potentially
- * larger initial bo sizes.
- */
-void
-ilo_builder_reset(struct ilo_builder *builder)
-{
- int i;
-
- for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++)
- ilo_builder_writer_reset(builder, i);
-}
-
-/**
- * Allocate and map the BOs. It may re-allocate or reuse existing BOs if
- * there is any.
- *
- * Most builder functions can only be called after ilo_builder_begin() and
- * before ilo_builder_end().
- */
-bool
-ilo_builder_begin(struct ilo_builder *builder)
-{
- int i;
-
- for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++) {
- if (!ilo_builder_writer_alloc_and_map(builder, i)) {
- ilo_builder_reset(builder);
- return false;
- }
-
- builder->begin_used[i] = builder->writers[i].used;
- }
-
- builder->unrecoverable_error = false;
- builder->sba_instruction_pos = 0;
-
- return true;
-}
-
-/**
- * Unmap BOs and make sure the written data landed the BOs. The batch buffer
- * ready for submission is returned.
- */
-struct intel_bo *
-ilo_builder_end(struct ilo_builder *builder, unsigned *used)
-{
- struct ilo_builder_writer *bat;
- int i;
-
- ilo_builder_batch_patch_sba(builder);
-
- assert(ilo_builder_validate(builder, 0, NULL));
-
- for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++) {
- if (!ilo_builder_writer_unmap(builder, i))
- builder->unrecoverable_error = true;
- }
-
- if (builder->unrecoverable_error)
- return NULL;
-
- bat = &builder->writers[ILO_BUILDER_WRITER_BATCH];
-
- *used = bat->used;
-
- return bat->bo;
-}
-
-/**
- * Return true if the builder is in a valid state, after accounting for the
- * additional BOs specified. The additional BOs can be listed to avoid
- * snapshotting and restoring when they are known ahead of time.
- *
- * The number of additional BOs should not be more than a few. Like two, for
- * copying between two BOs.
- *
- * Callers must make sure the builder is in a valid state when
- * ilo_builder_end() is called.
- */
-bool
-ilo_builder_validate(struct ilo_builder *builder,
- unsigned bo_count, struct intel_bo **bos)
-{
- const unsigned max_bo_count = 2;
- struct intel_bo *bos_to_submit[ILO_BUILDER_WRITER_COUNT + max_bo_count];
- int i;
-
- for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++)
- bos_to_submit[i] = builder->writers[i].bo;
-
- if (bo_count) {
- assert(bo_count <= max_bo_count);
- if (bo_count > max_bo_count)
- return false;
-
- memcpy(&bos_to_submit[ILO_BUILDER_WRITER_COUNT],
- bos, sizeof(*bos) * bo_count);
- i += bo_count;
- }
-
- return intel_winsys_can_submit_bo(builder->winsys, bos_to_submit, i);
-}
-
-/**
- * Take a snapshot of the writer state.
- */
-void
-ilo_builder_batch_snapshot(const struct ilo_builder *builder,
- struct ilo_builder_snapshot *snapshot)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- const struct ilo_builder_writer *writer = &builder->writers[which];
-
- snapshot->reloc_count = intel_bo_get_reloc_count(writer->bo);
- snapshot->used = writer->used;
- snapshot->stolen = writer->stolen;
- snapshot->item_used = writer->item_used;
-}
-
-/**
- * Restore the writer state to when the snapshot was taken, except that it
- * does not (unnecessarily) shrink BOs or the item array.
- */
-void
-ilo_builder_batch_restore(struct ilo_builder *builder,
- const struct ilo_builder_snapshot *snapshot)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- intel_bo_truncate_relocs(writer->bo, snapshot->reloc_count);
- writer->used = snapshot->used;
- writer->stolen = snapshot->stolen;
- writer->item_used = snapshot->item_used;
-}
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_BUILDER_H
-#define ILO_BUILDER_H
-
-#include "core/intel_winsys.h"
-#include "ilo_common.h"
-
-enum ilo_builder_writer_type {
- ILO_BUILDER_WRITER_BATCH,
- ILO_BUILDER_WRITER_INSTRUCTION,
-
- ILO_BUILDER_WRITER_COUNT,
-};
-
-enum ilo_builder_item_type {
- /* for dynamic buffer */
- ILO_BUILDER_ITEM_BLOB,
- ILO_BUILDER_ITEM_CLIP_VIEWPORT,
- ILO_BUILDER_ITEM_SF_VIEWPORT,
- ILO_BUILDER_ITEM_SCISSOR_RECT,
- ILO_BUILDER_ITEM_CC_VIEWPORT,
- ILO_BUILDER_ITEM_COLOR_CALC,
- ILO_BUILDER_ITEM_DEPTH_STENCIL,
- ILO_BUILDER_ITEM_BLEND,
- ILO_BUILDER_ITEM_SAMPLER,
- ILO_BUILDER_ITEM_INTERFACE_DESCRIPTOR,
-
- /* for surface buffer */
- ILO_BUILDER_ITEM_SURFACE,
- ILO_BUILDER_ITEM_BINDING_TABLE,
-
- /* for instruction buffer */
- ILO_BUILDER_ITEM_KERNEL,
-
- ILO_BUILDER_ITEM_COUNT,
-};
-
-struct ilo_builder_item {
- enum ilo_builder_item_type type;
- unsigned offset;
- unsigned size;
-};
-
-struct ilo_builder_writer {
- /* internal flags */
- unsigned flags;
-
- unsigned size;
- struct intel_bo *bo;
- void *ptr;
-
- /* data written to the bottom */
- unsigned used;
- /* data written to the top */
- unsigned stolen;
-
- /* for decoding */
- struct ilo_builder_item *items;
- unsigned item_alloc;
- unsigned item_used;
-};
-
-/**
- * A snapshot of the writer state.
- */
-struct ilo_builder_snapshot {
- unsigned reloc_count;
-
- unsigned used;
- unsigned stolen;
- unsigned item_used;
-};
-
-struct ilo_builder {
- const struct ilo_dev *dev;
- struct intel_winsys *winsys;
- uint32_t mocs;
-
- struct ilo_builder_writer writers[ILO_BUILDER_WRITER_COUNT];
- bool unrecoverable_error;
-
- /* for writers that have their data appended */
- unsigned begin_used[ILO_BUILDER_WRITER_COUNT];
-
- /* for STATE_BASE_ADDRESS */
- unsigned sba_instruction_pos;
-};
-
-void
-ilo_builder_init(struct ilo_builder *builder,
- const struct ilo_dev *dev,
- struct intel_winsys *winsys);
-
-void
-ilo_builder_reset(struct ilo_builder *builder);
-
-void
-ilo_builder_decode(struct ilo_builder *builder);
-
-bool
-ilo_builder_begin(struct ilo_builder *builder);
-
-struct intel_bo *
-ilo_builder_end(struct ilo_builder *builder, unsigned *used);
-
-bool
-ilo_builder_validate(struct ilo_builder *builder,
- unsigned bo_count, struct intel_bo **bos);
-
-/**
- * Return true if the builder has a relocation entry for \p bo.
- */
-static inline bool
-ilo_builder_has_reloc(const struct ilo_builder *builder,
- struct intel_bo *bo)
-{
- int i;
-
- for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++) {
- const struct ilo_builder_writer *writer = &builder->writers[i];
- if (intel_bo_has_reloc(writer->bo, bo))
- return true;
- }
-
- return false;
-}
-
-void
-ilo_builder_writer_discard(struct ilo_builder *builder,
- enum ilo_builder_writer_type which);
-
-bool
-ilo_builder_writer_grow(struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- unsigned new_size, bool preserve);
-
-bool
-ilo_builder_writer_record(struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- enum ilo_builder_item_type type,
- unsigned offset, unsigned size);
-
-static inline void
-ilo_builder_writer_checked_record(struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- enum ilo_builder_item_type item,
- unsigned offset, unsigned size)
-{
- if (unlikely(ilo_debug & (ILO_DEBUG_BATCH | ILO_DEBUG_HANG))) {
- if (!ilo_builder_writer_record(builder, which, item, offset, size)) {
- builder->unrecoverable_error = true;
- builder->writers[which].item_used = 0;
- }
- }
-}
-
-/**
- * Return an offset to a region that is aligned to \p alignment and has at
- * least \p size bytes. The region is reserved from the bottom.
- */
-static inline unsigned
-ilo_builder_writer_reserve_bottom(struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- unsigned alignment, unsigned size)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
- unsigned offset;
-
- assert(alignment && util_is_power_of_two(alignment));
- offset = align(writer->used, alignment);
-
- if (unlikely(offset + size > writer->size - writer->stolen)) {
- if (!ilo_builder_writer_grow(builder, which,
- offset + size + writer->stolen, true)) {
- builder->unrecoverable_error = true;
- ilo_builder_writer_discard(builder, which);
- offset = 0;
- }
-
- assert(offset + size <= writer->size - writer->stolen);
- }
-
- return offset;
-}
-
-/**
- * Similar to ilo_builder_writer_reserve_bottom(), but reserve from the top.
- */
-static inline unsigned
-ilo_builder_writer_reserve_top(struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- unsigned alignment, unsigned size)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
- unsigned offset;
-
- assert(alignment && util_is_power_of_two(alignment));
- offset = (writer->size - writer->stolen - size) & ~(alignment - 1);
-
- if (unlikely(offset < writer->used ||
- size > writer->size - writer->stolen)) {
- if (!ilo_builder_writer_grow(builder, which,
- align(writer->used, alignment) + size + writer->stolen, true)) {
- builder->unrecoverable_error = true;
- ilo_builder_writer_discard(builder, which);
- }
-
- offset = (writer->size - writer->stolen - size) & ~(alignment - 1);
- assert(offset + size <= writer->size - writer->stolen);
- }
-
- return offset;
-}
-
-/**
- * Add a relocation entry to the writer.
- */
-static inline void
-ilo_builder_writer_reloc(struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- unsigned offset, struct intel_bo *bo,
- unsigned bo_offset, unsigned reloc_flags,
- bool write_presumed_offset_hi)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
- uint64_t presumed_offset;
- int err;
-
- if (write_presumed_offset_hi)
- ILO_DEV_ASSERT(builder->dev, 8, 8);
- else
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- assert(offset + sizeof(uint32_t) <= writer->used ||
- (offset >= writer->size - writer->stolen &&
- offset + sizeof(uint32_t) <= writer->size));
-
- err = intel_bo_add_reloc(writer->bo, offset, bo, bo_offset,
- reloc_flags, &presumed_offset);
- if (unlikely(err))
- builder->unrecoverable_error = true;
-
- if (write_presumed_offset_hi) {
- *((uint64_t *) ((char *) writer->ptr + offset)) = presumed_offset;
- } else {
- /* 32-bit addressing */
- assert(presumed_offset == (uint64_t) ((uint32_t) presumed_offset));
- *((uint32_t *) ((char *) writer->ptr + offset)) = presumed_offset;
- }
-}
-
-/**
- * Reserve a region from the dynamic buffer. Both the offset, in bytes, and
- * the pointer to the reserved region are returned. The pointer is only valid
- * until the next reserve call.
- *
- * Note that \p alignment is in bytes and \p len is in DWords.
- */
-static inline uint32_t
-ilo_builder_dynamic_pointer(struct ilo_builder *builder,
- enum ilo_builder_item_type item,
- unsigned alignment, unsigned len,
- uint32_t **dw)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- const unsigned size = len << 2;
- const unsigned offset = ilo_builder_writer_reserve_top(builder,
- which, alignment, size);
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- /* all states are at least aligned to 32-bytes */
- if (item != ILO_BUILDER_ITEM_BLOB)
- assert(alignment % 32 == 0);
-
- *dw = (uint32_t *) ((char *) writer->ptr + offset);
-
- writer->stolen = writer->size - offset;
-
- ilo_builder_writer_checked_record(builder, which, item, offset, size);
-
- return offset;
-}
-
-/**
- * Write a dynamic state to the dynamic buffer.
- */
-static inline uint32_t
-ilo_builder_dynamic_write(struct ilo_builder *builder,
- enum ilo_builder_item_type item,
- unsigned alignment, unsigned len,
- const uint32_t *dw)
-{
- uint32_t offset, *dst;
-
- offset = ilo_builder_dynamic_pointer(builder, item, alignment, len, &dst);
- memcpy(dst, dw, len << 2);
-
- return offset;
-}
-
-/**
- * Reserve some space from the top (for prefetches).
- */
-static inline void
-ilo_builder_dynamic_pad_top(struct ilo_builder *builder, unsigned len)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- const unsigned size = len << 2;
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- if (writer->stolen < size) {
- ilo_builder_writer_reserve_top(builder, which,
- 1, size - writer->stolen);
- writer->stolen = size;
- }
-}
-
-static inline unsigned
-ilo_builder_dynamic_used(const struct ilo_builder *builder)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- const struct ilo_builder_writer *writer = &builder->writers[which];
-
- return writer->stolen >> 2;
-}
-
-/**
- * Reserve a region from the surface buffer. Both the offset, in bytes, and
- * the pointer to the reserved region are returned. The pointer is only valid
- * until the next reserve call.
- *
- * Note that \p alignment is in bytes and \p len is in DWords.
- */
-static inline uint32_t
-ilo_builder_surface_pointer(struct ilo_builder *builder,
- enum ilo_builder_item_type item,
- unsigned alignment, unsigned len,
- uint32_t **dw)
-{
- assert(item == ILO_BUILDER_ITEM_SURFACE ||
- item == ILO_BUILDER_ITEM_BINDING_TABLE);
-
- return ilo_builder_dynamic_pointer(builder, item, alignment, len, dw);
-}
-
-/**
- * Add a relocation entry for a DWord of a surface state.
- */
-static inline void
-ilo_builder_surface_reloc(struct ilo_builder *builder,
- uint32_t offset, unsigned dw_index,
- struct intel_bo *bo, unsigned bo_offset,
- unsigned reloc_flags)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
-
- ilo_builder_writer_reloc(builder, which, offset + (dw_index << 2),
- bo, bo_offset, reloc_flags, false);
-}
-
-static inline void
-ilo_builder_surface_reloc64(struct ilo_builder *builder,
- uint32_t offset, unsigned dw_index,
- struct intel_bo *bo, unsigned bo_offset,
- unsigned reloc_flags)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
-
- ilo_builder_writer_reloc(builder, which, offset + (dw_index << 2),
- bo, bo_offset, reloc_flags, true);
-}
-
-static inline unsigned
-ilo_builder_surface_used(const struct ilo_builder *builder)
-{
- return ilo_builder_dynamic_used(builder);
-}
-
-/**
- * Write a kernel to the instruction buffer. The offset, in bytes, of the
- * kernel is returned.
- */
-static inline uint32_t
-ilo_builder_instruction_write(struct ilo_builder *builder,
- unsigned size, const void *kernel)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_INSTRUCTION;
- /*
- * From the Sandy Bridge PRM, volume 4 part 2, page 112:
- *
- * "Due to prefetch of the instruction stream, the EUs may attempt to
- * access up to 8 instructions (128 bytes) beyond the end of the
- * kernel program - possibly into the next memory page. Although
- * these instructions will not be executed, software must account for
- * the prefetch in order to avoid invalid page access faults."
- */
- const unsigned reserved_size = size + 128;
- /* kernels are aligned to 64 bytes */
- const unsigned alignment = 64;
- const unsigned offset = ilo_builder_writer_reserve_bottom(builder,
- which, alignment, reserved_size);
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- memcpy((char *) writer->ptr + offset, kernel, size);
-
- writer->used = offset + size;
-
- ilo_builder_writer_checked_record(builder, which,
- ILO_BUILDER_ITEM_KERNEL, offset, size);
-
- return offset;
-}
-
-/**
- * Reserve a region from the batch buffer. Both the offset, in DWords, and
- * the pointer to the reserved region are returned. The pointer is only valid
- * until the next reserve call.
- *
- * Note that \p len is in DWords.
- */
-static inline unsigned
-ilo_builder_batch_pointer(struct ilo_builder *builder,
- unsigned len, uint32_t **dw)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- /*
- * We know the batch bo is always aligned. Using 1 here should allow the
- * compiler to optimize away aligning.
- */
- const unsigned alignment = 1;
- const unsigned size = len << 2;
- const unsigned offset = ilo_builder_writer_reserve_bottom(builder,
- which, alignment, size);
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- assert(offset % 4 == 0);
- *dw = (uint32_t *) ((char *) writer->ptr + offset);
-
- writer->used = offset + size;
-
- return offset >> 2;
-}
-
-/**
- * Write a command to the batch buffer.
- */
-static inline unsigned
-ilo_builder_batch_write(struct ilo_builder *builder,
- unsigned len, const uint32_t *dw)
-{
- unsigned pos;
- uint32_t *dst;
-
- pos = ilo_builder_batch_pointer(builder, len, &dst);
- memcpy(dst, dw, len << 2);
-
- return pos;
-}
-
-/**
- * Add a relocation entry for a DWord of a command.
- */
-static inline void
-ilo_builder_batch_reloc(struct ilo_builder *builder, unsigned pos,
- struct intel_bo *bo, unsigned bo_offset,
- unsigned reloc_flags)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
-
- ilo_builder_writer_reloc(builder, which, pos << 2,
- bo, bo_offset, reloc_flags, false);
-}
-
-static inline void
-ilo_builder_batch_reloc64(struct ilo_builder *builder, unsigned pos,
- struct intel_bo *bo, unsigned bo_offset,
- unsigned reloc_flags)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
-
- ilo_builder_writer_reloc(builder, which, pos << 2,
- bo, bo_offset, reloc_flags, true);
-}
-
-static inline unsigned
-ilo_builder_batch_used(const struct ilo_builder *builder)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- const struct ilo_builder_writer *writer = &builder->writers[which];
-
- return writer->used >> 2;
-}
-
-static inline unsigned
-ilo_builder_batch_space(const struct ilo_builder *builder)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- const struct ilo_builder_writer *writer = &builder->writers[which];
-
- return (writer->size - writer->stolen - writer->used) >> 2;
-}
-
-static inline void
-ilo_builder_batch_discard(struct ilo_builder *builder)
-{
- ilo_builder_writer_discard(builder, ILO_BUILDER_WRITER_BATCH);
-}
-
-static inline void
-ilo_builder_batch_print_stats(const struct ilo_builder *builder)
-{
- const enum ilo_builder_writer_type which = ILO_BUILDER_WRITER_BATCH;
- const struct ilo_builder_writer *writer = &builder->writers[which];
-
- ilo_printf("%d+%d bytes (%d%% full)\n",
- writer->used, writer->stolen,
- (writer->used + writer->stolen) * 100 / writer->size);
-}
-
-void
-ilo_builder_batch_snapshot(const struct ilo_builder *builder,
- struct ilo_builder_snapshot *snapshot);
-
-void
-ilo_builder_batch_restore(struct ilo_builder *builder,
- const struct ilo_builder_snapshot *snapshot);
-
-#endif /* ILO_BUILDER_H */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_BUILDER_3D_H
-#define ILO_BUILDER_3D_H
-
-#include "genhw/genhw.h"
-
-#include "ilo_common.h"
-#include "ilo_builder_3d_top.h"
-#include "ilo_builder_3d_bottom.h"
-
-static inline void
-gen6_3DPRIMITIVE(struct ilo_builder *builder,
- const struct pipe_draw_info *info,
- const struct ilo_ib_state *ib)
-{
- const uint8_t cmd_len = 6;
- const int prim = gen6_3d_translate_pipe_prim(info->mode);
- const int vb_access = (info->indexed) ?
- GEN6_3DPRIM_DW0_ACCESS_RANDOM : GEN6_3DPRIM_DW0_ACCESS_SEQUENTIAL;
- const uint32_t vb_start = info->start +
- ((info->indexed) ? ib->draw_start_offset : 0);
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) |
- vb_access |
- prim << GEN6_3DPRIM_DW0_TYPE__SHIFT |
- (cmd_len - 2);
- dw[1] = info->count;
- dw[2] = vb_start;
- dw[3] = info->instance_count;
- dw[4] = info->start_instance;
- dw[5] = info->index_bias;
-}
-
-static inline void
-gen7_3DPRIMITIVE(struct ilo_builder *builder,
- const struct pipe_draw_info *info,
- const struct ilo_ib_state *ib)
-{
- const uint8_t cmd_len = 7;
- const int prim = gen6_3d_translate_pipe_prim(info->mode);
- const int vb_access = (info->indexed) ?
- GEN7_3DPRIM_DW1_ACCESS_RANDOM : GEN7_3DPRIM_DW1_ACCESS_SEQUENTIAL;
- const uint32_t vb_start = info->start +
- ((info->indexed) ? ib->draw_start_offset : 0);
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) | (cmd_len - 2);
- dw[1] = vb_access | prim;
- dw[2] = info->count;
- dw[3] = vb_start;
- dw[4] = info->instance_count;
- dw[5] = info->start_instance;
- dw[6] = info->index_bias;
-}
-
-#endif /* ILO_BUILDER_3D_H */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_BUILDER_3D_BOTTOM_H
-#define ILO_BUILDER_3D_BOTTOM_H
-
-#include "genhw/genhw.h"
-#include "core/ilo_format.h"
-#include "core/intel_winsys.h"
-
-#include "ilo_common.h"
-#include "ilo_shader.h"
-#include "ilo_builder.h"
-#include "ilo_builder_3d_top.h"
-
-static inline void
-gen6_3DSTATE_CLIP(struct ilo_builder *builder,
- const struct ilo_rasterizer_state *rasterizer,
- const struct ilo_shader_state *fs,
- bool enable_guardband,
- int num_viewports)
-{
- const uint8_t cmd_len = 4;
- uint32_t dw1, dw2, dw3, *dw;
- int interps;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- dw1 = rasterizer->clip.payload[0];
- dw2 = rasterizer->clip.payload[1];
- dw3 = rasterizer->clip.payload[2];
-
- if (enable_guardband && rasterizer->clip.can_enable_guardband)
- dw2 |= GEN6_CLIP_DW2_GB_TEST_ENABLE;
-
- interps = (fs) ? ilo_shader_get_kernel_param(fs,
- ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) : 0;
-
- if (interps & (GEN6_INTERP_NONPERSPECTIVE_PIXEL |
- GEN6_INTERP_NONPERSPECTIVE_CENTROID |
- GEN6_INTERP_NONPERSPECTIVE_SAMPLE))
- dw2 |= GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE;
-
- dw3 |= GEN6_CLIP_DW3_RTAINDEX_FORCED_ZERO |
- (num_viewports - 1);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CLIP) | (cmd_len - 2);
- dw[1] = dw1;
- dw[2] = dw2;
- dw[3] = dw3;
-}
-
-static inline void
-gen6_disable_3DSTATE_CLIP(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CLIP) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
-}
-
-static inline void
-gen7_internal_3dstate_sf(struct ilo_builder *builder,
- uint8_t cmd_len, uint32_t *dw,
- const struct ilo_rasterizer_sf *sf,
- int num_samples)
-{
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- assert(cmd_len == 7);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
-
- if (!sf) {
- dw[1] = 0;
- dw[2] = (num_samples > 1) ? GEN7_SF_DW2_MSRASTMODE_ON_PATTERN : 0;
- dw[3] = 0;
- dw[4] = 0;
- dw[5] = 0;
- dw[6] = 0;
-
- return;
- }
-
- /* see rasterizer_init_sf_gen6() */
- STATIC_ASSERT(Elements(sf->payload) >= 3);
- dw[1] = sf->payload[0];
- dw[2] = sf->payload[1];
- dw[3] = sf->payload[2];
-
- if (num_samples > 1)
- dw[2] |= sf->dw_msaa;
-
- dw[4] = sf->dw_depth_offset_const;
- dw[5] = sf->dw_depth_offset_scale;
- dw[6] = sf->dw_depth_offset_clamp;
-}
-
-static inline void
-gen8_internal_3dstate_sbe(struct ilo_builder *builder,
- uint8_t cmd_len, uint32_t *dw,
- const struct ilo_shader_state *fs,
- int sprite_coord_mode)
-{
- const struct ilo_kernel_routing *routing;
- int vue_offset, vue_len, out_count;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(cmd_len == 4);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) | (cmd_len - 2);
-
- if (!fs) {
- dw[1] = 1 << GEN7_SBE_DW1_URB_READ_LEN__SHIFT;
- dw[2] = 0;
- dw[3] = 0;
- return;
- }
-
- routing = ilo_shader_get_kernel_routing(fs);
-
- vue_offset = routing->source_skip;
- assert(vue_offset % 2 == 0);
- vue_offset /= 2;
-
- vue_len = (routing->source_len + 1) / 2;
- if (!vue_len)
- vue_len = 1;
-
- out_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT);
- assert(out_count <= 32);
-
- dw[1] = out_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
- vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[1] |= GEN8_SBE_DW1_USE_URB_READ_LEN |
- GEN8_SBE_DW1_USE_URB_READ_OFFSET |
- vue_offset << GEN8_SBE_DW1_URB_READ_OFFSET__SHIFT;
- } else {
- dw[1] |= vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
- }
-
- if (routing->swizzle_enable)
- dw[1] |= GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE;
-
- switch (sprite_coord_mode) {
- case PIPE_SPRITE_COORD_UPPER_LEFT:
- dw[1] |= GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_UPPERLEFT;
- break;
- case PIPE_SPRITE_COORD_LOWER_LEFT:
- dw[1] |= GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_LOWERLEFT;
- break;
- }
-
- /*
- * From the Ivy Bridge PRM, volume 2 part 1, page 268:
- *
- * "This field (Point Sprite Texture Coordinate Enable) must be
- * programmed to 0 when non-point primitives are rendered."
- *
- * TODO We do not check that yet.
- */
- dw[2] = routing->point_sprite_enable;
-
- dw[3] = routing->const_interp_enable;
-}
-
-static inline void
-gen8_internal_3dstate_sbe_swiz(struct ilo_builder *builder,
- uint8_t cmd_len, uint32_t *dw,
- const struct ilo_shader_state *fs)
-{
- const struct ilo_kernel_routing *routing;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(cmd_len == 11);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_SBE_SWIZ) | (cmd_len - 2);
-
- if (!fs) {
- memset(&dw[1], 0, sizeof(*dw) * (cmd_len - 1));
- return;
- }
-
- routing = ilo_shader_get_kernel_routing(fs);
-
- STATIC_ASSERT(sizeof(routing->swizzles) >= sizeof(*dw) * 8);
- memcpy(&dw[1], routing->swizzles, sizeof(*dw) * 8);
-
- /* WrapShortest enables */
- dw[9] = 0;
- dw[10] = 0;
-}
-
-static inline void
-gen6_3DSTATE_SF(struct ilo_builder *builder,
- const struct ilo_rasterizer_state *rasterizer,
- const struct ilo_shader_state *fs,
- int sample_count)
-{
- const uint8_t cmd_len = 20;
- uint32_t gen8_3dstate_sbe[4], gen8_3dstate_sbe_swiz[11];
- uint32_t gen7_3dstate_sf[7];
- const struct ilo_rasterizer_sf *sf;
- int sprite_coord_mode;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- sf = (rasterizer) ? &rasterizer->sf : NULL;
- sprite_coord_mode = (rasterizer) ? rasterizer->state.sprite_coord_mode : 0;
-
- gen8_internal_3dstate_sbe(builder, Elements(gen8_3dstate_sbe),
- gen8_3dstate_sbe, fs, sprite_coord_mode);
- gen8_internal_3dstate_sbe_swiz(builder, Elements(gen8_3dstate_sbe_swiz),
- gen8_3dstate_sbe_swiz, fs);
- gen7_internal_3dstate_sf(builder, Elements(gen7_3dstate_sf),
- gen7_3dstate_sf, sf, sample_count);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
- dw[1] = gen8_3dstate_sbe[1];
- memcpy(&dw[2], &gen7_3dstate_sf[1], sizeof(*dw) * 6);
- memcpy(&dw[8], &gen8_3dstate_sbe_swiz[1], sizeof(*dw) * 8);
- dw[16] = gen8_3dstate_sbe[2];
- dw[17] = gen8_3dstate_sbe[3];
- dw[18] = gen8_3dstate_sbe_swiz[9];
- dw[19] = gen8_3dstate_sbe_swiz[10];
-}
-
-static inline void
-gen7_3DSTATE_SF(struct ilo_builder *builder,
- const struct ilo_rasterizer_sf *sf,
- enum pipe_format zs_format,
- int sample_count)
-{
- const uint8_t cmd_len = 7;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- gen7_internal_3dstate_sf(builder, cmd_len, dw, sf, sample_count);
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
- int hw_format;
-
- /* separate stencil */
- switch (zs_format) {
- case PIPE_FORMAT_Z16_UNORM:
- hw_format = GEN6_ZFORMAT_D16_UNORM;
- break;
- case PIPE_FORMAT_Z32_FLOAT:
- case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
- hw_format = GEN6_ZFORMAT_D32_FLOAT;
- break;
- case PIPE_FORMAT_Z24X8_UNORM:
- case PIPE_FORMAT_Z24_UNORM_S8_UINT:
- hw_format = GEN6_ZFORMAT_D24_UNORM_X8_UINT;
- break;
- default:
- /* FLOAT surface is assumed when there is no depth buffer */
- hw_format = GEN6_ZFORMAT_D32_FLOAT;
- break;
- }
-
- dw[1] |= hw_format << GEN7_SF_DW1_DEPTH_FORMAT__SHIFT;
- }
-}
-
-static inline void
-gen8_3DSTATE_SF(struct ilo_builder *builder,
- const struct ilo_rasterizer_sf *sf)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) | (cmd_len - 2);
-
- /* see rasterizer_init_sf_gen8() */
- STATIC_ASSERT(Elements(sf->payload) >= 3);
- dw[1] = sf->payload[0];
- dw[2] = sf->payload[1];
- dw[3] = sf->payload[2];
-}
-
-static inline void
-gen7_3DSTATE_SBE(struct ilo_builder *builder,
- const struct ilo_shader_state *fs,
- int sprite_coord_mode)
-{
- const uint8_t cmd_len = 14;
- uint32_t gen8_3dstate_sbe[4], gen8_3dstate_sbe_swiz[11];
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- gen8_internal_3dstate_sbe(builder, Elements(gen8_3dstate_sbe),
- gen8_3dstate_sbe, fs, sprite_coord_mode);
- gen8_internal_3dstate_sbe_swiz(builder, Elements(gen8_3dstate_sbe_swiz),
- gen8_3dstate_sbe_swiz, fs);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) | (cmd_len - 2);
- dw[1] = gen8_3dstate_sbe[1];
- memcpy(&dw[2], &gen8_3dstate_sbe_swiz[1], sizeof(*dw) * 8);
- dw[10] = gen8_3dstate_sbe[2];
- dw[11] = gen8_3dstate_sbe[3];
- dw[12] = gen8_3dstate_sbe_swiz[9];
- dw[13] = gen8_3dstate_sbe_swiz[10];
-}
-
-static inline void
-gen8_3DSTATE_SBE(struct ilo_builder *builder,
- const struct ilo_shader_state *fs,
- int sprite_coord_mode)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- gen8_internal_3dstate_sbe(builder, cmd_len, dw, fs, sprite_coord_mode);
-}
-
-static inline void
-gen8_3DSTATE_SBE_SWIZ(struct ilo_builder *builder,
- const struct ilo_shader_state *fs)
-{
- const uint8_t cmd_len = 11;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- gen8_internal_3dstate_sbe_swiz(builder, cmd_len, dw, fs);
-}
-
-static inline void
-gen8_3DSTATE_RASTER(struct ilo_builder *builder,
- const struct ilo_rasterizer_sf *sf)
-{
- const uint8_t cmd_len = 5;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_RASTER) | (cmd_len - 2);
- dw[1] = sf->dw_raster;
- dw[2] = sf->dw_depth_offset_const;
- dw[3] = sf->dw_depth_offset_scale;
- dw[4] = sf->dw_depth_offset_clamp;
-}
-
-static inline void
-gen6_3DSTATE_WM(struct ilo_builder *builder,
- const struct ilo_shader_state *fs,
- const struct ilo_rasterizer_state *rasterizer,
- bool dual_blend, bool cc_may_kill)
-{
- const uint8_t cmd_len = 9;
- const int num_samples = 1;
- const struct ilo_shader_cso *cso;
- uint32_t dw2, dw4, dw5, dw6, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- cso = ilo_shader_get_kernel_cso(fs);
- dw2 = cso->payload[0];
- dw4 = cso->payload[1];
- dw5 = cso->payload[2];
- dw6 = cso->payload[3];
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 248:
- *
- * "This bit (Statistics Enable) must be disabled if either of these
- * bits is set: Depth Buffer Clear , Hierarchical Depth Buffer Resolve
- * Enable or Depth Buffer Resolve Enable."
- */
- dw4 |= GEN6_WM_DW4_STATISTICS;
-
- if (cc_may_kill)
- dw5 |= GEN6_WM_DW5_PS_KILL_PIXEL | GEN6_WM_DW5_PS_DISPATCH_ENABLE;
-
- if (dual_blend)
- dw5 |= GEN6_WM_DW5_PS_DUAL_SOURCE_BLEND;
-
- dw5 |= rasterizer->wm.payload[0];
-
- dw6 |= rasterizer->wm.payload[1];
-
- if (num_samples > 1) {
- dw6 |= rasterizer->wm.dw_msaa_rast |
- rasterizer->wm.dw_msaa_disp;
- }
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
- dw[1] = ilo_shader_get_kernel_offset(fs);
- dw[2] = dw2;
- dw[3] = 0; /* scratch */
- dw[4] = dw4;
- dw[5] = dw5;
- dw[6] = dw6;
- dw[7] = 0; /* kernel 1 */
- dw[8] = 0; /* kernel 2 */
-}
-
-static inline void
-gen6_hiz_3DSTATE_WM(struct ilo_builder *builder, uint32_t hiz_op)
-{
- const uint8_t cmd_len = 9;
- const int max_threads = (builder->dev->gt == 2) ? 80 : 40;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- dw[4] = hiz_op;
- /* honor the valid range even if dispatching is disabled */
- dw[5] = (max_threads - 1) << GEN6_WM_DW5_MAX_THREADS__SHIFT;
- dw[6] = 0;
- dw[7] = 0;
- dw[8] = 0;
-}
-
-static inline void
-gen7_3DSTATE_WM(struct ilo_builder *builder,
- const struct ilo_shader_state *fs,
- const struct ilo_rasterizer_state *rasterizer,
- bool cc_may_kill)
-{
- const uint8_t cmd_len = 3;
- const int num_samples = 1;
- const struct ilo_shader_cso *cso;
- uint32_t dw1, dw2, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- /* see rasterizer_init_wm_gen7() */
- dw1 = rasterizer->wm.payload[0];
- dw2 = rasterizer->wm.payload[1];
-
- /* see fs_init_cso_gen7() */
- cso = ilo_shader_get_kernel_cso(fs);
- dw1 |= cso->payload[3];
-
- dw1 |= GEN7_WM_DW1_STATISTICS;
-
- if (cc_may_kill)
- dw1 |= GEN7_WM_DW1_PS_DISPATCH_ENABLE | GEN7_WM_DW1_PS_KILL_PIXEL;
-
- if (num_samples > 1) {
- dw1 |= rasterizer->wm.dw_msaa_rast;
- dw2 |= rasterizer->wm.dw_msaa_disp;
- }
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
- dw[1] = dw1;
- dw[2] = dw2;
-}
-
-static inline void
-gen8_3DSTATE_WM(struct ilo_builder *builder,
- const struct ilo_shader_state *fs,
- const struct ilo_rasterizer_state *rasterizer)
-{
- const uint8_t cmd_len = 2;
- const struct ilo_shader_cso *cso;
- uint32_t dw1, interps, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- /* see rasterizer_get_wm_gen8() */
- dw1 = rasterizer->wm.payload[0];
- dw1 |= GEN7_WM_DW1_STATISTICS;
-
- /* see fs_init_cso_gen8() */
- cso = ilo_shader_get_kernel_cso(fs);
- interps = cso->payload[4];
-
- assert(!(dw1 & interps));
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
- dw[1] = dw1 | interps;
-}
-
-static inline void
-gen7_hiz_3DSTATE_WM(struct ilo_builder *builder, uint32_t hiz_op)
-{
- const uint8_t cmd_len = 3;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
- dw[1] = hiz_op;
- dw[2] = 0;
-}
-
-static inline void
-gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_builder *builder,
- const struct ilo_dsa_state *dsa)
-{
- const uint8_t cmd_len = 3;
- uint32_t dw1, dw2, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- dw1 = dsa->payload[0];
- dw2 = dsa->payload[1];
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_DEPTH_STENCIL) | (cmd_len - 2);
- dw[1] = dw1;
- dw[2] = dw2;
-}
-
-static inline void
-gen8_3DSTATE_WM_HZ_OP(struct ilo_builder *builder, uint32_t op,
- uint16_t width, uint16_t height, int sample_count)
-{
- const uint8_t cmd_len = 5;
- const uint32_t sample_mask = ((1 << sample_count) - 1) | 0x1;
- uint32_t dw1, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- dw1 = op;
-
- switch (sample_count) {
- case 0:
- case 1:
- dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_1;
- break;
- case 2:
- dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_2;
- break;
- case 4:
- dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_4;
- break;
- case 8:
- dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_8;
- break;
- case 16:
- dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_16;
- break;
- default:
- assert(!"unsupported sample count");
- dw1 |= GEN8_WM_HZ_DW1_NUMSAMPLES_1;
- break;
- }
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_HZ_OP) | (cmd_len - 2);
- dw[1] = dw1;
- dw[2] = 0;
- /* exclusive? */
- dw[3] = height << 16 | width;
- dw[4] = sample_mask;
-}
-
-static inline void
-gen8_disable_3DSTATE_WM_HZ_OP(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 5;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_HZ_OP) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- dw[4] = 0;
-}
-
-static inline void
-gen8_3DSTATE_WM_CHROMAKEY(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_CHROMAKEY) | (cmd_len - 2);
- dw[1] = 0;
-}
-
-static inline void
-gen7_3DSTATE_PS(struct ilo_builder *builder,
- const struct ilo_shader_state *fs,
- bool dual_blend)
-{
- const uint8_t cmd_len = 8;
- const struct ilo_shader_cso *cso;
- uint32_t dw2, dw4, dw5, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- /* see fs_init_cso_gen7() */
- cso = ilo_shader_get_kernel_cso(fs);
- dw2 = cso->payload[0];
- dw4 = cso->payload[1];
- dw5 = cso->payload[2];
-
- if (dual_blend)
- dw4 |= GEN7_PS_DW4_DUAL_SOURCE_BLEND;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
- dw[1] = ilo_shader_get_kernel_offset(fs);
- dw[2] = dw2;
- dw[3] = 0; /* scratch */
- dw[4] = dw4;
- dw[5] = dw5;
- dw[6] = 0; /* kernel 1 */
- dw[7] = 0; /* kernel 2 */
-}
-
-static inline void
-gen7_disable_3DSTATE_PS(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 8;
- int max_threads;
- uint32_t dw4, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- /* GPU hangs if none of the dispatch enable bits is set */
- dw4 = GEN6_PS_DISPATCH_8 << GEN7_PS_DW4_DISPATCH_MODE__SHIFT;
-
- /* see brwCreateContext() */
- switch (ilo_dev_gen(builder->dev)) {
- case ILO_GEN(7.5):
- max_threads = (builder->dev->gt == 3) ? 408 :
- (builder->dev->gt == 2) ? 204 : 102;
- dw4 |= (max_threads - 1) << GEN75_PS_DW4_MAX_THREADS__SHIFT;
- break;
- case ILO_GEN(7):
- default:
- max_threads = (builder->dev->gt == 2) ? 172 : 48;
- dw4 |= (max_threads - 1) << GEN7_PS_DW4_MAX_THREADS__SHIFT;
- break;
- }
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- dw[4] = dw4;
- dw[5] = 0;
- dw[6] = 0;
- dw[7] = 0;
-}
-
-static inline void
-gen8_3DSTATE_PS(struct ilo_builder *builder,
- const struct ilo_shader_state *fs)
-{
- const uint8_t cmd_len = 12;
- const struct ilo_shader_cso *cso;
- uint32_t dw3, dw6, dw7, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- /* see fs_init_cso_gen8() */
- cso = ilo_shader_get_kernel_cso(fs);
- dw3 = cso->payload[0];
- dw6 = cso->payload[1];
- dw7 = cso->payload[2];
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
- dw[1] = ilo_shader_get_kernel_offset(fs);
- dw[2] = 0;
- dw[3] = dw3;
- dw[4] = 0; /* scratch */
- dw[5] = 0;
- dw[6] = dw6;
- dw[7] = dw7;
- dw[8] = 0; /* kernel 1 */
- dw[9] = 0;
- dw[10] = 0; /* kernel 2 */
- dw[11] = 0;
-}
-
-static inline void
-gen8_3DSTATE_PS_EXTRA(struct ilo_builder *builder,
- const struct ilo_shader_state *fs,
- bool cc_may_kill, bool per_sample)
-{
- const uint8_t cmd_len = 2;
- const struct ilo_shader_cso *cso;
- uint32_t dw1, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- /* see fs_init_cso_gen8() */
- cso = ilo_shader_get_kernel_cso(fs);
- dw1 = cso->payload[3];
-
- if (cc_may_kill)
- dw1 |= GEN8_PSX_DW1_DISPATCH_ENABLE | GEN8_PSX_DW1_KILL_PIXEL;
- if (per_sample)
- dw1 |= GEN8_PSX_DW1_PER_SAMPLE;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_EXTRA) | (cmd_len - 2);
- dw[1] = dw1;
-}
-
-static inline void
-gen8_3DSTATE_PS_BLEND(struct ilo_builder *builder,
- const struct ilo_blend_state *blend,
- const struct ilo_fb_state *fb,
- const struct ilo_dsa_state *dsa)
-{
- const uint8_t cmd_len = 2;
- uint32_t dw1, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- dw1 = 0;
- if (blend->alpha_to_coverage && fb->num_samples > 1)
- dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE;
-
- if (fb->state.nr_cbufs && fb->state.cbufs[0]) {
- const struct ilo_fb_blend_caps *caps = &fb->blend_caps[0];
-
- dw1 |= GEN8_PS_BLEND_DW1_WRITABLE_RT;
- if (caps->can_blend) {
- if (caps->dst_alpha_forced_one)
- dw1 |= blend->dw_ps_blend_dst_alpha_forced_one;
- else
- dw1 |= blend->dw_ps_blend;
- }
-
- if (caps->can_alpha_test)
- dw1 |= dsa->dw_ps_blend_alpha;
- } else {
- dw1 |= dsa->dw_ps_blend_alpha;
- }
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_BLEND) | (cmd_len - 2);
- dw[1] = dw1;
-}
-
-static inline void
-gen6_3DSTATE_CONSTANT_PS(struct ilo_builder *builder,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
- bufs, sizes, num_bufs);
-}
-
-static inline void
-gen7_3DSTATE_CONSTANT_PS(struct ilo_builder *builder,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
- bufs, sizes, num_bufs);
-}
-
-static inline void
-gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(struct ilo_builder *builder,
- uint32_t binding_table)
-{
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_PS,
- binding_table);
-}
-
-static inline void
-gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(struct ilo_builder *builder,
- uint32_t sampler_state)
-{
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_PS,
- sampler_state);
-}
-
-static inline void
-gen6_3DSTATE_MULTISAMPLE(struct ilo_builder *builder,
- int num_samples, const uint32_t *pattern,
- bool pixel_location_center)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 3;
- uint32_t dw1, dw2, dw3, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- dw1 = (pixel_location_center) ? GEN6_MULTISAMPLE_DW1_PIXLOC_CENTER :
- GEN6_MULTISAMPLE_DW1_PIXLOC_UL_CORNER;
-
- switch (num_samples) {
- case 0:
- case 1:
- dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
- dw2 = 0;
- dw3 = 0;
- break;
- case 4:
- dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
- dw2 = pattern[0];
- dw3 = 0;
- break;
- case 8:
- assert(ilo_dev_gen(builder->dev) >= ILO_GEN(7));
- dw1 |= GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
- dw2 = pattern[0];
- dw3 = pattern[1];
- break;
- default:
- assert(!"unsupported sample count");
- dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
- dw2 = 0;
- dw3 = 0;
- break;
- }
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE) | (cmd_len - 2);
- dw[1] = dw1;
- dw[2] = dw2;
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
- dw[3] = dw3;
-}
-
-static inline void
-gen8_3DSTATE_MULTISAMPLE(struct ilo_builder *builder,
- int num_samples,
- bool pixel_location_center)
-{
- const uint8_t cmd_len = 2;
- uint32_t dw1, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- dw1 = (pixel_location_center) ? GEN6_MULTISAMPLE_DW1_PIXLOC_CENTER :
- GEN6_MULTISAMPLE_DW1_PIXLOC_UL_CORNER;
-
- switch (num_samples) {
- case 0:
- case 1:
- dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
- break;
- case 2:
- dw1 |= GEN8_MULTISAMPLE_DW1_NUMSAMPLES_2;
- break;
- case 4:
- dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
- break;
- case 8:
- dw1 |= GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
- break;
- case 16:
- dw1 |= GEN8_MULTISAMPLE_DW1_NUMSAMPLES_16;
- break;
- default:
- assert(!"unsupported sample count");
- dw1 |= GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
- break;
- }
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE) | (cmd_len - 2);
- dw[1] = dw1;
-}
-
-static inline void
-gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_builder *builder,
- const uint32_t *pattern_1x,
- const uint32_t *pattern_2x,
- const uint32_t *pattern_4x,
- const uint32_t *pattern_8x,
- const uint32_t *pattern_16x)
-{
- const uint8_t cmd_len = 9;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_SAMPLE_PATTERN) | (cmd_len - 2);
- dw[1] = pattern_16x[3];
- dw[2] = pattern_16x[2];
- dw[3] = pattern_16x[1];
- dw[4] = pattern_16x[0];
- dw[5] = pattern_8x[1];
- dw[6] = pattern_8x[0];
- dw[7] = pattern_4x[0];
- dw[8] = pattern_1x[0] << 16 |
- pattern_2x[0];
-}
-
-static inline void
-gen6_3DSTATE_SAMPLE_MASK(struct ilo_builder *builder,
- unsigned sample_mask)
-{
- const uint8_t cmd_len = 2;
- const unsigned valid_mask = 0xf;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- sample_mask &= valid_mask;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK) | (cmd_len - 2);
- dw[1] = sample_mask;
-}
-
-static inline void
-gen7_3DSTATE_SAMPLE_MASK(struct ilo_builder *builder,
- unsigned sample_mask,
- int num_samples)
-{
- const uint8_t cmd_len = 2;
- const unsigned valid_mask = ((1 << num_samples) - 1) | 0x1;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- /*
- * From the Ivy Bridge PRM, volume 2 part 1, page 294:
- *
- * "If Number of Multisamples is NUMSAMPLES_1, bits 7:1 of this field
- * (Sample Mask) must be zero.
- *
- * If Number of Multisamples is NUMSAMPLES_4, bits 7:4 of this field
- * must be zero."
- */
- sample_mask &= valid_mask;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK) | (cmd_len - 2);
- dw[1] = sample_mask;
-}
-
-static inline void
-gen6_3DSTATE_DRAWING_RECTANGLE(struct ilo_builder *builder,
- unsigned x, unsigned y,
- unsigned width, unsigned height)
-{
- const uint8_t cmd_len = 4;
- unsigned xmax = x + width - 1;
- unsigned ymax = y + height - 1;
- unsigned rect_limit;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
- rect_limit = 16383;
- }
- else {
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 230:
- *
- * "[DevSNB] Errata: This field (Clipped Drawing Rectangle Y Min)
- * must be an even number"
- */
- assert(y % 2 == 0);
-
- rect_limit = 8191;
- }
-
- if (x > rect_limit) x = rect_limit;
- if (y > rect_limit) y = rect_limit;
- if (xmax > rect_limit) xmax = rect_limit;
- if (ymax > rect_limit) ymax = rect_limit;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_DRAWING_RECTANGLE) | (cmd_len - 2);
- dw[1] = y << 16 | x;
- dw[2] = ymax << 16 | xmax;
- /*
- * There is no need to set the origin. It is intended to support front
- * buffer rendering.
- */
- dw[3] = 0;
-}
-
-static inline void
-gen6_3DSTATE_POLY_STIPPLE_OFFSET(struct ilo_builder *builder,
- int x_offset, int y_offset)
-{
- const uint8_t cmd_len = 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(x_offset >= 0 && x_offset <= 31);
- assert(y_offset >= 0 && y_offset <= 31);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_POLY_STIPPLE_OFFSET) | (cmd_len - 2);
- dw[1] = x_offset << 8 | y_offset;
-}
-
-static inline void
-gen6_3DSTATE_POLY_STIPPLE_PATTERN(struct ilo_builder *builder,
- const struct pipe_poly_stipple *pattern)
-{
- const uint8_t cmd_len = 33;
- uint32_t *dw;
- int i;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_POLY_STIPPLE_PATTERN) | (cmd_len - 2);
- dw++;
-
- STATIC_ASSERT(Elements(pattern->stipple) == 32);
- for (i = 0; i < 32; i++)
- dw[i] = pattern->stipple[i];
-}
-
-static inline void
-gen6_3DSTATE_LINE_STIPPLE(struct ilo_builder *builder,
- unsigned pattern, unsigned factor)
-{
- const uint8_t cmd_len = 3;
- unsigned inverse;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert((pattern & 0xffff) == pattern);
- assert(factor >= 1 && factor <= 256);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_LINE_STIPPLE) | (cmd_len - 2);
- dw[1] = pattern;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
- /* in U1.16 */
- inverse = 65536 / factor;
-
- dw[2] = inverse << GEN7_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
- factor;
- }
- else {
- /* in U1.13 */
- inverse = 8192 / factor;
-
- dw[2] = inverse << GEN6_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
- factor;
- }
-}
-
-static inline void
-gen6_3DSTATE_AA_LINE_PARAMETERS(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 3;
- const uint32_t dw[3] = {
- GEN6_RENDER_CMD(3D, 3DSTATE_AA_LINE_PARAMETERS) | (cmd_len - 2),
- 0 << GEN6_AA_LINE_DW1_BIAS__SHIFT | 0,
- 0 << GEN6_AA_LINE_DW2_CAP_BIAS__SHIFT | 0,
- };
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- ilo_builder_batch_write(builder, cmd_len, dw);
-}
-
-static inline void
-gen6_3DSTATE_DEPTH_BUFFER(struct ilo_builder *builder,
- const struct ilo_zs_surface *zs,
- bool aligned_8x4)
-{
- const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
- GEN7_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER) :
- GEN6_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER);
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 7;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = cmd | (cmd_len - 2);
- dw[1] = zs->payload[0];
- dw[2] = 0;
-
- /* see ilo_gpe_init_zs_surface() */
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[3] = 0;
- dw[4] = (aligned_8x4) ? zs->dw_aligned_8x4 : zs->payload[2];
- dw[5] = zs->payload[3];
- dw[6] = zs->payload[4];
- dw[7] = zs->payload[5];
-
- dw[5] |= builder->mocs << GEN8_DEPTH_DW5_MOCS__SHIFT;
-
- if (zs->bo) {
- ilo_builder_batch_reloc64(builder, pos + 2, zs->bo,
- zs->payload[1], INTEL_RELOC_WRITE);
- }
- } else {
- dw[3] = (aligned_8x4) ? zs->dw_aligned_8x4 : zs->payload[2];
- dw[4] = zs->payload[3];
- dw[5] = zs->payload[4];
- dw[6] = zs->payload[5];
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
- dw[4] |= builder->mocs << GEN7_DEPTH_DW4_MOCS__SHIFT;
- else
- dw[6] |= builder->mocs << GEN6_DEPTH_DW6_MOCS__SHIFT;
-
- if (zs->bo) {
- ilo_builder_batch_reloc(builder, pos + 2, zs->bo,
- zs->payload[1], INTEL_RELOC_WRITE);
- }
- }
-}
-
-static inline void
-gen6_3DSTATE_STENCIL_BUFFER(struct ilo_builder *builder,
- const struct ilo_zs_surface *zs)
-{
- const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
- GEN7_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER) :
- GEN6_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER);
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = cmd | (cmd_len - 2);
- /* see ilo_gpe_init_zs_surface() */
- dw[1] = zs->payload[6];
- dw[2] = 0;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[1] |= builder->mocs << GEN8_STENCIL_DW1_MOCS__SHIFT;
-
- dw[3] = 0;
- dw[4] = zs->payload[8];
-
- if (zs->separate_s8_bo) {
- ilo_builder_batch_reloc64(builder, pos + 2,
- zs->separate_s8_bo, zs->payload[7], INTEL_RELOC_WRITE);
- }
- } else {
- dw[1] |= builder->mocs << GEN6_STENCIL_DW1_MOCS__SHIFT;
-
- if (zs->separate_s8_bo) {
- ilo_builder_batch_reloc(builder, pos + 2,
- zs->separate_s8_bo, zs->payload[7], INTEL_RELOC_WRITE);
- }
- }
-}
-
-static inline void
-gen6_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_builder *builder,
- const struct ilo_zs_surface *zs)
-{
- const uint32_t cmd = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ?
- GEN7_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER) :
- GEN6_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER);
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = cmd | (cmd_len - 2);
- /* see ilo_gpe_init_zs_surface() */
- dw[1] = zs->payload[9];
- dw[2] = 0;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[1] |= builder->mocs << GEN8_HIZ_DW1_MOCS__SHIFT;
-
- dw[3] = 0;
- dw[4] = zs->payload[11];
-
- if (zs->hiz_bo) {
- ilo_builder_batch_reloc64(builder, pos + 2,
- zs->hiz_bo, zs->payload[10], INTEL_RELOC_WRITE);
- }
- } else {
- dw[1] |= builder->mocs << GEN6_HIZ_DW1_MOCS__SHIFT;
-
- if (zs->hiz_bo) {
- ilo_builder_batch_reloc(builder, pos + 2,
- zs->hiz_bo, zs->payload[10], INTEL_RELOC_WRITE);
- }
- }
-}
-
-static inline void
-gen6_3DSTATE_CLEAR_PARAMS(struct ilo_builder *builder,
- uint32_t clear_val)
-{
- const uint8_t cmd_len = 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CLEAR_PARAMS) |
- GEN6_CLEAR_PARAMS_DW0_VALID |
- (cmd_len - 2);
- dw[1] = clear_val;
-}
-
-static inline void
-gen7_3DSTATE_CLEAR_PARAMS(struct ilo_builder *builder,
- uint32_t clear_val)
-{
- const uint8_t cmd_len = 3;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_CLEAR_PARAMS) | (cmd_len - 2);
- dw[1] = clear_val;
- dw[2] = GEN7_CLEAR_PARAMS_DW2_VALID;
-}
-
-static inline void
-gen6_3DSTATE_VIEWPORT_STATE_POINTERS(struct ilo_builder *builder,
- uint32_t clip_viewport,
- uint32_t sf_viewport,
- uint32_t cc_viewport)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VIEWPORT_STATE_POINTERS) |
- GEN6_VP_PTR_DW0_CLIP_CHANGED |
- GEN6_VP_PTR_DW0_SF_CHANGED |
- GEN6_VP_PTR_DW0_CC_CHANGED |
- (cmd_len - 2);
- dw[1] = clip_viewport;
- dw[2] = sf_viewport;
- dw[3] = cc_viewport;
-}
-
-static inline void
-gen6_3DSTATE_SCISSOR_STATE_POINTERS(struct ilo_builder *builder,
- uint32_t scissor_rect)
-{
- const uint8_t cmd_len = 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SCISSOR_STATE_POINTERS) |
- (cmd_len - 2);
- dw[1] = scissor_rect;
-}
-
-static inline void
-gen6_3DSTATE_CC_STATE_POINTERS(struct ilo_builder *builder,
- uint32_t blend_state,
- uint32_t depth_stencil_state,
- uint32_t color_calc_state)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_CC_STATE_POINTERS) | (cmd_len - 2);
- dw[1] = blend_state | GEN6_CC_PTR_DW1_BLEND_CHANGED;
- dw[2] = depth_stencil_state | GEN6_CC_PTR_DW2_ZS_CHANGED;
- dw[3] = color_calc_state | GEN6_CC_PTR_DW3_CC_CHANGED;
-}
-
-static inline void
-gen7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP(struct ilo_builder *builder,
- uint32_t sf_clip_viewport)
-{
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
- sf_clip_viewport);
-}
-
-static inline void
-gen7_3DSTATE_VIEWPORT_STATE_POINTERS_CC(struct ilo_builder *builder,
- uint32_t cc_viewport)
-{
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
- cc_viewport);
-}
-
-static inline void
-gen7_3DSTATE_CC_STATE_POINTERS(struct ilo_builder *builder,
- uint32_t color_calc_state)
-{
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
- color_calc_state |= 1;
-
- gen7_3dstate_pointer(builder,
- GEN6_RENDER_OPCODE_3DSTATE_CC_STATE_POINTERS, color_calc_state);
-}
-
-static inline void
-gen7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(struct ilo_builder *builder,
- uint32_t depth_stencil_state)
-{
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_DEPTH_STENCIL_STATE_POINTERS,
- depth_stencil_state);
-}
-
-static inline void
-gen7_3DSTATE_BLEND_STATE_POINTERS(struct ilo_builder *builder,
- uint32_t blend_state)
-{
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
- blend_state |= 1;
-
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_BLEND_STATE_POINTERS,
- blend_state);
-}
-
-static inline uint32_t
-gen6_CLIP_VIEWPORT(struct ilo_builder *builder,
- const struct ilo_viewport_cso *viewports,
- unsigned num_viewports)
-{
- const int state_align = 32;
- const int state_len = 4 * num_viewports;
- uint32_t state_offset, *dw;
- unsigned i;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 193:
- *
- * "The viewport-related state is stored as an array of up to 16
- * elements..."
- */
- assert(num_viewports && num_viewports <= 16);
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_CLIP_VIEWPORT, state_align, state_len, &dw);
-
- for (i = 0; i < num_viewports; i++) {
- const struct ilo_viewport_cso *vp = &viewports[i];
-
- dw[0] = fui(vp->min_gbx);
- dw[1] = fui(vp->max_gbx);
- dw[2] = fui(vp->min_gby);
- dw[3] = fui(vp->max_gby);
-
- dw += 4;
- }
-
- return state_offset;
-}
-
-static inline uint32_t
-gen6_SF_VIEWPORT(struct ilo_builder *builder,
- const struct ilo_viewport_cso *viewports,
- unsigned num_viewports)
-{
- const int state_align = 32;
- const int state_len = 8 * num_viewports;
- uint32_t state_offset, *dw;
- unsigned i;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 262:
- *
- * "The viewport-specific state used by the SF unit (SF_VIEWPORT) is
- * stored as an array of up to 16 elements..."
- */
- assert(num_viewports && num_viewports <= 16);
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_SF_VIEWPORT, state_align, state_len, &dw);
-
- for (i = 0; i < num_viewports; i++) {
- const struct ilo_viewport_cso *vp = &viewports[i];
-
- dw[0] = fui(vp->m00);
- dw[1] = fui(vp->m11);
- dw[2] = fui(vp->m22);
- dw[3] = fui(vp->m30);
- dw[4] = fui(vp->m31);
- dw[5] = fui(vp->m32);
- dw[6] = 0;
- dw[7] = 0;
-
- dw += 8;
- }
-
- return state_offset;
-}
-
-static inline uint32_t
-gen7_SF_CLIP_VIEWPORT(struct ilo_builder *builder,
- const struct ilo_viewport_cso *viewports,
- unsigned num_viewports)
-{
- const int state_align = 64;
- const int state_len = 16 * num_viewports;
- uint32_t state_offset, *dw;
- unsigned i;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- /*
- * From the Ivy Bridge PRM, volume 2 part 1, page 270:
- *
- * "The viewport-specific state used by both the SF and CL units
- * (SF_CLIP_VIEWPORT) is stored as an array of up to 16 elements, each
- * of which contains the DWords described below. The start of each
- * element is spaced 16 DWords apart. The location of first element of
- * the array, as specified by both Pointer to SF_VIEWPORT and Pointer
- * to CLIP_VIEWPORT, is aligned to a 64-byte boundary."
- */
- assert(num_viewports && num_viewports <= 16);
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_SF_VIEWPORT, state_align, state_len, &dw);
-
- for (i = 0; i < num_viewports; i++) {
- const struct ilo_viewport_cso *vp = &viewports[i];
-
- dw[0] = fui(vp->m00);
- dw[1] = fui(vp->m11);
- dw[2] = fui(vp->m22);
- dw[3] = fui(vp->m30);
- dw[4] = fui(vp->m31);
- dw[5] = fui(vp->m32);
- dw[6] = 0;
- dw[7] = 0;
-
- dw[8] = fui(vp->min_gbx);
- dw[9] = fui(vp->max_gbx);
- dw[10] = fui(vp->min_gby);
- dw[11] = fui(vp->max_gby);
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[12] = fui(vp->min_x);
- dw[13] = fui(vp->max_x - 1.0f);
- dw[14] = fui(vp->min_y);
- dw[15] = fui(vp->max_y - 1.0f);
- } else {
- dw[12] = 0;
- dw[13] = 0;
- dw[14] = 0;
- dw[15] = 0;
- }
-
- dw += 16;
- }
-
- return state_offset;
-}
-
-static inline uint32_t
-gen6_CC_VIEWPORT(struct ilo_builder *builder,
- const struct ilo_viewport_cso *viewports,
- unsigned num_viewports)
-{
- const int state_align = 32;
- const int state_len = 2 * num_viewports;
- uint32_t state_offset, *dw;
- unsigned i;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 385:
- *
- * "The viewport state is stored as an array of up to 16 elements..."
- */
- assert(num_viewports && num_viewports <= 16);
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_CC_VIEWPORT, state_align, state_len, &dw);
-
- for (i = 0; i < num_viewports; i++) {
- const struct ilo_viewport_cso *vp = &viewports[i];
-
- dw[0] = fui(vp->min_z);
- dw[1] = fui(vp->max_z);
-
- dw += 2;
- }
-
- return state_offset;
-}
-
-static inline uint32_t
-gen6_SCISSOR_RECT(struct ilo_builder *builder,
- const struct ilo_scissor_state *scissor,
- unsigned num_viewports)
-{
- const int state_align = 32;
- const int state_len = 2 * num_viewports;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 263:
- *
- * "The viewport-specific state used by the SF unit (SCISSOR_RECT) is
- * stored as an array of up to 16 elements..."
- */
- assert(num_viewports && num_viewports <= 16);
- assert(Elements(scissor->payload) >= state_len);
-
- return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_SCISSOR_RECT,
- state_align, state_len, scissor->payload);
-}
-
-static inline uint32_t
-gen6_COLOR_CALC_STATE(struct ilo_builder *builder,
- const struct pipe_stencil_ref *stencil_ref,
- ubyte alpha_ref,
- const struct pipe_blend_color *blend_color)
-{
- const int state_align = 64;
- const int state_len = 6;
- uint32_t state_offset, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_COLOR_CALC, state_align, state_len, &dw);
-
- dw[0] = stencil_ref->ref_value[0] << 24 |
- stencil_ref->ref_value[1] << 16 |
- GEN6_CC_DW0_ALPHATEST_UNORM8;
- dw[1] = alpha_ref;
- dw[2] = fui(blend_color->color[0]);
- dw[3] = fui(blend_color->color[1]);
- dw[4] = fui(blend_color->color[2]);
- dw[5] = fui(blend_color->color[3]);
-
- return state_offset;
-}
-
-static inline uint32_t
-gen6_DEPTH_STENCIL_STATE(struct ilo_builder *builder,
- const struct ilo_dsa_state *dsa)
-{
- const int state_align = 64;
- const int state_len = 3;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- STATIC_ASSERT(Elements(dsa->payload) >= state_len);
-
- return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_DEPTH_STENCIL,
- state_align, state_len, dsa->payload);
-}
-
-static inline uint32_t
-gen6_BLEND_STATE(struct ilo_builder *builder,
- const struct ilo_blend_state *blend,
- const struct ilo_fb_state *fb,
- const struct ilo_dsa_state *dsa)
-{
- const int state_align = 64;
- int state_len;
- uint32_t state_offset, *dw;
- unsigned num_targets, i;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 376:
- *
- * "The blend state is stored as an array of up to 8 elements..."
- */
- num_targets = fb->state.nr_cbufs;
- assert(num_targets <= 8);
-
- if (!num_targets) {
- if (!dsa->dw_blend_alpha)
- return 0;
- /* to be able to reference alpha func */
- num_targets = 1;
- }
-
- state_len = 2 * num_targets;
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
-
- for (i = 0; i < num_targets; i++) {
- const struct ilo_blend_cso *cso = &blend->cso[i];
-
- dw[0] = cso->payload[0];
- dw[1] = cso->payload[1] | blend->dw_shared;
-
- if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) {
- const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
-
- if (caps->can_blend) {
- if (caps->dst_alpha_forced_one)
- dw[0] |= cso->dw_blend_dst_alpha_forced_one;
- else
- dw[0] |= cso->dw_blend;
- }
-
- if (caps->can_logicop)
- dw[1] |= blend->dw_logicop;
-
- if (caps->can_alpha_test)
- dw[1] |= dsa->dw_blend_alpha;
- } else {
- dw[1] |= GEN6_RT_DW1_WRITE_DISABLE_A |
- GEN6_RT_DW1_WRITE_DISABLE_R |
- GEN6_RT_DW1_WRITE_DISABLE_G |
- GEN6_RT_DW1_WRITE_DISABLE_B |
- dsa->dw_blend_alpha;
- }
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 356:
- *
- * "When NumSamples = 1, AlphaToCoverage and AlphaToCoverage
- * Dither both must be disabled."
- *
- * There is no such limitation on GEN7, or for AlphaToOne. But GL
- * requires that anyway.
- */
- if (fb->num_samples > 1)
- dw[1] |= blend->dw_alpha_mod;
-
- dw += 2;
- }
-
- return state_offset;
-}
-
-static inline uint32_t
-gen8_BLEND_STATE(struct ilo_builder *builder,
- const struct ilo_blend_state *blend,
- const struct ilo_fb_state *fb,
- const struct ilo_dsa_state *dsa)
-{
- const int state_align = 64;
- const int state_len = 1 + 2 * fb->state.nr_cbufs;
- uint32_t state_offset, *dw;
- unsigned i;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- assert(fb->state.nr_cbufs <= 8);
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
-
- dw[0] = blend->dw_shared;
- if (fb->num_samples > 1)
- dw[0] |= blend->dw_alpha_mod;
- if (!fb->state.nr_cbufs || fb->blend_caps[0].can_alpha_test)
- dw[0] |= dsa->dw_blend_alpha;
- dw++;
-
- for (i = 0; i < fb->state.nr_cbufs; i++) {
- const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
- const struct ilo_blend_cso *cso = &blend->cso[i];
-
- dw[0] = cso->payload[0];
- dw[1] = cso->payload[1];
-
- if (fb->state.cbufs[i]) {
- if (caps->can_blend) {
- if (caps->dst_alpha_forced_one)
- dw[0] |= cso->dw_blend_dst_alpha_forced_one;
- else
- dw[0] |= cso->dw_blend;
- }
-
- if (caps->can_logicop)
- dw[1] |= blend->dw_logicop;
- } else {
- dw[0] |= GEN8_RT_DW0_WRITE_DISABLE_A |
- GEN8_RT_DW0_WRITE_DISABLE_R |
- GEN8_RT_DW0_WRITE_DISABLE_G |
- GEN8_RT_DW0_WRITE_DISABLE_B;
- }
-
- dw += 2;
- }
-
- return state_offset;
-}
-
-#endif /* ILO_BUILDER_3D_BOTTOM_H */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_BUILDER_3D_TOP_H
-#define ILO_BUILDER_3D_TOP_H
-
-#include "genhw/genhw.h"
-#include "core/ilo_state_3d.h"
-#include "core/intel_winsys.h"
-
-#include "ilo_common.h"
-#include "ilo_resource.h"
-#include "ilo_shader.h"
-#include "ilo_state.h"
-#include "ilo_builder.h"
-
-static inline void
-gen6_3DSTATE_URB(struct ilo_builder *builder,
- int vs_total_size, int gs_total_size,
- int vs_entry_size, int gs_entry_size)
-{
- const uint8_t cmd_len = 3;
- const int row_size = 128; /* 1024 bits */
- int vs_alloc_size, gs_alloc_size;
- int vs_num_entries, gs_num_entries;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- /* in 1024-bit URB rows */
- vs_alloc_size = (vs_entry_size + row_size - 1) / row_size;
- gs_alloc_size = (gs_entry_size + row_size - 1) / row_size;
-
- /* the valid range is [1, 5] */
- if (!vs_alloc_size)
- vs_alloc_size = 1;
- if (!gs_alloc_size)
- gs_alloc_size = 1;
- assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
-
- /* the valid range is [24, 256] in multiples of 4 */
- vs_num_entries = (vs_total_size / row_size / vs_alloc_size) & ~3;
- if (vs_num_entries > 256)
- vs_num_entries = 256;
- assert(vs_num_entries >= 24);
-
- /* the valid range is [0, 256] in multiples of 4 */
- gs_num_entries = (gs_total_size / row_size / gs_alloc_size) & ~3;
- if (gs_num_entries > 256)
- gs_num_entries = 256;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_URB) | (cmd_len - 2);
- dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
- vs_num_entries << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
- dw[2] = gs_num_entries << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
- (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
-}
-
-static inline void
-gen7_3dstate_push_constant_alloc(struct ilo_builder *builder,
- int subop, int offset, int size)
-{
- const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
- GEN6_RENDER_SUBTYPE_3D |
- subop;
- const uint8_t cmd_len = 2;
- const int slice_count = ((ilo_dev_gen(builder->dev) == ILO_GEN(7.5) &&
- builder->dev->gt == 3) ||
- ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 2 : 1;
- uint32_t *dw;
- int end;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- /* VS, HS, DS, GS, and PS variants */
- assert(subop >= GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_VS &&
- subop <= GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_PS);
-
- /*
- * From the Ivy Bridge PRM, volume 2 part 1, page 68:
- *
- * "(A table that says the maximum size of each constant buffer is
- * 16KB")
- *
- * From the Ivy Bridge PRM, volume 2 part 1, page 115:
- *
- * "The sum of the Constant Buffer Offset and the Constant Buffer Size
- * may not exceed the maximum value of the Constant Buffer Size."
- *
- * Thus, the valid range of buffer end is [0KB, 16KB].
- */
- end = (offset + size) / 1024;
- if (end > 16 * slice_count) {
- assert(!"invalid constant buffer end");
- end = 16 * slice_count;
- }
-
- /* the valid range of buffer offset is [0KB, 15KB] */
- offset = (offset + 1023) / 1024;
- if (offset > 15 * slice_count) {
- assert(!"invalid constant buffer offset");
- offset = 15 * slice_count;
- }
-
- if (offset > end) {
- assert(!size);
- offset = end;
- }
-
- /* the valid range of buffer size is [0KB, 15KB] */
- size = end - offset;
- if (size > 15 * slice_count) {
- assert(!"invalid constant buffer size");
- size = 15 * slice_count;
- }
-
- assert(offset % slice_count == 0 && size % slice_count == 0);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = cmd | (cmd_len - 2);
- dw[1] = offset << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
- size;
-}
-
-static inline void
-gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(struct ilo_builder *builder,
- int offset, int size)
-{
- gen7_3dstate_push_constant_alloc(builder,
- GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_VS, offset, size);
-}
-
-static inline void
-gen7_3DSTATE_PUSH_CONSTANT_ALLOC_HS(struct ilo_builder *builder,
- int offset, int size)
-{
- gen7_3dstate_push_constant_alloc(builder,
- GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_HS, offset, size);
-}
-
-static inline void
-gen7_3DSTATE_PUSH_CONSTANT_ALLOC_DS(struct ilo_builder *builder,
- int offset, int size)
-{
- gen7_3dstate_push_constant_alloc(builder,
- GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_DS, offset, size);
-}
-
-static inline void
-gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(struct ilo_builder *builder,
- int offset, int size)
-{
- gen7_3dstate_push_constant_alloc(builder,
- GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_GS, offset, size);
-}
-
-static inline void
-gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(struct ilo_builder *builder,
- int offset, int size)
-{
- gen7_3dstate_push_constant_alloc(builder,
- GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_PS, offset, size);
-}
-
-static inline void
-gen7_3dstate_urb(struct ilo_builder *builder,
- int subop, int offset, int size,
- int entry_size)
-{
- const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
- GEN6_RENDER_SUBTYPE_3D |
- subop;
- const uint8_t cmd_len = 2;
- const int row_size = 64; /* 512 bits */
- int alloc_size, num_entries, min_entries, max_entries;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- /* VS, HS, DS, and GS variants */
- assert(subop >= GEN7_RENDER_OPCODE_3DSTATE_URB_VS &&
- subop <= GEN7_RENDER_OPCODE_3DSTATE_URB_GS);
-
- /* in multiples of 8KB */
- assert(offset % 8192 == 0);
- offset /= 8192;
-
- /* in multiple of 512-bit rows */
- alloc_size = (entry_size + row_size - 1) / row_size;
- if (!alloc_size)
- alloc_size = 1;
-
- /*
- * From the Ivy Bridge PRM, volume 2 part 1, page 34:
- *
- * "VS URB Entry Allocation Size equal to 4(5 512-bit URB rows) may
- * cause performance to decrease due to banking in the URB. Element
- * sizes of 16 to 20 should be programmed with six 512-bit URB rows."
- */
- if (subop == GEN7_RENDER_OPCODE_3DSTATE_URB_VS && alloc_size == 5)
- alloc_size = 6;
-
- /* in multiples of 8 */
- num_entries = (size / row_size / alloc_size) & ~7;
-
- switch (subop) {
- case GEN7_RENDER_OPCODE_3DSTATE_URB_VS:
- switch (ilo_dev_gen(builder->dev)) {
- case ILO_GEN(8):
- max_entries = 2560;
- min_entries = 64;
- break;
- case ILO_GEN(7.5):
- max_entries = (builder->dev->gt >= 2) ? 1664 : 640;
- min_entries = (builder->dev->gt >= 2) ? 64 : 32;
- break;
- case ILO_GEN(7):
- default:
- max_entries = (builder->dev->gt == 2) ? 704 : 512;
- min_entries = 32;
- break;
- }
-
- assert(num_entries >= min_entries);
- if (num_entries > max_entries)
- num_entries = max_entries;
- break;
- case GEN7_RENDER_OPCODE_3DSTATE_URB_HS:
- max_entries = (builder->dev->gt == 2) ? 64 : 32;
- if (num_entries > max_entries)
- num_entries = max_entries;
- break;
- case GEN7_RENDER_OPCODE_3DSTATE_URB_DS:
- if (num_entries)
- assert(num_entries >= 138);
- break;
- case GEN7_RENDER_OPCODE_3DSTATE_URB_GS:
- switch (ilo_dev_gen(builder->dev)) {
- case ILO_GEN(8):
- max_entries = 960;
- break;
- case ILO_GEN(7.5):
- max_entries = (builder->dev->gt >= 2) ? 640 : 256;
- break;
- case ILO_GEN(7):
- default:
- max_entries = (builder->dev->gt == 2) ? 320 : 192;
- break;
- }
-
- if (num_entries > max_entries)
- num_entries = max_entries;
- break;
- default:
- break;
- }
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = cmd | (cmd_len - 2);
- dw[1] = offset << GEN7_URB_DW1_OFFSET__SHIFT |
- (alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
- num_entries;
-}
-
-static inline void
-gen7_3DSTATE_URB_VS(struct ilo_builder *builder,
- int offset, int size, int entry_size)
-{
- gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_VS,
- offset, size, entry_size);
-}
-
-static inline void
-gen7_3DSTATE_URB_HS(struct ilo_builder *builder,
- int offset, int size, int entry_size)
-{
- gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_HS,
- offset, size, entry_size);
-}
-
-static inline void
-gen7_3DSTATE_URB_DS(struct ilo_builder *builder,
- int offset, int size, int entry_size)
-{
- gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_DS,
- offset, size, entry_size);
-}
-
-static inline void
-gen7_3DSTATE_URB_GS(struct ilo_builder *builder,
- int offset, int size, int entry_size)
-{
- gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_GS,
- offset, size, entry_size);
-}
-
-static inline void
-gen75_3DSTATE_VF(struct ilo_builder *builder,
- bool enable_cut_index,
- uint32_t cut_index)
-{
- const uint8_t cmd_len = 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7.5, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2);
- if (enable_cut_index)
- dw[0] |= GEN75_VF_DW0_CUT_INDEX_ENABLE;
-
- dw[1] = cut_index;
-}
-
-static inline void
-gen6_3DSTATE_VF_STATISTICS(struct ilo_builder *builder,
- bool enable)
-{
- const uint8_t cmd_len = 1;
- const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, 3DSTATE_VF_STATISTICS) |
- enable;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- ilo_builder_batch_write(builder, cmd_len, &dw0);
-}
-
-/**
- * Translate a pipe primitive type to the matching hardware primitive type.
- */
-static inline int
-gen6_3d_translate_pipe_prim(unsigned prim)
-{
- static const int prim_mapping[ILO_PRIM_MAX] = {
- [PIPE_PRIM_POINTS] = GEN6_3DPRIM_POINTLIST,
- [PIPE_PRIM_LINES] = GEN6_3DPRIM_LINELIST,
- [PIPE_PRIM_LINE_LOOP] = GEN6_3DPRIM_LINELOOP,
- [PIPE_PRIM_LINE_STRIP] = GEN6_3DPRIM_LINESTRIP,
- [PIPE_PRIM_TRIANGLES] = GEN6_3DPRIM_TRILIST,
- [PIPE_PRIM_TRIANGLE_STRIP] = GEN6_3DPRIM_TRISTRIP,
- [PIPE_PRIM_TRIANGLE_FAN] = GEN6_3DPRIM_TRIFAN,
- [PIPE_PRIM_QUADS] = GEN6_3DPRIM_QUADLIST,
- [PIPE_PRIM_QUAD_STRIP] = GEN6_3DPRIM_QUADSTRIP,
- [PIPE_PRIM_POLYGON] = GEN6_3DPRIM_POLYGON,
- [PIPE_PRIM_LINES_ADJACENCY] = GEN6_3DPRIM_LINELIST_ADJ,
- [PIPE_PRIM_LINE_STRIP_ADJACENCY] = GEN6_3DPRIM_LINESTRIP_ADJ,
- [PIPE_PRIM_TRIANGLES_ADJACENCY] = GEN6_3DPRIM_TRILIST_ADJ,
- [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY] = GEN6_3DPRIM_TRISTRIP_ADJ,
- [ILO_PRIM_RECTANGLES] = GEN6_3DPRIM_RECTLIST,
- };
-
- assert(prim_mapping[prim]);
-
- return prim_mapping[prim];
-}
-
-static inline void
-gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, unsigned pipe_prim)
-{
- const uint8_t cmd_len = 2;
- const int prim = gen6_3d_translate_pipe_prim(pipe_prim);
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_TOPOLOGY) | (cmd_len - 2);
- dw[1] = prim;
-}
-
-static inline void
-gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder,
- int vb_index, uint32_t step_rate)
-{
- const uint8_t cmd_len = 3;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_INSTANCING) | (cmd_len - 2);
- dw[1] = vb_index;
- if (step_rate)
- dw[1] |= GEN8_INSTANCING_DW1_ENABLE;
- dw[2] = step_rate;
-}
-
-static inline void
-gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
- bool vid_enable, int vid_ve, int vid_comp,
- bool iid_enable, int iid_ve, int iid_comp)
-{
- const uint8_t cmd_len = 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_SGVS) | (cmd_len - 2);
- dw[1] = 0;
-
- if (iid_enable) {
- dw[1] |= GEN8_SGVS_DW1_IID_ENABLE |
- vid_comp << GEN8_SGVS_DW1_IID_VE_COMP__SHIFT |
- vid_ve << GEN8_SGVS_DW1_IID_VE_INDEX__SHIFT;
- }
-
- if (vid_enable) {
- dw[1] |= GEN8_SGVS_DW1_VID_ENABLE |
- vid_comp << GEN8_SGVS_DW1_VID_VE_COMP__SHIFT |
- vid_ve << GEN8_SGVS_DW1_VID_VE_INDEX__SHIFT;
- }
-}
-
-static inline void
-gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
- const struct ilo_ve_state *ve,
- const struct ilo_vb_state *vb)
-{
- uint8_t cmd_len;
- uint32_t *dw;
- unsigned pos, hw_idx;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 82:
- *
- * "From 1 to 33 VBs can be specified..."
- */
- assert(ve->vb_count <= 33);
-
- if (!ve->vb_count)
- return;
-
- cmd_len = 1 + 4 * ve->vb_count;
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
- dw++;
- pos++;
-
- for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) {
- const unsigned instance_divisor = ve->instance_divisors[hw_idx];
- const unsigned pipe_idx = ve->vb_mapping[hw_idx];
- const struct pipe_vertex_buffer *cso = &vb->states[pipe_idx];
-
- dw[0] = hw_idx << GEN6_VB_DW0_INDEX__SHIFT;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
- dw[0] |= builder->mocs << GEN8_VB_DW0_MOCS__SHIFT;
- else
- dw[0] |= builder->mocs << GEN6_VB_DW0_MOCS__SHIFT;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
- dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
-
- if (instance_divisor)
- dw[0] |= GEN6_VB_DW0_ACCESS_INSTANCEDATA;
- else
- dw[0] |= GEN6_VB_DW0_ACCESS_VERTEXDATA;
-
- /* use null vb if there is no buffer or the stride is out of range */
- if (!cso->buffer || cso->stride > 2048) {
- dw[0] |= GEN6_VB_DW0_IS_NULL;
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ?
- 0 : instance_divisor;
-
- continue;
- }
-
- dw[0] |= cso->stride << GEN6_VB_DW0_PITCH__SHIFT;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
- const uint32_t start_offset = cso->buffer_offset;
-
- ilo_builder_batch_reloc64(builder, pos + 1,
- buf->bo, start_offset, 0);
- dw[3] = buf->bo_size;
- } else {
- const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
- const uint32_t start_offset = cso->buffer_offset;
- const uint32_t end_offset = buf->bo_size - 1;
-
- dw[3] = instance_divisor;
-
- ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
- ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
- }
-
- dw += 4;
- pos += 4;
- }
-}
-
-/* the user vertex buffer must be uploaded with gen6_user_vertex_buffer() */
-static inline void
-gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
- uint32_t vb_begin, uint32_t vb_end,
- uint32_t stride)
-{
- const struct ilo_builder_writer *bat =
- &builder->writers[ILO_BUILDER_WRITER_BATCH];
- const uint8_t cmd_len = 1 + 4;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
- dw++;
- pos++;
-
- /* VERTEX_BUFFER_STATE */
- dw[0] = 0 << GEN6_VB_DW0_INDEX__SHIFT |
- GEN6_VB_DW0_ACCESS_VERTEXDATA |
- stride << GEN6_VB_DW0_PITCH__SHIFT;
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
- dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
-
- dw[3] = 0;
-
- ilo_builder_batch_reloc(builder, pos + 1, bat->bo, vb_begin, 0);
- ilo_builder_batch_reloc(builder, pos + 2, bat->bo, vb_end, 0);
-}
-
-static inline void
-gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder,
- const struct ilo_ve_state *ve)
-{
- uint8_t cmd_len;
- uint32_t *dw;
- unsigned i;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 92:
- *
- * "At least one VERTEX_ELEMENT_STATE structure must be included."
- *
- * From the Sandy Bridge PRM, volume 2 part 1, page 93:
- *
- * "Up to 34 (DevSNB+) vertex elements are supported."
- */
- assert(ve->count + ve->prepend_nosrc_cso >= 1);
- assert(ve->count + ve->prepend_nosrc_cso <= 34);
-
- STATIC_ASSERT(Elements(ve->cso[0].payload) == 2);
-
- cmd_len = 1 + 2 * (ve->count + ve->prepend_nosrc_cso);
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2);
- dw++;
-
- if (ve->prepend_nosrc_cso) {
- memcpy(dw, ve->nosrc_cso.payload, sizeof(ve->nosrc_cso.payload));
- dw += 2;
- }
-
- for (i = 0; i < ve->count - ve->last_cso_edgeflag; i++) {
- memcpy(dw, ve->cso[i].payload, sizeof(ve->cso[i].payload));
- dw += 2;
- }
-
- if (ve->last_cso_edgeflag)
- memcpy(dw, ve->edgeflag_cso.payload, sizeof(ve->edgeflag_cso.payload));
-}
-
-static inline void
-gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
- const struct ilo_ib_state *ib,
- bool enable_cut_index)
-{
- const uint8_t cmd_len = 3;
- struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
- uint32_t start_offset, end_offset;
- int format;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- if (!buf)
- return;
-
- /* this is moved to the new 3DSTATE_VF */
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5))
- assert(!enable_cut_index);
-
- switch (ib->hw_index_size) {
- case 4:
- format = GEN6_IB_DW0_FORMAT_DWORD;
- break;
- case 2:
- format = GEN6_IB_DW0_FORMAT_WORD;
- break;
- case 1:
- format = GEN6_IB_DW0_FORMAT_BYTE;
- break;
- default:
- assert(!"unknown index size");
- format = GEN6_IB_DW0_FORMAT_BYTE;
- break;
- }
-
- /*
- * set start_offset to 0 here and adjust pipe_draw_info::start with
- * ib->draw_start_offset in 3DPRIMITIVE
- */
- start_offset = 0;
- end_offset = buf->bo_size;
-
- /* end_offset must also be aligned and is inclusive */
- end_offset -= (end_offset % ib->hw_index_size);
- end_offset--;
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) |
- builder->mocs << GEN6_IB_DW0_MOCS__SHIFT |
- format;
- if (enable_cut_index)
- dw[0] |= GEN6_IB_DW0_CUT_INDEX_ENABLE;
-
- ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
- ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
-}
-
-static inline void
-gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
- const struct ilo_ib_state *ib)
-{
- const uint8_t cmd_len = 5;
- struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
- int format;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- if (!buf)
- return;
-
- switch (ib->hw_index_size) {
- case 4:
- format = GEN8_IB_DW1_FORMAT_DWORD;
- break;
- case 2:
- format = GEN8_IB_DW1_FORMAT_WORD;
- break;
- case 1:
- format = GEN8_IB_DW1_FORMAT_BYTE;
- break;
- default:
- assert(!"unknown index size");
- format = GEN8_IB_DW1_FORMAT_BYTE;
- break;
- }
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2);
- dw[1] = format |
- builder->mocs << GEN8_IB_DW1_MOCS__SHIFT;
- dw[4] = buf->bo_size;
-
- /* ignore ib->offset here in favor of adjusting 3DPRIMITIVE */
- ilo_builder_batch_reloc64(builder, pos + 2, buf->bo, 0, 0);
-}
-
-static inline void
-gen6_3DSTATE_VS(struct ilo_builder *builder,
- const struct ilo_shader_state *vs)
-{
- const uint8_t cmd_len = 6;
- const struct ilo_shader_cso *cso;
- uint32_t dw2, dw4, dw5, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- cso = ilo_shader_get_kernel_cso(vs);
- dw2 = cso->payload[0];
- dw4 = cso->payload[1];
- dw5 = cso->payload[2];
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
- dw[1] = ilo_shader_get_kernel_offset(vs);
- dw[2] = dw2;
- dw[3] = 0; /* scratch */
- dw[4] = dw4;
- dw[5] = dw5;
-}
-
-static inline void
-gen8_3DSTATE_VS(struct ilo_builder *builder,
- const struct ilo_shader_state *vs,
- uint32_t clip_plane_enable)
-{
- const uint8_t cmd_len = 9;
- const struct ilo_shader_cso *cso;
- uint32_t dw3, dw6, dw7, dw8, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- cso = ilo_shader_get_kernel_cso(vs);
- dw3 = cso->payload[0];
- dw6 = cso->payload[1];
- dw7 = cso->payload[2];
- dw8 = clip_plane_enable << GEN8_VS_DW8_UCP_CLIP_ENABLES__SHIFT;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
- dw[1] = ilo_shader_get_kernel_offset(vs);
- dw[2] = 0;
- dw[3] = dw3;
- dw[4] = 0; /* scratch */
- dw[5] = 0;
- dw[6] = dw6;
- dw[7] = dw7;
- dw[8] = dw8;
-}
-
-static inline void
-gen6_disable_3DSTATE_VS(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 6;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- dw[4] = 0;
- dw[5] = 0;
-}
-
-static inline void
-gen7_disable_3DSTATE_HS(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 9 : 7;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- dw[4] = 0;
- dw[5] = 0;
- dw[6] = 0;
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[7] = 0;
- dw[8] = 0;
- }
-}
-
-static inline void
-gen7_3DSTATE_TE(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
-}
-
-static inline void
-gen7_disable_3DSTATE_DS(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 9 : 6;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- dw[4] = 0;
- dw[5] = 0;
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[6] = 0;
- dw[7] = 0;
- dw[8] = 0;
- }
-}
-
-static inline void
-gen6_3DSTATE_GS(struct ilo_builder *builder,
- const struct ilo_shader_state *gs)
-{
- const uint8_t cmd_len = 7;
- const struct ilo_shader_cso *cso;
- uint32_t dw2, dw4, dw5, dw6, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- cso = ilo_shader_get_kernel_cso(gs);
- dw2 = cso->payload[0];
- dw4 = cso->payload[1];
- dw5 = cso->payload[2];
- dw6 = cso->payload[3];
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
- dw[1] = ilo_shader_get_kernel_offset(gs);
- dw[2] = dw2;
- dw[3] = 0; /* scratch */
- dw[4] = dw4;
- dw[5] = dw5;
- dw[6] = dw6;
-}
-
-static inline void
-gen6_so_3DSTATE_GS(struct ilo_builder *builder,
- const struct ilo_shader_state *vs,
- int verts_per_prim)
-{
- const uint8_t cmd_len = 7;
- struct ilo_shader_cso cso;
- enum ilo_kernel_param param;
- uint32_t dw2, dw4, dw5, dw6, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- assert(ilo_shader_get_kernel_param(vs, ILO_KERNEL_VS_GEN6_SO));
-
- switch (verts_per_prim) {
- case 1:
- param = ILO_KERNEL_VS_GEN6_SO_POINT_OFFSET;
- break;
- case 2:
- param = ILO_KERNEL_VS_GEN6_SO_LINE_OFFSET;
- break;
- default:
- param = ILO_KERNEL_VS_GEN6_SO_TRI_OFFSET;
- break;
- }
-
- /* cannot use VS's CSO */
- ilo_gpe_init_gs_cso(builder->dev, vs, &cso);
- dw2 = cso.payload[0];
- dw4 = cso.payload[1];
- dw5 = cso.payload[2];
- dw6 = cso.payload[3];
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
- dw[1] = ilo_shader_get_kernel_offset(vs) +
- ilo_shader_get_kernel_param(vs, param);
- dw[2] = dw2;
- dw[3] = 0;
- dw[4] = dw4;
- dw[5] = dw5;
- dw[6] = dw6;
-}
-
-static inline void
-gen6_disable_3DSTATE_GS(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 7;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- /* honor the valid range of URB read length */
- dw[4] = 1 << GEN6_GS_DW4_URB_READ_LEN__SHIFT;
- dw[5] = GEN6_GS_DW5_STATISTICS;
- dw[6] = 0;
-}
-
-static inline void
-gen6_3DSTATE_GS_SVB_INDEX(struct ilo_builder *builder,
- int index, unsigned svbi,
- unsigned max_svbi,
- bool load_vertex_count)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
- assert(index >= 0 && index < 4);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS_SVB_INDEX) | (cmd_len - 2);
-
- dw[1] = index << GEN6_SVBI_DW1_INDEX__SHIFT;
- if (load_vertex_count)
- dw[1] |= GEN6_SVBI_DW1_LOAD_INTERNAL_VERTEX_COUNT;
-
- dw[2] = svbi;
- dw[3] = max_svbi;
-}
-
-static inline void
-gen7_3DSTATE_GS(struct ilo_builder *builder,
- const struct ilo_shader_state *gs)
-{
- const uint8_t cmd_len = 7;
- const struct ilo_shader_cso *cso;
- uint32_t dw2, dw4, dw5, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- cso = ilo_shader_get_kernel_cso(gs);
- dw2 = cso->payload[0];
- dw4 = cso->payload[1];
- dw5 = cso->payload[2];
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
- dw[1] = ilo_shader_get_kernel_offset(gs);
- dw[2] = dw2;
- dw[3] = 0; /* scratch */
- dw[4] = dw4;
- dw[5] = dw5;
- dw[6] = 0;
-}
-
-static inline void
-gen7_disable_3DSTATE_GS(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 10 : 7;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- dw[4] = 0;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[7] = GEN8_GS_DW7_STATISTICS;
- dw[8] = 0;
- dw[9] = 0;
- } else {
- dw[5] = GEN7_GS_DW5_STATISTICS;
- dw[6] = 0;
- }
-}
-
-static inline void
-gen7_3DSTATE_STREAMOUT(struct ilo_builder *builder,
- int render_stream,
- bool render_disable,
- int vertex_attrib_count,
- const int *buf_strides)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
- uint32_t *dw;
- int buf_mask;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_STREAMOUT) | (cmd_len - 2);
-
- dw[1] = render_stream << GEN7_SO_DW1_RENDER_STREAM_SELECT__SHIFT;
- if (render_disable)
- dw[1] |= GEN7_SO_DW1_RENDER_DISABLE;
-
- if (buf_strides) {
- buf_mask = ((bool) buf_strides[3]) << 3 |
- ((bool) buf_strides[2]) << 2 |
- ((bool) buf_strides[1]) << 1 |
- ((bool) buf_strides[0]);
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[3] = buf_strides[1] << 16 | buf_strides[0];
- dw[4] = buf_strides[3] << 16 | buf_strides[1];
- }
- } else {
- buf_mask = 0;
- }
-
- if (buf_mask) {
- int read_len;
-
- dw[1] |= GEN7_SO_DW1_SO_ENABLE |
- GEN7_SO_DW1_STATISTICS;
- /* API_OPENGL */
- if (true)
- dw[1] |= GEN7_SO_DW1_REORDER_TRAILING;
- if (ilo_dev_gen(builder->dev) < ILO_GEN(8))
- dw[1] |= buf_mask << GEN7_SO_DW1_BUFFER_ENABLES__SHIFT;
-
- read_len = (vertex_attrib_count + 1) / 2;
- if (!read_len)
- read_len = 1;
-
- dw[2] = 0 << GEN7_SO_DW2_STREAM3_READ_OFFSET__SHIFT |
- (read_len - 1) << GEN7_SO_DW2_STREAM3_READ_LEN__SHIFT |
- 0 << GEN7_SO_DW2_STREAM2_READ_OFFSET__SHIFT |
- (read_len - 1) << GEN7_SO_DW2_STREAM2_READ_LEN__SHIFT |
- 0 << GEN7_SO_DW2_STREAM1_READ_OFFSET__SHIFT |
- (read_len - 1) << GEN7_SO_DW2_STREAM1_READ_LEN__SHIFT |
- 0 << GEN7_SO_DW2_STREAM0_READ_OFFSET__SHIFT |
- (read_len - 1) << GEN7_SO_DW2_STREAM0_READ_LEN__SHIFT;
- } else {
- dw[2] = 0;
- }
-}
-
-static inline void
-gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
- const struct pipe_stream_output_info *so_info)
-{
- /*
- * Note that "DWord Length" has 9 bits for this command and the type of
- * cmd_len cannot be uint8_t.
- */
- uint16_t cmd_len;
- struct {
- int buf_selects;
- int decl_count;
- uint16_t decls[128];
- } streams[4];
- unsigned buf_offsets[PIPE_MAX_SO_BUFFERS];
- int hw_decl_count, i;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- memset(streams, 0, sizeof(streams));
- memset(buf_offsets, 0, sizeof(buf_offsets));
-
- for (i = 0; i < so_info->num_outputs; i++) {
- unsigned decl, st, buf, reg, mask;
-
- st = so_info->output[i].stream;
- buf = so_info->output[i].output_buffer;
-
- /* pad with holes */
- while (buf_offsets[buf] < so_info->output[i].dst_offset) {
- int num_dwords;
-
- num_dwords = so_info->output[i].dst_offset - buf_offsets[buf];
- if (num_dwords > 4)
- num_dwords = 4;
-
- decl = buf << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
- GEN7_SO_DECL_HOLE_FLAG |
- ((1 << num_dwords) - 1) << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
-
- assert(streams[st].decl_count < Elements(streams[st].decls));
- streams[st].decls[streams[st].decl_count++] = decl;
- buf_offsets[buf] += num_dwords;
- }
- assert(buf_offsets[buf] == so_info->output[i].dst_offset);
-
- reg = so_info->output[i].register_index;
- mask = ((1 << so_info->output[i].num_components) - 1) <<
- so_info->output[i].start_component;
-
- decl = buf << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
- reg << GEN7_SO_DECL_REG_INDEX__SHIFT |
- mask << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
-
- assert(streams[st].decl_count < Elements(streams[st].decls));
-
- streams[st].buf_selects |= 1 << buf;
- streams[st].decls[streams[st].decl_count++] = decl;
- buf_offsets[buf] += so_info->output[i].num_components;
- }
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) {
- hw_decl_count = MAX4(streams[0].decl_count, streams[1].decl_count,
- streams[2].decl_count, streams[3].decl_count);
- } else {
- /*
- * From the Ivy Bridge PRM, volume 2 part 1, page 201:
- *
- * "Errata: All 128 decls for all four streams must be included
- * whenever this command is issued. The "Num Entries [n]" fields
- * still contain the actual numbers of valid decls."
- */
- hw_decl_count = 128;
- }
-
- cmd_len = 3 + 2 * hw_decl_count;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_DECL_LIST) | (cmd_len - 2);
- dw[1] = streams[3].buf_selects << GEN7_SO_DECL_DW1_STREAM3_BUFFER_SELECTS__SHIFT |
- streams[2].buf_selects << GEN7_SO_DECL_DW1_STREAM2_BUFFER_SELECTS__SHIFT |
- streams[1].buf_selects << GEN7_SO_DECL_DW1_STREAM1_BUFFER_SELECTS__SHIFT |
- streams[0].buf_selects << GEN7_SO_DECL_DW1_STREAM0_BUFFER_SELECTS__SHIFT;
- dw[2] = streams[3].decl_count << GEN7_SO_DECL_DW2_STREAM3_ENTRY_COUNT__SHIFT |
- streams[2].decl_count << GEN7_SO_DECL_DW2_STREAM2_ENTRY_COUNT__SHIFT |
- streams[1].decl_count << GEN7_SO_DECL_DW2_STREAM1_ENTRY_COUNT__SHIFT |
- streams[0].decl_count << GEN7_SO_DECL_DW2_STREAM0_ENTRY_COUNT__SHIFT;
- dw += 3;
-
- for (i = 0; i < hw_decl_count; i++) {
- dw[0] = streams[1].decls[i] << 16 | streams[0].decls[i];
- dw[1] = streams[3].decls[i] << 16 | streams[2].decls[i];
- dw += 2;
- }
-}
-
-static inline void
-gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index, int stride,
- const struct pipe_stream_output_target *so_target)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
- struct ilo_buffer *buf;
- int start, end;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- buf = ilo_buffer(so_target->buffer);
-
- /* DWord-aligned */
- assert(stride % 4 == 0);
- assert(so_target->buffer_offset % 4 == 0);
-
- stride &= ~3;
- start = so_target->buffer_offset & ~3;
- end = (start + so_target->buffer_size) & ~3;
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
- dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT |
- stride;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[1] |= builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
-
- dw[4] = end - start;
- dw[5] = 0;
- dw[6] = 0;
- dw[7] = 0;
-
- ilo_builder_batch_reloc64(builder, pos + 2,
- buf->bo, start, INTEL_RELOC_WRITE);
- } else {
- dw[1] |= builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT;
-
- ilo_builder_batch_reloc(builder, pos + 2,
- buf->bo, start, INTEL_RELOC_WRITE);
- ilo_builder_batch_reloc(builder, pos + 3,
- buf->bo, end, INTEL_RELOC_WRITE);
- }
-}
-
-static inline void
-gen7_disable_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
- dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT;
- dw[2] = 0;
- dw[3] = 0;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[4] = 0;
- dw[5] = 0;
- dw[6] = 0;
- dw[7] = 0;
- }
-}
-
-static inline void
-gen6_3DSTATE_BINDING_TABLE_POINTERS(struct ilo_builder *builder,
- uint32_t vs_binding_table,
- uint32_t gs_binding_table,
- uint32_t ps_binding_table)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_BINDING_TABLE_POINTERS) |
- GEN6_BINDING_TABLE_PTR_DW0_VS_CHANGED |
- GEN6_BINDING_TABLE_PTR_DW0_GS_CHANGED |
- GEN6_BINDING_TABLE_PTR_DW0_PS_CHANGED |
- (cmd_len - 2);
- dw[1] = vs_binding_table;
- dw[2] = gs_binding_table;
- dw[3] = ps_binding_table;
-}
-
-static inline void
-gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct ilo_builder *builder,
- uint32_t vs_sampler_state,
- uint32_t gs_sampler_state,
- uint32_t ps_sampler_state)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLER_STATE_POINTERS) |
- GEN6_SAMPLER_PTR_DW0_VS_CHANGED |
- GEN6_SAMPLER_PTR_DW0_GS_CHANGED |
- GEN6_SAMPLER_PTR_DW0_PS_CHANGED |
- (cmd_len - 2);
- dw[1] = vs_sampler_state;
- dw[2] = gs_sampler_state;
- dw[3] = ps_sampler_state;
-}
-
-static inline void
-gen7_3dstate_pointer(struct ilo_builder *builder,
- int subop, uint32_t pointer)
-{
- const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
- GEN6_RENDER_SUBTYPE_3D |
- subop;
- const uint8_t cmd_len = 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = cmd | (cmd_len - 2);
- dw[1] = pointer;
-}
-
-static inline void
-gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(struct ilo_builder *builder,
- uint32_t binding_table)
-{
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_VS,
- binding_table);
-}
-
-static inline void
-gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(struct ilo_builder *builder,
- uint32_t binding_table)
-{
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_HS,
- binding_table);
-}
-
-static inline void
-gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(struct ilo_builder *builder,
- uint32_t binding_table)
-{
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_DS,
- binding_table);
-}
-
-static inline void
-gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(struct ilo_builder *builder,
- uint32_t binding_table)
-{
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_GS,
- binding_table);
-}
-
-static inline void
-gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(struct ilo_builder *builder,
- uint32_t sampler_state)
-{
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_VS,
- sampler_state);
-}
-
-static inline void
-gen7_3DSTATE_SAMPLER_STATE_POINTERS_HS(struct ilo_builder *builder,
- uint32_t sampler_state)
-{
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_HS,
- sampler_state);
-}
-
-static inline void
-gen7_3DSTATE_SAMPLER_STATE_POINTERS_DS(struct ilo_builder *builder,
- uint32_t sampler_state)
-{
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_DS,
- sampler_state);
-}
-
-static inline void
-gen7_3DSTATE_SAMPLER_STATE_POINTERS_GS(struct ilo_builder *builder,
- uint32_t sampler_state)
-{
- gen7_3dstate_pointer(builder,
- GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_GS,
- sampler_state);
-}
-
-static inline void
-gen6_3dstate_constant(struct ilo_builder *builder, int subop,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
- GEN6_RENDER_SUBTYPE_3D |
- subop;
- const uint8_t cmd_len = 5;
- unsigned buf_enabled = 0x0;
- uint32_t buf_dw[4], *dw;
- int max_read_length, total_read_length;
- int i;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- assert(num_bufs <= 4);
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 138:
- *
- * "(3DSTATE_CONSTANT_VS) The sum of all four read length fields (each
- * incremented to represent the actual read length) must be less than
- * or equal to 32"
- *
- * From the Sandy Bridge PRM, volume 2 part 1, page 161:
- *
- * "(3DSTATE_CONSTANT_GS) The sum of all four read length fields (each
- * incremented to represent the actual read length) must be less than
- * or equal to 64"
- *
- * From the Sandy Bridge PRM, volume 2 part 1, page 287:
- *
- * "(3DSTATE_CONSTANT_PS) The sum of all four read length fields (each
- * incremented to represent the actual read length) must be less than
- * or equal to 64"
- */
- switch (subop) {
- case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS:
- max_read_length = 32;
- break;
- case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS:
- case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS:
- max_read_length = 64;
- break;
- default:
- assert(!"unknown pcb subop");
- max_read_length = 0;
- break;
- }
-
- total_read_length = 0;
- for (i = 0; i < 4; i++) {
- if (i < num_bufs && sizes[i]) {
- /* in 256-bit units */
- const int read_len = (sizes[i] + 31) / 32;
-
- assert(bufs[i] % 32 == 0);
- assert(read_len <= 32);
-
- buf_enabled |= 1 << i;
- buf_dw[i] = bufs[i] | (read_len - 1);
-
- total_read_length += read_len;
- } else {
- buf_dw[i] = 0;
- }
- }
-
- assert(total_read_length <= max_read_length);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = cmd | (cmd_len - 2) |
- buf_enabled << GEN6_CONSTANT_DW0_BUFFER_ENABLES__SHIFT |
- builder->mocs << GEN6_CONSTANT_DW0_MOCS__SHIFT;
-
- memcpy(&dw[1], buf_dw, sizeof(buf_dw));
-}
-
-static inline void
-gen6_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
- bufs, sizes, num_bufs);
-}
-
-static inline void
-gen6_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
- bufs, sizes, num_bufs);
-}
-
-static inline void
-gen7_3dstate_constant(struct ilo_builder *builder,
- int subop,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
- GEN6_RENDER_SUBTYPE_3D |
- subop;
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 11 : 7;
- uint32_t payload[6], *dw;
- int total_read_length, i;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- /* VS, HS, DS, GS, and PS variants */
- assert(subop >= GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS &&
- subop <= GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS &&
- subop != GEN6_RENDER_OPCODE_3DSTATE_SAMPLE_MASK);
-
- assert(num_bufs <= 4);
-
- payload[0] = 0;
- payload[1] = 0;
-
- total_read_length = 0;
- for (i = 0; i < 4; i++) {
- int read_len;
-
- /*
- * From the Ivy Bridge PRM, volume 2 part 1, page 112:
- *
- * "Constant buffers must be enabled in order from Constant Buffer 0
- * to Constant Buffer 3 within this command. For example, it is
- * not allowed to enable Constant Buffer 1 by programming a
- * non-zero value in the VS Constant Buffer 1 Read Length without a
- * non-zero value in VS Constant Buffer 0 Read Length."
- */
- if (i >= num_bufs || !sizes[i]) {
- for (; i < 4; i++) {
- assert(i >= num_bufs || !sizes[i]);
- payload[2 + i] = 0;
- }
- break;
- }
-
- /* read lengths are in 256-bit units */
- read_len = (sizes[i] + 31) / 32;
- /* the lower 5 bits are used for memory object control state */
- assert(bufs[i] % 32 == 0);
-
- payload[i / 2] |= read_len << ((i % 2) ? 16 : 0);
- payload[2 + i] = bufs[i];
-
- total_read_length += read_len;
- }
-
- /*
- * From the Ivy Bridge PRM, volume 2 part 1, page 113:
- *
- * "The sum of all four read length fields must be less than or equal
- * to the size of 64"
- */
- assert(total_read_length <= 64);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = cmd | (cmd_len - 2);
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[1] = payload[0];
- dw[2] = payload[1];
- dw[3] = payload[2];
- dw[4] = 0;
- dw[5] = payload[3];
- dw[6] = 0;
- dw[7] = payload[4];
- dw[8] = 0;
- dw[9] = payload[5];
- dw[10] = 0;
- } else {
- payload[2] |= builder->mocs << GEN7_CONSTANT_DW_ADDR_MOCS__SHIFT;
-
- memcpy(&dw[1], payload, sizeof(payload));
- }
-}
-
-static inline void
-gen7_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
- bufs, sizes, num_bufs);
-}
-
-static inline void
-gen7_3DSTATE_CONSTANT_HS(struct ilo_builder *builder,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_HS,
- bufs, sizes, num_bufs);
-}
-
-static inline void
-gen7_3DSTATE_CONSTANT_DS(struct ilo_builder *builder,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS,
- bufs, sizes, num_bufs);
-}
-
-static inline void
-gen7_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
- const uint32_t *bufs, const int *sizes,
- int num_bufs)
-{
- gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
- bufs, sizes, num_bufs);
-}
-
-static inline uint32_t
-gen6_BINDING_TABLE_STATE(struct ilo_builder *builder,
- const uint32_t *surface_states,
- int num_surface_states)
-{
- const int state_align = 32;
- const int state_len = num_surface_states;
- uint32_t state_offset, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- /*
- * From the Sandy Bridge PRM, volume 4 part 1, page 69:
- *
- * "It is stored as an array of up to 256 elements..."
- */
- assert(num_surface_states <= 256);
-
- if (!num_surface_states)
- return 0;
-
- state_offset = ilo_builder_surface_pointer(builder,
- ILO_BUILDER_ITEM_BINDING_TABLE, state_align, state_len, &dw);
- memcpy(dw, surface_states, state_len << 2);
-
- return state_offset;
-}
-
-static inline uint32_t
-gen6_SURFACE_STATE(struct ilo_builder *builder,
- const struct ilo_view_surface *surf,
- bool for_render)
-{
- int state_align, state_len;
- uint32_t state_offset, *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- state_align = 64;
- state_len = 13;
-
- state_offset = ilo_builder_surface_pointer(builder,
- ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
- memcpy(dw, surf->payload, state_len << 2);
-
- if (surf->bo) {
- const uint32_t mocs = (surf->scanout) ?
- (GEN8_MOCS_MT_PTE | GEN8_MOCS_CT_L3) : builder->mocs;
-
- dw[1] |= mocs << GEN8_SURFACE_DW1_MOCS__SHIFT;
-
- ilo_builder_surface_reloc64(builder, state_offset, 8, surf->bo,
- surf->payload[8], (for_render) ? INTEL_RELOC_WRITE : 0);
- }
- } else {
- state_align = 32;
- state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 8 : 6;
-
- state_offset = ilo_builder_surface_pointer(builder,
- ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
- memcpy(dw, surf->payload, state_len << 2);
-
- if (surf->bo) {
- /*
- * For scanouts, we should not enable caching in LLC. Since we only
- * enable that on Gen8+, we are fine here.
- */
- dw[5] |= builder->mocs << GEN6_SURFACE_DW5_MOCS__SHIFT;
-
- ilo_builder_surface_reloc(builder, state_offset, 1, surf->bo,
- surf->payload[1], (for_render) ? INTEL_RELOC_WRITE : 0);
- }
- }
-
- return state_offset;
-}
-
-static inline uint32_t
-gen6_so_SURFACE_STATE(struct ilo_builder *builder,
- const struct pipe_stream_output_target *so,
- const struct pipe_stream_output_info *so_info,
- int so_index)
-{
- struct ilo_buffer *buf = ilo_buffer(so->buffer);
- unsigned bo_offset, struct_size;
- enum pipe_format elem_format;
- struct ilo_view_surface surf;
-
- ILO_DEV_ASSERT(builder->dev, 6, 6);
-
- bo_offset = so->buffer_offset + so_info->output[so_index].dst_offset * 4;
- struct_size = so_info->stride[so_info->output[so_index].output_buffer] * 4;
-
- switch (so_info->output[so_index].num_components) {
- case 1:
- elem_format = PIPE_FORMAT_R32_FLOAT;
- break;
- case 2:
- elem_format = PIPE_FORMAT_R32G32_FLOAT;
- break;
- case 3:
- elem_format = PIPE_FORMAT_R32G32B32_FLOAT;
- break;
- case 4:
- elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- break;
- default:
- assert(!"unexpected SO components length");
- elem_format = PIPE_FORMAT_R32_FLOAT;
- break;
- }
-
- ilo_gpe_init_view_surface_for_buffer(builder->dev, buf, bo_offset,
- so->buffer_size, struct_size, elem_format, false, true, &surf);
-
- return gen6_SURFACE_STATE(builder, &surf, false);
-}
-
-static inline uint32_t
-gen6_SAMPLER_STATE(struct ilo_builder *builder,
- const struct ilo_sampler_cso * const *samplers,
- const struct pipe_sampler_view * const *views,
- const uint32_t *sampler_border_colors,
- int num_samplers)
-{
- const int state_align = 32;
- const int state_len = 4 * num_samplers;
- uint32_t state_offset, *dw;
- int i;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- /*
- * From the Sandy Bridge PRM, volume 4 part 1, page 101:
- *
- * "The sampler state is stored as an array of up to 16 elements..."
- */
- assert(num_samplers <= 16);
-
- if (!num_samplers)
- return 0;
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 132:
- *
- * "(Sampler Count of 3DSTATE_VS) Specifies how many samplers (in
- * multiples of 4) the vertex shader 0 kernel uses. Used only for
- * prefetching the associated sampler state entries.
- *
- * It also applies to other shader stages.
- */
- ilo_builder_dynamic_pad_top(builder, 4 * (4 - (num_samplers % 4)));
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_SAMPLER, state_align, state_len, &dw);
-
- for (i = 0; i < num_samplers; i++) {
- const struct ilo_sampler_cso *sampler = samplers[i];
- const struct pipe_sampler_view *view = views[i];
- const uint32_t border_color = sampler_border_colors[i];
- uint32_t dw_filter, dw_wrap;
-
- /* there may be holes */
- if (!sampler || !view) {
- /* disabled sampler */
- dw[0] = 1 << 31;
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
- dw += 4;
-
- continue;
- }
-
- /* determine filter and wrap modes */
- switch (view->texture->target) {
- case PIPE_TEXTURE_1D:
- dw_filter = (sampler->anisotropic) ?
- sampler->dw_filter_aniso : sampler->dw_filter;
- dw_wrap = sampler->dw_wrap_1d;
- break;
- case PIPE_TEXTURE_3D:
- /*
- * From the Sandy Bridge PRM, volume 4 part 1, page 103:
- *
- * "Only MAPFILTER_NEAREST and MAPFILTER_LINEAR are supported for
- * surfaces of type SURFTYPE_3D."
- */
- dw_filter = sampler->dw_filter;
- dw_wrap = sampler->dw_wrap;
- break;
- case PIPE_TEXTURE_CUBE:
- dw_filter = (sampler->anisotropic) ?
- sampler->dw_filter_aniso : sampler->dw_filter;
- dw_wrap = sampler->dw_wrap_cube;
- break;
- default:
- dw_filter = (sampler->anisotropic) ?
- sampler->dw_filter_aniso : sampler->dw_filter;
- dw_wrap = sampler->dw_wrap;
- break;
- }
-
- dw[0] = sampler->payload[0];
- dw[1] = sampler->payload[1];
- assert(!(border_color & 0x1f));
- dw[2] = border_color;
- dw[3] = sampler->payload[2];
-
- dw[0] |= dw_filter;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
- dw[3] |= dw_wrap;
- }
- else {
- /*
- * From the Sandy Bridge PRM, volume 4 part 1, page 21:
- *
- * "[DevSNB] Errata: Incorrect behavior is observed in cases
- * where the min and mag mode filters are different and
- * SurfMinLOD is nonzero. The determination of MagMode uses the
- * following equation instead of the one in the above
- * pseudocode: MagMode = (LOD + SurfMinLOD - Base <= 0)"
- *
- * As a way to work around that, we set Base to
- * view->u.tex.first_level.
- */
- dw[0] |= view->u.tex.first_level << 22;
-
- dw[1] |= dw_wrap;
- }
-
- dw += 4;
- }
-
- return state_offset;
-}
-
-static inline uint32_t
-gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder *builder,
- const struct ilo_sampler_cso *sampler)
-{
- const int state_align =
- (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 64 : 32;
- const int state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 12;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(Elements(sampler->payload) >= 3 + state_len);
-
- /* see ilo_gpe_init_sampler_cso() */
- return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
- state_align, state_len, &sampler->payload[3]);
-}
-
-static inline uint32_t
-gen6_push_constant_buffer(struct ilo_builder *builder,
- int size, void **pcb)
-{
- /*
- * For all VS, GS, FS, and CS push constant buffers, they must be aligned
- * to 32 bytes, and their sizes are specified in 256-bit units.
- */
- const int state_align = 32;
- const int state_len = align(size, 32) / 4;
- uint32_t state_offset;
- char *buf;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_BLOB, state_align, state_len, (uint32_t **) &buf);
-
- /* zero out the unused range */
- if (size < state_len * 4)
- memset(&buf[size], 0, state_len * 4 - size);
-
- if (pcb)
- *pcb = buf;
-
- return state_offset;
-}
-
-static inline uint32_t
-gen6_user_vertex_buffer(struct ilo_builder *builder,
- int size, const void *vertices)
-{
- const int state_align = 8;
- const int state_len = size / 4;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- assert(size % 4 == 0);
-
- return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
- state_align, state_len, vertices);
-}
-
-#endif /* ILO_BUILDER_3D_TOP_H */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_BUILDER_BLT_H
-#define ILO_BUILDER_BLT_H
-
-#include "genhw/genhw.h"
-#include "core/intel_winsys.h"
-
-#include "ilo_common.h"
-#include "ilo_builder.h"
-
-enum gen6_blt_mask {
- GEN6_BLT_MASK_8,
- GEN6_BLT_MASK_16,
- GEN6_BLT_MASK_32,
- GEN6_BLT_MASK_32_LO,
- GEN6_BLT_MASK_32_HI,
-};
-
-struct gen6_blt_bo {
- struct intel_bo *bo;
- uint32_t offset;
- int16_t pitch;
-};
-
-struct gen6_blt_xy_bo {
- struct intel_bo *bo;
- uint32_t offset;
- int16_t pitch;
-
- enum gen_surface_tiling tiling;
- int16_t x, y;
-};
-
-/*
- * From the Sandy Bridge PRM, volume 1 part 5, page 7:
- *
- * "The BLT engine is capable of transferring very large quantities of
- * graphics data. Any graphics data read from and written to the
- * destination is permitted to represent a number of pixels that occupies
- * up to 65,536 scan lines and up to 32,768 bytes per scan line at the
- * destination. The maximum number of pixels that may be represented per
- * scan line's worth of graphics data depends on the color depth."
- */
-static const int gen6_blt_max_bytes_per_scanline = 32768;
-static const int gen6_blt_max_scanlines = 65536;
-
-static inline uint32_t
-gen6_blt_translate_value_mask(enum gen6_blt_mask value_mask)
-{
- switch (value_mask) {
- case GEN6_BLT_MASK_8: return GEN6_BLITTER_BR13_FORMAT_8;
- case GEN6_BLT_MASK_16: return GEN6_BLITTER_BR13_FORMAT_565;
- default: return GEN6_BLITTER_BR13_FORMAT_8888;
- }
-}
-
-static inline uint32_t
-gen6_blt_translate_value_cpp(enum gen6_blt_mask value_mask)
-{
- switch (value_mask) {
- case GEN6_BLT_MASK_8: return 1;
- case GEN6_BLT_MASK_16: return 2;
- default: return 4;
- }
-}
-
-static inline uint32_t
-gen6_blt_translate_write_mask(enum gen6_blt_mask write_mask)
-{
- switch (write_mask) {
- case GEN6_BLT_MASK_32: return GEN6_BLITTER_BR00_WRITE_RGB |
- GEN6_BLITTER_BR00_WRITE_A;
- case GEN6_BLT_MASK_32_LO: return GEN6_BLITTER_BR00_WRITE_RGB;
- case GEN6_BLT_MASK_32_HI: return GEN6_BLITTER_BR00_WRITE_A;
- default: return 0;
- }
-}
-
-static inline void
-gen6_COLOR_BLT(struct ilo_builder *builder,
- const struct gen6_blt_bo *dst, uint32_t pattern,
- uint16_t width, uint16_t height, uint8_t rop,
- enum gen6_blt_mask value_mask,
- enum gen6_blt_mask write_mask)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
- const int cpp = gen6_blt_translate_value_cpp(value_mask);
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(width < gen6_blt_max_bytes_per_scanline);
- assert(height < gen6_blt_max_scanlines);
- /* offsets are naturally aligned and pitches are dword-aligned */
- assert(dst->offset % cpp == 0 && dst->pitch % 4 == 0);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_BLITTER_CMD(COLOR_BLT) |
- gen6_blt_translate_write_mask(write_mask) |
- (cmd_len - 2);
- dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
- gen6_blt_translate_value_mask(value_mask) |
- dst->pitch;
- dw[2] = height << 16 | width;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[5] = pattern;
-
- ilo_builder_batch_reloc64(builder, pos + 3,
- dst->bo, dst->offset, INTEL_RELOC_WRITE);
- } else {
- dw[4] = pattern;
-
- ilo_builder_batch_reloc(builder, pos + 3,
- dst->bo, dst->offset, INTEL_RELOC_WRITE);
- }
-}
-
-static inline void
-gen6_XY_COLOR_BLT(struct ilo_builder *builder,
- const struct gen6_blt_xy_bo *dst, uint32_t pattern,
- uint16_t width, uint16_t height, uint8_t rop,
- enum gen6_blt_mask value_mask,
- enum gen6_blt_mask write_mask)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 7 : 6;
- const int cpp = gen6_blt_translate_value_cpp(value_mask);
- int dst_align = 4, dst_pitch_shift = 0;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(width * cpp < gen6_blt_max_bytes_per_scanline);
- assert(height < gen6_blt_max_scanlines);
- /* INT16_MAX */
- assert(dst->x + width <= 32767 && dst->y + height <= 32767);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_BLITTER_CMD(XY_COLOR_BLT) |
- gen6_blt_translate_write_mask(write_mask) |
- (cmd_len - 2);
-
- if (dst->tiling != GEN6_TILING_NONE) {
- dw[0] |= GEN6_BLITTER_BR00_DST_TILED;
-
- assert(dst->tiling == GEN6_TILING_X || dst->tiling == GEN6_TILING_Y);
- dst_align = (dst->tiling == GEN6_TILING_Y) ? 128 : 512;
- /* in dwords when tiled */
- dst_pitch_shift = 2;
- }
-
- assert(dst->offset % dst_align == 0 && dst->pitch % dst_align == 0);
-
- dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
- gen6_blt_translate_value_mask(value_mask) |
- dst->pitch >> dst_pitch_shift;
- dw[2] = dst->y << 16 | dst->x;
- dw[3] = (dst->y + height) << 16 | (dst->x + width);
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[6] = pattern;
-
- ilo_builder_batch_reloc64(builder, pos + 4,
- dst->bo, dst->offset, INTEL_RELOC_WRITE);
- } else {
- dw[5] = pattern;
-
- ilo_builder_batch_reloc(builder, pos + 4,
- dst->bo, dst->offset, INTEL_RELOC_WRITE);
- }
-}
-
-static inline void
-gen6_SRC_COPY_BLT(struct ilo_builder *builder,
- const struct gen6_blt_bo *dst,
- const struct gen6_blt_bo *src,
- uint16_t width, uint16_t height, uint8_t rop,
- enum gen6_blt_mask value_mask,
- enum gen6_blt_mask write_mask)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 6;
- const int cpp = gen6_blt_translate_value_cpp(value_mask);
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(width < gen6_blt_max_bytes_per_scanline);
- assert(height < gen6_blt_max_scanlines);
- /* offsets are naturally aligned and pitches are dword-aligned */
- assert(dst->offset % cpp == 0 && dst->pitch % 4 == 0);
- assert(src->offset % cpp == 0 && src->pitch % 4 == 0);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_BLITTER_CMD(SRC_COPY_BLT) |
- gen6_blt_translate_write_mask(write_mask) |
- (cmd_len - 2);
- dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
- gen6_blt_translate_value_mask(value_mask) |
- dst->pitch;
- dw[2] = height << 16 | width;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[5] = src->pitch;
-
- ilo_builder_batch_reloc64(builder, pos + 3,
- dst->bo, dst->offset, INTEL_RELOC_WRITE);
- ilo_builder_batch_reloc64(builder, pos + 6, src->bo, src->offset, 0);
- } else {
- dw[4] = src->pitch;
-
- ilo_builder_batch_reloc(builder, pos + 3,
- dst->bo, dst->offset, INTEL_RELOC_WRITE);
- ilo_builder_batch_reloc(builder, pos + 5, src->bo, src->offset, 0);
- }
-}
-
-static inline void
-gen6_XY_SRC_COPY_BLT(struct ilo_builder *builder,
- const struct gen6_blt_xy_bo *dst,
- const struct gen6_blt_xy_bo *src,
- uint16_t width, uint16_t height, uint8_t rop,
- enum gen6_blt_mask value_mask,
- enum gen6_blt_mask write_mask)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 10 : 8;
- const int cpp = gen6_blt_translate_value_cpp(value_mask);
- int dst_align = 4, dst_pitch_shift = 0;
- int src_align = 4, src_pitch_shift = 0;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(width * cpp < gen6_blt_max_bytes_per_scanline);
- assert(height < gen6_blt_max_scanlines);
- /* INT16_MAX */
- assert(dst->x + width <= 32767 && dst->y + height <= 32767);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_BLITTER_CMD(XY_SRC_COPY_BLT) |
- gen6_blt_translate_write_mask(write_mask) |
- (cmd_len - 2);
-
- if (dst->tiling != GEN6_TILING_NONE) {
- dw[0] |= GEN6_BLITTER_BR00_DST_TILED;
-
- assert(dst->tiling == GEN6_TILING_X || dst->tiling == GEN6_TILING_Y);
- dst_align = (dst->tiling == GEN6_TILING_Y) ? 128 : 512;
- /* in dwords when tiled */
- dst_pitch_shift = 2;
- }
-
- if (src->tiling != GEN6_TILING_NONE) {
- dw[0] |= GEN6_BLITTER_BR00_SRC_TILED;
-
- assert(src->tiling == GEN6_TILING_X || src->tiling == GEN6_TILING_Y);
- src_align = (src->tiling == GEN6_TILING_Y) ? 128 : 512;
- /* in dwords when tiled */
- src_pitch_shift = 2;
- }
-
- assert(dst->offset % dst_align == 0 && dst->pitch % dst_align == 0);
- assert(src->offset % src_align == 0 && src->pitch % src_align == 0);
-
- dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
- gen6_blt_translate_value_mask(value_mask) |
- dst->pitch >> dst_pitch_shift;
- dw[2] = dst->y << 16 | dst->x;
- dw[3] = (dst->y + height) << 16 | (dst->x + width);
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[6] = src->y << 16 | src->x;
- dw[7] = src->pitch >> src_pitch_shift;
-
- ilo_builder_batch_reloc64(builder, pos + 4,
- dst->bo, dst->offset, INTEL_RELOC_WRITE);
- ilo_builder_batch_reloc64(builder, pos + 8, src->bo, src->offset, 0);
- } else {
- dw[5] = src->y << 16 | src->x;
- dw[6] = src->pitch >> src_pitch_shift;
-
- ilo_builder_batch_reloc(builder, pos + 4,
- dst->bo, dst->offset, INTEL_RELOC_WRITE);
- ilo_builder_batch_reloc(builder, pos + 7, src->bo, src->offset, 0);
- }
-}
-
-#endif /* ILO_BUILDER_BLT_H */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include "genhw/genhw.h"
-#include "shader/toy_compiler.h"
-#include "core/intel_winsys.h"
-#include "ilo_builder.h"
-
-static const uint32_t *
-writer_pointer(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- unsigned offset)
-{
- const struct ilo_builder_writer *writer = &builder->writers[which];
- return (const uint32_t *) ((const char *) writer->ptr + offset);
-}
-
-static uint32_t _util_printf_format(5, 6)
-writer_dw(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- unsigned offset, unsigned dw_index,
- const char *format, ...)
-{
- const uint32_t *dw = writer_pointer(builder, which, offset);
- va_list ap;
- char desc[16];
- int len;
-
- ilo_printf("0x%08x: 0x%08x: ",
- offset + (dw_index << 2), dw[dw_index]);
-
- va_start(ap, format);
- len = vsnprintf(desc, sizeof(desc), format, ap);
- va_end(ap);
-
- if (len >= sizeof(desc)) {
- len = sizeof(desc) - 1;
- desc[len] = '\0';
- }
-
- if (desc[len - 1] == '\n') {
- desc[len - 1] = '\0';
- ilo_printf("%8s: \n", desc);
- } else {
- ilo_printf("%8s: ", desc);
- }
-
- return dw[dw_index];
-}
-
-static void
-writer_decode_blob(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t);
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i += 4) {
- const uint32_t *dw = writer_pointer(builder, which, offset);
-
- writer_dw(builder, which, offset, 0, "BLOB%d", i / 4);
-
- switch (count - i) {
- case 1:
- ilo_printf("(%10.4f, %10c, %10c, %10c) "
- "(0x%08x, %10c, %10c, %10c)\n",
- uif(dw[0]), 'X', 'X', 'X',
- dw[0], 'X', 'X', 'X');
- break;
- case 2:
- ilo_printf("(%10.4f, %10.4f, %10c, %10c) "
- "(0x%08x, 0x%08x, %10c, %10c)\n",
- uif(dw[0]), uif(dw[1]), 'X', 'X',
- dw[0], dw[1], 'X', 'X');
- break;
- case 3:
- ilo_printf("(%10.4f, %10.4f, %10.4f, %10c) "
- "(0x%08x, 0x%08x, 0x%08x, %10c)\n",
- uif(dw[0]), uif(dw[1]), uif(dw[2]), 'X',
- dw[0], dw[1], dw[2], 'X');
- break;
- default:
- ilo_printf("(%10.4f, %10.4f, %10.4f, %10.4f) "
- "(0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
- uif(dw[0]), uif(dw[1]), uif(dw[2]), uif(dw[3]),
- dw[0], dw[1], dw[2], dw[3]);
- break;
- }
-
- offset += state_size * 4;
- }
-}
-
-static void
-writer_decode_clip_viewport(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 4;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i++) {
- uint32_t dw;
-
- dw = writer_dw(builder, which, offset, 0, "CLIP VP%d", i);
- ilo_printf("xmin = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 1, "CLIP VP%d", i);
- ilo_printf("xmax = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 2, "CLIP VP%d", i);
- ilo_printf("ymin = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 3, "CLIP VP%d", i);
- ilo_printf("ymax = %f\n", uif(dw));
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_sf_clip_viewport_gen7(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 16;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i++) {
- uint32_t dw;
-
- dw = writer_dw(builder, which, offset, 0, "SF_CLIP VP%d", i);
- ilo_printf("m00 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 1, "SF_CLIP VP%d", i);
- ilo_printf("m11 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 2, "SF_CLIP VP%d", i);
- ilo_printf("m22 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 3, "SF_CLIP VP%d", i);
- ilo_printf("m30 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 4, "SF_CLIP VP%d", i);
- ilo_printf("m31 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 5, "SF_CLIP VP%d", i);
- ilo_printf("m32 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 8, "SF_CLIP VP%d", i);
- ilo_printf("guardband xmin = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 9, "SF_CLIP VP%d", i);
- ilo_printf("guardband xmax = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 10, "SF_CLIP VP%d", i);
- ilo_printf("guardband ymin = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 11, "SF_CLIP VP%d", i);
- ilo_printf("guardband ymax = %f\n", uif(dw));
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw = writer_dw(builder, which, offset, 12, "SF_CLIP VP%d", i);
- ilo_printf("extent xmin = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 13, "SF_CLIP VP%d", i);
- ilo_printf("extent xmax = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 14, "SF_CLIP VP%d", i);
- ilo_printf("extent ymin = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 15, "SF_CLIP VP%d", i);
- ilo_printf("extent ymax = %f\n", uif(dw));
- }
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_sf_viewport_gen6(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 8;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i++) {
- uint32_t dw;
-
- dw = writer_dw(builder, which, offset, 0, "SF VP%d", i);
- ilo_printf("m00 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 1, "SF VP%d", i);
- ilo_printf("m11 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 2, "SF VP%d", i);
- ilo_printf("m22 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 3, "SF VP%d", i);
- ilo_printf("m30 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 4, "SF VP%d", i);
- ilo_printf("m31 = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 5, "SF VP%d", i);
- ilo_printf("m32 = %f\n", uif(dw));
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_sf_viewport(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
- writer_decode_sf_clip_viewport_gen7(builder, which, item);
- else
- writer_decode_sf_viewport_gen6(builder, which, item);
-}
-
-static void
-writer_decode_scissor_rect(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 2;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i++) {
- uint32_t dw;
-
- dw = writer_dw(builder, which, offset, 0, "SCISSOR%d", i);
- ilo_printf("xmin %d, ymin %d\n",
- GEN_EXTRACT(dw, GEN6_SCISSOR_DW0_MIN_X),
- GEN_EXTRACT(dw, GEN6_SCISSOR_DW0_MIN_Y));
-
- dw = writer_dw(builder, which, offset, 1, "SCISSOR%d", i);
- ilo_printf("xmax %d, ymax %d\n",
- GEN_EXTRACT(dw, GEN6_SCISSOR_DW1_MAX_X),
- GEN_EXTRACT(dw, GEN6_SCISSOR_DW1_MAX_Y));
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_cc_viewport(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 2;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i++) {
- uint32_t dw;
-
- dw = writer_dw(builder, which, offset, 0, "CC VP%d", i);
- ilo_printf("min_depth = %f\n", uif(dw));
-
- dw = writer_dw(builder, which, offset, 1, "CC VP%d", i);
- ilo_printf("max_depth = %f\n", uif(dw));
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_color_calc(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- uint32_t dw;
-
- dw = writer_dw(builder, which, item->offset, 0, "CC");
- ilo_printf("alpha test format %s, round disable %d, "
- "stencil ref %d, bf stencil ref %d\n",
- GEN_EXTRACT(dw, GEN6_CC_DW0_ALPHATEST) ? "FLOAT32" : "UNORM8",
- (bool) (dw & GEN6_CC_DW0_ROUND_DISABLE_DISABLE),
- GEN_EXTRACT(dw, GEN6_CC_DW0_STENCIL0_REF),
- GEN_EXTRACT(dw, GEN6_CC_DW0_STENCIL1_REF));
-
- writer_dw(builder, which, item->offset, 1, "CC\n");
-
- dw = writer_dw(builder, which, item->offset, 2, "CC");
- ilo_printf("constant red %f\n", uif(dw));
-
- dw = writer_dw(builder, which, item->offset, 3, "CC");
- ilo_printf("constant green %f\n", uif(dw));
-
- dw = writer_dw(builder, which, item->offset, 4, "CC");
- ilo_printf("constant blue %f\n", uif(dw));
-
- dw = writer_dw(builder, which, item->offset, 5, "CC");
- ilo_printf("constant alpha %f\n", uif(dw));
-}
-
-static void
-writer_decode_depth_stencil(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- uint32_t dw;
-
- dw = writer_dw(builder, which, item->offset, 0, "D_S");
- ilo_printf("stencil %sable, func %d, write %sable\n",
- (dw & GEN6_ZS_DW0_STENCIL_TEST_ENABLE) ? "en" : "dis",
- GEN_EXTRACT(dw, GEN6_ZS_DW0_STENCIL0_FUNC),
- (dw & GEN6_ZS_DW0_STENCIL_WRITE_ENABLE) ? "en" : "dis");
-
- dw = writer_dw(builder, which, item->offset, 1, "D_S");
- ilo_printf("stencil test mask 0x%x, write mask 0x%x\n",
- GEN_EXTRACT(dw, GEN6_ZS_DW1_STENCIL0_VALUEMASK),
- GEN_EXTRACT(dw, GEN6_ZS_DW1_STENCIL0_WRITEMASK));
-
- dw = writer_dw(builder, which, item->offset, 2, "D_S");
- ilo_printf("depth test %sable, func %d, write %sable\n",
- (dw & GEN6_ZS_DW2_DEPTH_TEST_ENABLE) ? "en" : "dis",
- GEN_EXTRACT(dw, GEN6_ZS_DW2_DEPTH_FUNC),
- (dw & GEN6_ZS_DW2_DEPTH_WRITE_ENABLE) ? "en" : "dis");
-}
-
-static void
-writer_decode_blend(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 2;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- writer_dw(builder, which, offset, 0, "BLEND\n");
- offset += 4;
- }
-
- for (i = 0; i < count; i++) {
- writer_dw(builder, which, offset, 0, "BLEND%d\n", i);
- writer_dw(builder, which, offset, 1, "BLEND%d\n", i);
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_sampler(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 4;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i++) {
- writer_dw(builder, which, offset, 0, "WM SAMP%d", i);
- ilo_printf("filtering\n");
-
- writer_dw(builder, which, offset, 1, "WM SAMP%d", i);
- ilo_printf("wrapping, lod\n");
-
- writer_dw(builder, which, offset, 2, "WM SAMP%d", i);
- ilo_printf("default color pointer\n");
-
- writer_dw(builder, which, offset, 3, "WM SAMP%d", i);
- ilo_printf("chroma key, aniso\n");
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_interface_descriptor(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 8;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i++) {
- writer_dw(builder, which, offset, 0, "IDRT[%d]", i);
- ilo_printf("kernel\n");
-
- writer_dw(builder, which, offset, 1, "IDRT[%d]", i);
- ilo_printf("spf, fp mode\n");
-
- writer_dw(builder, which, offset, 2, "IDRT[%d]", i);
- ilo_printf("sampler\n");
-
- writer_dw(builder, which, offset, 3, "IDRT[%d]", i);
- ilo_printf("binding table\n");
-
- writer_dw(builder, which, offset, 4, "IDRT[%d]", i);
- ilo_printf("curbe read len\n");
-
- writer_dw(builder, which, offset, 5, "IDRT[%d]", i);
- ilo_printf("rounding mode, slm size\n");
-
- writer_dw(builder, which, offset, 6, "IDRT[%d]", i);
- ilo_printf("cross-thread curbe read len\n");
-
- writer_dw(builder, which, offset, 7, "IDRT[%d]", i);
- ilo_printf("mbz\n");
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_surface_gen7(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- uint32_t dw;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw = writer_dw(builder, which, item->offset, 0, "SURF");
- ilo_printf("type 0x%x, format 0x%x, tiling %d, %s array\n",
- GEN_EXTRACT(dw, GEN7_SURFACE_DW0_TYPE),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW0_FORMAT),
- GEN_EXTRACT(dw, GEN8_SURFACE_DW0_TILING),
- (dw & GEN7_SURFACE_DW0_IS_ARRAY) ? "is" : "not");
-
- writer_dw(builder, which, item->offset, 1, "SURF");
- ilo_printf("qpitch\n");
- } else {
- dw = writer_dw(builder, which, item->offset, 0, "SURF");
- ilo_printf("type 0x%x, format 0x%x, tiling %d, %s array\n",
- GEN_EXTRACT(dw, GEN7_SURFACE_DW0_TYPE),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW0_FORMAT),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW0_TILING),
- (dw & GEN7_SURFACE_DW0_IS_ARRAY) ? "is" : "not");
-
- writer_dw(builder, which, item->offset, 1, "SURF");
- ilo_printf("offset\n");
- }
-
- dw = writer_dw(builder, which, item->offset, 2, "SURF");
- ilo_printf("%dx%d size\n",
- GEN_EXTRACT(dw, GEN7_SURFACE_DW2_WIDTH),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW2_HEIGHT));
-
- dw = writer_dw(builder, which, item->offset, 3, "SURF");
- ilo_printf("depth %d, pitch %d\n",
- GEN_EXTRACT(dw, GEN7_SURFACE_DW3_DEPTH),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW3_PITCH));
-
- dw = writer_dw(builder, which, item->offset, 4, "SURF");
- ilo_printf("min array element %d, array extent %d\n",
- GEN_EXTRACT(dw, GEN7_SURFACE_DW4_MIN_ARRAY_ELEMENT),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW4_RT_VIEW_EXTENT));
-
- dw = writer_dw(builder, which, item->offset, 5, "SURF");
- ilo_printf("mip base %d, mips %d, x,y offset: %d,%d\n",
- GEN_EXTRACT(dw, GEN7_SURFACE_DW5_MIN_LOD),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW5_MIP_COUNT_LOD),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW5_X_OFFSET),
- GEN_EXTRACT(dw, GEN7_SURFACE_DW5_Y_OFFSET));
-
- writer_dw(builder, which, item->offset, 6, "SURF\n");
- writer_dw(builder, which, item->offset, 7, "SURF\n");
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- writer_dw(builder, which, item->offset, 8, "SURF\n");
- writer_dw(builder, which, item->offset, 9, "SURF\n");
- writer_dw(builder, which, item->offset, 10, "SURF\n");
- writer_dw(builder, which, item->offset, 11, "SURF\n");
- writer_dw(builder, which, item->offset, 12, "SURF\n");
- }
-}
-
-static void
-writer_decode_surface_gen6(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- uint32_t dw;
-
- dw = writer_dw(builder, which, item->offset, 0, "SURF");
- ilo_printf("type 0x%x, format 0x%x\n",
- GEN_EXTRACT(dw, GEN6_SURFACE_DW0_TYPE),
- GEN_EXTRACT(dw, GEN6_SURFACE_DW0_FORMAT));
-
- writer_dw(builder, which, item->offset, 1, "SURF");
- ilo_printf("offset\n");
-
- dw = writer_dw(builder, which, item->offset, 2, "SURF");
- ilo_printf("%dx%d size, %d mips\n",
- GEN_EXTRACT(dw, GEN6_SURFACE_DW2_WIDTH),
- GEN_EXTRACT(dw, GEN6_SURFACE_DW2_HEIGHT),
- GEN_EXTRACT(dw, GEN6_SURFACE_DW2_MIP_COUNT_LOD));
-
- dw = writer_dw(builder, which, item->offset, 3, "SURF");
- ilo_printf("pitch %d, tiling %d\n",
- GEN_EXTRACT(dw, GEN6_SURFACE_DW3_PITCH),
- GEN_EXTRACT(dw, GEN6_SURFACE_DW3_TILING));
-
- dw = writer_dw(builder, which, item->offset, 4, "SURF");
- ilo_printf("mip base %d\n",
- GEN_EXTRACT(dw, GEN6_SURFACE_DW4_MIN_LOD));
-
- dw = writer_dw(builder, which, item->offset, 5, "SURF");
- ilo_printf("x,y offset: %d,%d\n",
- GEN_EXTRACT(dw, GEN6_SURFACE_DW5_X_OFFSET),
- GEN_EXTRACT(dw, GEN6_SURFACE_DW5_Y_OFFSET));
-}
-
-static void
-writer_decode_surface(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
- writer_decode_surface_gen7(builder, which, item);
- else
- writer_decode_surface_gen6(builder, which, item);
-}
-
-static void
-writer_decode_binding_table(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const unsigned state_size = sizeof(uint32_t) * 1;
- const unsigned count = item->size / state_size;
- unsigned offset = item->offset;
- unsigned i;
-
- for (i = 0; i < count; i++) {
- writer_dw(builder, which, offset, 0, "BIND");
- ilo_printf("BINDING_TABLE_STATE[%d]\n", i);
-
- offset += state_size;
- }
-}
-
-static void
-writer_decode_kernel(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item)
-{
- const void *kernel;
-
- ilo_printf("0x%08x:\n", item->offset);
- kernel = (const void *) writer_pointer(builder, which, item->offset);
- toy_compiler_disassemble(builder->dev, kernel, item->size, true);
-}
-
-static const struct {
- void (*func)(const struct ilo_builder *builder,
- enum ilo_builder_writer_type which,
- const struct ilo_builder_item *item);
-} writer_decode_table[ILO_BUILDER_ITEM_COUNT] = {
- [ILO_BUILDER_ITEM_BLOB] = { writer_decode_blob },
- [ILO_BUILDER_ITEM_CLIP_VIEWPORT] = { writer_decode_clip_viewport },
- [ILO_BUILDER_ITEM_SF_VIEWPORT] = { writer_decode_sf_viewport },
- [ILO_BUILDER_ITEM_SCISSOR_RECT] = { writer_decode_scissor_rect },
- [ILO_BUILDER_ITEM_CC_VIEWPORT] = { writer_decode_cc_viewport },
- [ILO_BUILDER_ITEM_COLOR_CALC] = { writer_decode_color_calc },
- [ILO_BUILDER_ITEM_DEPTH_STENCIL] = { writer_decode_depth_stencil },
- [ILO_BUILDER_ITEM_BLEND] = { writer_decode_blend },
- [ILO_BUILDER_ITEM_SAMPLER] = { writer_decode_sampler },
- [ILO_BUILDER_ITEM_INTERFACE_DESCRIPTOR] = { writer_decode_interface_descriptor },
- [ILO_BUILDER_ITEM_SURFACE] = { writer_decode_surface },
- [ILO_BUILDER_ITEM_BINDING_TABLE] = { writer_decode_binding_table },
- [ILO_BUILDER_ITEM_KERNEL] = { writer_decode_kernel },
-};
-
-static void
-ilo_builder_writer_decode_items(struct ilo_builder *builder,
- enum ilo_builder_writer_type which)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
- int i;
-
- if (!writer->item_used)
- return;
-
- writer->ptr = intel_bo_map(writer->bo, false);
- if (!writer->ptr)
- return;
-
- for (i = 0; i < writer->item_used; i++) {
- const struct ilo_builder_item *item = &writer->items[i];
-
- writer_decode_table[item->type].func(builder, which, item);
- }
-
- intel_bo_unmap(writer->bo);
- writer->ptr = NULL;
-}
-
-static void
-ilo_builder_writer_decode(struct ilo_builder *builder,
- enum ilo_builder_writer_type which)
-{
- struct ilo_builder_writer *writer = &builder->writers[which];
-
- assert(writer->bo && !writer->ptr);
-
- switch (which) {
- case ILO_BUILDER_WRITER_BATCH:
- ilo_printf("decoding batch buffer: %d bytes\n", writer->used);
- if (writer->used)
- intel_winsys_decode_bo(builder->winsys, writer->bo, writer->used);
-
- ilo_printf("decoding dynamic/surface buffer: %d states\n",
- writer->item_used);
- ilo_builder_writer_decode_items(builder, which);
- break;
- case ILO_BUILDER_WRITER_INSTRUCTION:
- if (true) {
- ilo_printf("skipping instruction buffer: %d kernels\n",
- writer->item_used);
- } else {
- ilo_printf("decoding instruction buffer: %d kernels\n",
- writer->item_used);
-
- ilo_builder_writer_decode_items(builder, which);
- }
- break;
- default:
- break;
- }
-}
-
-/**
- * Decode the builder according to the recorded items. This can be called
- * only after a successful ilo_builder_end().
- */
-void
-ilo_builder_decode(struct ilo_builder *builder)
-{
- int i;
-
- assert(!builder->unrecoverable_error);
-
- for (i = 0; i < ILO_BUILDER_WRITER_COUNT; i++)
- ilo_builder_writer_decode(builder, i);
-}
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_BUILDER_MEDIA_H
-#define ILO_BUILDER_MEDIA_H
-
-#include "genhw/genhw.h"
-#include "core/intel_winsys.h"
-
-#include "ilo_common.h"
-#include "ilo_shader.h"
-#include "ilo_builder.h"
-
-struct gen6_idrt_data {
- const struct ilo_shader_state *cs;
-
- uint32_t sampler_offset;
- uint32_t binding_table_offset;
-
- unsigned curbe_size;
- unsigned thread_group_size;
-};
-
-static inline void
-gen6_MEDIA_VFE_STATE(struct ilo_builder *builder,
- unsigned curbe_alloc, bool use_slm)
-{
- const uint8_t cmd_len = 8;
- const unsigned idrt_alloc =
- ((ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) ? 64 : 32) * 32;
- int max_threads;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- max_threads = builder->dev->thread_count;
-
- curbe_alloc = align(curbe_alloc, 32);
- assert(idrt_alloc + curbe_alloc <= builder->dev->urb_size / (use_slm + 1));
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_VFE_STATE) | (cmd_len - 2);
- dw[1] = 0; /* scratch */
-
- dw[2] = (max_threads - 1) << GEN6_VFE_DW2_MAX_THREADS__SHIFT |
- 0 << GEN6_VFE_DW2_URB_ENTRY_COUNT__SHIFT |
- GEN6_VFE_DW2_RESET_GATEWAY_TIMER |
- GEN6_VFE_DW2_BYPASS_GATEWAY_CONTROL;
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
- dw[2] |= GEN7_VFE_DW2_GPGPU_MODE;
-
- dw[3] = 0;
-
- dw[4] = 0 << GEN6_VFE_DW4_URB_ENTRY_SIZE__SHIFT |
- (curbe_alloc / 32);
-
- dw[5] = 0;
- dw[6] = 0;
- dw[7] = 0;
-}
-
-static inline void
-gen6_MEDIA_CURBE_LOAD(struct ilo_builder *builder,
- uint32_t offset, unsigned size)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- assert(offset % 32 == 0 && size % 32 == 0);
- /* GPU hangs if size is zero */
- assert(size);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_CURBE_LOAD) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = size;
- dw[3] = offset;
-}
-
-static inline void
-gen6_MEDIA_INTERFACE_DESCRIPTOR_LOAD(struct ilo_builder *builder,
- uint32_t offset, unsigned size)
-{
- const uint8_t cmd_len = 4;
- const unsigned idrt_alloc =
- ((ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) ? 64 : 32) * 32;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- assert(offset % 32 == 0 && size % 32 == 0);
- assert(size && size <= idrt_alloc);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_INTERFACE_DESCRIPTOR_LOAD) |
- (cmd_len - 2);
- dw[1] = 0;
- dw[2] = size;
- dw[3] = offset;
-}
-
-static inline void
-gen6_MEDIA_STATE_FLUSH(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_STATE_FLUSH) | (cmd_len - 2);
- dw[1] = 0;
-}
-
-static inline void
-gen7_GPGPU_WALKER(struct ilo_builder *builder,
- const unsigned thread_group_offset[3],
- const unsigned thread_group_dim[3],
- unsigned thread_group_size,
- unsigned simd_size)
-{
- const uint8_t cmd_len = 11;
- uint32_t right_execmask, bottom_execmask;
- unsigned thread_count;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- assert(simd_size == 16 || simd_size == 8);
-
- thread_count = (thread_group_size + simd_size - 1) / simd_size;
- assert(thread_count <= 64);
-
- right_execmask = thread_group_size % simd_size;
- if (right_execmask)
- right_execmask = (1 << right_execmask) - 1;
- else
- right_execmask = (1 << simd_size) - 1;
-
- bottom_execmask = 0xffffffff;
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_RENDER_CMD(MEDIA, GPGPU_WALKER) | (cmd_len - 2);
- dw[1] = 0; /* always first IDRT */
-
- dw[2] = (thread_count - 1) << GEN7_GPGPU_DW2_THREAD_MAX_X__SHIFT;
- if (simd_size == 16)
- dw[2] |= GEN7_GPGPU_DW2_SIMD_SIZE_SIMD16;
- else
- dw[2] |= GEN7_GPGPU_DW2_SIMD_SIZE_SIMD8;
-
- dw[3] = thread_group_offset[0];
- dw[4] = thread_group_dim[0];
- dw[5] = thread_group_offset[1];
- dw[6] = thread_group_dim[1];
- dw[7] = thread_group_offset[2];
- dw[8] = thread_group_dim[2];
-
- dw[9] = right_execmask;
- dw[10] = bottom_execmask;
-}
-
-static inline uint32_t
-gen6_INTERFACE_DESCRIPTOR_DATA(struct ilo_builder *builder,
- const struct gen6_idrt_data *data,
- int idrt_count)
-{
- /*
- * From the Sandy Bridge PRM, volume 2 part 2, page 34:
- *
- * "(Interface Descriptor Total Length) This field must have the same
- * alignment as the Interface Descriptor Data Start Address.
- *
- * It must be DQWord (32-byte) aligned..."
- *
- * From the Sandy Bridge PRM, volume 2 part 2, page 35:
- *
- * "(Interface Descriptor Data Start Address) Specifies the 32-byte
- * aligned address of the Interface Descriptor data."
- */
- const int state_align = 32;
- const int state_len = (32 / 4) * idrt_count;
- uint32_t state_offset, *dw;
- int i;
-
- ILO_DEV_ASSERT(builder->dev, 7, 7.5);
-
- state_offset = ilo_builder_dynamic_pointer(builder,
- ILO_BUILDER_ITEM_INTERFACE_DESCRIPTOR, state_align, state_len, &dw);
-
- for (i = 0; i < idrt_count; i++) {
- const struct gen6_idrt_data *idrt = &data[i];
- const struct ilo_shader_state *cs = idrt->cs;
- unsigned sampler_count, bt_size, slm_size;
-
- sampler_count =
- ilo_shader_get_kernel_param(cs, ILO_KERNEL_SAMPLER_COUNT);
- assert(sampler_count <= 16);
- sampler_count = (sampler_count + 3) / 4;
-
- bt_size =
- ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TOTAL_COUNT);
- if (bt_size > 31)
- bt_size = 31;
-
- slm_size = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_LOCAL_SIZE);
-
- assert(idrt->curbe_size / 32 <= 63);
-
- dw[0] = ilo_shader_get_kernel_offset(idrt->cs);
- dw[1] = 0;
- dw[2] = idrt->sampler_offset |
- sampler_count << GEN6_IDRT_DW2_SAMPLER_COUNT__SHIFT;
- dw[3] = idrt->binding_table_offset |
- bt_size << GEN6_IDRT_DW3_BINDING_TABLE_SIZE__SHIFT;
-
- dw[4] = (idrt->curbe_size / 32) << GEN6_IDRT_DW4_CURBE_READ_LEN__SHIFT |
- 0 << GEN6_IDRT_DW4_CURBE_READ_OFFSET__SHIFT;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
- dw[5] = GEN7_IDRT_DW5_ROUNDING_MODE_RTNE;
-
- if (slm_size) {
- assert(slm_size <= 64 * 1024);
- slm_size = util_next_power_of_two((slm_size + 4095) / 4096);
-
- dw[5] |= GEN7_IDRT_DW5_BARRIER_ENABLE |
- slm_size << GEN7_IDRT_DW5_SLM_SIZE__SHIFT |
- idrt->thread_group_size <<
- GEN7_IDRT_DW5_THREAD_GROUP_SIZE__SHIFT;
- }
- } else {
- dw[5] = 0;
- }
-
- dw[6] = 0;
- dw[7] = 0;
-
- dw += 8;
- }
-
- return state_offset;
-}
-
-#endif /* ILO_BUILDER_MEDIA_H */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_BUILDER_MI_H
-#define ILO_BUILDER_MI_H
-
-#include "genhw/genhw.h"
-#include "core/intel_winsys.h"
-
-#include "ilo_common.h"
-#include "ilo_builder.h"
-
-static inline void
-gen6_MI_STORE_DATA_IMM(struct ilo_builder *builder,
- struct intel_bo *bo, uint32_t bo_offset,
- uint64_t val)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
- uint32_t reloc_flags = INTEL_RELOC_WRITE;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(bo_offset % 8 == 0);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_MI_CMD(MI_STORE_DATA_IMM) | (cmd_len - 2);
- /* must use GGTT on GEN6 as in PIPE_CONTROL */
- if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
- dw[0] |= GEN6_MI_STORE_DATA_IMM_DW0_USE_GGTT;
- reloc_flags |= INTEL_RELOC_GGTT;
- }
-
- dw[1] = 0; /* MBZ */
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[4] = (uint32_t) val;
- dw[5] = (uint32_t) (val >> 32);
-
- ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, reloc_flags);
- } else {
- dw[3] = (uint32_t) val;
- dw[4] = (uint32_t) (val >> 32);
-
- ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, reloc_flags);
- }
-}
-
-static inline void
-gen6_MI_LOAD_REGISTER_IMM(struct ilo_builder *builder,
- uint32_t reg, uint32_t val)
-{
- const uint8_t cmd_len = 3;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(reg % 4 == 0);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_MI_CMD(MI_LOAD_REGISTER_IMM) | (cmd_len - 2);
- dw[1] = reg;
- dw[2] = val;
-}
-
-static inline void
-gen6_MI_STORE_REGISTER_MEM(struct ilo_builder *builder, uint32_t reg,
- struct intel_bo *bo, uint32_t bo_offset)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 4 : 3;
- uint32_t reloc_flags = INTEL_RELOC_WRITE;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- assert(reg % 4 == 0 && bo_offset % 4 == 0);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_MI_CMD(MI_STORE_REGISTER_MEM) | (cmd_len - 2);
- dw[1] = reg;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, reloc_flags);
- } else {
- /* must use GGTT on Gen6 as in PIPE_CONTROL */
- if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
- dw[0] |= GEN6_MI_STORE_REGISTER_MEM_DW0_USE_GGTT;
- reloc_flags |= INTEL_RELOC_GGTT;
- }
-
- ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, reloc_flags);
- }
-}
-
-static inline void
-gen6_MI_FLUSH_DW(struct ilo_builder *builder)
-{
- const uint8_t cmd_len = 4;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_MI_CMD(MI_FLUSH_DW) | (cmd_len - 2);
- dw[1] = 0;
- dw[2] = 0;
- dw[3] = 0;
-}
-
-static inline void
-gen6_MI_REPORT_PERF_COUNT(struct ilo_builder *builder,
- struct intel_bo *bo, uint32_t bo_offset,
- uint32_t report_id)
-{
- const uint8_t cmd_len = 3;
- uint32_t reloc_flags = INTEL_RELOC_WRITE;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- assert(bo_offset % 64 == 0);
-
- /* must use GGTT on GEN6 as in PIPE_CONTROL */
- if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
- bo_offset |= GEN6_MI_REPORT_PERF_COUNT_DW1_USE_GGTT;
- reloc_flags |= INTEL_RELOC_GGTT;
- }
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_MI_CMD(MI_REPORT_PERF_COUNT) | (cmd_len - 2);
- dw[2] = report_id;
-
- ilo_builder_batch_reloc(builder, pos + 1, bo, bo_offset, reloc_flags);
-}
-
-static inline void
-gen7_MI_LOAD_REGISTER_MEM(struct ilo_builder *builder, uint32_t reg,
- struct intel_bo *bo, uint32_t bo_offset)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 4 : 3;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 7, 8);
-
- assert(reg % 4 == 0 && bo_offset % 4 == 0);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN7_MI_CMD(MI_LOAD_REGISTER_MEM) | (cmd_len - 2);
- dw[1] = reg;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
- ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, 0);
- else
- ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, 0);
-}
-
-/**
- * Add a MI_BATCH_BUFFER_END to the batch buffer. Pad with MI_NOOP if
- * necessary.
- */
-static inline void
-gen6_mi_batch_buffer_end(struct ilo_builder *builder)
-{
- /*
- * From the Sandy Bridge PRM, volume 1 part 1, page 107:
- *
- * "The batch buffer must be QWord aligned and a multiple of QWords in
- * length."
- */
- const bool pad = !(builder->writers[ILO_BUILDER_WRITER_BATCH].used & 0x7);
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- if (pad) {
- ilo_builder_batch_pointer(builder, 2, &dw);
- dw[0] = GEN6_MI_CMD(MI_BATCH_BUFFER_END);
- dw[1] = GEN6_MI_CMD(MI_NOOP);
- } else {
- ilo_builder_batch_pointer(builder, 1, &dw);
- dw[0] = GEN6_MI_CMD(MI_BATCH_BUFFER_END);
- }
-}
-
-#endif /* ILO_BUILDER_MI_H */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_BUILDER_RENDER_H
-#define ILO_BUILDER_RENDER_H
-
-#include "genhw/genhw.h"
-#include "core/intel_winsys.h"
-
-#include "ilo_common.h"
-#include "ilo_builder.h"
-
-static inline void
-gen6_STATE_SIP(struct ilo_builder *builder, uint32_t sip)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 3 : 2;
- uint32_t *dw;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(COMMON, STATE_SIP) | (cmd_len - 2);
- dw[1] = sip;
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
- dw[2] = 0;
-}
-
-static inline void
-gen6_PIPELINE_SELECT(struct ilo_builder *builder, int pipeline)
-{
- const uint8_t cmd_len = 1;
- const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, PIPELINE_SELECT) |
- pipeline;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- switch (pipeline) {
- case GEN6_PIPELINE_SELECT_DW0_SELECT_3D:
- case GEN6_PIPELINE_SELECT_DW0_SELECT_MEDIA:
- break;
- case GEN7_PIPELINE_SELECT_DW0_SELECT_GPGPU:
- assert(ilo_dev_gen(builder->dev) >= ILO_GEN(7));
- break;
- default:
- assert(!"unknown pipeline");
- break;
- }
-
- ilo_builder_batch_write(builder, cmd_len, &dw0);
-}
-
-static inline void
-gen6_PIPE_CONTROL(struct ilo_builder *builder, uint32_t dw1,
- struct intel_bo *bo, uint32_t bo_offset,
- uint64_t imm)
-{
- const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
- uint32_t reloc_flags = INTEL_RELOC_WRITE;
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 8);
-
- if (dw1 & GEN6_PIPE_CONTROL_CS_STALL) {
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 73:
- *
- * "1 of the following must also be set (when CS stall is set):
- *
- * * Depth Cache Flush Enable ([0] of DW1)
- * * Stall at Pixel Scoreboard ([1] of DW1)
- * * Depth Stall ([13] of DW1)
- * * Post-Sync Operation ([13] of DW1)
- * * Render Target Cache Flush Enable ([12] of DW1)
- * * Notify Enable ([8] of DW1)"
- *
- * From the Ivy Bridge PRM, volume 2 part 1, page 61:
- *
- * "One of the following must also be set (when CS stall is set):
- *
- * * Render Target Cache Flush Enable ([12] of DW1)
- * * Depth Cache Flush Enable ([0] of DW1)
- * * Stall at Pixel Scoreboard ([1] of DW1)
- * * Depth Stall ([13] of DW1)
- * * Post-Sync Operation ([13] of DW1)"
- */
- uint32_t bit_test = GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
- GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
- GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
- GEN6_PIPE_CONTROL_DEPTH_STALL;
-
- /* post-sync op */
- bit_test |= GEN6_PIPE_CONTROL_WRITE_IMM |
- GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT |
- GEN6_PIPE_CONTROL_WRITE_TIMESTAMP;
-
- if (ilo_dev_gen(builder->dev) == ILO_GEN(6))
- bit_test |= GEN6_PIPE_CONTROL_NOTIFY_ENABLE;
-
- assert(dw1 & bit_test);
- }
-
- if (dw1 & GEN6_PIPE_CONTROL_DEPTH_STALL) {
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 73:
- *
- * "Following bits must be clear (when Depth Stall is set):
- *
- * * Render Target Cache Flush Enable ([12] of DW1)
- * * Depth Cache Flush Enable ([0] of DW1)"
- */
- assert(!(dw1 & (GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
- GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH)));
- }
-
- switch (dw1 & GEN6_PIPE_CONTROL_WRITE__MASK) {
- case GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT:
- case GEN6_PIPE_CONTROL_WRITE_TIMESTAMP:
- assert(!imm);
- break;
- default:
- break;
- }
-
- assert(bo_offset % 8 == 0);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(3D, PIPE_CONTROL) | (cmd_len - 2);
- dw[1] = dw1;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- dw[4] = (uint32_t) imm;
- dw[5] = (uint32_t) (imm >> 32);
-
- if (bo) {
- ilo_builder_batch_reloc64(builder, pos + 2,
- bo, bo_offset, reloc_flags);
- } else {
- dw[2] = 0;
- dw[3] = 0;
- }
-
- } else {
- dw[3] = (uint32_t) imm;
- dw[4] = (uint32_t) (imm >> 32);
-
- if (bo) {
- /*
- * From the Sandy Bridge PRM, volume 1 part 3, page 19:
- *
- * "[DevSNB] PPGTT memory writes by MI_* (such as
- * MI_STORE_DATA_IMM) and PIPE_CONTROL are not supported."
- */
- if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
- bo_offset |= GEN6_PIPE_CONTROL_DW2_USE_GGTT;
- reloc_flags |= INTEL_RELOC_GGTT;
- }
-
- ilo_builder_batch_reloc(builder, pos + 2,
- bo, bo_offset, reloc_flags);
- } else {
- dw[2] = 0;
- }
- }
-}
-
-static inline void
-ilo_builder_batch_patch_sba(struct ilo_builder *builder)
-{
- const struct ilo_builder_writer *inst =
- &builder->writers[ILO_BUILDER_WRITER_INSTRUCTION];
-
- if (!builder->sba_instruction_pos)
- return;
-
- if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
- ilo_builder_batch_reloc64(builder, builder->sba_instruction_pos,
- inst->bo,
- builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
- 0);
- } else {
- ilo_builder_batch_reloc(builder, builder->sba_instruction_pos, inst->bo,
- builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
- 0);
- }
-}
-
-/**
- * Add a STATE_BASE_ADDRESS to the batch buffer. The relocation entry for the
- * instruction buffer is not added until ilo_builder_end() or next
- * gen6_state_base_address().
- */
-static inline void
-gen6_state_base_address(struct ilo_builder *builder, bool init_all)
-{
- const uint8_t cmd_len = 10;
- const struct ilo_builder_writer *bat =
- &builder->writers[ILO_BUILDER_WRITER_BATCH];
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 6, 7.5);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(COMMON, STATE_BASE_ADDRESS) | (cmd_len - 2);
- dw[1] = builder->mocs << GEN6_SBA_MOCS__SHIFT |
- builder->mocs << GEN6_SBA_DW1_GENERAL_STATELESS_MOCS__SHIFT |
- init_all;
-
- ilo_builder_batch_reloc(builder, pos + 2, bat->bo,
- builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
- 0);
- ilo_builder_batch_reloc(builder, pos + 3, bat->bo,
- builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
- 0);
-
- dw[4] = builder->mocs << GEN6_SBA_MOCS__SHIFT | init_all;
-
- /*
- * Since the instruction writer has WRITER_FLAG_APPEND set, it is tempting
- * not to set Instruction Base Address. The problem is that we do not know
- * if the bo has been or will be moved by the kernel. We need a relocation
- * entry because of that.
- *
- * And since we also set WRITER_FLAG_GROW, we have to wait until
- * ilo_builder_end(), when the final bo is known, to add the relocation
- * entry.
- */
- ilo_builder_batch_patch_sba(builder);
- builder->sba_instruction_pos = pos + 5;
-
- /* skip range checks */
- dw[6] = init_all;
- dw[7] = 0xfffff000 + init_all;
- dw[8] = 0xfffff000 + init_all;
- dw[9] = init_all;
-}
-
-static inline void
-gen8_state_base_address(struct ilo_builder *builder, bool init_all)
-{
- const uint8_t cmd_len = 16;
- const struct ilo_builder_writer *bat =
- &builder->writers[ILO_BUILDER_WRITER_BATCH];
- uint32_t *dw;
- unsigned pos;
-
- ILO_DEV_ASSERT(builder->dev, 8, 8);
-
- pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
-
- dw[0] = GEN6_RENDER_CMD(COMMON, STATE_BASE_ADDRESS) | (cmd_len - 2);
- dw[1] = builder->mocs << GEN8_SBA_MOCS__SHIFT | init_all;
- dw[2] = 0;
- dw[3] = builder->mocs << GEN8_SBA_DW3_STATELESS_MOCS__SHIFT;
- ilo_builder_batch_reloc64(builder, pos + 4, bat->bo,
- builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
- 0);
- ilo_builder_batch_reloc64(builder, pos + 6, bat->bo,
- builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
- 0);
- dw[8] = builder->mocs << GEN8_SBA_MOCS__SHIFT | init_all;
- dw[9] = 0;
-
- ilo_builder_batch_patch_sba(builder);
- builder->sba_instruction_pos = pos + 10;
-
- /* skip range checks */
- dw[12] = 0xfffff000 + init_all;
- dw[13] = 0xfffff000 + init_all;
- dw[14] = 0xfffff000 + init_all;
- dw[15] = 0xfffff000 + init_all;
-}
-
-#endif /* ILO_BUILDER_RENDER_H */
* Chia-I Wu <olv@lunarg.com>
*/
+#include "core/ilo_builder_mi.h"
#include "core/intel_winsys.h"
-#include "ilo_builder_mi.h"
#include "ilo_shader.h"
#include "ilo_cp.h"
#ifndef ILO_CP_H
#define ILO_CP_H
+#include "core/ilo_builder.h"
#include "core/intel_winsys.h"
-#include "ilo_builder.h"
#include "ilo_common.h"
struct ilo_cp;
*/
#include "genhw/genhw.h"
-#include "util/u_prim.h"
+#include "core/ilo_builder.h"
+#include "core/ilo_builder_mi.h"
+#include "core/ilo_builder_render.h"
#include "core/intel_winsys.h"
+#include "util/u_prim.h"
-#include "ilo_builder.h"
-#include "ilo_builder_mi.h"
-#include "ilo_builder_render.h"
#include "ilo_query.h"
#include "ilo_render_gen.h"
* Chia-I Wu <olv@lunarg.com>
*/
+#include "core/ilo_builder_3d.h"
+#include "core/ilo_builder_media.h"
+
#include "ilo_common.h"
#include "ilo_blitter.h"
-#include "ilo_builder_3d.h"
-#include "ilo_builder_media.h"
#include "ilo_state.h"
#include "ilo_render_gen.h"
#ifndef ILO_RENDER_GEN_H
#define ILO_RENDER_GEN_H
+#include "core/ilo_builder.h"
+#include "core/ilo_builder_3d.h"
+#include "core/ilo_builder_render.h"
+
#include "ilo_common.h"
-#include "ilo_builder.h"
-#include "ilo_builder_3d.h"
-#include "ilo_builder_render.h"
#include "ilo_state.h"
#include "ilo_render.h"
*/
#include "genhw/genhw.h"
+#include "core/ilo_builder_3d.h"
+#include "core/ilo_builder_mi.h"
+#include "core/ilo_builder_render.h"
#include "util/u_dual_blend.h"
#include "util/u_prim.h"
#include "ilo_blitter.h"
-#include "ilo_builder_3d.h"
-#include "ilo_builder_mi.h"
-#include "ilo_builder_render.h"
#include "ilo_query.h"
#include "ilo_shader.h"
#include "ilo_state.h"
*/
#include "genhw/genhw.h"
+#include "core/ilo_builder_3d.h"
+#include "core/ilo_builder_render.h"
#include "util/u_dual_blend.h"
#include "ilo_blitter.h"
-#include "ilo_builder_3d.h"
-#include "ilo_builder_render.h"
#include "ilo_shader.h"
#include "ilo_state.h"
#include "ilo_render_gen.h"
*/
#include "genhw/genhw.h"
+#include "core/ilo_builder_3d.h"
+#include "core/ilo_builder_render.h"
#include "util/u_dual_blend.h"
#include "ilo_blitter.h"
-#include "ilo_builder_3d.h"
-#include "ilo_builder_render.h"
#include "ilo_shader.h"
#include "ilo_state.h"
#include "ilo_render_gen.h"
*/
#include "genhw/genhw.h"
+#include "core/ilo_builder_media.h"
+#include "core/ilo_builder_mi.h"
+#include "core/ilo_builder_render.h"
-#include "ilo_builder_media.h"
-#include "ilo_builder_mi.h"
-#include "ilo_builder_render.h"
#include "ilo_state.h"
#include "ilo_render_gen.h"
* Chia-I Wu <olv@lunarg.com>
*/
+#include "core/ilo_builder_3d.h"
+
#include "ilo_common.h"
#include "ilo_blitter.h"
-#include "ilo_builder_3d.h"
#include "ilo_state.h"
#include "ilo_render_gen.h"
*/
#include "genhw/genhw.h" /* for SBE setup */
-#include "tgsi/tgsi_parse.h"
+#include "core/ilo_builder.h"
#include "core/ilo_state_3d.h"
#include "core/intel_winsys.h"
-
#include "shader/ilo_shader_internal.h"
-#include "ilo_builder.h"
+#include "tgsi/tgsi_parse.h"
+
#include "ilo_state.h"
#include "ilo_shader.h"