*/
#include "pipe/p_defines.h"
+#include "util/u_framebuffer.h"
#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
#include "nvc0/nvc0_query_hw.h"
#include "nvc0/nvc0_3d.xml.h"
-#include "nv50/nv50_texture.xml.h"
#include "nouveau_gldefs.h"
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->blend = hwcso;
- nvc0->dirty |= NVC0_NEW_BLEND;
+ nvc0->dirty_3d |= NVC0_NEW_3D_BLEND;
}
static void
if (cso->offset_point || cso->offset_line || cso->offset_tri) {
SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);
SB_DATA (so, fui(cso->offset_scale));
- SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
- SB_DATA (so, fui(cso->offset_units * 2.0f));
+ if (!cso->offset_units_unscaled) {
+ SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
+ SB_DATA (so, fui(cso->offset_units * 2.0f));
+ }
SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1);
SB_DATA (so, fui(cso->offset_clamp));
}
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->rast = hwcso;
- nvc0->dirty |= NVC0_NEW_RASTERIZER;
+ nvc0->dirty_3d |= NVC0_NEW_3D_RASTERIZER;
}
static void
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->zsa = hwcso;
- nvc0->dirty |= NVC0_NEW_ZSA;
+ nvc0->dirty_3d |= NVC0_NEW_3D_ZSA;
}
static void
{
unsigned s, i;
- for (s = 0; s < 5; ++s)
+ for (s = 0; s < 6; ++s)
for (i = 0; i < nvc0_context(pipe)->num_samplers[s]; ++i)
if (nvc0_context(pipe)->samplers[s][i] == hwcso)
nvc0_context(pipe)->samplers[s][i] = NULL;
nvc0->num_samplers[s] = nr;
- nvc0->dirty |= NVC0_NEW_SAMPLERS;
+ nvc0->dirty_3d |= NVC0_NEW_3D_SAMPLERS;
}
static void
continue;
nvc0->textures_dirty[s] |= 1 << i;
+ if (views[i] && views[i]->texture) {
+ struct pipe_resource *res = views[i]->texture;
+ if (res->target == PIPE_BUFFER &&
+ (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT))
+ nvc0->textures_coherent[s] |= 1 << i;
+ else
+ nvc0->textures_coherent[s] &= ~(1 << i);
+ } else {
+ nvc0->textures_coherent[s] &= ~(1 << i);
+ }
+
if (old) {
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i));
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i));
nvc0_screen_tic_unlock(nvc0->screen, old);
}
for (i = nr; i < nvc0->num_textures[s]; ++i) {
struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
if (old) {
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i));
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i));
nvc0_screen_tic_unlock(nvc0->screen, old);
pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
}
nvc0->num_textures[s] = nr;
- nvc0->dirty |= NVC0_NEW_TEXTURES;
+ nvc0->dirty_3d |= NVC0_NEW_3D_TEXTURES;
}
static void
{
struct nouveau_bufctx *bctx = (s == 5) ? nvc0->bufctx_cp : nvc0->bufctx_3d;
const unsigned end = start + nr;
- const unsigned bin = (s == 5) ? NVC0_BIND_CP_TEX(0) : NVC0_BIND_TEX(s, 0);
+ const unsigned bin = (s == 5) ? NVC0_BIND_CP_TEX(0) : NVC0_BIND_3D_TEX(s, 0);
int last_valid = -1;
unsigned i;
continue;
nvc0->textures_dirty[s] |= 1 << i;
+ if (views[p] && views[p]->texture) {
+ struct pipe_resource *res = views[p]->texture;
+ if (res->target == PIPE_BUFFER &&
+ (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT))
+ nvc0->textures_coherent[s] |= 1 << i;
+ else
+ nvc0->textures_coherent[s] &= ~(1 << i);
+ } else {
+ nvc0->textures_coherent[s] &= ~(1 << i);
+ }
+
if (nvc0->textures[s][i]) {
struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
nouveau_bufctx_reset(bctx, bin + i);
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->vertprog = hwcso;
- nvc0->dirty |= NVC0_NEW_VERTPROG;
+ nvc0->dirty_3d |= NVC0_NEW_3D_VERTPROG;
}
static void *
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->fragprog = hwcso;
- nvc0->dirty |= NVC0_NEW_FRAGPROG;
+ nvc0->dirty_3d |= NVC0_NEW_3D_FRAGPROG;
}
static void *
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->gmtyprog = hwcso;
- nvc0->dirty |= NVC0_NEW_GMTYPROG;
+ nvc0->dirty_3d |= NVC0_NEW_3D_GMTYPROG;
}
static void *
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->tctlprog = hwcso;
- nvc0->dirty |= NVC0_NEW_TCTLPROG;
+ nvc0->dirty_3d |= NVC0_NEW_3D_TCTLPROG;
}
static void *
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->tevlprog = hwcso;
- nvc0->dirty |= NVC0_NEW_TEVLPROG;
+ nvc0->dirty_3d |= NVC0_NEW_3D_TEVLPROG;
}
static void *
static void
nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_constant_buffer *cb)
+ const struct pipe_constant_buffer *cb)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
struct pipe_resource *res = cb ? cb->buffer : NULL;
const unsigned i = index;
if (unlikely(shader == PIPE_SHADER_COMPUTE)) {
- assert(!cb || !cb->user_buffer);
+ if (nvc0->constbuf[s][i].user)
+ nvc0->constbuf[s][i].u.buf = NULL;
+ else
if (nvc0->constbuf[s][i].u.buf)
nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_CB(i));
nvc0->constbuf[s][i].u.buf = NULL;
else
if (nvc0->constbuf[s][i].u.buf)
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(s, i));
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_CB(s, i));
- nvc0->dirty |= NVC0_NEW_CONSTBUF;
+ nvc0->dirty_3d |= NVC0_NEW_3D_CONSTBUF;
}
nvc0->constbuf_dirty[s] |= 1 << i;
nvc0->constbuf[s][i].u.data = cb->user_buffer;
nvc0->constbuf[s][i].size = MIN2(cb->buffer_size, 0x10000);
nvc0->constbuf_valid[s] |= 1 << i;
+ nvc0->constbuf_coherent[s] &= ~(1 << i);
} else
if (cb) {
nvc0->constbuf[s][i].offset = cb->buffer_offset;
nvc0->constbuf[s][i].size = MIN2(align(cb->buffer_size, 0x100), 0x10000);
nvc0->constbuf_valid[s] |= 1 << i;
+ if (res && res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
+ nvc0->constbuf_coherent[s] |= 1 << i;
+ else
+ nvc0->constbuf_coherent[s] &= ~(1 << i);
}
else {
nvc0->constbuf_valid[s] &= ~(1 << i);
+ nvc0->constbuf_coherent[s] &= ~(1 << i);
}
}
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->blend_colour = *bcol;
- nvc0->dirty |= NVC0_NEW_BLEND_COLOUR;
+ nvc0->dirty_3d |= NVC0_NEW_3D_BLEND_COLOUR;
}
static void
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->stencil_ref = *sr;
- nvc0->dirty |= NVC0_NEW_STENCIL_REF;
+ nvc0->dirty_3d |= NVC0_NEW_3D_STENCIL_REF;
}
static void
memcpy(nvc0->clip.ucp, clip->ucp, sizeof(clip->ucp));
- nvc0->dirty |= NVC0_NEW_CLIP;
+ nvc0->dirty_3d |= NVC0_NEW_3D_CLIP;
}
static void
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->sample_mask = sample_mask;
- nvc0->dirty |= NVC0_NEW_SAMPLE_MASK;
+ nvc0->dirty_3d |= NVC0_NEW_3D_SAMPLE_MASK;
}
static void
if (nvc0->min_samples != min_samples) {
nvc0->min_samples = min_samples;
- nvc0->dirty |= NVC0_NEW_MIN_SAMPLES;
+ nvc0->dirty_3d |= NVC0_NEW_3D_MIN_SAMPLES;
}
}
const struct pipe_framebuffer_state *fb)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- unsigned i;
-
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
-
- for (i = 0; i < fb->nr_cbufs; ++i)
- pipe_surface_reference(&nvc0->framebuffer.cbufs[i], fb->cbufs[i]);
- for (; i < nvc0->framebuffer.nr_cbufs; ++i)
- pipe_surface_reference(&nvc0->framebuffer.cbufs[i], NULL);
- nvc0->framebuffer.nr_cbufs = fb->nr_cbufs;
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB);
- nvc0->framebuffer.width = fb->width;
- nvc0->framebuffer.height = fb->height;
+ util_copy_framebuffer_state(&nvc0->framebuffer, fb);
- pipe_surface_reference(&nvc0->framebuffer.zsbuf, fb->zsbuf);
-
- nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
+ nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER;
}
static void
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->stipple = *stipple;
- nvc0->dirty |= NVC0_NEW_STIPPLE;
+ nvc0->dirty_3d |= NVC0_NEW_3D_STIPPLE;
}
static void
continue;
nvc0->scissors[start_slot + i] = scissor[i];
nvc0->scissors_dirty |= 1 << (start_slot + i);
- nvc0->dirty |= NVC0_NEW_SCISSOR;
+ nvc0->dirty_3d |= NVC0_NEW_3D_SCISSOR;
}
}
continue;
nvc0->viewports[start_slot + i] = vpt[i];
nvc0->viewports_dirty |= 1 << (start_slot + i);
- nvc0->dirty |= NVC0_NEW_VIEWPORT;
+ nvc0->dirty_3d |= NVC0_NEW_3D_VIEWPORT;
}
}
+static void
+nvc0_set_window_rectangles(struct pipe_context *pipe,
+ boolean include,
+ unsigned num_rectangles,
+ const struct pipe_scissor_state *rectangles)
+{
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
+
+ nvc0->window_rect.inclusive = include;
+ nvc0->window_rect.rects = MIN2(num_rectangles, NVC0_MAX_WINDOW_RECTANGLES);
+ memcpy(nvc0->window_rect.rect, rectangles,
+ sizeof(struct pipe_scissor_state) * nvc0->window_rect.rects);
+
+ nvc0->dirty_3d |= NVC0_NEW_3D_WINDOW_RECTS;
+}
+
static void
nvc0_set_tess_state(struct pipe_context *pipe,
const float default_tess_outer[4],
memcpy(nvc0->default_tess_outer, default_tess_outer, 4 * sizeof(float));
memcpy(nvc0->default_tess_inner, default_tess_inner, 2 * sizeof(float));
- nvc0->dirty |= NVC0_NEW_TESSFACTOR;
+ nvc0->dirty_3d |= NVC0_NEW_3D_TESSFACTOR;
}
static void
struct nvc0_context *nvc0 = nvc0_context(pipe);
unsigned i;
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
- nvc0->dirty |= NVC0_NEW_ARRAYS;
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_VTX);
+ nvc0->dirty_3d |= NVC0_NEW_3D_ARRAYS;
util_set_vertex_buffers_count(nvc0->vtxbuf, &nvc0->num_vtxbufs, vb,
start_slot, count);
if (!vb) {
nvc0->vbo_user &= ~(((1ull << count) - 1) << start_slot);
nvc0->constant_vbos &= ~(((1ull << count) - 1) << start_slot);
+ nvc0->vtxbufs_coherent &= ~(((1ull << count) - 1) << start_slot);
return;
}
nvc0->constant_vbos |= 1 << dst_index;
else
nvc0->constant_vbos &= ~(1 << dst_index);
+ nvc0->vtxbufs_coherent &= ~(1 << dst_index);
} else {
nvc0->vbo_user &= ~(1 << dst_index);
nvc0->constant_vbos &= ~(1 << dst_index);
+
+ if (vb[i].buffer &&
+ vb[i].buffer->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
+ nvc0->vtxbufs_coherent |= (1 << dst_index);
+ else
+ nvc0->vtxbufs_coherent &= ~(1 << dst_index);
}
}
}
struct nvc0_context *nvc0 = nvc0_context(pipe);
if (nvc0->idxbuf.buffer)
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_IDX);
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_IDX);
if (ib) {
pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
nvc0->idxbuf.index_size = ib->index_size;
if (ib->buffer) {
nvc0->idxbuf.offset = ib->offset;
- nvc0->dirty |= NVC0_NEW_IDXBUF;
+ nvc0->dirty_3d |= NVC0_NEW_3D_IDXBUF;
} else {
nvc0->idxbuf.user_buffer = ib->user_buffer;
- nvc0->dirty &= ~NVC0_NEW_IDXBUF;
+ nvc0->dirty_3d &= ~NVC0_NEW_3D_IDXBUF;
}
} else {
- nvc0->dirty &= ~NVC0_NEW_IDXBUF;
+ nvc0->dirty_3d &= ~NVC0_NEW_3D_IDXBUF;
pipe_resource_reference(&nvc0->idxbuf.buffer, NULL);
}
}
struct nvc0_context *nvc0 = nvc0_context(pipe);
nvc0->vertex = hwcso;
- nvc0->dirty |= NVC0_NEW_VERTEX;
+ nvc0->dirty_3d |= NVC0_NEW_3D_VERTEX;
}
static struct pipe_stream_output_target *
}
nvc0->num_tfbbufs = num_targets;
- if (nvc0->tfbbuf_dirty)
- nvc0->dirty |= NVC0_NEW_TFB_TARGETS;
+ if (nvc0->tfbbuf_dirty) {
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TFB);
+ nvc0->dirty_3d |= NVC0_NEW_3D_TFB_TARGETS;
+ }
}
static void
nvc0->surfaces_dirty[t] |= mask;
if (t == 0)
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_SUF);
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF);
else
nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
}
nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES;
}
+static bool
+nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s,
+ unsigned start, unsigned nr,
+ const struct pipe_image_view *pimages)
+{
+ const unsigned end = start + nr;
+ unsigned mask = 0;
+ unsigned i;
+
+ assert(s < 6);
+
+ if (pimages) {
+ for (i = start; i < end; ++i) {
+ struct pipe_image_view *img = &nvc0->images[s][i];
+ const unsigned p = i - start;
+
+ if (img->resource == pimages[p].resource &&
+ img->format == pimages[p].format &&
+ img->access == pimages[p].access) {
+ if (img->resource == NULL)
+ continue;
+ if (img->resource->target == PIPE_BUFFER &&
+ img->u.buf.first_element == pimages[p].u.buf.first_element &&
+ img->u.buf.last_element == pimages[p].u.buf.last_element)
+ continue;
+ if (img->resource->target != PIPE_BUFFER &&
+ img->u.tex.first_layer == pimages[p].u.tex.first_layer &&
+ img->u.tex.last_layer == pimages[p].u.tex.last_layer &&
+ img->u.tex.level == pimages[p].u.tex.level)
+ continue;
+ }
+
+ mask |= (1 << i);
+ if (pimages[p].resource)
+ nvc0->images_valid[s] |= (1 << i);
+ else
+ nvc0->images_valid[s] &= ~(1 << i);
+
+ img->format = pimages[p].format;
+ img->access = pimages[p].access;
+ if (pimages[p].resource && pimages[p].resource->target == PIPE_BUFFER)
+ img->u.buf = pimages[p].u.buf;
+ else
+ img->u.tex = pimages[p].u.tex;
+
+ pipe_resource_reference(
+ &img->resource, pimages[p].resource);
+ }
+ if (!mask)
+ return false;
+ } else {
+ mask = ((1 << nr) - 1) << start;
+ if (!(nvc0->images_valid[s] & mask))
+ return false;
+ for (i = start; i < end; ++i)
+ pipe_resource_reference(&nvc0->images[s][i].resource, NULL);
+ nvc0->images_valid[s] &= ~mask;
+ }
+ nvc0->images_dirty[s] |= mask;
+
+ if (s == 5)
+ nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
+ else
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF);
+
+ return true;
+}
+
static void
nvc0_set_shader_images(struct pipe_context *pipe, unsigned shader,
- unsigned start_slot, unsigned count,
- struct pipe_image_view **views)
+ unsigned start, unsigned nr,
+ const struct pipe_image_view *images)
+{
+ const unsigned s = nvc0_shader_stage(shader);
+ if (!nvc0_bind_images_range(nvc0_context(pipe), s, start, nr, images))
+ return;
+
+ if (s == 5)
+ nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES;
+ else
+ nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_SURFACES;
+}
+
+static bool
+nvc0_bind_buffers_range(struct nvc0_context *nvc0, const unsigned t,
+ unsigned start, unsigned nr,
+ const struct pipe_shader_buffer *pbuffers)
{
-#if 0
- nvc0_bind_surfaces_range(nvc0_context(pipe), 0, start, nr, views);
+ const unsigned end = start + nr;
+ unsigned mask = 0;
+ unsigned i;
+
+ assert(t < 6);
- nvc0_context(pipe)->dirty |= NVC0_NEW_SURFACES;
-#endif
+ if (pbuffers) {
+ for (i = start; i < end; ++i) {
+ struct pipe_shader_buffer *buf = &nvc0->buffers[t][i];
+ const unsigned p = i - start;
+ if (buf->buffer == pbuffers[p].buffer &&
+ buf->buffer_offset == pbuffers[p].buffer_offset &&
+ buf->buffer_size == pbuffers[p].buffer_size)
+ continue;
+
+ mask |= (1 << i);
+ if (pbuffers[p].buffer)
+ nvc0->buffers_valid[t] |= (1 << i);
+ else
+ nvc0->buffers_valid[t] &= ~(1 << i);
+ buf->buffer_offset = pbuffers[p].buffer_offset;
+ buf->buffer_size = pbuffers[p].buffer_size;
+ pipe_resource_reference(&buf->buffer, pbuffers[p].buffer);
+ }
+ if (!mask)
+ return false;
+ } else {
+ mask = ((1 << nr) - 1) << start;
+ if (!(nvc0->buffers_valid[t] & mask))
+ return false;
+ for (i = start; i < end; ++i)
+ pipe_resource_reference(&nvc0->buffers[t][i].buffer, NULL);
+ nvc0->buffers_valid[t] &= ~mask;
+ }
+ nvc0->buffers_dirty[t] |= mask;
+
+ if (t == 5)
+ nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_BUF);
+ else
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_BUF);
+
+ return true;
+}
+
+static void
+nvc0_set_shader_buffers(struct pipe_context *pipe,
+ unsigned shader,
+ unsigned start, unsigned nr,
+ const struct pipe_shader_buffer *buffers)
+{
+ const unsigned s = nvc0_shader_stage(shader);
+ if (!nvc0_bind_buffers_range(nvc0_context(pipe), s, start, nr, buffers))
+ return;
+
+ if (s == 5)
+ nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_BUFFERS;
+ else
+ nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_BUFFERS;
}
static inline void
nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_GLOBAL);
- nvc0->dirty_cp = NVC0_NEW_CP_GLOBALS;
+ nvc0->dirty_cp |= NVC0_NEW_CP_GLOBALS;
}
void
pipe->set_polygon_stipple = nvc0_set_polygon_stipple;
pipe->set_scissor_states = nvc0_set_scissor_states;
pipe->set_viewport_states = nvc0_set_viewport_states;
+ pipe->set_window_rectangles = nvc0_set_window_rectangles;
pipe->set_tess_state = nvc0_set_tess_state;
pipe->create_vertex_elements_state = nvc0_vertex_state_create;
pipe->set_global_binding = nvc0_set_global_bindings;
pipe->set_compute_resources = nvc0_set_compute_resources;
pipe->set_shader_images = nvc0_set_shader_images;
+ pipe->set_shader_buffers = nvc0_set_shader_buffers;
nvc0->sample_mask = ~0;
nvc0->min_samples = 1;