gallium: add pipe_resource::nr_storage_samples, and set it same as nr_samples
Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
This commit is contained in:
@@ -69,6 +69,7 @@ void trace_dump_resource_template(const struct pipe_resource *templat)
|
||||
|
||||
trace_dump_member(uint, templat, last_level);
|
||||
trace_dump_member(uint, templat, nr_samples);
|
||||
trace_dump_member(uint, templat, nr_storage_samples);
|
||||
trace_dump_member(uint, templat, usage);
|
||||
trace_dump_member(uint, templat, bind);
|
||||
trace_dump_member(uint, templat, flags);
|
||||
|
@@ -240,7 +240,7 @@ pp_jimenezmlaa_init_run(struct pp_queue_t *ppq, unsigned int n,
|
||||
res.width0 = res.height0 = 165;
|
||||
res.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
res.usage = PIPE_USAGE_DEFAULT;
|
||||
res.depth0 = res.array_size = res.nr_samples = 1;
|
||||
res.depth0 = res.array_size = res.nr_samples = res.nr_storage_samples = 1;
|
||||
|
||||
if (!ppq->p->screen->is_format_supported(ppq->p->screen, res.format,
|
||||
res.target, 1, res.bind))
|
||||
|
@@ -319,6 +319,7 @@ util_dump_resource(FILE *stream, const struct pipe_resource *state)
|
||||
|
||||
util_dump_member(stream, uint, state, last_level);
|
||||
util_dump_member(stream, uint, state, nr_samples);
|
||||
util_dump_member(stream, uint, state, nr_storage_samples);
|
||||
util_dump_member(stream, uint, state, usage);
|
||||
util_dump_member(stream, uint, state, bind);
|
||||
util_dump_member(stream, uint, state, flags);
|
||||
|
@@ -55,6 +55,7 @@ util_create_texture2d(struct pipe_screen *screen, unsigned width,
|
||||
templ.depth0 = 1;
|
||||
templ.array_size = 1;
|
||||
templ.nr_samples = num_samples;
|
||||
templ.nr_storage_samples = num_samples;
|
||||
templ.format = format;
|
||||
templ.usage = PIPE_USAGE_DEFAULT;
|
||||
templ.bind = PIPE_BIND_SAMPLER_VIEW |
|
||||
|
@@ -789,8 +789,27 @@ For cube maps this must be 6, for other textures 1.
|
||||
|
||||
**last_level** the last mip map level present.
|
||||
|
||||
**nr_samples** the nr of msaa samples. 0 (or 1) specifies a resource
|
||||
which isn't multisampled.
|
||||
**nr_samples**: Number of samples determining quality, driving the rasterizer,
|
||||
shading, and framebuffer. It is the number of samples seen by the whole
|
||||
graphics pipeline. 0 and 1 specify a resource which isn't multisampled.
|
||||
|
||||
**nr_storage_samples**: Only color buffers can set this lower than nr_samples.
|
||||
Multiple samples within a pixel can have the same color. ``nr_storage_samples``
|
||||
determines how many slots for different colors there are per pixel.
|
||||
If there are not enough slots to store all sample colors, some samples will
|
||||
have an undefined color (called "undefined samples").
|
||||
|
||||
The resolve blit behavior is driver-specific, but can be one of these two:
|
||||
1. Only defined samples will be averaged. Undefined samples will be ignored.
|
||||
2. Undefined samples will be approximated by looking at surrounding defined
|
||||
samples (even in different pixels).
|
||||
|
||||
Blits and MSAA texturing: If the sample being fetched is undefined, one of
|
||||
the defined samples is returned instead.
|
||||
|
||||
Sample shading (``set_min_samples``) will operate at a sample frequency that
|
||||
is at most ``nr_storage_samples``. Greater ``min_samples`` values will be
|
||||
replaced by ``nr_storage_samples``.
|
||||
|
||||
**usage** one of the :ref:`PIPE_USAGE` flags.
|
||||
|
||||
|
@@ -519,7 +519,6 @@ struct pipe_box
|
||||
struct pipe_resource
|
||||
{
|
||||
struct pipe_reference reference;
|
||||
struct pipe_screen *screen; /**< screen that this texture belongs to */
|
||||
|
||||
unsigned width0; /**< Used by both buffers and textures. */
|
||||
uint16_t height0; /* Textures: The maximum height/depth/array_size is 16k. */
|
||||
@@ -529,9 +528,20 @@ struct pipe_resource
|
||||
enum pipe_format format:16; /**< PIPE_FORMAT_x */
|
||||
enum pipe_texture_target target:8; /**< PIPE_TEXTURE_x */
|
||||
unsigned last_level:8; /**< Index of last mipmap level present/defined */
|
||||
unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */
|
||||
unsigned usage:8; /**< PIPE_USAGE_x (not a bitmask) */
|
||||
|
||||
/** Number of samples determining quality, driving rasterizer, shading,
|
||||
* and framebuffer.
|
||||
*/
|
||||
unsigned nr_samples:8;
|
||||
|
||||
/** Multiple samples within a pixel can have the same value.
|
||||
* nr_storage_samples determines how many slots for different values
|
||||
* there are per pixel. Only color buffers can set this lower than
|
||||
* nr_samples.
|
||||
*/
|
||||
unsigned nr_storage_samples:8;
|
||||
|
||||
unsigned usage:8; /**< PIPE_USAGE_x (not a bitmask) */
|
||||
unsigned bind; /**< bitmask of PIPE_BIND_x */
|
||||
unsigned flags; /**< bitmask of PIPE_RESOURCE_FLAG_x */
|
||||
|
||||
@@ -540,6 +550,8 @@ struct pipe_resource
|
||||
* next plane.
|
||||
*/
|
||||
struct pipe_resource *next;
|
||||
/* The screen pointer should be last for optimal structure packing. */
|
||||
struct pipe_screen *screen; /**< screen that this texture belongs to */
|
||||
};
|
||||
|
||||
|
||||
|
@@ -832,6 +832,7 @@ dri2_allocate_textures(struct dri_context *ctx,
|
||||
templ.bind = drawable->textures[statt]->bind &
|
||||
~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED);
|
||||
templ.nr_samples = drawable->stvis.samples;
|
||||
templ.nr_storage_samples = drawable->stvis.samples;
|
||||
|
||||
/* Try to reuse the resource.
|
||||
* (the other resource parameters should be constant)
|
||||
@@ -883,10 +884,12 @@ dri2_allocate_textures(struct dri_context *ctx,
|
||||
|
||||
if (drawable->stvis.samples > 1) {
|
||||
templ.nr_samples = drawable->stvis.samples;
|
||||
templ.nr_storage_samples = drawable->stvis.samples;
|
||||
zsbuf = &drawable->msaa_textures[statt];
|
||||
}
|
||||
else {
|
||||
templ.nr_samples = 0;
|
||||
templ.nr_storage_samples = 0;
|
||||
zsbuf = &drawable->textures[statt];
|
||||
}
|
||||
|
||||
|
@@ -136,6 +136,7 @@ xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
|
||||
templ.array_size = 1;
|
||||
templ.last_level = 0;
|
||||
templ.nr_samples = xstfb->stvis.samples;
|
||||
templ.nr_storage_samples = xstfb->stvis.samples;
|
||||
|
||||
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
|
||||
enum pipe_format format;
|
||||
|
@@ -121,6 +121,7 @@ NineBuffer9_ctor( struct NineBuffer9 *This,
|
||||
info->array_size = 1;
|
||||
info->last_level = 0;
|
||||
info->nr_samples = 0;
|
||||
info->nr_storage_samples = 0;
|
||||
|
||||
hr = NineResource9_ctor(&This->base, pParams, NULL, TRUE,
|
||||
Type, Pool, Usage);
|
||||
|
@@ -90,6 +90,7 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This,
|
||||
info->last_level = util_logbase2(EdgeLength);
|
||||
info->array_size = 6;
|
||||
info->nr_samples = 0;
|
||||
info->nr_storage_samples = 0;
|
||||
info->bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
info->usage = PIPE_USAGE_DEFAULT;
|
||||
info->flags = 0;
|
||||
|
@@ -3008,7 +3008,7 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
|
||||
templ.bind = PIPE_BIND_STREAM_OUTPUT;
|
||||
templ.usage = PIPE_USAGE_STREAM;
|
||||
templ.height0 = templ.depth0 = templ.array_size = 1;
|
||||
templ.last_level = templ.nr_samples = 0;
|
||||
templ.last_level = templ.nr_samples = templ.nr_storage_samples = 0;
|
||||
|
||||
resource = screen_sw->resource_create(screen_sw, &templ);
|
||||
if (!resource)
|
||||
|
@@ -104,6 +104,7 @@ NineSurface9_ctor( struct NineSurface9 *This,
|
||||
This->base.info.last_level = 0;
|
||||
This->base.info.array_size = 1;
|
||||
This->base.info.nr_samples = multisample_type;
|
||||
This->base.info.nr_storage_samples = multisample_type;
|
||||
This->base.info.usage = PIPE_USAGE_DEFAULT;
|
||||
This->base.info.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */
|
||||
|
||||
@@ -803,6 +804,7 @@ NineSurface9_SetResourceResize( struct NineSurface9 *This,
|
||||
This->desc.Width = This->base.info.width0 = resource->width0;
|
||||
This->desc.Height = This->base.info.height0 = resource->height0;
|
||||
This->base.info.nr_samples = resource->nr_samples;
|
||||
This->base.info.nr_storage_samples = resource->nr_storage_samples;
|
||||
|
||||
This->stride = nine_format_get_stride(This->base.info.format,
|
||||
This->desc.Width);
|
||||
|
@@ -307,6 +307,7 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This,
|
||||
for (i = 0; i < newBufferCount; ++i) {
|
||||
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||
tmplt.nr_samples = multisample_type;
|
||||
tmplt.nr_storage_samples = multisample_type;
|
||||
if (!has_present_buffers)
|
||||
tmplt.bind |= NINE_BIND_PRESENTBUFFER_FLAGS;
|
||||
tmplt.format = d3d9_to_pipe_format_checked(This->screen,
|
||||
@@ -345,6 +346,7 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This,
|
||||
tmplt.format = PIPE_FORMAT_B8G8R8X8_UNORM;
|
||||
tmplt.bind = NINE_BIND_PRESENTBUFFER_FLAGS;
|
||||
tmplt.nr_samples = 0;
|
||||
tmplt.nr_storage_samples = 0;
|
||||
if (This->actx->linear_framebuffer)
|
||||
tmplt.bind |= PIPE_BIND_LINEAR;
|
||||
if (pParams->SwapEffect != D3DSWAPEFFECT_DISCARD)
|
||||
@@ -361,6 +363,7 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This,
|
||||
if (pParams->EnableAutoDepthStencil) {
|
||||
tmplt.bind = d3d9_get_pipe_depth_format_bindings(pParams->AutoDepthStencilFormat);
|
||||
tmplt.nr_samples = multisample_type;
|
||||
tmplt.nr_storage_samples = multisample_type;
|
||||
tmplt.format = d3d9_to_pipe_format_checked(This->screen,
|
||||
pParams->AutoDepthStencilFormat,
|
||||
PIPE_TEXTURE_2D,
|
||||
|
@@ -131,6 +131,7 @@ NineTexture9_ctor( struct NineTexture9 *This,
|
||||
info->last_level = util_logbase2(MAX2(Width, Height));
|
||||
info->array_size = 1;
|
||||
info->nr_samples = 0;
|
||||
info->nr_storage_samples = 0;
|
||||
info->bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
info->usage = PIPE_USAGE_DEFAULT;
|
||||
info->flags = 0;
|
||||
|
@@ -92,6 +92,7 @@ NineVolume9_ctor( struct NineVolume9 *This,
|
||||
This->info.last_level = 0;
|
||||
This->info.array_size = 1;
|
||||
This->info.nr_samples = 0;
|
||||
This->info.nr_storage_samples = 0;
|
||||
This->info.usage = PIPE_USAGE_DEFAULT;
|
||||
This->info.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
This->info.flags = 0;
|
||||
|
@@ -88,6 +88,7 @@ NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This,
|
||||
info->last_level = util_logbase2(MAX2(MAX2(Width, Height), Depth));
|
||||
info->array_size = 1;
|
||||
info->nr_samples = 0;
|
||||
info->nr_storage_samples = 0;
|
||||
info->bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
info->usage = PIPE_USAGE_DEFAULT;
|
||||
info->flags = 0;
|
||||
|
@@ -95,6 +95,7 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
|
||||
templ.array_size = 1;
|
||||
templ.last_level = 0;
|
||||
templ.nr_samples = stwfb->stvis.samples;
|
||||
templ.nr_storage_samples = stwfb->stvis.samples;;
|
||||
|
||||
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
|
||||
enum pipe_format format;
|
||||
|
@@ -73,7 +73,6 @@ static void init( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
|
@@ -301,7 +301,6 @@ static void init_tex( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
|
||||
|
||||
@@ -411,7 +410,6 @@ static void init( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
|
@@ -77,7 +77,6 @@ graw_util_create_window(struct graw_info *info,
|
||||
resource_temp.depth0 = 1;
|
||||
resource_temp.array_size = 1;
|
||||
resource_temp.last_level = 0;
|
||||
resource_temp.nr_samples = 1;
|
||||
resource_temp.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
info->color_buf[i] = info->screen->resource_create(info->screen,
|
||||
@@ -109,7 +108,6 @@ graw_util_create_window(struct graw_info *info,
|
||||
resource_temp.depth0 = 1;
|
||||
resource_temp.array_size = 1;
|
||||
resource_temp.last_level = 0;
|
||||
resource_temp.nr_samples = 1;
|
||||
resource_temp.bind = PIPE_BIND_DEPTH_STENCIL;
|
||||
info->zs_buf = info->screen->resource_create(info->screen, &resource_temp);
|
||||
if (!info->zs_buf) {
|
||||
@@ -233,7 +231,6 @@ graw_util_create_tex2d(const struct graw_info *info,
|
||||
temp.depth0 = 1;
|
||||
temp.last_level = 0;
|
||||
temp.array_size = 1;
|
||||
temp.nr_samples = 1;
|
||||
temp.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
|
||||
tex = info->screen->resource_create(info->screen, &temp);
|
||||
|
@@ -158,7 +158,6 @@ static void init_fs_constbuf( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = PIPE_BIND_CONSTANT_BUFFER;
|
||||
|
||||
constbuf1 = screen->resource_create(screen, &templat);
|
||||
@@ -392,7 +391,6 @@ static void init_tex( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
|
||||
|
||||
@@ -502,7 +500,6 @@ static void init( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
|
@@ -216,7 +216,6 @@ static void init_tex( void )
|
||||
templat.height0 = SIZE;
|
||||
templat.depth0 = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
|
||||
|
||||
@@ -326,7 +325,6 @@ static void init( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
|
@@ -199,7 +199,6 @@ static void init( void )
|
||||
templat.height0 = HEIGHT;
|
||||
templat.depth0 = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
|
@@ -207,7 +207,6 @@ static void init( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
|
@@ -258,7 +258,6 @@ static void init( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
|
@@ -90,7 +90,6 @@ static void init_fs_constbuf( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = PIPE_BIND_CONSTANT_BUFFER;
|
||||
|
||||
constbuf = screen->resource_create(screen,
|
||||
@@ -290,7 +289,6 @@ static void init_tex( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
|
||||
|
||||
@@ -400,7 +398,6 @@ static void init( void )
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
|
@@ -360,7 +360,7 @@ same_size_and_swizzle(const struct util_format_description *d1,
|
||||
|
||||
static struct pipe_resource *
|
||||
create_texture(struct pipe_screen *screen, enum pipe_format format,
|
||||
unsigned nr_samples,
|
||||
unsigned nr_samples, unsigned nr_storage_samples,
|
||||
unsigned width, unsigned height, unsigned depth)
|
||||
{
|
||||
struct pipe_resource templ;
|
||||
@@ -372,6 +372,7 @@ create_texture(struct pipe_screen *screen, enum pipe_format format,
|
||||
templ.depth0 = 1;
|
||||
templ.array_size = depth;
|
||||
templ.nr_samples = nr_samples;
|
||||
templ.nr_storage_samples = nr_storage_samples;
|
||||
templ.usage = PIPE_USAGE_DEFAULT;
|
||||
templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||
|
||||
@@ -443,7 +444,7 @@ handle_complex_copy(struct pipe_context *pipe,
|
||||
* then proceed the generic swizzled_copy.
|
||||
*/
|
||||
temp = create_texture(pipe->screen, canon_format, src->nr_samples,
|
||||
src_box->width,
|
||||
src->nr_storage_samples, src_box->width,
|
||||
src_box->height, src_box->depth);
|
||||
|
||||
u_box_3d(0, 0, 0, src_box->width, src_box->height, src_box->depth,
|
||||
@@ -468,7 +469,7 @@ handle_complex_copy(struct pipe_context *pipe,
|
||||
/* Use the temporary texture. First, use the generic copy, but use
|
||||
* a canonical format in the destination. Then convert */
|
||||
temp = create_texture(pipe->screen, canon_format, dst->nr_samples,
|
||||
src_box->width,
|
||||
dst->nr_storage_samples, src_box->width,
|
||||
src_box->height, src_box->depth);
|
||||
|
||||
u_box_3d(0, 0, 0, src_box->width, src_box->height, src_box->depth,
|
||||
|
@@ -204,6 +204,8 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx,
|
||||
templ.depth0 = 1;
|
||||
templ.array_size = 1;
|
||||
templ.nr_samples = rb->NumSamples;
|
||||
templ.nr_storage_samples = rb->NumSamples;
|
||||
|
||||
if (util_format_is_depth_or_stencil(format)) {
|
||||
templ.bind = PIPE_BIND_DEPTH_STENCIL;
|
||||
}
|
||||
|
@@ -2791,6 +2791,7 @@ st_texture_create_from_memory(struct st_context *st,
|
||||
/* only set this for OpenGL textures, not renderbuffers */
|
||||
pt.flags = PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY;
|
||||
pt.nr_samples = nr_samples;
|
||||
pt.nr_storage_samples = nr_samples;
|
||||
|
||||
newtex = screen->resource_from_memobj(screen, &pt, memObj->memory, offset);
|
||||
|
||||
@@ -2956,6 +2957,7 @@ st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
|
||||
pt.target = gl_target_to_pipe(target);
|
||||
pt.format = st_mesa_format_to_pipe_format(st, format);
|
||||
pt.nr_samples = numSamples;
|
||||
pt.nr_storage_samples = numSamples;
|
||||
|
||||
st_gl_texture_dims_to_pipe_dims(target,
|
||||
width, height, depth,
|
||||
|
@@ -95,6 +95,7 @@ st_texture_create(struct st_context *st,
|
||||
/* only set this for OpenGL textures, not renderbuffers */
|
||||
pt.flags = PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY;
|
||||
pt.nr_samples = nr_samples;
|
||||
pt.nr_storage_samples = nr_samples;
|
||||
|
||||
newtex = screen->resource_create(screen, &pt);
|
||||
|
||||
|
Reference in New Issue
Block a user