From 9b72bf5bd22c14c4cc17b6945d4b74f4c0eae80a Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 1 May 2015 15:33:56 +0800 Subject: ilo: move command builder to core --- src/gallium/drivers/ilo/Makefile.sources | 20 +- src/gallium/drivers/ilo/core/ilo_builder.c | 495 +++++ src/gallium/drivers/ilo/core/ilo_builder.h | 557 ++++++ src/gallium/drivers/ilo/core/ilo_builder_3d.h | 92 + .../drivers/ilo/core/ilo_builder_3d_bottom.h | 1815 +++++++++++++++++++ src/gallium/drivers/ilo/core/ilo_builder_3d_top.h | 1899 ++++++++++++++++++++ src/gallium/drivers/ilo/core/ilo_builder_blt.h | 322 ++++ src/gallium/drivers/ilo/core/ilo_builder_decode.c | 685 +++++++ src/gallium/drivers/ilo/core/ilo_builder_media.h | 277 +++ src/gallium/drivers/ilo/core/ilo_builder_mi.h | 220 +++ src/gallium/drivers/ilo/core/ilo_builder_render.h | 303 ++++ src/gallium/drivers/ilo/ilo_blitter_blt.c | 4 +- src/gallium/drivers/ilo/ilo_builder.c | 495 ----- src/gallium/drivers/ilo/ilo_builder.h | 554 ------ src/gallium/drivers/ilo/ilo_builder_3d.h | 91 - src/gallium/drivers/ilo/ilo_builder_3d_bottom.h | 1814 ------------------- src/gallium/drivers/ilo/ilo_builder_3d_top.h | 1899 -------------------- src/gallium/drivers/ilo/ilo_builder_blt.h | 321 ---- src/gallium/drivers/ilo/ilo_builder_decode.c | 684 ------- src/gallium/drivers/ilo/ilo_builder_media.h | 276 --- src/gallium/drivers/ilo/ilo_builder_mi.h | 219 --- src/gallium/drivers/ilo/ilo_builder_render.h | 302 ---- src/gallium/drivers/ilo/ilo_cp.c | 2 +- src/gallium/drivers/ilo/ilo_cp.h | 2 +- src/gallium/drivers/ilo/ilo_render.c | 8 +- src/gallium/drivers/ilo/ilo_render_dynamic.c | 5 +- src/gallium/drivers/ilo/ilo_render_gen.h | 7 +- src/gallium/drivers/ilo/ilo_render_gen6.c | 6 +- src/gallium/drivers/ilo/ilo_render_gen7.c | 4 +- src/gallium/drivers/ilo/ilo_render_gen8.c | 4 +- src/gallium/drivers/ilo/ilo_render_media.c | 6 +- src/gallium/drivers/ilo/ilo_render_surface.c | 3 +- src/gallium/drivers/ilo/ilo_shader.c | 6 +- 33 files changed, 6705 insertions(+), 6692 deletions(-) create mode 100644 src/gallium/drivers/ilo/core/ilo_builder.c create mode 100644 src/gallium/drivers/ilo/core/ilo_builder.h create mode 100644 src/gallium/drivers/ilo/core/ilo_builder_3d.h create mode 100644 src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h create mode 100644 src/gallium/drivers/ilo/core/ilo_builder_3d_top.h create mode 100644 src/gallium/drivers/ilo/core/ilo_builder_blt.h create mode 100644 src/gallium/drivers/ilo/core/ilo_builder_decode.c create mode 100644 src/gallium/drivers/ilo/core/ilo_builder_media.h create mode 100644 src/gallium/drivers/ilo/core/ilo_builder_mi.h create mode 100644 src/gallium/drivers/ilo/core/ilo_builder_render.h delete mode 100644 src/gallium/drivers/ilo/ilo_builder.c delete mode 100644 src/gallium/drivers/ilo/ilo_builder.h delete mode 100644 src/gallium/drivers/ilo/ilo_builder_3d.h delete mode 100644 src/gallium/drivers/ilo/ilo_builder_3d_bottom.h delete mode 100644 src/gallium/drivers/ilo/ilo_builder_3d_top.h delete mode 100644 src/gallium/drivers/ilo/ilo_builder_blt.h delete mode 100644 src/gallium/drivers/ilo/ilo_builder_decode.c delete mode 100644 src/gallium/drivers/ilo/ilo_builder_media.h delete mode 100644 src/gallium/drivers/ilo/ilo_builder_mi.h delete mode 100644 src/gallium/drivers/ilo/ilo_builder_render.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/ilo/Makefile.sources b/src/gallium/drivers/ilo/Makefile.sources index 1743f7c7659..91a6f65f2e9 100644 --- a/src/gallium/drivers/ilo/Makefile.sources +++ b/src/gallium/drivers/ilo/Makefile.sources @@ -1,5 +1,15 @@ 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 \ @@ -21,16 +31,6 @@ C_SOURCES := \ 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 \ diff --git a/src/gallium/drivers/ilo/core/ilo_builder.c b/src/gallium/drivers/ilo/core/ilo_builder.c new file mode 100644 index 00000000000..3c5eef9bcbc --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder.c @@ -0,0 +1,495 @@ +/* + * 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 + */ + +#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; +} diff --git a/src/gallium/drivers/ilo/core/ilo_builder.h b/src/gallium/drivers/ilo/core/ilo_builder.h new file mode 100644 index 00000000000..6e26f22aff1 --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder.h @@ -0,0 +1,557 @@ +/* + * 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 + */ + +#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 */ diff --git a/src/gallium/drivers/ilo/core/ilo_builder_3d.h b/src/gallium/drivers/ilo/core/ilo_builder_3d.h new file mode 100644 index 00000000000..6cf1732ee1c --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder_3d.h @@ -0,0 +1,92 @@ +/* + * 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 + */ + +#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 */ diff --git a/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h b/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h new file mode 100644 index 00000000000..16ec4afd15b --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h @@ -0,0 +1,1815 @@ +/* + * 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 + */ + +#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 */ diff --git a/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h b/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h new file mode 100644 index 00000000000..05dbce7c905 --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h @@ -0,0 +1,1899 @@ +/* + * 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 + */ + +#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 */ diff --git a/src/gallium/drivers/ilo/core/ilo_builder_blt.h b/src/gallium/drivers/ilo/core/ilo_builder_blt.h new file mode 100644 index 00000000000..4cc55984334 --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder_blt.h @@ -0,0 +1,322 @@ +/* + * 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 + */ + +#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 */ diff --git a/src/gallium/drivers/ilo/core/ilo_builder_decode.c b/src/gallium/drivers/ilo/core/ilo_builder_decode.c new file mode 100644 index 00000000000..cedaab1559d --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder_decode.c @@ -0,0 +1,685 @@ +/* + * 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 + */ + +#include +#include +#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); +} diff --git a/src/gallium/drivers/ilo/core/ilo_builder_media.h b/src/gallium/drivers/ilo/core/ilo_builder_media.h new file mode 100644 index 00000000000..7fbe6d41635 --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder_media.h @@ -0,0 +1,277 @@ +/* + * 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 + */ + +#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 */ diff --git a/src/gallium/drivers/ilo/core/ilo_builder_mi.h b/src/gallium/drivers/ilo/core/ilo_builder_mi.h new file mode 100644 index 00000000000..7d1d2c9a072 --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder_mi.h @@ -0,0 +1,220 @@ +/* + * 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 + */ + +#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 */ diff --git a/src/gallium/drivers/ilo/core/ilo_builder_render.h b/src/gallium/drivers/ilo/core/ilo_builder_render.h new file mode 100644 index 00000000000..e2191496439 --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_builder_render.h @@ -0,0 +1,303 @@ +/* + * 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 + */ + +#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 */ diff --git a/src/gallium/drivers/ilo/ilo_blitter_blt.c b/src/gallium/drivers/ilo/ilo_blitter_blt.c index 965f7f2b748..d55dc35e360 100644 --- a/src/gallium/drivers/ilo/ilo_blitter_blt.c +++ b/src/gallium/drivers/ilo/ilo_blitter_blt.c @@ -26,10 +26,10 @@ */ #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" diff --git a/src/gallium/drivers/ilo/ilo_builder.c b/src/gallium/drivers/ilo/ilo_builder.c deleted file mode 100644 index 3c5eef9bcbc..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * 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 - */ - -#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; -} diff --git a/src/gallium/drivers/ilo/ilo_builder.h b/src/gallium/drivers/ilo/ilo_builder.h deleted file mode 100644 index 3045f5f0604..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder.h +++ /dev/null @@ -1,554 +0,0 @@ -/* - * 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 - */ - -#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 */ diff --git a/src/gallium/drivers/ilo/ilo_builder_3d.h b/src/gallium/drivers/ilo/ilo_builder_3d.h deleted file mode 100644 index 9f80398204a..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder_3d.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 - */ - -#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 */ diff --git a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h deleted file mode 100644 index ace2304276c..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h +++ /dev/null @@ -1,1814 +0,0 @@ -/* - * 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 - */ - -#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 */ diff --git a/src/gallium/drivers/ilo/ilo_builder_3d_top.h b/src/gallium/drivers/ilo/ilo_builder_3d_top.h deleted file mode 100644 index bc6925db217..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder_3d_top.h +++ /dev/null @@ -1,1899 +0,0 @@ -/* - * 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 - */ - -#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 */ diff --git a/src/gallium/drivers/ilo/ilo_builder_blt.h b/src/gallium/drivers/ilo/ilo_builder_blt.h deleted file mode 100644 index 72aa5c35afa..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder_blt.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 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 - */ - -#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 */ diff --git a/src/gallium/drivers/ilo/ilo_builder_decode.c b/src/gallium/drivers/ilo/ilo_builder_decode.c deleted file mode 100644 index 039346aa5de..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder_decode.c +++ /dev/null @@ -1,684 +0,0 @@ -/* - * 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 - */ - -#include -#include -#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); -} diff --git a/src/gallium/drivers/ilo/ilo_builder_media.h b/src/gallium/drivers/ilo/ilo_builder_media.h deleted file mode 100644 index ed269441f9d..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder_media.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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 - */ - -#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 */ diff --git a/src/gallium/drivers/ilo/ilo_builder_mi.h b/src/gallium/drivers/ilo/ilo_builder_mi.h deleted file mode 100644 index a34edc7d7e0..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder_mi.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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 - */ - -#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 */ diff --git a/src/gallium/drivers/ilo/ilo_builder_render.h b/src/gallium/drivers/ilo/ilo_builder_render.h deleted file mode 100644 index 33d5a9249fb..00000000000 --- a/src/gallium/drivers/ilo/ilo_builder_render.h +++ /dev/null @@ -1,302 +0,0 @@ -/* - * 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 - */ - -#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 */ diff --git a/src/gallium/drivers/ilo/ilo_cp.c b/src/gallium/drivers/ilo/ilo_cp.c index a73c528caab..1f5d4ec7658 100644 --- a/src/gallium/drivers/ilo/ilo_cp.c +++ b/src/gallium/drivers/ilo/ilo_cp.c @@ -25,9 +25,9 @@ * Chia-I Wu */ +#include "core/ilo_builder_mi.h" #include "core/intel_winsys.h" -#include "ilo_builder_mi.h" #include "ilo_shader.h" #include "ilo_cp.h" diff --git a/src/gallium/drivers/ilo/ilo_cp.h b/src/gallium/drivers/ilo/ilo_cp.h index eab4b29b725..016f5e0f9ed 100644 --- a/src/gallium/drivers/ilo/ilo_cp.h +++ b/src/gallium/drivers/ilo/ilo_cp.h @@ -28,9 +28,9 @@ #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; diff --git a/src/gallium/drivers/ilo/ilo_render.c b/src/gallium/drivers/ilo/ilo_render.c index 227faed8c58..f5be3360f05 100644 --- a/src/gallium/drivers/ilo/ilo_render.c +++ b/src/gallium/drivers/ilo/ilo_render.c @@ -26,12 +26,12 @@ */ #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" diff --git a/src/gallium/drivers/ilo/ilo_render_dynamic.c b/src/gallium/drivers/ilo/ilo_render_dynamic.c index 24a3825ebbb..ef92b12da83 100644 --- a/src/gallium/drivers/ilo/ilo_render_dynamic.c +++ b/src/gallium/drivers/ilo/ilo_render_dynamic.c @@ -25,10 +25,11 @@ * Chia-I Wu */ +#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" diff --git a/src/gallium/drivers/ilo/ilo_render_gen.h b/src/gallium/drivers/ilo/ilo_render_gen.h index 72c9bc01677..acfe8be3088 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen.h +++ b/src/gallium/drivers/ilo/ilo_render_gen.h @@ -28,10 +28,11 @@ #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" diff --git a/src/gallium/drivers/ilo/ilo_render_gen6.c b/src/gallium/drivers/ilo/ilo_render_gen6.c index 1c101acb867..47f711e7956 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen6.c +++ b/src/gallium/drivers/ilo/ilo_render_gen6.c @@ -26,13 +26,13 @@ */ #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" diff --git a/src/gallium/drivers/ilo/ilo_render_gen7.c b/src/gallium/drivers/ilo/ilo_render_gen7.c index 8801d147217..07fe7c83536 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen7.c +++ b/src/gallium/drivers/ilo/ilo_render_gen7.c @@ -26,11 +26,11 @@ */ #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" diff --git a/src/gallium/drivers/ilo/ilo_render_gen8.c b/src/gallium/drivers/ilo/ilo_render_gen8.c index f6d8d6666a3..715b93611f1 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen8.c +++ b/src/gallium/drivers/ilo/ilo_render_gen8.c @@ -26,11 +26,11 @@ */ #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" diff --git a/src/gallium/drivers/ilo/ilo_render_media.c b/src/gallium/drivers/ilo/ilo_render_media.c index f6b466c2996..387920a912c 100644 --- a/src/gallium/drivers/ilo/ilo_render_media.c +++ b/src/gallium/drivers/ilo/ilo_render_media.c @@ -26,10 +26,10 @@ */ #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" diff --git a/src/gallium/drivers/ilo/ilo_render_surface.c b/src/gallium/drivers/ilo/ilo_render_surface.c index 97660d0a2ed..b345dfb4fc4 100644 --- a/src/gallium/drivers/ilo/ilo_render_surface.c +++ b/src/gallium/drivers/ilo/ilo_render_surface.c @@ -25,9 +25,10 @@ * Chia-I Wu */ +#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" diff --git a/src/gallium/drivers/ilo/ilo_shader.c b/src/gallium/drivers/ilo/ilo_shader.c index 8a2926c1945..799db2cbfcb 100644 --- a/src/gallium/drivers/ilo/ilo_shader.c +++ b/src/gallium/drivers/ilo/ilo_shader.c @@ -26,12 +26,12 @@ */ #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" -- cgit v1.2.3