diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index af2faea3bfe..6d00bd4de24 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -629,26 +629,14 @@ brw_emit_buffer_surface_state(struct brw_context *brw, .mocs = brw_get_bo_mocs(devinfo, bo)); } -void -brw_update_buffer_texture_surface(struct gl_context *ctx, - unsigned unit, - uint32_t *surf_offset) +static unsigned +buffer_texture_range_size(struct brw_context *brw, + struct gl_texture_object *obj) { - struct brw_context *brw = brw_context(ctx); - struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; - struct intel_buffer_object *intel_obj = - intel_buffer_object(tObj->BufferObject); - uint32_t size = tObj->BufferSize; - struct brw_bo *bo = NULL; - mesa_format format = tObj->_BufferObjectFormat; - const enum isl_format isl_format = brw_isl_format_for_mesa_format(format); - int texel_size = _mesa_get_format_bytes(format); - - if (intel_obj) { - size = MIN2(size, intel_obj->Base.Size); - bo = intel_bufferobj_buffer(brw, intel_obj, tObj->BufferOffset, size, - false); - } + assert(obj->Target == GL_TEXTURE_BUFFER); + const unsigned texel_size = _mesa_get_format_bytes(obj->_BufferObjectFormat); + const unsigned buffer_size = (!obj->BufferObject ? 0 : + obj->BufferObject->Size); /* The ARB_texture_buffer_specification says: * @@ -666,7 +654,29 @@ brw_update_buffer_texture_surface(struct gl_context *ctx, * so that when ISL divides by stride to obtain the number of texels, that * texel count is clamped to MAX_TEXTURE_BUFFER_SIZE. */ - size = MIN2(size, ctx->Const.MaxTextureBufferSize * (unsigned) texel_size); + return MIN3((unsigned)obj->BufferSize, + buffer_size - obj->BufferOffset, + brw->ctx.Const.MaxTextureBufferSize * texel_size); +} + +void +brw_update_buffer_texture_surface(struct gl_context *ctx, + unsigned unit, + uint32_t *surf_offset) +{ + struct brw_context *brw = brw_context(ctx); + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + struct intel_buffer_object *intel_obj = + intel_buffer_object(tObj->BufferObject); + const unsigned size = buffer_texture_range_size(brw, tObj); + struct brw_bo *bo = NULL; + mesa_format format = tObj->_BufferObjectFormat; + const enum isl_format isl_format = brw_isl_format_for_mesa_format(format); + int texel_size = _mesa_get_format_bytes(format); + + if (intel_obj) + bo = intel_bufferobj_buffer(brw, intel_obj, tObj->BufferOffset, size, + false); if (isl_format == ISL_FORMAT_UNSUPPORTED) { _mesa_problem(NULL, "bad format %s for texture buffer\n", @@ -1468,7 +1478,7 @@ update_buffer_image_param(struct brw_context *brw, struct brw_image_param *param) { struct gl_buffer_object *obj = u->TexObj->BufferObject; - const uint32_t size = MIN2((uint32_t)u->TexObj->BufferSize, obj->Size); + const unsigned size = buffer_texture_range_size(brw, u->TexObj); update_default_image_param(brw, u, surface_idx, param); param->size[0] = size / _mesa_get_format_bytes(u->_ActualFormat); @@ -1500,14 +1510,17 @@ update_image_surface(struct brw_context *brw, const unsigned format = get_image_format(brw, u->_ActualFormat, access); if (obj->Target == GL_TEXTURE_BUFFER) { - struct intel_buffer_object *intel_obj = - intel_buffer_object(obj->BufferObject); const unsigned texel_size = (format == ISL_FORMAT_RAW ? 1 : _mesa_get_format_bytes(u->_ActualFormat)); + const unsigned buffer_size = buffer_texture_range_size(brw, obj); + struct brw_bo *const bo = !obj->BufferObject ? NULL : + intel_bufferobj_buffer(brw, intel_buffer_object(obj->BufferObject), + obj->BufferOffset, buffer_size, + access != GL_READ_ONLY); brw_emit_buffer_surface_state( - brw, surf_offset, intel_obj->buffer, obj->BufferOffset, - format, intel_obj->Base.Size, texel_size, + brw, surf_offset, bo, obj->BufferOffset, + format, buffer_size, texel_size, access != GL_READ_ONLY ? RELOC_WRITE : 0); update_buffer_image_param(brw, u, surface_idx, param); diff --git a/src/mesa/main/shaderimage.c b/src/mesa/main/shaderimage.c index 596eadd4f85..054ab1d95e4 100644 --- a/src/mesa/main/shaderimage.c +++ b/src/mesa/main/shaderimage.c @@ -479,13 +479,6 @@ _mesa_is_image_unit_valid(struct gl_context *ctx, struct gl_image_unit *u) if (!t) return GL_FALSE; - /* The GL 4.5 Core spec doesn't say anything about buffers. In practice, - * the image buffer format is always compatible with the underlying - * buffer storage. - */ - if (t->Target == GL_TEXTURE_BUFFER) - return GL_TRUE; - if (!t->_BaseComplete && !t->_MipmapComplete) _mesa_test_texobj_completeness(ctx, t); @@ -499,14 +492,20 @@ _mesa_is_image_unit_valid(struct gl_context *ctx, struct gl_image_unit *u) u->_Layer >= _mesa_get_texture_layers(t, u->Level)) return GL_FALSE; - struct gl_texture_image *img = (t->Target == GL_TEXTURE_CUBE_MAP ? - t->Image[u->_Layer][u->Level] : - t->Image[0][u->Level]); + if (t->Target == GL_TEXTURE_BUFFER) { + tex_format = _mesa_get_shader_image_format(t->BufferObjectFormat); - if (!img || img->Border || img->NumSamples > ctx->Const.MaxImageSamples) - return GL_FALSE; + } else { + struct gl_texture_image *img = (t->Target == GL_TEXTURE_CUBE_MAP ? + t->Image[u->_Layer][u->Level] : + t->Image[0][u->Level]); + + if (!img || img->Border || img->NumSamples > ctx->Const.MaxImageSamples) + return GL_FALSE; + + tex_format = _mesa_get_shader_image_format(img->InternalFormat); + } - tex_format = _mesa_get_shader_image_format(img->InternalFormat); if (!tex_format) return GL_FALSE;