From c2ae9b4052701f8fde47947acb9ee47a878e1409 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Wed, 4 Jul 2018 10:21:41 +0100 Subject: [PATCH] nvc0: implement multisampled images on Maxwell+ Changes in v2: - make loadSuInfo32() protected without making the rest protected - move NVC0_SU_INFO_* into nv50_ir_lowering_nvc0.h instead of duplicating NVC0_SU_INFO_MS Signed-off-by: Rhys Perry Reviewed-by: Karol Herbst --- .../codegen/nv50_ir_lowering_gm107.cpp | 13 ++++++++ .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 31 ++----------------- .../nouveau/codegen/nv50_ir_lowering_nvc0.h | 31 ++++++++++++++++++- .../drivers/nouveau/nv50/nv50_resource.h | 1 + .../drivers/nouveau/nvc0/nvc0_screen.c | 7 ----- src/gallium/drivers/nouveau/nvc0/nvc0_tex.c | 4 +-- 6 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_gm107.cpp index 209f5c67ab0..c7436e2e297 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_gm107.cpp @@ -315,6 +315,19 @@ GM107LoweringPass::handleSUQ(TexInstruction *suq) samples->tex.query = TXQ_TYPE; } + if (suq->tex.target.isMS()) { + bld.setPosition(suq, true); + + if (mask & 0x1) + bld.mkOp2(OP_SHR, TYPE_U32, suq->getDef(0), suq->getDef(0), + loadSuInfo32(ind, slot, NVC0_SU_INFO_MS(0), suq->tex.bindless)); + if (mask & 0x2) { + int d = util_bitcount(mask & 0x1); + bld.mkOp2(OP_SHR, TYPE_U32, suq->getDef(d), suq->getDef(d), + loadSuInfo32(ind, slot, NVC0_SU_INFO_MS(1), suq->tex.bindless)); + } + } + return true; } diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp index 5723847234e..597dcdffbe2 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -1712,35 +1712,6 @@ NVC0LoweringPass::loadMsInfo32(Value *ptr, uint32_t off) mkLoadv(TYPE_U32, bld.mkSymbol(FILE_MEMORY_CONST, b, TYPE_U32, off), ptr); } -/* On nvc0, surface info is obtained via the surface binding points passed - * to the SULD/SUST instructions. - * On nve4, surface info is stored in c[] and is used by various special - * instructions, e.g. for clamping coordinates or generating an address. - * They couldn't just have added an equivalent to TIC now, couldn't they ? - */ -#define NVC0_SU_INFO_ADDR 0x00 -#define NVC0_SU_INFO_FMT 0x04 -#define NVC0_SU_INFO_DIM_X 0x08 -#define NVC0_SU_INFO_PITCH 0x0c -#define NVC0_SU_INFO_DIM_Y 0x10 -#define NVC0_SU_INFO_ARRAY 0x14 -#define NVC0_SU_INFO_DIM_Z 0x18 -#define NVC0_SU_INFO_UNK1C 0x1c -#define NVC0_SU_INFO_WIDTH 0x20 -#define NVC0_SU_INFO_HEIGHT 0x24 -#define NVC0_SU_INFO_DEPTH 0x28 -#define NVC0_SU_INFO_TARGET 0x2c -#define NVC0_SU_INFO_BSIZE 0x30 -#define NVC0_SU_INFO_RAW_X 0x34 -#define NVC0_SU_INFO_MS_X 0x38 -#define NVC0_SU_INFO_MS_Y 0x3c - -#define NVC0_SU_INFO__STRIDE 0x40 - -#define NVC0_SU_INFO_DIM(i) (0x08 + (i) * 8) -#define NVC0_SU_INFO_SIZE(i) (0x20 + (i) * 4) -#define NVC0_SU_INFO_MS(i) (0x38 + (i) * 4) - inline Value * NVC0LoweringPass::loadSuInfo32(Value *ptr, int slot, uint32_t off, bool bindless) { @@ -2349,6 +2320,8 @@ NVC0LoweringPass::processSurfaceCoordsGM107(TexInstruction *su) bld.setPosition(su, false); + adjustCoordinatesMS(su); + // add texture handle switch (su->op) { case OP_SUSTP: diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h index 91771fbf7e9..8724c09afd9 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h @@ -23,6 +23,35 @@ #include "codegen/nv50_ir.h" #include "codegen/nv50_ir_build_util.h" +/* On nvc0, surface info is obtained via the surface binding points passed + * to the SULD/SUST instructions. + * On nve4, surface info is stored in c[] and is used by various special + * instructions, e.g. for clamping coordinates or generating an address. + * They couldn't just have added an equivalent to TIC now, couldn't they ? + */ +#define NVC0_SU_INFO_ADDR 0x00 +#define NVC0_SU_INFO_FMT 0x04 +#define NVC0_SU_INFO_DIM_X 0x08 +#define NVC0_SU_INFO_PITCH 0x0c +#define NVC0_SU_INFO_DIM_Y 0x10 +#define NVC0_SU_INFO_ARRAY 0x14 +#define NVC0_SU_INFO_DIM_Z 0x18 +#define NVC0_SU_INFO_UNK1C 0x1c +#define NVC0_SU_INFO_WIDTH 0x20 +#define NVC0_SU_INFO_HEIGHT 0x24 +#define NVC0_SU_INFO_DEPTH 0x28 +#define NVC0_SU_INFO_TARGET 0x2c +#define NVC0_SU_INFO_BSIZE 0x30 +#define NVC0_SU_INFO_RAW_X 0x34 +#define NVC0_SU_INFO_MS_X 0x38 +#define NVC0_SU_INFO_MS_Y 0x3c + +#define NVC0_SU_INFO__STRIDE 0x40 + +#define NVC0_SU_INFO_DIM(i) (0x08 + (i) * 8) +#define NVC0_SU_INFO_SIZE(i) (0x20 + (i) * 4) +#define NVC0_SU_INFO_MS(i) (0x38 + (i) * 4) + namespace nv50_ir { class NVC0LegalizeSSA : public Pass @@ -119,6 +148,7 @@ protected: void handlePIXLD(Instruction *); void checkPredicate(Instruction *); + Value *loadSuInfo32(Value *ptr, int slot, uint32_t off, bool bindless); virtual bool visit(Instruction *); @@ -131,7 +161,6 @@ private: Value *loadResInfo32(Value *ptr, uint32_t off, uint16_t base); Value *loadResInfo64(Value *ptr, uint32_t off, uint16_t base); Value *loadResLength32(Value *ptr, uint32_t off, uint16_t base); - Value *loadSuInfo32(Value *ptr, int slot, uint32_t off, bool bindless); Value *loadBufInfo64(Value *ptr, uint32_t off); Value *loadBufLength32(Value *ptr, uint32_t off); Value *loadUboInfo64(Value *ptr, uint32_t off); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.h b/src/gallium/drivers/nouveau/nv50/nv50_resource.h index 5d03925b0d0..c64b045364f 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_resource.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.h @@ -66,6 +66,7 @@ nv50_miptree(struct pipe_resource *pt) #define NV50_TEXVIEW_SCALED_COORDS (1 << 0) #define NV50_TEXVIEW_FILTER_MSAA8 (1 << 1) #define NV50_TEXVIEW_ACCESS_RESOLVE (1 << 2) +#define NV50_TEXVIEW_IMAGE_GM107 (1 << 3) /* Internal functions: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index a217f9e1665..37e10dcd07f 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -85,13 +85,6 @@ nvc0_screen_is_format_supported(struct pipe_screen *pscreen, PIPE_BIND_SHARED); if (bindings & PIPE_BIND_SHADER_IMAGE) { - if (sample_count > 0 && - nouveau_screen(pscreen)->class_3d >= GM107_3D_CLASS) { - /* MS images are currently unsupported on Maxwell because they have to - * be handled explicitly. */ - return false; - } - if (format == PIPE_FORMAT_B8G8R8A8_UNORM && nouveau_screen(pscreen)->class_3d < NVE4_3D_CLASS) { /* This should work on Fermi, but for currently unknown reasons it diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c index e7cd60169e9..f40600e48aa 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c @@ -208,7 +208,7 @@ gm107_create_texture_view(struct pipe_context *pipe, GM107_TIC2_3_LOD_ANISO_QUALITY_HIGH | GM107_TIC2_3_LOD_ISO_QUALITY_HIGH; - if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) { + if (flags & (NV50_TEXVIEW_ACCESS_RESOLVE | NV50_TEXVIEW_IMAGE_GM107)) { width = mt->base.base.width0 << mt->ms_x; height = mt->base.base.height0 << mt->ms_y; } else { @@ -268,7 +268,7 @@ gm107_create_texture_view_from_image(struct pipe_context *pipe, templ.u.tex.first_level = templ.u.tex.last_level = view->u.tex.level; } - flags = NV50_TEXVIEW_SCALED_COORDS; + flags = NV50_TEXVIEW_SCALED_COORDS | NV50_TEXVIEW_IMAGE_GM107; return nvc0_create_texture_view(pipe, &res->base, &templ, flags, target); } -- 2.30.2