summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
new file mode 100644
index 0000000..cac958d
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright © 2013-2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#include "brw_fs_surface_builder.h"
+#include "brw_fs.h"
+
+using namespace brw;
+
+namespace brw {
+ namespace surface_access {
+ namespace {
+ /**
+ * Generate a logical send opcode for a surface message and return
+ * the result.
+ */
+ fs_reg
+ emit_send(const fs_builder &bld, enum opcode opcode,
+ const fs_reg &addr, const fs_reg &src, const fs_reg &surface,
+ unsigned dims, unsigned arg, unsigned rsize,
+ brw_predicate pred = BRW_PREDICATE_NONE)
+ {
+ /* Reduce the dynamically uniform surface index to a single
+ * scalar.
+ */
+ const fs_reg usurface = bld.emit_uniformize(surface);
+ const fs_reg srcs[] = {
+ addr, src, usurface, fs_reg(dims), fs_reg(arg)
+ };
+ const fs_reg dst = bld.vgrf(BRW_REGISTER_TYPE_UD, rsize);
+ fs_inst *inst = bld.emit(opcode, dst, srcs, ARRAY_SIZE(srcs));
+
+ inst->regs_written = rsize * bld.dispatch_width() / 8;
+ inst->predicate = pred;
+ return dst;
+ }
+ }
+
+ /**
+ * Emit an untyped surface read opcode. \p dims determines the number
+ * of components of the address and \p size the number of components of
+ * the returned value.
+ */
+ fs_reg
+ emit_untyped_read(const fs_builder &bld,
+ const fs_reg &surface, const fs_reg &addr,
+ unsigned dims, unsigned size,
+ brw_predicate pred)
+ {
+ return emit_send(bld, SHADER_OPCODE_UNTYPED_SURFACE_READ_LOGICAL,
+ addr, fs_reg(), surface, dims, size, size, pred);
+ }
+
+ /**
+ * Emit an untyped surface write opcode. \p dims determines the number
+ * of components of the address and \p size the number of components of
+ * the argument.
+ */
+ void
+ emit_untyped_write(const fs_builder &bld, const fs_reg &surface,
+ const fs_reg &addr, const fs_reg &src,
+ unsigned dims, unsigned size,
+ brw_predicate pred)
+ {
+ emit_send(bld, SHADER_OPCODE_UNTYPED_SURFACE_WRITE_LOGICAL,
+ addr, src, surface, dims, size, 0, pred);
+ }
+
+ /**
+ * Emit an untyped surface atomic opcode. \p dims determines the number
+ * of components of the address and \p rsize the number of components of
+ * the returned value (either zero or one).
+ */
+ fs_reg
+ emit_untyped_atomic(const fs_builder &bld,
+ const fs_reg &surface, const fs_reg &addr,
+ const fs_reg &src0, const fs_reg &src1,
+ unsigned dims, unsigned rsize, unsigned op,
+ brw_predicate pred)
+ {
+ /* FINISHME: Factor out this frequently recurring pattern into a
+ * helper function.
+ */
+ const unsigned n = (src0.file != BAD_FILE) + (src1.file != BAD_FILE);
+ const fs_reg srcs[] = { src0, src1 };
+ const fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_UD, n);
+ bld.LOAD_PAYLOAD(tmp, srcs, n, 0);
+
+ return emit_send(bld, SHADER_OPCODE_UNTYPED_ATOMIC_LOGICAL,
+ addr, tmp, surface, dims, op, rsize, pred);
+ }
+
+ /**
+ * Emit a typed surface read opcode. \p dims determines the number of
+ * components of the address and \p size the number of components of the
+ * returned value.
+ */
+ fs_reg
+ emit_typed_read(const fs_builder &bld, const fs_reg &surface,
+ const fs_reg &addr, unsigned dims, unsigned size)
+ {
+ return emit_send(bld, SHADER_OPCODE_TYPED_SURFACE_READ_LOGICAL,
+ addr, fs_reg(), surface, dims, size, size);
+ }
+
+ /**
+ * Emit a typed surface write opcode. \p dims determines the number of
+ * components of the address and \p size the number of components of the
+ * argument.
+ */
+ void
+ emit_typed_write(const fs_builder &bld, const fs_reg &surface,
+ const fs_reg &addr, const fs_reg &src,
+ unsigned dims, unsigned size)
+ {
+ emit_send(bld, SHADER_OPCODE_TYPED_SURFACE_WRITE_LOGICAL,
+ addr, src, surface, dims, size, 0);
+ }
+
+ /**
+ * Emit a typed surface atomic opcode. \p dims determines the number of
+ * components of the address and \p rsize the number of components of
+ * the returned value (either zero or one).
+ */
+ fs_reg
+ emit_typed_atomic(const fs_builder &bld, const fs_reg &surface,
+ const fs_reg &addr,
+ const fs_reg &src0, const fs_reg &src1,
+ unsigned dims, unsigned rsize, unsigned op,
+ brw_predicate pred)
+ {
+ /* FINISHME: Factor out this frequently recurring pattern into a
+ * helper function.
+ */
+ const unsigned n = (src0.file != BAD_FILE) + (src1.file != BAD_FILE);
+ const fs_reg srcs[] = { src0, src1 };
+ const fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_UD, n);
+ bld.LOAD_PAYLOAD(tmp, srcs, n, 0);
+
+ return emit_send(bld, SHADER_OPCODE_TYPED_ATOMIC_LOGICAL,
+ addr, tmp, surface, dims, op, rsize);
+ }
+ }
+}