1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2014 Ilia Mirkin. All Rights Reserved. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 7bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 8bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 9bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 10bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 11bf215546Sopenharmony_ci * the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 14bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 15bf215546Sopenharmony_ci * of the Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24bf215546Sopenharmony_ci * 25bf215546Sopenharmony_ci **************************************************************************/ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "program/prog_parameter.h" 29bf215546Sopenharmony_ci#include "program/prog_print.h" 30bf215546Sopenharmony_ci#include "compiler/glsl/ir_uniform.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "pipe/p_context.h" 33bf215546Sopenharmony_ci#include "pipe/p_defines.h" 34bf215546Sopenharmony_ci#include "util/u_inlines.h" 35bf215546Sopenharmony_ci#include "util/u_surface.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "st_debug.h" 38bf215546Sopenharmony_ci#include "st_context.h" 39bf215546Sopenharmony_ci#include "st_atom.h" 40bf215546Sopenharmony_ci#include "st_program.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistatic void 43bf215546Sopenharmony_cist_binding_to_sb(struct gl_buffer_binding *binding, 44bf215546Sopenharmony_ci struct pipe_shader_buffer *sb, 45bf215546Sopenharmony_ci unsigned alignment) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci struct gl_buffer_object *st_obj = binding->BufferObject; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci if (st_obj && st_obj->buffer) { 50bf215546Sopenharmony_ci unsigned offset = 0; 51bf215546Sopenharmony_ci sb->buffer = st_obj->buffer; 52bf215546Sopenharmony_ci offset = binding->Offset % alignment; 53bf215546Sopenharmony_ci sb->buffer_offset = binding->Offset - offset; 54bf215546Sopenharmony_ci sb->buffer_size = st_obj->buffer->width0 - sb->buffer_offset; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci /* AutomaticSize is FALSE if the buffer was set with BindBufferRange. 57bf215546Sopenharmony_ci * Take the minimum just to be sure. 58bf215546Sopenharmony_ci */ 59bf215546Sopenharmony_ci if (!binding->AutomaticSize) 60bf215546Sopenharmony_ci sb->buffer_size = MIN2(sb->buffer_size, (unsigned) binding->Size + offset); 61bf215546Sopenharmony_ci } else { 62bf215546Sopenharmony_ci sb->buffer = NULL; 63bf215546Sopenharmony_ci sb->buffer_offset = 0; 64bf215546Sopenharmony_ci sb->buffer_size = 0; 65bf215546Sopenharmony_ci } 66bf215546Sopenharmony_ci} 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_cistatic void 69bf215546Sopenharmony_cist_bind_atomics(struct st_context *st, struct gl_program *prog, 70bf215546Sopenharmony_ci gl_shader_stage stage) 71bf215546Sopenharmony_ci{ 72bf215546Sopenharmony_ci unsigned i; 73bf215546Sopenharmony_ci enum pipe_shader_type shader_type = pipe_shader_type_from_mesa(stage); 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci if (!prog || !st->pipe->set_shader_buffers || st->has_hw_atomics) 76bf215546Sopenharmony_ci return; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci /* For !has_hw_atomics, the atomic counters have been rewritten to be above 79bf215546Sopenharmony_ci * the SSBOs used by the program. 80bf215546Sopenharmony_ci */ 81bf215546Sopenharmony_ci unsigned buffer_base = prog->info.num_ssbos; 82bf215546Sopenharmony_ci unsigned used_bindings = 0; 83bf215546Sopenharmony_ci for (i = 0; i < prog->sh.data->NumAtomicBuffers; i++) { 84bf215546Sopenharmony_ci struct gl_active_atomic_buffer *atomic = 85bf215546Sopenharmony_ci &prog->sh.data->AtomicBuffers[i]; 86bf215546Sopenharmony_ci struct pipe_shader_buffer sb; 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci st_binding_to_sb(&st->ctx->AtomicBufferBindings[atomic->Binding], &sb, 89bf215546Sopenharmony_ci st->ctx->Const.ShaderStorageBufferOffsetAlignment); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci st->pipe->set_shader_buffers(st->pipe, shader_type, 92bf215546Sopenharmony_ci buffer_base + atomic->Binding, 1, &sb, 0x1); 93bf215546Sopenharmony_ci used_bindings = MAX2(atomic->Binding + 1, used_bindings); 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci st->last_used_atomic_bindings[shader_type] = used_bindings; 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_civoid 99bf215546Sopenharmony_cist_bind_vs_atomics(struct st_context *st) 100bf215546Sopenharmony_ci{ 101bf215546Sopenharmony_ci struct gl_program *prog = 102bf215546Sopenharmony_ci st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci st_bind_atomics(st, prog, MESA_SHADER_VERTEX); 105bf215546Sopenharmony_ci} 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_civoid 108bf215546Sopenharmony_cist_bind_fs_atomics(struct st_context *st) 109bf215546Sopenharmony_ci{ 110bf215546Sopenharmony_ci struct gl_program *prog = 111bf215546Sopenharmony_ci st->ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci st_bind_atomics(st, prog, MESA_SHADER_FRAGMENT); 114bf215546Sopenharmony_ci} 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_civoid 117bf215546Sopenharmony_cist_bind_gs_atomics(struct st_context *st) 118bf215546Sopenharmony_ci{ 119bf215546Sopenharmony_ci struct gl_program *prog = 120bf215546Sopenharmony_ci st->ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci st_bind_atomics(st, prog, MESA_SHADER_GEOMETRY); 123bf215546Sopenharmony_ci} 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_civoid 126bf215546Sopenharmony_cist_bind_tcs_atomics(struct st_context *st) 127bf215546Sopenharmony_ci{ 128bf215546Sopenharmony_ci struct gl_program *prog = 129bf215546Sopenharmony_ci st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci st_bind_atomics(st, prog, MESA_SHADER_TESS_CTRL); 132bf215546Sopenharmony_ci} 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_civoid 135bf215546Sopenharmony_cist_bind_tes_atomics(struct st_context *st) 136bf215546Sopenharmony_ci{ 137bf215546Sopenharmony_ci struct gl_program *prog = 138bf215546Sopenharmony_ci st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci st_bind_atomics(st, prog, MESA_SHADER_TESS_EVAL); 141bf215546Sopenharmony_ci} 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_civoid 144bf215546Sopenharmony_cist_bind_cs_atomics(struct st_context *st) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci if (st->has_hw_atomics) { 147bf215546Sopenharmony_ci st_bind_hw_atomic_buffers(st); 148bf215546Sopenharmony_ci return; 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci struct gl_program *prog = 151bf215546Sopenharmony_ci st->ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci st_bind_atomics(st, prog, MESA_SHADER_COMPUTE); 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_civoid 157bf215546Sopenharmony_cist_bind_hw_atomic_buffers(struct st_context *st) 158bf215546Sopenharmony_ci{ 159bf215546Sopenharmony_ci struct pipe_shader_buffer buffers[PIPE_MAX_HW_ATOMIC_BUFFERS]; 160bf215546Sopenharmony_ci int i; 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci if (!st->has_hw_atomics) 163bf215546Sopenharmony_ci return; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci for (i = 0; i < st->ctx->Const.MaxAtomicBufferBindings; i++) 166bf215546Sopenharmony_ci st_binding_to_sb(&st->ctx->AtomicBufferBindings[i], &buffers[i], 1); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci st->pipe->set_hw_atomic_buffers(st->pipe, 0, st->ctx->Const.MaxAtomicBufferBindings, buffers); 169bf215546Sopenharmony_ci} 170