summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/nv50
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-11-09 12:39:05 -0500
committerIlia Mirkin <[email protected]>2015-11-11 19:20:41 -0500
commitc4182bb9b0897b4a4ac4f06b54fc7f6a2ddeb105 (patch)
tree6d5e91bf1d0851901a6ffb2c56642f9ab9beab25 /src/gallium/drivers/nouveau/nv50
parentae39b0fda81ce592b8c965b715469650d35e5fef (diff)
nv50,nvc0: add ARB_clear_texture support
Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/nv50')
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_resource.h7
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_surface.c92
3 files changed, 95 insertions, 6 deletions
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.h b/src/gallium/drivers/nouveau/nv50/nv50_resource.h
index a46e622c597..b40370a1d78 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_resource.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.h
@@ -151,4 +151,11 @@ nv50_surface_from_buffer(struct pipe_context *pipe,
void
nv50_surface_destroy(struct pipe_context *, struct pipe_surface *);
+void
+nv50_clear_texture(struct pipe_context *pipe,
+ struct pipe_resource *res,
+ unsigned level,
+ const struct pipe_box *box,
+ const void *data);
+
#endif /* __NV50_RESOURCE_H__ */
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index adf67b77bca..f47e998ab1e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -182,6 +182,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_TXQS:
case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
case PIPE_CAP_SHAREABLE_SHADERS:
+ case PIPE_CAP_CLEAR_TEXTURE:
return 1;
case PIPE_CAP_SEAMLESS_CUBE_MAP:
return 1; /* class_3d >= NVA0_3D_CLASS; */
@@ -218,7 +219,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
- case PIPE_CAP_CLEAR_TEXTURE:
return 0;
case PIPE_CAP_VENDOR_ID:
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index 237d76d6adb..916a7d44a31 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -27,6 +27,7 @@
#include "util/u_inlines.h"
#include "util/u_pack_color.h"
#include "util/u_format.h"
+#include "util/u_math.h"
#include "util/u_surface.h"
#include "tgsi/tgsi_ureg.h"
@@ -324,6 +325,9 @@ nv50_clear_render_target(struct pipe_context *pipe,
else
PUSH_DATA(push, 512);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
+ PUSH_DATA (push, mt->ms_mode);
+
if (!nouveau_bo_memtype(bo)) {
BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
PUSH_DATA (push, 0);
@@ -404,6 +408,9 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
PUSH_DATA (push, 512);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
+ PUSH_DATA (push, mt->ms_mode);
+
BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
PUSH_DATA (push, (width << 16) | dstx);
PUSH_DATA (push, (height << 16) | dsty);
@@ -418,6 +425,80 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
}
void
+nv50_clear_texture(struct pipe_context *pipe,
+ struct pipe_resource *res,
+ unsigned level,
+ const struct pipe_box *box,
+ const void *data)
+{
+ struct pipe_surface tmpl = {{0}}, *sf;
+
+ tmpl.format = res->format;
+ tmpl.u.tex.first_layer = box->z;
+ tmpl.u.tex.last_layer = box->z + box->depth - 1;
+ tmpl.u.tex.level = level;
+ sf = pipe->create_surface(pipe, res, &tmpl);
+ if (!sf)
+ return;
+
+ if (util_format_is_depth_or_stencil(res->format)) {
+ float depth = 0;
+ uint8_t stencil = 0;
+ unsigned clear = 0;
+ const struct util_format_description *desc =
+ util_format_description(res->format);
+
+ if (util_format_has_depth(desc)) {
+ clear |= PIPE_CLEAR_DEPTH;
+ desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
+ }
+ if (util_format_has_stencil(desc)) {
+ clear |= PIPE_CLEAR_STENCIL;
+ desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
+ }
+ pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil,
+ box->x, box->y, box->width, box->height);
+ } else {
+ union pipe_color_union color;
+
+ switch (util_format_get_blocksizebits(res->format)) {
+ case 128:
+ sf->format = PIPE_FORMAT_R32G32B32A32_UINT;
+ memcpy(&color.ui, data, 128 / 8);
+ break;
+ case 64:
+ sf->format = PIPE_FORMAT_R32G32_UINT;
+ memcpy(&color.ui, data, 64 / 8);
+ memset(&color.ui[2], 0, 64 / 8);
+ break;
+ case 32:
+ sf->format = PIPE_FORMAT_R32_UINT;
+ memcpy(&color.ui, data, 32 / 8);
+ memset(&color.ui[1], 0, 96 / 8);
+ break;
+ case 16:
+ sf->format = PIPE_FORMAT_R16_UINT;
+ color.ui[0] = util_cpu_to_le32(
+ util_le16_to_cpu(*(unsigned short *)data));
+ memset(&color.ui[1], 0, 96 / 8);
+ break;
+ case 8:
+ sf->format = PIPE_FORMAT_R8_UINT;
+ color.ui[0] = util_cpu_to_le32(*(unsigned char *)data);
+ memset(&color.ui[1], 0, 96 / 8);
+ break;
+ default:
+ assert(!"Unknown texel element size");
+ return;
+ }
+
+ pipe->clear_render_target(pipe, sf, &color,
+ box->x, box->y, box->width, box->height);
+ }
+ pipe->surface_destroy(pipe, sf);
+}
+
+void
nv50_clear(struct pipe_context *pipe, unsigned buffers,
const union pipe_color_union *color,
double depth, unsigned stencil)
@@ -464,11 +545,9 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
if (mode) {
int zs_layers = 0, color0_layers = 0;
if (fb->cbufs[0] && (mode & 0x3c))
- color0_layers = fb->cbufs[0]->u.tex.last_layer -
- fb->cbufs[0]->u.tex.first_layer + 1;
+ color0_layers = nv50_surface(fb->cbufs[0])->depth;
if (fb->zsbuf && (mode & ~0x3c))
- zs_layers = fb->zsbuf->u.tex.last_layer -
- fb->zsbuf->u.tex.first_layer + 1;
+ zs_layers = nv50_surface(fb->zsbuf)->depth;
for (j = 0; j < MIN2(zs_layers, color0_layers); j++) {
BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
@@ -488,7 +567,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
struct pipe_surface *sf = fb->cbufs[i];
if (!sf || !(buffers & (PIPE_CLEAR_COLOR0 << i)))
continue;
- for (j = 0; j <= sf->u.tex.last_layer - sf->u.tex.first_layer; j++) {
+ for (j = 0; j < nv50_surface(sf)->depth; j++) {
BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
PUSH_DATA (push, (i << 6) | 0x3c |
(j << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
@@ -585,6 +664,8 @@ nv50_clear_buffer(struct pipe_context *pipe,
PUSH_DATA (push, height);
BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
+ PUSH_DATA (push, 0);
/* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
@@ -1593,6 +1674,7 @@ nv50_init_surface_functions(struct nv50_context *nv50)
pipe->resource_copy_region = nv50_resource_copy_region;
pipe->blit = nv50_blit;
pipe->flush_resource = nv50_flush_resource;
+ pipe->clear_texture = nv50_clear_texture;
pipe->clear_render_target = nv50_clear_render_target;
pipe->clear_depth_stencil = nv50_clear_depth_stencil;
pipe->clear_buffer = nv50_clear_buffer;