mesa/src/intel/compiler/brw_fs_surface_builder.cpp

209 lines
8.4 KiB
C++
Raw Normal View History

/*
* 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 "isl/isl.h"
#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, brw_imm_ud(dims), brw_imm_ud(arg)
};
const fs_reg dst = bld.vgrf(BRW_REGISTER_TYPE_UD, rsize);
fs_inst *inst = bld.emit(opcode, dst, srcs, ARRAY_SIZE(srcs));
inst->size_written = rsize * dst.component_size(inst->exec_size);
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 an untyped surface atomic float 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_float(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(src0.type, n);
bld.LOAD_PAYLOAD(tmp, srcs, n, 0);
return emit_send(bld, SHADER_OPCODE_UNTYPED_ATOMIC_FLOAT_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);
}
fs_reg
emit_byte_scattered_read(const fs_builder &bld,
const fs_reg &surface, const fs_reg &addr,
unsigned dims, unsigned size,
unsigned bit_size, brw_predicate pred)
{
return emit_send(bld, SHADER_OPCODE_BYTE_SCATTERED_READ_LOGICAL,
addr, fs_reg(), surface, dims, bit_size, size, pred);
}
void
emit_byte_scattered_write(const fs_builder &bld, const fs_reg &surface,
const fs_reg &addr, const fs_reg &src,
unsigned dims,
unsigned bit_size, brw_predicate pred)
{
emit_send(bld, SHADER_OPCODE_BYTE_SCATTERED_WRITE_LOGICAL,
addr, src, surface, dims, bit_size, 0, pred);
}
}
}