diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index a9104a90095..6b64ba132c7 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -164,6 +164,107 @@ st_bufferobj_get_subdata(struct gl_context *ctx, offset, size, data); } + +/** + * Return bitmask of PIPE_BIND_x flags corresponding a GL buffer target. + */ +static unsigned +buffer_target_to_bind_flags(GLenum target) +{ + switch (target) { + case GL_PIXEL_PACK_BUFFER_ARB: + case GL_PIXEL_UNPACK_BUFFER_ARB: + return PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + case GL_ARRAY_BUFFER_ARB: + return PIPE_BIND_VERTEX_BUFFER; + case GL_ELEMENT_ARRAY_BUFFER_ARB: + return PIPE_BIND_INDEX_BUFFER; + case GL_TEXTURE_BUFFER: + return PIPE_BIND_SAMPLER_VIEW; + case GL_TRANSFORM_FEEDBACK_BUFFER: + return PIPE_BIND_STREAM_OUTPUT; + case GL_UNIFORM_BUFFER: + return PIPE_BIND_CONSTANT_BUFFER; + case GL_DRAW_INDIRECT_BUFFER: + case GL_PARAMETER_BUFFER_ARB: + return PIPE_BIND_COMMAND_ARGS_BUFFER; + case GL_ATOMIC_COUNTER_BUFFER: + case GL_SHADER_STORAGE_BUFFER: + return PIPE_BIND_SHADER_BUFFER; + case GL_QUERY_BUFFER: + return PIPE_BIND_QUERY_BUFFER; + default: + return 0; + } +} + + +/** + * Return bitmask of PIPE_RESOURCE_x flags corresponding to GL_MAP_x flags. + */ +static unsigned +storage_flags_to_buffer_flags(GLbitfield storageFlags) +{ + unsigned flags = 0; + if (storageFlags & GL_MAP_PERSISTENT_BIT) + flags |= PIPE_RESOURCE_FLAG_MAP_PERSISTENT; + if (storageFlags & GL_MAP_COHERENT_BIT) + flags |= PIPE_RESOURCE_FLAG_MAP_COHERENT; + if (storageFlags & GL_SPARSE_STORAGE_BIT_ARB) + flags |= PIPE_RESOURCE_FLAG_SPARSE; + return flags; +} + + +/** + * From a buffer object's target, immutability flag, storage flags and + * usage hint, return a pipe_resource_usage value (PIPE_USAGE_DYNAMIC, + * STREAM, etc). + */ +static const enum pipe_resource_usage +buffer_usage(GLenum target, GLboolean immutable, + GLbitfield storageFlags, GLenum usage) +{ + if (immutable) { + /* BufferStorage */ + if (storageFlags & GL_CLIENT_STORAGE_BIT) { + if (storageFlags & GL_MAP_READ_BIT) + return PIPE_USAGE_STAGING; + else + return PIPE_USAGE_STREAM; + } else { + return PIPE_USAGE_DEFAULT; + } + } + else { + /* BufferData */ + switch (usage) { + case GL_DYNAMIC_DRAW: + case GL_DYNAMIC_COPY: + return PIPE_USAGE_DYNAMIC; + case GL_STREAM_DRAW: + case GL_STREAM_COPY: + /* XXX: Remove this test and fall-through when we have PBO unpacking + * acceleration. Right now, PBO unpacking is done by the CPU, so we + * have to make sure CPU reads are fast. + */ + if (target != GL_PIXEL_UNPACK_BUFFER_ARB) { + return PIPE_USAGE_STREAM; + } + /* fall through */ + case GL_STATIC_READ: + case GL_DYNAMIC_READ: + case GL_STREAM_READ: + return PIPE_USAGE_STAGING; + case GL_STATIC_DRAW: + case GL_STATIC_COPY: + default: + return PIPE_USAGE_DEFAULT; + } + } +} + + static ALWAYS_INLINE GLboolean bufferobj_data(struct gl_context *ctx, GLenum target, @@ -180,7 +281,6 @@ bufferobj_data(struct gl_context *ctx, struct pipe_screen *screen = pipe->screen; struct st_buffer_object *st_obj = st_buffer_object(obj); struct st_memory_object *st_mem_obj = st_memory_object(memObj); - unsigned bind, pipe_usage, pipe_flags = 0; if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD && size && st_obj->buffer && @@ -206,97 +306,13 @@ bufferobj_data(struct gl_context *ctx, st_obj->Base.Usage = usage; st_obj->Base.StorageFlags = storageFlags; - switch (target) { - case GL_PIXEL_PACK_BUFFER_ARB: - case GL_PIXEL_UNPACK_BUFFER_ARB: - bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; - break; - case GL_ARRAY_BUFFER_ARB: - bind = PIPE_BIND_VERTEX_BUFFER; - break; - case GL_ELEMENT_ARRAY_BUFFER_ARB: - bind = PIPE_BIND_INDEX_BUFFER; - break; - case GL_TEXTURE_BUFFER: - bind = PIPE_BIND_SAMPLER_VIEW; - break; - case GL_TRANSFORM_FEEDBACK_BUFFER: - bind = PIPE_BIND_STREAM_OUTPUT; - break; - case GL_UNIFORM_BUFFER: - bind = PIPE_BIND_CONSTANT_BUFFER; - break; - case GL_DRAW_INDIRECT_BUFFER: - case GL_PARAMETER_BUFFER_ARB: - bind = PIPE_BIND_COMMAND_ARGS_BUFFER; - break; - case GL_ATOMIC_COUNTER_BUFFER: - case GL_SHADER_STORAGE_BUFFER: - bind = PIPE_BIND_SHADER_BUFFER; - break; - case GL_QUERY_BUFFER: - bind = PIPE_BIND_QUERY_BUFFER; - break; - default: - bind = 0; - } - - /* Set usage. */ - if (st_obj->Base.Immutable) { - /* BufferStorage */ - if (storageFlags & GL_CLIENT_STORAGE_BIT) { - if (storageFlags & GL_MAP_READ_BIT) - pipe_usage = PIPE_USAGE_STAGING; - else - pipe_usage = PIPE_USAGE_STREAM; - } else { - pipe_usage = PIPE_USAGE_DEFAULT; - } - } - else { - /* BufferData */ - switch (usage) { - case GL_STATIC_DRAW: - case GL_STATIC_COPY: - default: - pipe_usage = PIPE_USAGE_DEFAULT; - break; - case GL_DYNAMIC_DRAW: - case GL_DYNAMIC_COPY: - pipe_usage = PIPE_USAGE_DYNAMIC; - break; - case GL_STREAM_DRAW: - case GL_STREAM_COPY: - /* XXX: Remove this test and fall-through when we have PBO unpacking - * acceleration. Right now, PBO unpacking is done by the CPU, so we - * have to make sure CPU reads are fast. - */ - if (target != GL_PIXEL_UNPACK_BUFFER_ARB) { - pipe_usage = PIPE_USAGE_STREAM; - break; - } - /* fall through */ - case GL_STATIC_READ: - case GL_DYNAMIC_READ: - case GL_STREAM_READ: - pipe_usage = PIPE_USAGE_STAGING; - break; - } - } - - /* Set flags. */ - if (storageFlags & GL_MAP_PERSISTENT_BIT) - pipe_flags |= PIPE_RESOURCE_FLAG_MAP_PERSISTENT; - if (storageFlags & GL_MAP_COHERENT_BIT) - pipe_flags |= PIPE_RESOURCE_FLAG_MAP_COHERENT; - if (storageFlags & GL_SPARSE_STORAGE_BIT_ARB) - pipe_flags |= PIPE_RESOURCE_FLAG_SPARSE; - pipe_resource_reference( &st_obj->buffer, NULL ); + const unsigned bindings = buffer_target_to_bind_flags(target); + if (ST_DEBUG & DEBUG_BUFFER) { debug_printf("Create buffer size %" PRId64 " bind 0x%x\n", - (int64_t) size, bind); + (int64_t) size, bindings); } if (size != 0) { @@ -305,9 +321,10 @@ bufferobj_data(struct gl_context *ctx, memset(&buffer, 0, sizeof buffer); buffer.target = PIPE_BUFFER; buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */ - buffer.bind = bind; - buffer.usage = pipe_usage; - buffer.flags = pipe_flags; + buffer.bind = bindings; + buffer.usage = + buffer_usage(target, st_obj->Base.Immutable, storageFlags, usage); + buffer.flags = storage_flags_to_buffer_flags(storageFlags); buffer.width0 = size; buffer.height0 = 1; buffer.depth0 = 1;