diff options
-rw-r--r-- | docs/GL3.txt | 2 | ||||
-rw-r--r-- | docs/relnotes/11.1.0.html | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_resource.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_surface.c | 92 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 5 |
7 files changed, 103 insertions, 8 deletions
diff --git a/docs/GL3.txt b/docs/GL3.txt index 845672b07d5..b768eea789a 100644 --- a/docs/GL3.txt +++ b/docs/GL3.txt @@ -177,7 +177,7 @@ GL 4.4, GLSL 4.40: GL_MAX_VERTEX_ATTRIB_STRIDE DONE (all drivers) GL_ARB_buffer_storage DONE (i965, nv50, nvc0, r600, radeonsi) - GL_ARB_clear_texture DONE (i965) (gallium - in progress, VMware) + GL_ARB_clear_texture DONE (i965, nv50, nvc0) GL_ARB_enhanced_layouts in progress (Timothy) - compile-time constant expressions in progress - explicit byte offsets for blocks in progress diff --git a/docs/relnotes/11.1.0.html b/docs/relnotes/11.1.0.html index 14656fd97c9..82ee3c4037b 100644 --- a/docs/relnotes/11.1.0.html +++ b/docs/relnotes/11.1.0.html @@ -46,6 +46,7 @@ Note: some of the new features are only available with certain drivers. <ul> <li>GL_ARB_arrays_of_arrays on i965</li> <li>GL_ARB_blend_func_extended on freedreno (a3xx)</li> +<li>GL_ARB_clear_texture on nv50, nvc0</li> <li>GL_ARB_copy_image on nv50, nvc0, radeonsi</li> <li>GL_ARB_gpu_shader_fp64 on r600 for Cypress/Cayman/Aruba chips</li> <li>GL_ARB_gpu_shader5 on r600 for Evergreen and later chips</li> 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; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 4a4d7025fa6..461fcaaf677 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -182,6 +182,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: case PIPE_CAP_FORCE_PERSAMPLE_INTERP: case PIPE_CAP_SHAREABLE_SHADERS: + case PIPE_CAP_CLEAR_TEXTURE: return 1; case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: return (class_3d >= NVE4_3D_CLASS) ? 1 : 0; @@ -204,7 +205,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VERTEXID_NOBASE: case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: - case PIPE_CAP_CLEAR_TEXTURE: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c index 5f47bad22f3..cdb1fc1145f 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c @@ -319,6 +319,7 @@ nvc0_clear_render_target(struct pipe_context *pipe, PUSH_DATA(push, dst->u.tex.first_layer + sf->depth); PUSH_DATA(push, mt->layer_stride >> 2); PUSH_DATA(push, dst->u.tex.first_layer); + IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), mt->ms_mode); } else { if (res->base.target == PIPE_BUFFER) { PUSH_DATA(push, 262144); @@ -334,6 +335,7 @@ nvc0_clear_render_target(struct pipe_context *pipe, PUSH_DATA(push, 0); IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0); /* tiled textures don't have to be fenced, they're not mapped directly */ nvc0_resource_fence(res, NOUVEAU_BO_WR); @@ -466,6 +468,7 @@ nvc0_clear_buffer(struct pipe_context *pipe, PUSH_DATA (push, 0); IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0); IMMED_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 0x3c); @@ -540,6 +543,7 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe, PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth)); BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1); PUSH_DATA (push, dst->u.tex.first_layer); + IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), mt->ms_mode); BEGIN_NIC0(push, NVC0_3D(CLEAR_BUFFERS), sf->depth); for (z = 0; z < sf->depth; ++z) { @@ -1541,5 +1545,6 @@ nvc0_init_surface_functions(struct nvc0_context *nvc0) pipe->flush_resource = nvc0_flush_resource; pipe->clear_render_target = nvc0_clear_render_target; pipe->clear_depth_stencil = nvc0_clear_depth_stencil; + pipe->clear_texture = nv50_clear_texture; pipe->clear_buffer = nvc0_clear_buffer; } |