#include "util/u_inlines.h"
#include "util/u_cpu_detect.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/simple_list.h"
unsigned depth = pt->depth0;
uint64_t total_size = 0;
unsigned layers = pt->array_size;
+ unsigned num_samples = util_res_sample_count(pt);
+
/* XXX:
* This alignment here (same for displaytarget) was added for the purpose of
* ARB_map_buffer_alignment. I am not convinced it's needed for non-buffer
depth = u_minify(depth, 1);
}
+ lpr->sample_stride = total_size;
+ total_size *= num_samples;
+
if (allocate) {
lpr->tex_data = align_malloc(total_size, mip_align);
if (!lpr->tex_data) {
* Check the size of the texture specified by 'res'.
* \return TRUE if OK, FALSE if too large.
*/
-static boolean
+static bool
llvmpipe_can_create_resource(struct pipe_screen *screen,
const struct pipe_resource *res)
{
static boolean
llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
- struct llvmpipe_resource *lpr)
+ struct llvmpipe_resource *lpr,
+ const void *map_front_private)
{
struct sw_winsys *winsys = screen->winsys;
lpr->base.format,
width, height,
64,
+ map_front_private,
&lpr->row_stride[0] );
if (lpr->dt == NULL)
return FALSE;
- {
+ if (!map_front_private) {
void *map = winsys->displaytarget_map(winsys, lpr->dt,
PIPE_TRANSFER_WRITE);
static struct pipe_resource *
-llvmpipe_resource_create(struct pipe_screen *_screen,
- const struct pipe_resource *templat)
+llvmpipe_resource_create_front(struct pipe_screen *_screen,
+ const struct pipe_resource *templat,
+ const void *map_front_private)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED)) {
/* displayable surface */
- if (!llvmpipe_displaytarget_layout(screen, lpr))
+ if (!llvmpipe_displaytarget_layout(screen, lpr, map_front_private))
goto fail;
}
else {
}
+static struct pipe_resource *
+llvmpipe_resource_create(struct pipe_screen *_screen,
+ const struct pipe_resource *templat)
+{
+ return llvmpipe_resource_create_front(_screen, templat, NULL);
+}
+
+
static void
llvmpipe_resource_destroy(struct pipe_screen *pscreen,
struct pipe_resource *pt)
static struct pipe_resource *
llvmpipe_resource_from_handle(struct pipe_screen *screen,
const struct pipe_resource *template,
- struct winsys_handle *whandle)
+ struct winsys_handle *whandle,
+ unsigned usage)
{
struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
struct llvmpipe_resource *lpr;
}
-static boolean
+static bool
llvmpipe_resource_get_handle(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_resource *pt,
- struct winsys_handle *whandle)
+ struct winsys_handle *whandle,
+ unsigned usage)
{
struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
assert(lpr->dt);
if (!lpr->dt)
- return FALSE;
+ return false;
return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle);
}
-static void *
-llvmpipe_transfer_map( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- struct pipe_transfer **transfer )
+void *
+llvmpipe_transfer_map_ms( struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ unsigned sample,
+ const struct pipe_box *box,
+ struct pipe_transfer **transfer )
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
}
}
- /* Check if we're mapping the current constant buffer */
+ /* Check if we're mapping a current constant buffer */
if ((usage & PIPE_TRANSFER_WRITE) &&
(resource->bind & PIPE_BIND_CONSTANT_BUFFER)) {
unsigned i;
- for (i = 0; i < Elements(llvmpipe->constants[PIPE_SHADER_FRAGMENT]); ++i) {
+ for (i = 0; i < ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]); ++i) {
if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][i].buffer) {
/* constants may have changed */
- llvmpipe->dirty |= LP_NEW_CONSTANTS;
+ llvmpipe->dirty |= LP_NEW_FS_CONSTANTS;
break;
}
}
box->y / util_format_get_blockheight(format) * pt->stride +
box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+ map += sample * lpr->sample_stride;
return map;
}
+static void *
+llvmpipe_transfer_map( struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **transfer )
+{
+ return llvmpipe_transfer_map_ms(pipe, resource, level, usage, 0, box, transfer);
+}
static void
llvmpipe_transfer_unmap(struct pipe_context *pipe,
unsigned level)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
-
- /*
- * XXX checking only resources with the right bind flags
- * is unsafe since with opengl state tracker we can end up
- * with resources bound to places they weren't supposed to be
- * (buffers bound as sampler views is one possibility here).
- */
if (!(presource->bind & (PIPE_BIND_DEPTH_STENCIL |
PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_SAMPLER_VIEW)))
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_SHADER_BUFFER |
+ PIPE_BIND_SHADER_IMAGE)))
return LP_UNREFERENCED;
return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
bytes = size / 8;
- if (!util_is_power_of_two(bytes)) {
+ if (!util_is_power_of_two_or_zero(bytes)) {
bytes /= desc->nr_channels;
}
/**
* Create buffer which wraps user-space data.
+ * XXX unreachable.
*/
struct pipe_resource *
llvmpipe_user_buffer_create(struct pipe_screen *screen,
struct llvmpipe_resource *buffer;
buffer = CALLOC_STRUCT(llvmpipe_resource);
- if(!buffer)
+ if (!buffer)
return NULL;
pipe_reference_init(&buffer->base.reference, 1);
return size;
}
+static void
+llvmpipe_memory_barrier(struct pipe_context *pipe,
+ unsigned flags)
+{
+ /* this may be an overly large hammer for this nut. */
+ llvmpipe_finish(pipe, "barrier");
+}
#ifdef DEBUG
void
#endif
screen->resource_create = llvmpipe_resource_create;
+/* screen->resource_create_front = llvmpipe_resource_create_front; */
screen->resource_destroy = llvmpipe_resource_destroy;
screen->resource_from_handle = llvmpipe_resource_from_handle;
screen->resource_get_handle = llvmpipe_resource_get_handle;
pipe->transfer_unmap = llvmpipe_transfer_unmap;
pipe->transfer_flush_region = u_default_transfer_flush_region;
- pipe->transfer_inline_write = u_default_transfer_inline_write;
+ pipe->buffer_subdata = u_default_buffer_subdata;
+ pipe->texture_subdata = u_default_texture_subdata;
+
+ pipe->memory_barrier = llvmpipe_memory_barrier;
}