[Mesa-dev] [RFC PATCH 22/65] mesa: handle bindless uniforms bound to texture/image units
Samuel Pitoiset
samuel.pitoiset at gmail.com
Fri May 26 12:10:10 UTC 2017
On 05/26/2017 11:09 AM, Nicolai Hähnle wrote:
> On 25.05.2017 12:51, Samuel Pitoiset wrote:
>> On 05/24/2017 01:01 PM, Nicolai Hähnle wrote:
>>> Something else just occurred to me. Do you have a test case where an
>>> array of bindless sampler uniforms is set at once with glUniform1iv?
>>
>> https://hastebin.com/jiduzevage
>>
>> Works fine.
>
> I really think this is pure chance (and I think I see why it works in
> the code), but in part it's because you didn't test rendering with a
> uniform array of samplers.
>
> On the second thought, the whole uni->is_bindless_handle design can't
> possibly work. Consider an array
>
> layout(bindless_texture) uniform sampler2D tex[2];
>
> which is bound with
>
> glUniform1i(loc, tex_unit);
> glUniformHandleui64ARB(loc + 1, handle);
>
> We don't need uni->is_bindless_handle; what we do need is that each of
> _mesa_uniform, _mesa_uniform_handle, and _mesa_get_uniform use size_mul
> == 2 unconditionally when the uniform is bindless.
Ah right, this can't fly. I will fix it.
Thanks.
>
> Cheers,
> Nicolai
>
>
>>> That should have a 32- vs. 64-bit mismatch when the user-supplied
>>> array is directly memcpy()'d to uni->storage. I think you need to fix
>>> that mismatch. On the plus side, that probably makes patch #23
>>> unnecessary.
>>
>> I don't see where a mismatch could happen actually.
>>
>>>
>>> Cheers,
>>> Nicolai
>>>
>>>
>>> On 19.05.2017 18:52, Samuel Pitoiset wrote:
>>>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>>>> ---
>>>> src/mesa/main/uniform_query.cpp | 122
>>>> ++++++++++++++++++++++++++++++++++++++--
>>>> 1 file changed, 116 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/src/mesa/main/uniform_query.cpp
>>>> b/src/mesa/main/uniform_query.cpp
>>>> index cc145f29e9..be04e48d53 100644
>>>> --- a/src/mesa/main/uniform_query.cpp
>>>> +++ b/src/mesa/main/uniform_query.cpp
>>>> @@ -993,9 +993,25 @@ _mesa_uniform(GLint location, GLsizei count,
>>>> const GLvoid *values,
>>>> bool changed = false;
>>>> for (int j = 0; j < count; j++) {
>>>> unsigned unit = uni->opaque[i].index + offset + j;
>>>> - if (sh->Program->SamplerUnits[unit] != ((unsigned *)
>>>> values)[j]) {
>>>> - sh->Program->SamplerUnits[unit] = ((unsigned *)
>>>> values)[j];
>>>> - changed = true;
>>>> + unsigned value = ((unsigned *)values)[j];
>>>> +
>>>> + if (uni->is_bindless) {
>>>> + struct gl_bindless_sampler *sampler =
>>>> + &sh->Program->sh.BindlessSamplers[unit];
>>>> +
>>>> + /* Mark this bindless sampler as bound to a texture
>>>> unit.
>>>> + */
>>>> + if (sampler->unit != value) {
>>>> + sampler->unit = value;
>>>> + changed = true;
>>>> + }
>>>> + sampler->bound = true;
>>>> + sh->Program->sh.HasBoundBindlessSampler = true;
>>>> + } else {
>>>> + if (sh->Program->SamplerUnits[unit] != value) {
>>>> + sh->Program->SamplerUnits[unit] = value;
>>>> + changed = true;
>>>> + }
>>>> }
>>>> }
>>>> @@ -1024,9 +1040,23 @@ _mesa_uniform(GLint location, GLsizei count,
>>>> const GLvoid *values,
>>>> if (!uni->opaque[i].active)
>>>> continue;
>>>> - for (int j = 0; j < count; j++)
>>>> - sh->Program->sh.ImageUnits[uni->opaque[i].index +
>>>> offset + j] =
>>>> - ((GLint *) values)[j];
>>>> + for (int j = 0; j < count; j++) {
>>>> + unsigned unit = uni->opaque[i].index + offset + j;
>>>> + unsigned value = ((unsigned *)values)[j];
>>>> +
>>>> + if (uni->is_bindless) {
>>>> + struct gl_bindless_image *image =
>>>> + &sh->Program->sh.BindlessImages[unit];
>>>> +
>>>> + /* Mark this bindless image as bound to an image unit.
>>>> + */
>>>> + image->unit = value;
>>>> + image->bound = true;
>>>> + sh->Program->sh.HasBoundBindlessImage = true;
>>>> + } else {
>>>> + sh->Program->sh.ImageUnits[unit] = value;
>>>> + }
>>>> + }
>>>> }
>>>> ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
>>>> @@ -1173,6 +1203,40 @@ _mesa_uniform_matrix(GLint location, GLsizei
>>>> count,
>>>> _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
>>>> }
>>>> +static void
>>>> +update_bound_bindless_sampler_flag(struct gl_program *prog)
>>>> +{
>>>> + unsigned i;
>>>> +
>>>> + if (likely(!prog->sh.HasBoundBindlessSampler))
>>>> + return;
>>>> +
>>>> + for (i = 0; i < prog->sh.NumBindlessSamplers; i++) {
>>>> + struct gl_bindless_sampler *sampler =
>>>> &prog->sh.BindlessSamplers[i];
>>>> +
>>>> + if (sampler->bound)
>>>> + return;
>>>> + }
>>>> + prog->sh.HasBoundBindlessSampler = false;
>>>> +}
>>>> +
>>>> +static void
>>>> +update_bound_bindless_image_flag(struct gl_program *prog)
>>>> +{
>>>> + unsigned i;
>>>> +
>>>> + if (likely(!prog->sh.HasBoundBindlessImage))
>>>> + return;
>>>> +
>>>> + for (i = 0; i < prog->sh.NumBindlessImages; i++) {
>>>> + struct gl_bindless_image *image = &prog->sh.BindlessImages[i];
>>>> +
>>>> + if (image->bound)
>>>> + return;
>>>> + }
>>>> + prog->sh.HasBoundBindlessImage = false;
>>>> +}
>>>> +
>>>> /**
>>>> * Called via glUniformHandleui64*ARB() functions.
>>>> */
>>>> @@ -1236,6 +1300,52 @@ _mesa_uniform_handle(GLint location, GLsizei
>>>> count, const GLvoid *values,
>>>> sizeof(uni->storage[0]) * components * count * size_mul);
>>>> _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
>>>> +
>>>> + if (uni->type->is_sampler()) {
>>>> + /* Mark this bindless sampler as not bound to a texture unit
>>>> because
>>>> + * it refers to a texture handle.
>>>> + */
>>>> + for (int i = 0; i < MESA_SHADER_STAGES; i++) {
>>>> + struct gl_linked_shader *const sh =
>>>> shProg->_LinkedShaders[i];
>>>> +
>>>> + /* If the shader stage doesn't use the sampler uniform,
>>>> skip this. */
>>>> + if (!uni->opaque[i].active)
>>>> + continue;
>>>> +
>>>> + for (int j = 0; j < count; j++) {
>>>> + unsigned unit = uni->opaque[i].index + offset + j;
>>>> + struct gl_bindless_sampler *sampler =
>>>> + &sh->Program->sh.BindlessSamplers[unit];
>>>> +
>>>> + sampler->bound = false;
>>>> + }
>>>> +
>>>> + update_bound_bindless_sampler_flag(sh->Program);
>>>> + }
>>>> + }
>>>> +
>>>> + if (uni->type->is_image()) {
>>>> + /* Mark this bindless image as not bound to an image unit
>>>> because it
>>>> + * refers to a texture handle.
>>>> + */
>>>> + for (int i = 0; i < MESA_SHADER_STAGES; i++) {
>>>> + struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
>>>> +
>>>> + /* If the shader stage doesn't use the sampler uniform,
>>>> skip this. */
>>>> + if (!uni->opaque[i].active)
>>>> + continue;
>>>> +
>>>> + for (int j = 0; j < count; j++) {
>>>> + unsigned unit = uni->opaque[i].index + offset + j;
>>>> + struct gl_bindless_image *image =
>>>> + &sh->Program->sh.BindlessImages[unit];
>>>> +
>>>> + image->bound = false;
>>>> + }
>>>> +
>>>> + update_bound_bindless_image_flag(sh->Program);
>>>> + }
>>>> + }
>>>> }
>>>> extern "C" bool
>>>>
>>>
>>>
>
>
More information about the mesa-dev
mailing list