1eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 2eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Copyright 2016 Red Hat. 3eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * 4eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a 5eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * copy of this software and associated documentation files (the "Software"), 6eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * to deal in the Software without restriction, including without limitation 7eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * on the rights to use, copy, modify, merge, publish, distribute, sub 8eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * license, and/or sell copies of the Software, and to permit persons to whom 9eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * the Software is furnished to do so, subject to the following conditions: 10eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * 11eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * The above copyright notice and this permission notice (including the next 12eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * paragraph) shall be included in all copies or substantial portions of the 13eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Software. 14eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * 15eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * USE OR OTHER DEALINGS IN THE SOFTWARE. 22eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 23eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 24eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie#include "sp_context.h" 25eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie#include "sp_image.h" 26eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie#include "sp_texture.h" 27eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 28eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie#include "util/u_format.h" 29eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 30eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 31eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Get the offset into the base image 32eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * first element for a buffer or layer/level for texture. 33eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 34eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic uint32_t 35eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlieget_image_offset(const struct softpipe_resource *spr, 36eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const struct pipe_image_view *iview, 37eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie enum pipe_format format, unsigned r_coord) 38eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 39eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int base_layer = 0; 40eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 41eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (spr->base.target == PIPE_BUFFER) 42325379096f54dde39171d1b8804e29a8003bb3c7Marek Olšák return iview->u.buf.offset; 43eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 44eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (spr->base.target == PIPE_TEXTURE_1D_ARRAY || 45eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie spr->base.target == PIPE_TEXTURE_2D_ARRAY || 46eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie spr->base.target == PIPE_TEXTURE_CUBE_ARRAY || 47eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie spr->base.target == PIPE_TEXTURE_CUBE || 48eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie spr->base.target == PIPE_TEXTURE_3D) 49eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie base_layer = r_coord + iview->u.tex.first_layer; 50eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return softpipe_get_tex_image_offset(spr, iview->u.tex.level, base_layer); 51eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 52eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 53eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 54eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Does this texture instruction have a layer or depth parameter. 55eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 56eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic inline bool 57eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehas_layer_or_depth(unsigned tgsi_tex_instr) 58eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 59eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return (tgsi_tex_instr == TGSI_TEXTURE_3D || 60eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_tex_instr == TGSI_TEXTURE_CUBE || 61eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY || 62eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_tex_instr == TGSI_TEXTURE_2D_ARRAY || 63eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_tex_instr == TGSI_TEXTURE_CUBE_ARRAY || 64eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_tex_instr == TGSI_TEXTURE_2D_ARRAY_MSAA); 65eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 66eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 67eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 68eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Is this texture instruction a single non-array coordinate. 69eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 70eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic inline bool 71eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehas_1coord(unsigned tgsi_tex_instr) 72eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 73eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return (tgsi_tex_instr == TGSI_TEXTURE_BUFFER || 74eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_tex_instr == TGSI_TEXTURE_1D || 75eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY); 76eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 77eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 78eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 79eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * check the bounds vs w/h/d 80eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 81eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic inline bool 82eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliebounds_check(int width, int height, int depth, 83eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int s, int t, int r) 84eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 85eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (s < 0 || s >= width) 86eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return false; 87eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (t < 0 || t >= height) 88eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return false; 89eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (r < 0 || r >= depth) 90eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return false; 91eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 92eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 93eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 94eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 95eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Checks if the texture target compatible with the image resource 96eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * pipe target. 97eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 98eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic inline bool 99eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehas_compat_target(unsigned pipe_target, unsigned tgsi_target) 100eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 101eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie switch (pipe_target) { 102eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_TEXTURE_1D: 103eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_target == TGSI_TEXTURE_1D) 104eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 105eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 106eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_TEXTURE_2D: 107eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_target == TGSI_TEXTURE_2D) 108eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 109eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 110eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_TEXTURE_RECT: 111eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_target == TGSI_TEXTURE_RECT) 112eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 113eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 114eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_TEXTURE_3D: 115eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_target == TGSI_TEXTURE_3D || 116eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_target == TGSI_TEXTURE_2D) 117eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 118eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 119eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_TEXTURE_CUBE: 120eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_target == TGSI_TEXTURE_CUBE || 121eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_target == TGSI_TEXTURE_2D) 122eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 123eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 124eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_TEXTURE_1D_ARRAY: 125eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_target == TGSI_TEXTURE_1D || 126eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_target == TGSI_TEXTURE_1D_ARRAY) 127eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 128eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 129eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_TEXTURE_2D_ARRAY: 130eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_target == TGSI_TEXTURE_2D || 131eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_target == TGSI_TEXTURE_2D_ARRAY) 132eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 133eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 134eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_TEXTURE_CUBE_ARRAY: 135eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_target == TGSI_TEXTURE_CUBE || 136eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_target == TGSI_TEXTURE_CUBE_ARRAY || 137eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie tgsi_target == TGSI_TEXTURE_2D) 138eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 139eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 140eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case PIPE_BUFFER: 141eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return (tgsi_target == TGSI_TEXTURE_BUFFER); 142eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 143eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return false; 144eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 145eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 146eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic bool 147eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlieget_dimensions(const struct pipe_image_view *iview, 148eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const struct softpipe_resource *spr, 149eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned tgsi_tex_instr, 150eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie enum pipe_format pformat, 151eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned *width, 152eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned *height, 153eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned *depth) 154eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 155eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (tgsi_tex_instr == TGSI_TEXTURE_BUFFER) { 156325379096f54dde39171d1b8804e29a8003bb3c7Marek Olšák *width = iview->u.buf.size / util_format_get_blocksize(pformat); 157eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *height = 1; 158eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *depth = 1; 159eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie /* 160eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Bounds check the buffer size from the view 161eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * and the buffer size from the underlying buffer. 162eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 163eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (util_format_get_stride(pformat, *width) > 164eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_get_stride(spr->base.format, spr->base.width0)) 165eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return false; 166eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } else { 167eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned level; 168eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 169eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie level = spr->base.target == PIPE_BUFFER ? 0 : iview->u.tex.level; 170eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *width = u_minify(spr->base.width0, level); 171eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *height = u_minify(spr->base.height0, level); 172eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 173c3b88cc2c15f19e748c9c406e9ab053975adab7eMarek Olšák if (spr->base.target == PIPE_TEXTURE_3D) 174eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *depth = u_minify(spr->base.depth0, level); 175eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie else 176eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *depth = spr->base.array_size; 177eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 178eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie /* Make sure the resource and view have compatiable formats */ 179eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (util_format_get_blocksize(pformat) > 180eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_get_blocksize(spr->base.format)) 181eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return false; 182eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 183eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return true; 184eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 185eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 186eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void 187eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliefill_coords(const struct tgsi_image_params *params, 188eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned index, 189eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int s[TGSI_QUAD_SIZE], 190eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int t[TGSI_QUAD_SIZE], 191eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int r[TGSI_QUAD_SIZE], 192eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int *s_coord, int *t_coord, int *r_coord) 193eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 194eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *s_coord = s[index]; 195eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *t_coord = has_1coord(params->tgsi_tex_instr) ? 0 : t[index]; 196eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *r_coord = has_layer_or_depth(params->tgsi_tex_instr) ? 197eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie (params->tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY ? t[index] : r[index]) : 0; 198eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 199eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 200eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement the image LOAD operation. 201eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 202eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void 203eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_tgsi_load(const struct tgsi_image *image, 204eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const struct tgsi_image_params *params, 205eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int s[TGSI_QUAD_SIZE], 206eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int t[TGSI_QUAD_SIZE], 207eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int r[TGSI_QUAD_SIZE], 208eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int sample[TGSI_QUAD_SIZE], 209eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) 210eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 211eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image; 212eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct pipe_image_view *iview; 213eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct softpipe_resource *spr; 214eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned width, height, depth; 215eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned stride; 216eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int c, j; 217eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie char *data_ptr; 218eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned offset = 0; 219eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 2206d6525a377250865cc6baa2c9cd5c6c0b6cd3f9cThomas Hindoe Paaboel Andersen if (params->unit >= PIPE_MAX_SHADER_IMAGES) 221eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie goto fail_write_all_zero; 222eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie iview = &sp_img->sp_iview[params->unit]; 223eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie spr = (struct softpipe_resource *)iview->resource; 224eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!spr) 225eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie goto fail_write_all_zero; 226eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 227eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!has_compat_target(spr->base.target, params->tgsi_tex_instr)) 228eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie goto fail_write_all_zero; 229eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 230eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!get_dimensions(iview, spr, params->tgsi_tex_instr, 231eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie params->format, &width, &height, &depth)) 232eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 233eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 234eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie stride = util_format_get_stride(params->format, width); 235eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 236eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (j = 0; j < TGSI_QUAD_SIZE; j++) { 237eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int s_coord, t_coord, r_coord; 238eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie bool fill_zero = false; 239eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 240eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!(params->execmask & (1 << j))) 241eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie fill_zero = true; 242eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 243eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord); 244eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!bounds_check(width, height, depth, 245eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, r_coord)) 246eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie fill_zero = true; 247eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 248eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (fill_zero) { 249eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int nc = util_format_get_nr_components(params->format); 250eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int ival = util_format_is_pure_integer(params->format); 251eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) { 252eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie rgba[c][j] = 0; 253eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (c == 3 && nc < 4) { 254eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (ival) 255eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[j] = 1; 256eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie else 257eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie rgba[c][j] = 1.0; 258eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 259eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 260eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie continue; 261eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 262eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie offset = get_image_offset(spr, iview, params->format, r_coord); 263eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie data_ptr = (char *)spr->data + offset; 264eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 265eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (util_format_is_pure_sint(params->format)) { 266eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int32_t sdata[4]; 267eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 268eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_read_4i(params->format, 269eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata, 0, 270eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie data_ptr, stride, 271eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, 1, 1); 272eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) 273eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[j] = sdata[c]; 274eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } else if (util_format_is_pure_uint(params->format)) { 275eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie uint32_t sdata[4]; 276eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_read_4ui(params->format, 277eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata, 0, 278eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie data_ptr, stride, 279eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, 1, 1); 280eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) 281eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[j] = sdata[c]; 282eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } else { 283eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float sdata[4]; 284eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_read_4f(params->format, 285eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata, 0, 286eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie data_ptr, stride, 287eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, 1, 1); 288eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) 289eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie rgba[c][j] = sdata[c]; 290eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 291eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 292eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 293eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliefail_write_all_zero: 294eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (j = 0; j < TGSI_QUAD_SIZE; j++) { 295eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) 296eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie rgba[c][j] = 0; 297eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 298eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 299eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 300eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 301eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 302eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement the image STORE operation. 303eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 304eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void 305eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_tgsi_store(const struct tgsi_image *image, 306eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const struct tgsi_image_params *params, 307eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int s[TGSI_QUAD_SIZE], 308eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int t[TGSI_QUAD_SIZE], 309eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int r[TGSI_QUAD_SIZE], 310eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int sample[TGSI_QUAD_SIZE], 311eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) 312eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 313eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image; 314eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct pipe_image_view *iview; 315eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct softpipe_resource *spr; 316eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned width, height, depth; 317eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned stride; 318eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie char *data_ptr; 319eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int j, c; 320eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned offset = 0; 321eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned pformat = params->format; 322eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 3236d6525a377250865cc6baa2c9cd5c6c0b6cd3f9cThomas Hindoe Paaboel Andersen if (params->unit >= PIPE_MAX_SHADER_IMAGES) 324eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 325eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie iview = &sp_img->sp_iview[params->unit]; 326eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie spr = (struct softpipe_resource *)iview->resource; 327eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!spr) 328eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 329eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!has_compat_target(spr->base.target, params->tgsi_tex_instr)) 330eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 331eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 332eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (params->format == PIPE_FORMAT_NONE) 333eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie pformat = spr->base.format; 334eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 335eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!get_dimensions(iview, spr, params->tgsi_tex_instr, 336eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie pformat, &width, &height, &depth)) 337eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 338eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 339eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie stride = util_format_get_stride(pformat, width); 340eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 341eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (j = 0; j < TGSI_QUAD_SIZE; j++) { 342eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int s_coord, t_coord, r_coord; 343eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 344eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!(params->execmask & (1 << j))) 345eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie continue; 346eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 347eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord); 348eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!bounds_check(width, height, depth, 349eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, r_coord)) 350eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie continue; 351eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 352eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie offset = get_image_offset(spr, iview, pformat, r_coord); 353eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie data_ptr = (char *)spr->data + offset; 354eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 355eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (util_format_is_pure_sint(pformat)) { 356eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int32_t sdata[4]; 357eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) 358eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = ((int32_t *)rgba[c])[j]; 359eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_write_4i(pformat, sdata, 0, data_ptr, stride, 360eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, 1, 1); 361eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } else if (util_format_is_pure_uint(pformat)) { 362eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie uint32_t sdata[4]; 363eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) 364eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = ((uint32_t *)rgba[c])[j]; 365eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_write_4ui(pformat, sdata, 0, data_ptr, stride, 366eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, 1, 1); 367eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } else { 368eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float sdata[4]; 369eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) 370eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = rgba[c][j]; 371eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_write_4f(pformat, sdata, 0, data_ptr, stride, 372eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, 1, 1); 373eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 374eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 375eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 376eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 377eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 378eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement atomic operations on unsigned integers. 379eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 380eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void 381eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehandle_op_uint(const struct pipe_image_view *iview, 382eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const struct tgsi_image_params *params, 383eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie bool just_read, 384eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie char *data_ptr, 385eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie uint qi, 386eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned stride, 387eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned opcode, 388eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int s, 389eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int t, 390eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE], 391eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) 392eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 393eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie uint c; 394eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int nc = util_format_get_nr_components(params->format); 395eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned sdata[4]; 396eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 397eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_read_4ui(params->format, 398eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata, 0, 399eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie data_ptr, stride, 400eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s, t, 1, 1); 401eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 402eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (just_read) { 403eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 404eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = sdata[c]; 405eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 406eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 407eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 408eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie switch (opcode) { 409eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMUADD: 410eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 411eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned temp = sdata[c]; 412eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] += ((uint32_t *)rgba[c])[qi]; 413eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = temp; 414eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 415eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 416eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMXCHG: 417eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 418eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned temp = sdata[c]; 419eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = ((uint32_t *)rgba[c])[qi]; 420eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = temp; 421eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 422eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 423eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMCAS: 424eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 425eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned dst_x = sdata[c]; 426eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned cmp_x = ((uint32_t *)rgba[c])[qi]; 427eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned src_x = ((uint32_t *)rgba2[c])[qi]; 428eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned temp = sdata[c]; 429eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = (dst_x == cmp_x) ? src_x : dst_x; 430eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = temp; 431eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 432eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 433eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMAND: 434eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 435eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned temp = sdata[c]; 436eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] &= ((uint32_t *)rgba[c])[qi]; 437eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = temp; 438eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 439eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 440eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMOR: 441eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 442eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned temp = sdata[c]; 443eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] |= ((uint32_t *)rgba[c])[qi]; 444eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = temp; 445eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 446eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 447eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMXOR: 448eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 449eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned temp = sdata[c]; 450eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] ^= ((uint32_t *)rgba[c])[qi]; 451eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = temp; 452eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 453eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 454eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMUMIN: 455eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 456eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned dst_x = sdata[c]; 457eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned src_x = ((uint32_t *)rgba[c])[qi]; 458eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = MIN2(dst_x, src_x); 459eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = dst_x; 460eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 461eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 462eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMUMAX: 463eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 464eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned dst_x = sdata[c]; 465eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned src_x = ((uint32_t *)rgba[c])[qi]; 466eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = MAX2(dst_x, src_x); 467eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = dst_x; 468eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 469eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 470eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMIMIN: 471eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 472eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int dst_x = sdata[c]; 473eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int src_x = ((uint32_t *)rgba[c])[qi]; 474eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = MIN2(dst_x, src_x); 475eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = dst_x; 476eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 477eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 478eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMIMAX: 479eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 480eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int dst_x = sdata[c]; 481eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int src_x = ((uint32_t *)rgba[c])[qi]; 482eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = MAX2(dst_x, src_x); 483eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((uint32_t *)rgba[c])[qi] = dst_x; 484eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 485eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 486eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie default: 487eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie assert(!"Unexpected TGSI opcode in sp_tgsi_op"); 488eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 489eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 490eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_write_4ui(params->format, sdata, 0, data_ptr, stride, 491eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s, t, 1, 1); 492eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 493eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 494eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 495eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement atomic operations on signed integers. 496eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 497eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void 498eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehandle_op_int(const struct pipe_image_view *iview, 499eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const struct tgsi_image_params *params, 500eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie bool just_read, 501eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie char *data_ptr, 502eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie uint qi, 503eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned stride, 504eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned opcode, 505eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int s, 506eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int t, 507eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE], 508eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) 509eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 510eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie uint c; 511eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int nc = util_format_get_nr_components(params->format); 512eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int sdata[4]; 513eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_read_4i(params->format, 514eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata, 0, 515eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie data_ptr, stride, 516eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s, t, 1, 1); 517eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 518eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (just_read) { 519eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 520eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = sdata[c]; 521eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 522eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 523eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 524eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie switch (opcode) { 525eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMUADD: 526eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 527eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int temp = sdata[c]; 528eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] += ((int32_t *)rgba[c])[qi]; 529eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = temp; 530eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 531eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 532eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMXCHG: 533eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 534eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int temp = sdata[c]; 535eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = ((int32_t *)rgba[c])[qi]; 536eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = temp; 537eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 538eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 539eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMCAS: 540eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 541eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int dst_x = sdata[c]; 542eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int cmp_x = ((int32_t *)rgba[c])[qi]; 543eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int src_x = ((int32_t *)rgba2[c])[qi]; 544eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int temp = sdata[c]; 545eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = (dst_x == cmp_x) ? src_x : dst_x; 546eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = temp; 547eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 548eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 549eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMAND: 550eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 551eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int temp = sdata[c]; 552eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] &= ((int32_t *)rgba[c])[qi]; 553eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = temp; 554eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 555eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 556eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMOR: 557eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 558eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int temp = sdata[c]; 559eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] |= ((int32_t *)rgba[c])[qi]; 560eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = temp; 561eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 562eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 563eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMXOR: 564eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 565eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int temp = sdata[c]; 566eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] ^= ((int32_t *)rgba[c])[qi]; 567eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = temp; 568eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 569eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 570eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMUMIN: 571eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 572eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int dst_x = sdata[c]; 573eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int src_x = ((int32_t *)rgba[c])[qi]; 574eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = MIN2(dst_x, src_x); 575eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = dst_x; 576eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 577eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 578eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMUMAX: 579eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 580eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int dst_x = sdata[c]; 581eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int src_x = ((int32_t *)rgba[c])[qi]; 582eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = MAX2(dst_x, src_x); 583eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = dst_x; 584eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 585eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 586eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMIMIN: 587eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 588eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int dst_x = sdata[c]; 589eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int src_x = ((int32_t *)rgba[c])[qi]; 590eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = MIN2(dst_x, src_x); 591eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = dst_x; 592eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 593eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 594eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_OPCODE_ATOMIMAX: 595eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < nc; c++) { 596eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int dst_x = sdata[c]; 597eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int src_x = ((int32_t *)rgba[c])[qi]; 598eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie sdata[c] = MAX2(dst_x, src_x); 599eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[qi] = dst_x; 600eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 601eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 602eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie default: 603eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie assert(!"Unexpected TGSI opcode in sp_tgsi_op"); 604eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 605eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 606eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie util_format_write_4i(params->format, sdata, 0, data_ptr, stride, 607eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s, t, 1, 1); 608eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 609eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 610277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie/* GLES OES_shader_image_atomic.txt allows XCHG on R32F */ 611277170eeea00e001635aa0c8ac90012a6f98f299Dave Airliestatic void 612277170eeea00e001635aa0c8ac90012a6f98f299Dave Airliehandle_op_r32f_xchg(const struct pipe_image_view *iview, 613277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie const struct tgsi_image_params *params, 614277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie bool just_read, 615277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie char *data_ptr, 616277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie uint qi, 617277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie unsigned stride, 618277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie unsigned opcode, 619277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie int s, 620277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie int t, 621277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) 622277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie{ 623277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie float sdata[4]; 624277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie uint c; 625277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie int nc = 1; 626277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie util_format_read_4f(params->format, 627277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie sdata, 0, 628277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie data_ptr, stride, 629277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie s, t, 1, 1); 630277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie if (just_read) { 631277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie for (c = 0; c < nc; c++) { 632277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie ((int32_t *)rgba[c])[qi] = sdata[c]; 633277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie } 634277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie return; 635277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie } 636277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie 637277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie for (c = 0; c < nc; c++) { 638277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie int temp = sdata[c]; 639277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie sdata[c] = ((float *)rgba[c])[qi]; 640277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie ((float *)rgba[c])[qi] = temp; 641277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie } 642277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie util_format_write_4f(params->format, sdata, 0, data_ptr, stride, 643277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie s, t, 1, 1); 644277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie} 645277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie 646eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/* 647eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement atomic image operations. 648eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */ 649eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void 650eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_tgsi_op(const struct tgsi_image *image, 651eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const struct tgsi_image_params *params, 652eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned opcode, 653eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int s[TGSI_QUAD_SIZE], 654eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int t[TGSI_QUAD_SIZE], 655eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int r[TGSI_QUAD_SIZE], 656eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const int sample[TGSI_QUAD_SIZE], 657eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE], 658eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) 659eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 660eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image; 661eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct pipe_image_view *iview; 662eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct softpipe_resource *spr; 663eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned width, height, depth; 664eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned stride; 665eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int j, c; 666eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie unsigned offset; 667eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie char *data_ptr; 668eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 6696d6525a377250865cc6baa2c9cd5c6c0b6cd3f9cThomas Hindoe Paaboel Andersen if (params->unit >= PIPE_MAX_SHADER_IMAGES) 670eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 671eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie iview = &sp_img->sp_iview[params->unit]; 672eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie spr = (struct softpipe_resource *)iview->resource; 673eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!spr) 674eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie goto fail_write_all_zero; 675eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!has_compat_target(spr->base.target, params->tgsi_tex_instr)) 676eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie goto fail_write_all_zero; 677eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 678eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!get_dimensions(iview, spr, params->tgsi_tex_instr, 679eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie params->format, &width, &height, &depth)) 680eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie goto fail_write_all_zero; 681eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 682eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie stride = util_format_get_stride(spr->base.format, width); 683eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 684eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (j = 0; j < TGSI_QUAD_SIZE; j++) { 685eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int s_coord, t_coord, r_coord; 686eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie bool just_read = false; 687eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 688eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord); 689eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!bounds_check(width, height, depth, 690eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie s_coord, t_coord, r_coord)) { 691eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int nc = util_format_get_nr_components(params->format); 692eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int ival = util_format_is_pure_integer(params->format); 693eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int c; 694eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) { 695eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie rgba[c][j] = 0; 696eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (c == 3 && nc < 4) { 697eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (ival) 698eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie ((int32_t *)rgba[c])[j] = 1; 699eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie else 700eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie rgba[c][j] = 1.0; 701eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 702eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 703eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie continue; 704eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 705eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 706eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie /* just readback the value for atomic if execmask isn't set */ 707eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!(params->execmask & (1 << j))) { 708eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie just_read = true; 709eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 710eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 711eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie offset = get_image_offset(spr, iview, params->format, r_coord); 712eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie data_ptr = (char *)spr->data + offset; 713eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 714eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie /* we should see atomic operations on r32 formats */ 715eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (util_format_is_pure_uint(params->format)) 716eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie handle_op_uint(iview, params, just_read, data_ptr, j, stride, 717eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie opcode, s_coord, t_coord, rgba, rgba2); 718eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie else if (util_format_is_pure_sint(params->format)) 719eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie handle_op_int(iview, params, just_read, data_ptr, j, stride, 720eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie opcode, s_coord, t_coord, rgba, rgba2); 721277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie else if (params->format == PIPE_FORMAT_R32_FLOAT && 722277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie opcode == TGSI_OPCODE_ATOMXCHG) 723277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie handle_op_r32f_xchg(iview, params, just_read, data_ptr, j, stride, 724277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie opcode, s_coord, t_coord, rgba); 725eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie else 726eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie assert(0); 727eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 728eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 729eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliefail_write_all_zero: 730eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (j = 0; j < TGSI_QUAD_SIZE; j++) { 731eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie for (c = 0; c < 4; c++) 732eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie rgba[c][j] = 0; 733eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 734eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 735eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 736eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 737eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void 738eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_tgsi_get_dims(const struct tgsi_image *image, 739eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie const struct tgsi_image_params *params, 740eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int dims[4]) 741eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 742eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image; 743eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct pipe_image_view *iview; 744eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct softpipe_resource *spr; 745eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie int level; 746eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 7476d6525a377250865cc6baa2c9cd5c6c0b6cd3f9cThomas Hindoe Paaboel Andersen if (params->unit >= PIPE_MAX_SHADER_IMAGES) 748eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 749eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie iview = &sp_img->sp_iview[params->unit]; 750eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie spr = (struct softpipe_resource *)iview->resource; 751eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!spr) 752eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 753eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 754eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (params->tgsi_tex_instr == TGSI_TEXTURE_BUFFER) { 755325379096f54dde39171d1b8804e29a8003bb3c7Marek Olšák dims[0] = iview->u.buf.size / util_format_get_blocksize(iview->format); 756eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[1] = dims[2] = dims[3] = 0; 757eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 758eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 759eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 760eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie level = iview->u.tex.level; 761eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[0] = u_minify(spr->base.width0, level); 762eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie switch (params->tgsi_tex_instr) { 763eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_TEXTURE_1D_ARRAY: 764eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[1] = iview->u.tex.last_layer - iview->u.tex.first_layer + 1; 765eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie /* fallthrough */ 766eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_TEXTURE_1D: 767eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 768eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_TEXTURE_2D_ARRAY: 769eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[2] = iview->u.tex.last_layer - iview->u.tex.first_layer + 1; 770eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie /* fallthrough */ 771eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_TEXTURE_2D: 772eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_TEXTURE_CUBE: 773eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_TEXTURE_RECT: 774eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[1] = u_minify(spr->base.height0, level); 775eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 776eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_TEXTURE_3D: 777eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[1] = u_minify(spr->base.height0, level); 778eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[2] = u_minify(spr->base.depth0, level); 779eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 780eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie case TGSI_TEXTURE_CUBE_ARRAY: 781eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[1] = u_minify(spr->base.height0, level); 782eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie dims[2] = (iview->u.tex.last_layer - iview->u.tex.first_layer + 1) / 6; 783eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie break; 784eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie default: 785eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie assert(!"unexpected texture target in sp_get_dims()"); 786eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return; 787eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie } 788eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie} 789eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 790eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestruct sp_tgsi_image * 791eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_create_tgsi_image(void) 792eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{ 793eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie struct sp_tgsi_image *img = CALLOC_STRUCT(sp_tgsi_image); 794eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie if (!img) 795eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return NULL; 796eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie 797eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie img->base.load = sp_tgsi_load; 798eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie img->base.store = sp_tgsi_store; 799eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie img->base.op = sp_tgsi_op; 800eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie img->base.get_dims = sp_tgsi_get_dims; 801eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie return img; 802eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}; 803