Commit 6303231a authored by Charmaine Lee's avatar Charmaine Lee Committed by Brian Paul

svga: add DXGenMips command support

For those formats that support hw mipmap generation, use the
DXGenMips command. Otherwise fallback to the mipmap generation utility.

Tested with piglit, OpenGL apps (Heaven, Turbine, Cinebench)

v2: make sure the texture surface was created with the render target bind flag
    set relocation flag to SVGA_RELOC_WRITE for the texture surface
Reviewed-by: Brian Paul's avatarBrian Paul <brianp@vmware.com>
Reviewed-by: Jose Fonseca's avatarJose Fonseca <jfonseca@vmware.com>
parent 78e628ae
......@@ -638,4 +638,8 @@ SVGA3D_vgpu10_UpdateSubResource(struct svga_winsys_context *swc,
const SVGA3dBox *box,
unsigned subResource);
enum pipe_error
SVGA3D_vgpu10_GenMips(struct svga_winsys_context *swc,
const SVGA3dShaderResourceViewId shaderResourceViewId,
struct svga_winsys_surface *view);
#endif /* __SVGA3D_H__ */
......@@ -1293,3 +1293,24 @@ SVGA3D_vgpu10_UpdateSubResource(struct svga_winsys_context *swc,
swc->commit(swc);
return PIPE_OK;
}
enum pipe_error
SVGA3D_vgpu10_GenMips(struct svga_winsys_context *swc,
SVGA3dShaderResourceViewId shaderResourceViewId,
struct svga_winsys_surface *view)
{
SVGA3dCmdDXGenMips *cmd;
cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_GENMIPS,
sizeof(SVGA3dCmdDXGenMips), 1);
if (!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
swc->surface_relocation(swc, &cmd->shaderResourceViewId, NULL, view,
SVGA_RELOC_WRITE);
cmd->shaderResourceViewId = shaderResourceViewId;
swc->commit(swc);
return PIPE_OK;
}
This diff is collapsed.
......@@ -52,6 +52,10 @@ struct svga_screen;
#define VF_PUINT_TO_USCALED (1 << 6) /* 10_10_10_2 to uscaled */
#define VF_PUINT_TO_SSCALED (1 << 7) /* 10_10_10_2 to sscaled */
/**
* Texture format flags.
*/
#define TF_GEN_MIPS (1 << 8) /* supports hw generate mipmap */
void
svga_translate_vertex_format_vgpu10(enum pipe_format format,
......@@ -80,6 +84,9 @@ svga_format_name(SVGA3dSurfaceFormat format);
boolean
svga_format_is_integer(SVGA3dSurfaceFormat format);
boolean
svga_format_support_gen_mips(enum pipe_format format);
enum tgsi_return_type
svga_get_texture_datatype(enum pipe_format format);
......
......@@ -107,6 +107,12 @@ svga_init_resource_functions(struct svga_context *svga)
svga->pipe.transfer_flush_region = u_transfer_flush_region_vtbl;
svga->pipe.transfer_unmap = u_transfer_unmap_vtbl;
svga->pipe.transfer_inline_write = u_transfer_inline_write_vtbl;
if (svga_have_vgpu10(svga)) {
svga->pipe.generate_mipmap = svga_texture_generate_mipmap;
} else {
svga->pipe.generate_mipmap = NULL;
}
}
void
......
......@@ -993,3 +993,61 @@ svga_texture_from_handle(struct pipe_screen *screen,
return &tex->b.b;
}
boolean
svga_texture_generate_mipmap(struct pipe_context *pipe,
struct pipe_resource *pt,
enum pipe_format format,
unsigned base_level,
unsigned last_level,
unsigned first_layer,
unsigned last_layer)
{
struct pipe_sampler_view templ, *psv;
struct svga_pipe_sampler_view *sv;
struct svga_context *svga = svga_context(pipe);
struct svga_texture *tex = svga_texture(pt);
enum pipe_error ret;
assert(svga_have_vgpu10(svga));
/* Only support 2D texture for now */
if (pt->target != PIPE_TEXTURE_2D)
return FALSE;
/* Fallback to the mipmap generation utility for those formats that
* do not support hw generate mipmap
*/
if (!svga_format_support_gen_mips(format))
return FALSE;
/* Make sure the texture surface was created with
* SVGA3D_SURFACE_BIND_RENDER_TARGET
*/
if (!tex->handle || !(tex->key.flags & SVGA3D_SURFACE_BIND_RENDER_TARGET))
return FALSE;
templ.format = format;
templ.u.tex.first_layer = first_layer;
templ.u.tex.last_layer = last_layer;
templ.u.tex.first_level = base_level;
templ.u.tex.last_level = last_level;
psv = pipe->create_sampler_view(pipe, pt, &templ);
if (psv == NULL)
return FALSE;
sv = svga_pipe_sampler_view(psv);
svga_validate_pipe_sampler_view(svga, sv);
ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
}
pipe_sampler_view_reference(&psv, NULL);
svga->hud.num_generate_mipmap++;
return TRUE;
}
......@@ -217,7 +217,14 @@ svga_texture_from_handle(struct pipe_screen * screen,
const struct pipe_resource *template,
struct winsys_handle *whandle);
boolean
svga_texture_generate_mipmap(struct pipe_context *pipe,
struct pipe_resource *pt,
enum pipe_format format,
unsigned base_level,
unsigned last_level,
unsigned first_layer,
unsigned last_layer);
#endif /* SVGA_TEXTURE_H */
......@@ -35,6 +35,7 @@
struct pipe_context;
struct pipe_screen;
struct svga_context;
struct svga_pipe_sampler_view;
struct svga_winsys_surface;
struct svga_surface;
enum SVGA3dSurfaceFormat;
......@@ -102,4 +103,9 @@ boolean
svga_check_sampler_view_resource_collision(struct svga_context *svga,
struct svga_winsys_surface *res,
unsigned shader);
enum pipe_error
svga_validate_pipe_sampler_view(struct svga_context *svga,
struct svga_pipe_sampler_view *sv);
#endif
......@@ -319,6 +319,9 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_PRIMITIVE_RESTART:
return 1; /* may be a sw fallback, depending on restart index */
case PIPE_CAP_GENERATE_MIPMAP:
return sws->have_vgpu10;
/* Unsupported features */
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
......@@ -392,7 +395,6 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_DRAW_PARAMETERS:
case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
case PIPE_CAP_GENERATE_MIPMAP:
return 0;
}
......
......@@ -90,7 +90,7 @@ svga_check_sampler_view_resource_collision(struct svga_context *svga,
* Create a DX ShaderResourceSamplerView for the given pipe_sampler_view,
* if needed.
*/
static enum pipe_error
enum pipe_error
svga_validate_pipe_sampler_view(struct svga_context *svga,
struct svga_pipe_sampler_view *sv)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment